generated from exercism/generic-test-runner
/
run.ex
127 lines (108 loc) · 3.35 KB
/
run.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
include std/filesys.e
include std/cmdline.e
include std/io.e
include std/sequence.e as seq
include std/search.e as srch
include std/regex.e as re
include std/text.e
include std/convert.e
include json.e
without trace
integer false = 0
integer true = not false
re:regex err_id = re:new("<([0-9]+)>::(.*)")
function first_failure(sequence lines, sequence fallback)
for i = 1 to length(lines) do
sequence line = lines[i]
if match("failed:", line) then
return trim(line)
end if
end for
return fallback
end function
function failures(sequence txt)
sequence parts = seq:split(txt,", ")
for i = 1 to length(parts) do
if match("failed",parts[i]) then
return parts[i]
end if
end for
return ""
end function
function check_for_error(sequence lines, atom current)
sequence message = ""
object res = re:matches(err_id, lines[current])
if not atom(res) then
message = res[1]
atom err_number = to_integer(res[2])
if err_number = 74 then
-- need to extract the next line of the data[i]
message &= (" " & trim(lines[current+1]))
end if
return {true, message}
else
return {false, message}
end if
end function
function check_for_failure(sequence lines, atom current)
sequence message = ""
integer result = match("100% success", lines[current])
if result then
return {false, message}
end if
result = match("% success", lines[current])
if result then
return {true, first_failure(lines, lines[current])}
else
return {false, message}
end if
end function
procedure process(sequence slug, sequence soln_folder, sequence outp_folder)
sequence solution_dir = canonical_path(soln_folder)
sequence output_dir = canonical_path(outp_folder)
sequence results_file = join_path({output_dir, "/results.json"})
--puts(1, solution_dir & "\n")
--puts(1, output_dir & "\n")
--puts(1, results_file & "\n")
create_directory(output_dir)
printf(1, "%s: testing...", {slug})
sequence outfile = join_path({output_dir,"t_" & slug & ".out"})
sequence cmd = build_commandline({"eui","-batch","-d","UNITTEST",join_path({solution_dir,"t_" & slug & ".e"}),"2>", outfile})
system(cmd,2)
atom ifh = open(outfile, "r")
sequence data = read_lines(ifh)
close(ifh)
sequence status = "pass"
sequence message = ""
--trace(1)
for i = 1 to length(data) do
sequence response = check_for_error(data, i)
if response[1] then
status = "error"
message = response[2]
exit
end if
response = check_for_failure(data, i)
if response[1] then
status = "fail"
message = response[2]
exit
end if
end for
sequence JSON = {JSON_OBJECT,
{
{"version", {JSON_NUMBER, 1}},
{"status", {JSON_STRING, status}},
{"message", {JSON_STRING, message}}
}
}
atom ofh = open(results_file,"w")
json_print(ofh, JSON, false)
close(ofh)
end procedure
sequence cmdline = command_line()
if (length(cmdline) < 5) then
puts(1, "usage: eui ./bin/run.ex exercise-slug path/to/solution/folder/ path/to/output/directory/\n")
else
process(cmdline[3], cmdline[4], cmdline[5])
end if