feat: option ignoring whitespace
This commit is contained in:
parent
756a531bac
commit
96c71bcd63
|
@ -4,14 +4,16 @@ 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"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Conf struct {
|
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 stdoutLine != resultLine {
|
||||||
if i < len(stdoutLines) {
|
diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine))
|
||||||
stdoutLine = stdoutLines[i]
|
diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine))
|
||||||
}
|
} else {
|
||||||
resultLine := ""
|
diffBuilder.WriteString(fmt.Sprintf(" %s\n", stdoutLine))
|
||||||
if i < len(resultLines) {
|
|
||||||
resultLine = resultLines[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
if stdoutLine != resultLine {
|
|
||||||
if stdoutLine != "" {
|
|
||||||
diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine))
|
|
||||||
}
|
|
||||||
if resultLine != "" {
|
|
||||||
diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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 stdoutLine != resultLine {
|
||||||
if index < len(stdoutLines) {
|
diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine))
|
||||||
stdoutLine = stdoutLines[index]
|
diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine))
|
||||||
}
|
|
||||||
resultLine := ""
|
|
||||||
if index < len(resultLines) {
|
|
||||||
resultLine = resultLines[index]
|
|
||||||
}
|
|
||||||
|
|
||||||
if stdoutLine != resultLine {
|
|
||||||
if stdoutLine != "" {
|
|
||||||
diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine))
|
|
||||||
}
|
|
||||||
if 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 stdoutLine != resultLine {
|
||||||
if i < len(stdoutLines) {
|
diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine))
|
||||||
stdoutLine = stdoutLines[i]
|
diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine))
|
||||||
}
|
} else {
|
||||||
resultLine := ""
|
diffBuilder.WriteString(fmt.Sprintf(" %s\n", stdoutLine))
|
||||||
if i < len(resultLines) {
|
|
||||||
resultLine = resultLines[i]
|
|
||||||
}
|
|
||||||
|
|
||||||
if stdoutLine != resultLine {
|
|
||||||
if stdoutLine != "" {
|
|
||||||
diffBuilder.WriteString(fmt.Sprintf("- %s\n", stdoutLine))
|
|
||||||
}
|
|
||||||
if resultLine != "" {
|
|
||||||
diffBuilder.WriteString(fmt.Sprintf("+ %s\n", resultLine))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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