|
|
@ -20,10 +20,13 @@ const (
|
|
|
|
|
|
|
|
|
|
|
|
type Conf struct {
|
|
|
|
type Conf struct {
|
|
|
|
Cases []struct {
|
|
|
|
Cases []struct {
|
|
|
|
|
|
|
|
Outputs []struct {
|
|
|
|
Score int
|
|
|
|
Score int
|
|
|
|
StdoutPath string
|
|
|
|
FileName string
|
|
|
|
|
|
|
|
AnswerPath string
|
|
|
|
IgnoreWhitespace bool
|
|
|
|
IgnoreWhitespace bool
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type Diff struct{}
|
|
|
|
type Diff struct{}
|
|
|
@ -43,25 +46,20 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) (
|
|
|
|
for i, caseConf := range conf.Cases {
|
|
|
|
for i, caseConf := range conf.Cases {
|
|
|
|
result := results[i]
|
|
|
|
result := results[i]
|
|
|
|
score := 0
|
|
|
|
score := 0
|
|
|
|
var comment string
|
|
|
|
comment := ""
|
|
|
|
|
|
|
|
for _, output := range caseConf.Outputs {
|
|
|
|
stdout, err := os.ReadFile(caseConf.StdoutPath)
|
|
|
|
answer, err := os.ReadFile(output.AnswerPath)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return nil, true, err
|
|
|
|
return nil, true, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
comment = fmt.Sprintf(
|
|
|
|
|
|
|
|
"executor status: run time: %d ns, memory: %d bytes\n",
|
|
|
|
|
|
|
|
result.RunTime, result.Memory,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If no difference, assign score
|
|
|
|
// If no difference, assign score
|
|
|
|
if compareChars(string(stdout), result.Files["stdout"], caseConf.IgnoreWhitespace) {
|
|
|
|
if compareChars(string(answer), result.Files[output.FileName], output.IgnoreWhitespace) {
|
|
|
|
score = caseConf.Score
|
|
|
|
score += output.Score
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Convert stdout to string and split by lines
|
|
|
|
// Convert answer to string and split by lines
|
|
|
|
stdoutLines := strings.Split(string(stdout), "\n")
|
|
|
|
stdoutLines := strings.Split(string(answer), "\n")
|
|
|
|
resultLines := strings.Split(result.Files["stdout"], "\n")
|
|
|
|
resultLines := strings.Split(result.Files[output.FileName], "\n")
|
|
|
|
|
|
|
|
|
|
|
|
// Generate Myers diff
|
|
|
|
// Generate Myers diff
|
|
|
|
diffOps := myersDiff(stdoutLines, resultLines)
|
|
|
|
diffOps := myersDiff(stdoutLines, resultLines)
|
|
|
@ -69,10 +67,11 @@ func (*Diff) Run(results []stage.ExecutorResult, confAny any) (
|
|
|
|
// Generate diff block with surrounding context
|
|
|
|
// Generate diff block with surrounding context
|
|
|
|
diffOutput := generateDiffWithContext(stdoutLines, resultLines, diffOps)
|
|
|
|
diffOutput := generateDiffWithContext(stdoutLines, resultLines, diffOps)
|
|
|
|
comment += fmt.Sprintf(
|
|
|
|
comment += fmt.Sprintf(
|
|
|
|
"difference found:\n```diff\n%s```",
|
|
|
|
"difference found in %s:\n```diff\n%s```\n",
|
|
|
|
diffOutput,
|
|
|
|
output.FileName, diffOutput,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res = append(res, stage.ParserResult{
|
|
|
|
res = append(res, stage.ParserResult{
|
|
|
|
Score: score,
|
|
|
|
Score: score,
|
|
|
|