feat: option ignoring whitespace
This commit is contained in:
		
							parent
							
								
									756a531bac
								
							
						
					
					
						commit
						96c71bcd63
					
				|  | @ -4,6 +4,7 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"strings" | 	"strings" | ||||||
|  | 	"unicode" | ||||||
| 
 | 
 | ||||||
| 	"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" | 	"focs.ji.sjtu.edu.cn/git/FOCS-dev/JOJ3/internal/stage" | ||||||
| ) | ) | ||||||
|  | @ -12,6 +13,7 @@ type Conf struct { | ||||||
| 	Cases []struct { | 	Cases []struct { | ||||||
| 		Score            int | 		Score            int | ||||||
| 		StdoutPath       string | 		StdoutPath       string | ||||||
|  | 		ignoreWhitespace bool | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -43,8 +45,9 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) ( | ||||||
| 			"executor status: run time: %d ns, memory: %d bytes\n", | 			"executor status: run time: %d ns, memory: %d bytes\n", | ||||||
| 			result.RunTime, result.Memory, | 			result.RunTime, result.Memory, | ||||||
| 		) | 		) | ||||||
|  | 
 | ||||||
| 		// If no difference, assign score
 | 		// If no difference, assign score
 | ||||||
| 		if string(stdout) == result.Files["stdout"] { | 		if compareChars(string(stdout), result.Files["stdout"], caseConf.ignoreWhitespace) { | ||||||
| 			score = caseConf.Score | 			score = caseConf.Score | ||||||
| 		} else { | 		} else { | ||||||
| 			// Convert stdout to string and split by lines
 | 			// Convert stdout to string and split by lines
 | ||||||
|  | @ -52,7 +55,7 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) ( | ||||||
| 			resultLines := strings.Split(result.Files["stdout"], "\n") | 			resultLines := strings.Split(result.Files["stdout"], "\n") | ||||||
| 
 | 
 | ||||||
| 			// Find the first difference
 | 			// Find the first difference
 | ||||||
| 			diffIndex := findFirstDifferenceIndex(stdoutLines, resultLines) | 			diffIndex := findFirstDifferenceIndex(stdoutLines, resultLines, caseConf.ignoreWhitespace) | ||||||
| 			if diffIndex != -1 { | 			if diffIndex != -1 { | ||||||
| 				// Generate diff block with surrounding context
 | 				// Generate diff block with surrounding context
 | ||||||
| 				diffOutput := generateDiffWithContext(stdoutLines, resultLines, diffIndex, 10) | 				diffOutput := generateDiffWithContext(stdoutLines, resultLines, diffIndex, 10) | ||||||
|  | @ -73,15 +76,43 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) ( | ||||||
| 	return res, false, nil | 	return res, false, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // compareChars compares two strings character by character, optionally ignoring whitespace.
 | ||||||
|  | func compareChars(stdout, result string, ignoreWhitespace bool) bool { | ||||||
|  | 	if ignoreWhitespace { | ||||||
|  | 		stdout = removeWhitespace(stdout) | ||||||
|  | 		result = removeWhitespace(result) | ||||||
|  | 	} | ||||||
|  | 	return stdout == result | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // removeWhitespace removes all whitespace characters from the string.
 | ||||||
|  | func removeWhitespace(s string) string { | ||||||
|  | 	var b strings.Builder | ||||||
|  | 	for _, r := range s { | ||||||
|  | 		if !unicode.IsSpace(r) { | ||||||
|  | 			b.WriteRune(r) | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	return b.String() | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // findFirstDifferenceIndex finds the index of the first line where stdout and result differ.
 | // findFirstDifferenceIndex finds the index of the first line where stdout and result differ.
 | ||||||
| func findFirstDifferenceIndex(stdoutLines, resultLines []string) int { | func findFirstDifferenceIndex(stdoutLines, resultLines []string, ignoreWhitespace bool) int { | ||||||
| 	maxLines := len(stdoutLines) | 	maxLines := len(stdoutLines) | ||||||
| 	if len(resultLines) > maxLines { | 	if len(resultLines) > maxLines { | ||||||
| 		maxLines = len(resultLines) | 		maxLines = len(resultLines) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	for i := 0; i < maxLines; i++ { | 	for i := 0; i < maxLines; i++ { | ||||||
| 		if i >= len(stdoutLines) || i >= len(resultLines) || stdoutLines[i] != resultLines[i] { | 		stdoutLine := stdoutLines[i] | ||||||
|  | 		resultLine := resultLines[i] | ||||||
|  | 
 | ||||||
|  | 		if ignoreWhitespace { | ||||||
|  | 			stdoutLine = removeWhitespace(stdoutLine) | ||||||
|  | 			resultLine = removeWhitespace(resultLine) | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if stdoutLine != resultLine { | ||||||
| 			return i | 			return i | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -103,74 +134,43 @@ func generateDiffWithContext(stdoutLines, resultLines []string, index, contextSi | ||||||
| 
 | 
 | ||||||
| 	// Adding context before the diff
 | 	// Adding context before the diff
 | ||||||
| 	for i := start; i < index; i++ { | 	for i := start; i < index; i++ { | ||||||
| 		if i < len(stdoutLines) || i < len(resultLines) { | 		stdoutLine, resultLine := getLine(stdoutLines, resultLines, i) | ||||||
| 			stdoutLine := "" |  | ||||||
| 			if i < len(stdoutLines) { |  | ||||||
| 				stdoutLine = stdoutLines[i] |  | ||||||
| 			} |  | ||||||
| 			resultLine := "" |  | ||||||
| 			if i < len(resultLines) { |  | ||||||
| 				resultLine = resultLines[i] |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		if stdoutLine != resultLine { | 		if stdoutLine != resultLine { | ||||||
| 				if stdoutLine != "" { |  | ||||||
| 			diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine)) | 			diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine)) | ||||||
| 				} |  | ||||||
| 				if resultLine != "" { |  | ||||||
| 			diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine)) | 			diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine)) | ||||||
| 				} |  | ||||||
| 		} else { | 		} else { | ||||||
| 			diffBuilder.WriteString(fmt.Sprintf("  %s\n", stdoutLine)) | 			diffBuilder.WriteString(fmt.Sprintf("  %s\n", stdoutLine)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// Adding the diff line
 | 	// Adding the diff line
 | ||||||
| 	if index < len(stdoutLines) || index < len(resultLines) { | 	stdoutLine, resultLine := getLine(stdoutLines, resultLines, index) | ||||||
| 		stdoutLine := "" |  | ||||||
| 		if index < len(stdoutLines) { |  | ||||||
| 			stdoutLine = stdoutLines[index] |  | ||||||
| 		} |  | ||||||
| 		resultLine := "" |  | ||||||
| 		if index < len(resultLines) { |  | ||||||
| 			resultLine = resultLines[index] |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 	if stdoutLine != resultLine { | 	if stdoutLine != resultLine { | ||||||
| 			if stdoutLine != "" { |  | ||||||
| 		diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine)) | 		diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine)) | ||||||
| 			} |  | ||||||
| 			if resultLine != "" { |  | ||||||
| 		diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine)) | 		diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine)) | ||||||
| 	} | 	} | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// Adding context after the diff
 | 	// Adding context after the diff
 | ||||||
| 	for i := index + 1; i < end; i++ { | 	for i := index + 1; i < end; i++ { | ||||||
| 		if i < len(stdoutLines) || i < len(resultLines) { | 		stdoutLine, resultLine := getLine(stdoutLines, resultLines, i) | ||||||
| 			stdoutLine := "" |  | ||||||
| 			if i < len(stdoutLines) { |  | ||||||
| 				stdoutLine = stdoutLines[i] |  | ||||||
| 			} |  | ||||||
| 			resultLine := "" |  | ||||||
| 			if i < len(resultLines) { |  | ||||||
| 				resultLine = resultLines[i] |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		if stdoutLine != resultLine { | 		if stdoutLine != resultLine { | ||||||
| 				if stdoutLine != "" { |  | ||||||
| 			diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine)) | 			diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine)) | ||||||
| 				} |  | ||||||
| 				if resultLine != "" { |  | ||||||
| 			diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine)) | 			diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine)) | ||||||
| 				} |  | ||||||
| 		} else { | 		} else { | ||||||
| 			diffBuilder.WriteString(fmt.Sprintf("  %s\n", stdoutLine)) | 			diffBuilder.WriteString(fmt.Sprintf("  %s\n", stdoutLine)) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	return diffBuilder.String() | 	return diffBuilder.String() | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | // getLine safely retrieves lines from both stdout and result
 | ||||||
|  | func getLine(stdoutLines, resultLines []string, i int) (stdoutLine, resultLine string) { | ||||||
|  | 	if i < len(stdoutLines) { | ||||||
|  | 		stdoutLine = stdoutLines[i] | ||||||
|  | 	} | ||||||
|  | 	if i < len(resultLines) { | ||||||
|  | 		resultLine = resultLines[i] | ||||||
|  | 	} | ||||||
|  | 	return | ||||||
|  | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 zzjc1234
						zzjc1234