1
1
package commands
2
2
3
3
import (
4
- "bufio"
5
4
"bytes"
6
5
"errors"
7
6
"fmt"
8
7
"github.com/chermehdi/egor/config"
8
+ "github.com/fatih/color"
9
+ "github.com/jedib0t/go-pretty/table"
9
10
"io/ioutil"
10
11
"os"
11
12
"os/exec"
23
24
WA int8 = 3
24
25
)
25
26
27
+ var (
28
+ green = color .New (color .FgGreen ).SprintfFunc ()
29
+ red = color .New (color .FgRed ).SprintfFunc ()
30
+ magenta = color .New (color .FgMagenta ).SprintfFunc ()
31
+ yellow = color .New (color .FgYellow ).SprintfFunc ()
32
+ )
33
+
26
34
// Checks the output of a given testcase against it's expected output
27
35
type Checker interface {
28
36
// Execute the check (got, expected) and returns
@@ -36,8 +44,8 @@ type DiffChecker struct {
36
44
37
45
func (c * DiffChecker ) Check (got , expected string ) error {
38
46
// Compare the trimmed output from both input and output
39
- if strings .Trim (got , " \t \n \r " ) != strings .Trim (expected , " \t \n \r " ) {
40
- return errors .New (fmt .Sprintf ("Checker failed, expected %s, found %s" , got , expected ))
47
+ if strings .TrimRight (got , " \t \n \r " ) != strings .TrimRight (expected , " \t \n \r " ) {
48
+ return errors .New (fmt .Sprintf ("Checker failed, expected: \n %s \n found: \n %s" , expected , got ))
41
49
}
42
50
return nil
43
51
}
@@ -94,21 +102,56 @@ type Judge interface {
94
102
95
103
// This represents the result of running the testcases of a given task
96
104
type JudgeReport interface {
97
- Add (status CaseStatus )
105
+ // Add the pair To the list of executions processed
106
+ Add (status CaseStatus , description CaseDescription )
98
107
99
- Display () string
108
+ // Display the current report to os.Stdout
109
+ Display ()
100
110
}
101
111
102
112
type ConsoleJudgeReport struct {
103
113
Stats []CaseStatus
114
+ Descs []CaseDescription
104
115
}
105
116
106
- func (c * ConsoleJudgeReport ) Add (status CaseStatus ) {
117
+ func (c * ConsoleJudgeReport ) Add (status CaseStatus , description CaseDescription ) {
107
118
c .Stats = append (c .Stats , status )
119
+ c .Descs = append (c .Descs , description )
108
120
}
109
121
110
- func (c * ConsoleJudgeReport ) Display () string {
111
- panic ("implement me" )
122
+ func getDisplayStatus (status int8 ) string {
123
+ switch status {
124
+ case AC :
125
+ return green ("AC" )
126
+ case RE :
127
+ return magenta ("RE" )
128
+ case SK :
129
+ return yellow ("SK" )
130
+ case WA :
131
+ return red ("WA" )
132
+ }
133
+ return "Unknown"
134
+ }
135
+
136
+ func (c * ConsoleJudgeReport ) Display () {
137
+ t := table .NewWriter ()
138
+ t .SetOutputMirror (os .Stdout )
139
+ t .AppendHeader (table.Row {"#" , "Test Name" , "Status" , "Custom" , "Additional infos" })
140
+ for i , stat := range c .Stats {
141
+ output := "None"
142
+ if stat .CheckerError != nil {
143
+ output = fmt .Sprintf ("FAILED, %s" , stat .CheckerError .Error ())
144
+ }
145
+ t .AppendRow ([]interface {}{
146
+ i ,
147
+ c .Descs [i ].InputFile ,
148
+ getDisplayStatus (stat .Status ),
149
+ c .Descs [i ].CustomCase ,
150
+ output ,
151
+ })
152
+ }
153
+ t .SetStyle (table .StyleLight )
154
+ t .Render ()
112
155
}
113
156
114
157
func newJudgeReport () JudgeReport {
@@ -130,14 +173,18 @@ func (judge *JavaJudge) Setup() error {
130
173
return err
131
174
}
132
175
workDirPath := path .Join (currentDir , "work" )
133
- if err = os .Mkdir (workDirPath , 777 ); err != nil {
176
+ if err = os .Mkdir (workDirPath , 0777 ); err != nil {
134
177
return err
135
178
}
136
179
//TODO(chermehdi): make the executables path configurable #14
137
-
138
180
// Compilation for Java
139
- cmd := exec .Command ("javac" , judge .Meta .TaskFile , "-d" , workDirPath )
181
+ var stderrBuffer bytes.Buffer
182
+ cmd := exec .Command ("javac" , judge .Meta .TaskFile , "-d" , "work" )
183
+ cmd .Dir = currentDir
184
+ fmt .Printf ("javac %s -d \" %s\" \n " , judge .Meta .TaskFile , workDirPath )
185
+ cmd .Stderr = & stderrBuffer
140
186
if err = cmd .Run (); err != nil {
187
+ color .Red ("Could not compile %s, Cause: \n " , stderrBuffer .String ())
141
188
return err
142
189
}
143
190
judge .CurrentWorkDir = workDirPath
@@ -146,8 +193,7 @@ func (judge *JavaJudge) Setup() error {
146
193
147
194
func (judge * JavaJudge ) RunTestCase (desc CaseDescription ) CaseStatus {
148
195
// We suppose that all java executables will be called Main
149
- execFilePath := path .Join (judge .CurrentWorkDir , "Main" )
150
- cmd := exec .Command ("java" , execFilePath )
196
+ cmd := exec .Command ("java" , "Main" )
151
197
cmd .Dir = judge .CurrentWorkDir
152
198
inputFile , err := os .Open (desc .InputFile )
153
199
if err != nil {
@@ -169,7 +215,7 @@ func (judge *JavaJudge) RunTestCase(desc CaseDescription) CaseStatus {
169
215
170
216
var stderrBuffer bytes.Buffer
171
217
cmd .Stdin = inputFile
172
- cmd .Stdout = bufio . NewWriter ( outputFile )
218
+ cmd .Stdout = outputFile
173
219
cmd .Stderr = & stderrBuffer
174
220
if err = cmd .Run (); err != nil {
175
221
return CaseStatus {
@@ -188,6 +234,7 @@ func (judge *JavaJudge) RunTestCase(desc CaseDescription) CaseStatus {
188
234
}
189
235
}
190
236
output , err := ioutil .ReadFile (desc .WorkFile )
237
+
191
238
if err != nil {
192
239
return CaseStatus {
193
240
Status : RE ,
@@ -204,7 +251,7 @@ func (judge *JavaJudge) RunTestCase(desc CaseDescription) CaseStatus {
204
251
}
205
252
return CaseStatus {
206
253
Status : AC ,
207
- CheckerError : err ,
254
+ CheckerError : nil ,
208
255
Stderr : stderrBuffer .String (),
209
256
}
210
257
}
@@ -254,7 +301,7 @@ func (judge *PythonJudge) Cleanup() error {
254
301
func NewJudgeFor (meta config.EgorMeta ) (Judge , error ) {
255
302
switch meta .TaskLang {
256
303
case "java" :
257
- return & JavaJudge {Meta : meta }, nil
304
+ return & JavaJudge {Meta : meta , Checker : & DiffChecker {} }, nil
258
305
case "cpp" :
259
306
case "c" :
260
307
return & CppJudge {Meta : meta }, nil
@@ -265,6 +312,7 @@ func NewJudgeFor(meta config.EgorMeta) (Judge, error) {
265
312
}
266
313
267
314
func RunAction (_ * cli.Context ) error {
315
+ color .Green ("in the run action" )
268
316
configuration , err := config .LoadDefaultConfiguration ()
269
317
if err != nil {
270
318
return err
@@ -288,12 +336,15 @@ func RunAction(_ *cli.Context) error {
288
336
}
289
337
defer judge .Cleanup ()
290
338
report := newJudgeReport ()
339
+
291
340
for i , input := range egorMeta .Inputs {
292
341
output := egorMeta .Outputs [i ]
293
342
caseDescription := NewCaseDescription (input , output )
294
343
status := judge .RunTestCase (* caseDescription )
295
- report .Add (status )
344
+ report .Add (status , * caseDescription )
296
345
}
346
+ report .Display ()
347
+ return nil
297
348
}
298
349
299
350
var TestCommand = cli.Command {
0 commit comments