Skip to content

Commit

Permalink
initial (#1)
Browse files Browse the repository at this point in the history
* initial

* Update README.md

restored

* Update run-tests-in-docker.sh

restore

* Update run-tests.sh

remove debug line

* t -> test_case
  • Loading branch information
petelomax authored Aug 1, 2024
1 parent 157ebfb commit b3dd571
Show file tree
Hide file tree
Showing 20 changed files with 272 additions and 34 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
/tests/**/*/results.json
/tests/all-fail/backup
/tests/empty-file/backup
/tests/partial-fail/backup
/tests/success/backup
/tests/syntax-error/backup
/bin/backup
22 changes: 20 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
FROM alpine:3.18
FROM ubuntu:24.04

ARG PHIX_VERSION=1.0.5a

RUN apt update && apt install -y wget unzip

RUN zipname="phix.${PHIX_VERSION}.zip" && \
wget "http://phix.x10.mx/p64" && \
wget "http://phix.x10.mx/${zipname}" && \
mv p64 p && \
chmod 777 p && \
mv p /usr/local/bin/p && \
unzip "${zipname}" -d /usr/local/phix && \
mv /usr/local/phix/builtins /usr/local/bin/builtins && \
cd /usr/local/bin && \
find "/usr/local/phix" -type f -executable -exec ln -s {} \; && \
echo "done?"

RUN p --version

# install packages required to run the tests
RUN apk add --no-cache jq coreutils
#RUN apk add --no-cache jq coreutils

WORKDIR /opt/test-runner
COPY . .
Expand Down
2 changes: 1 addition & 1 deletion bin/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ for test_dir in tests/*; do
expected_file="expected_${file}"
echo "${test_dir_name}: comparing ${file} to ${expected_file}"

if ! diff "${test_dir_path}/${file}" "${test_dir_path}/${expected_file}"; then
if ! diff -w "${test_dir_path}/${file}" "${test_dir_path}/${expected_file}"; then
exit_code=1
fi
done
Expand Down
101 changes: 101 additions & 0 deletions bin/run.exw
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
requires("1.0.5") -- (assert(a&b&c) bug, -nopause)
without trace
include builtins/json.e

procedure process()
sequence cl = command_line()
integer cll = length(cl)
if cll<4 then
puts(1, "usage: p ./bin/run.exw slug input_dir output_dir\n")
return
end if
string exercise_folder = cl[4], -- eg exercism/phix/exercises/practice/acronym
slug = split_path(exercise_folder)[$], -- eg acronym
sol_dir = get_proper_path(exercise_folder),
out_dir = get_proper_path(cl[5]),
test_src = join_path({sol_dir, "test.exw"}),
res_file = join_path({out_dir, "results.json"})

if not file_exists(sol_dir) then
crash("%s does not exist",{sol_dir})
end if
if not file_exists(out_dir) then
assert(create_directory(out_dir),"cannot create directory "&out_dir)
end if

-- printf(1, "%s: testing...\n", {slug})

assert(chdir(sol_dir),"cannot chdir to %s",{sol_dir})
string cmd = sprintf(`p -nopause %s > "%s" 2>&1`, {test_src, res_file})
--?cmd

integer res = system_exec(cmd,4) -- (4 === result/wait and redirect/builtin)
--?res

sequence lines = get_text(res_file,GT_LF_STRIPPED)
--?lines

string status = "pass", message = ""

--printf(1,"DATA:\n%s\n",{join(lines,"<\n")})
integer begins_hat = 0, begins_3 = 0, crashmsg = false
for i,l in lines do
if begins_hat=0
and begins("^",trim_head(l)) then
begins_hat = i
elsif begins("... called from ",l)
or begins("...included by ",l)
or begins("Global & Local Variables",l) then
begins_3 = i-1
exit
elsif match("passed: ",l) then
lines[i] = ""
elsif i=5 and begins("--> see ",l) then
crashmsg = true
exit
end if
end for
if crashmsg then
status = "error"
message = lines[3]
elsif begins_3
or begins_hat then
-- compilation error
status = "error"
if begins_3=0 then begins_3 = begins_hat end if
-- We might want to limit this to, say, 8 lines?
message = join(filter(lines[2..begins_3],"!=",""),'\n')
else
-- check for unit test errors or success
integer first_failure = 0
lines = filter(lines,"!=","")
for i,l in lines do
if match("100% success", l) then exit end if // all good
if match("% success", l) then // < 100% then...
status = "fail"
if first_failure==0 then first_failure = i end if
message = trim(lines[first_failure])
exit
end if
if first_failure==0 and match("failed:", l) then
first_failure = i
end if
end for
end if
// if status is still "pass" then res //must// be 0, shirley:
assert(status!="pass" or res==0,"pass with res=%d??",{res})

sequence json = {JSON_OBJECT, {"version", 1}, {"status", status}, {"message", message}}
integer ofn = open(res_file,"w")
object pjres = print_json(ofn, json) -- (separate line so available for debugging)
assert(pjres!=0,"bad json??")
close(ofn)
--temp:
--{} = print_json(1,json)
--?{res,status}
-- if res!=0 then crash(status) end if

end procedure

process()

24 changes: 1 addition & 23 deletions bin/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,28 +33,6 @@ echo "${slug}: testing..."

# Run the tests for the provided implementation file and redirect stdout and
# stderr to capture it
test_output=$(false)
# TODO: substitute "false" with the actual command to run the test:
# test_output=$(command_to_run_tests 2>&1)

# Write the results.json file based on the exit code of the command that was
# just executed that tested the implementation file
if [ $? -eq 0 ]; then
jq -n '{version: 1, status: "pass"}' > ${results_file}
else
# OPTIONAL: Sanitize the output
# In some cases, the test output might be overly verbose, in which case stripping
# the unneeded information can be very helpful to the student
# sanitized_test_output=$(printf "${test_output}" | sed -n '/Test results:/,$p')

# OPTIONAL: Manually add colors to the output to help scanning the output for errors
# If the test output does not contain colors to help identify failing (or passing)
# tests, it can be helpful to manually add colors to the output
# colorized_test_output=$(echo "${test_output}" \
# | GREP_COLOR='01;31' grep --color=always -E -e '^(ERROR:.*|.*failed)$|$' \
# | GREP_COLOR='01;32' grep --color=always -E -e '^.*passed$|$')

jq -n --arg output "${test_output}" '{version: 1, status: "fail", message: $output}' > ${results_file}
fi
p bin/run.exw "${slug}" ${solution_dir} "${output_dir}"

echo "${slug}: done"
6 changes: 3 additions & 3 deletions tests/all-fail/expected_results.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": 1,
"status": "fail",
"message": "TODO: replace with correct output"
"version":1,
"status":"fail",
"message":"failed: year not divisible by 4 in common year: 1 should equal 0"
}
7 changes: 7 additions & 0 deletions tests/all-fail/leap.e
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
local function good_leap(integer year)
return rmdr(year,4)=0 and (rmdr(year,100)!=0 or rmdr(year,400)=0)
end function

global function leap(integer year)
return not good_leap(year)
end function
22 changes: 22 additions & 0 deletions tests/all-fail/test.exw
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include leap.e

--<do not edit>
constant canonical_data = {
{2015,false,"year not divisible by 4 in common year"},
{1970,false,"year divisible by 2, not divisible by 4 in common year"},
{1996,true,"year divisible by 4, not divisible by 100 in leap year"},
{1960,true,"year divisible by 4 and 5 is still a leap year"},
{2100,false,"year divisible by 100, not divisible by 400 in common year"},
{1900,false,"year divisible by 100 but not by 3 is still not a leap year"},
{2000,true,"year divisible by 400 is leap year"},
{2400,true,"year divisible by 400 but not by 125 is still a leap year"},
{1800,false,"year divisible by 200, not divisible by 400 in common year"},
}
--</do not edit>

set_test_verbosity(TEST_SHOW_ALL)
for test_case in canonical_data do
{integer year, bool expected, string desc} = test_case
test_equal(leap(year),expected,desc)
end for
test_summary()
6 changes: 4 additions & 2 deletions tests/empty-file/expected_results.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"version": 1,
"status": "fail",
"message": "TODO: replace with correct output"
"status": "error",
"message": "/opt/test-runner/tests/empty-file/test.exw:20
test_equal(leap(year),expected,desc)
^ undefined identifier leap"
}
1 change: 1 addition & 0 deletions tests/empty-file/leap.e
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

22 changes: 22 additions & 0 deletions tests/empty-file/test.exw
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include leap.e

--<do not edit>
constant canonical_data = {
{2015,false,"year not divisible by 4 in common year"},
{1970,false,"year divisible by 2, not divisible by 4 in common year"},
{1996,true,"year divisible by 4, not divisible by 100 in leap year"},
{1960,true,"year divisible by 4 and 5 is still a leap year"},
{2100,false,"year divisible by 100, not divisible by 400 in common year"},
{1900,false,"year divisible by 100 but not by 3 is still not a leap year"},
{2000,true,"year divisible by 400 is leap year"},
{2400,true,"year divisible by 400 but not by 125 is still a leap year"},
{1800,false,"year divisible by 200, not divisible by 400 in common year"},
}
--</do not edit>

set_test_verbosity(TEST_SHOW_ALL)
for test_case in canonical_data do
{integer year, bool expected, string desc} = test_case
test_equal(leap(year),expected,desc)
end for
test_summary()
2 changes: 1 addition & 1 deletion tests/partial-fail/expected_results.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": 1,
"status": "fail",
"message": "TODO: replace with correct output"
"message": "failed: year divisible by 100, not divisible by 400 in common year: 1 should equal 0"
}
4 changes: 4 additions & 0 deletions tests/partial-fail/leap.e
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global function leap(integer year)
return rmdr(year,4)=0 -- and (rmdr(year,100)!=0 or rmdr(year,400)=0)
end function

22 changes: 22 additions & 0 deletions tests/partial-fail/test.exw
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include leap.e

--<do not edit>
constant canonical_data = {
{2015,false,"year not divisible by 4 in common year"},
{1970,false,"year divisible by 2, not divisible by 4 in common year"},
{1996,true,"year divisible by 4, not divisible by 100 in leap year"},
{1960,true,"year divisible by 4 and 5 is still a leap year"},
{2100,false,"year divisible by 100, not divisible by 400 in common year"},
{1900,false,"year divisible by 100 but not by 3 is still not a leap year"},
{2000,true,"year divisible by 400 is leap year"},
{2400,true,"year divisible by 400 but not by 125 is still a leap year"},
{1800,false,"year divisible by 200, not divisible by 400 in common year"},
}
--</do not edit>

set_test_verbosity(TEST_SHOW_ALL)
for test_case in canonical_data do
{integer year, bool expected, string desc} = test_case
test_equal(leap(year),expected,desc)
end for
test_summary()
3 changes: 2 additions & 1 deletion tests/success/expected_results.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"version": 1,
"status": "pass"
"status": "pass",
"message": ""
}
4 changes: 4 additions & 0 deletions tests/success/leap.e
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global function leap(integer year)
return rmdr(year,4)=0 and (rmdr(year,100)!=0 or rmdr(year,400)=0)
end function

22 changes: 22 additions & 0 deletions tests/success/test.exw
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include leap.e

--<do not edit>
constant canonical_data = {
{2015,false,"year not divisible by 4 in common year"},
{1970,false,"year divisible by 2, not divisible by 4 in common year"},
{1996,true,"year divisible by 4, not divisible by 100 in leap year"},
{1960,true,"year divisible by 4 and 5 is still a leap year"},
{2100,false,"year divisible by 100, not divisible by 400 in common year"},
{1900,false,"year divisible by 100 but not by 3 is still not a leap year"},
{2000,true,"year divisible by 400 is leap year"},
{2400,true,"year divisible by 400 but not by 125 is still a leap year"},
{1800,false,"year divisible by 200, not divisible by 400 in common year"},
}
--</do not edit>

set_test_verbosity(TEST_SHOW_ALL)
for test_case in canonical_data do
{integer year, bool expected, string desc} = test_case
test_equal(leap(year),expected,desc)
end for
test_summary()
4 changes: 3 additions & 1 deletion tests/syntax-error/expected_results.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"version": 1,
"status": "error",
"message": "TODO: replace with correct output"
"message": "/opt/test-runner/tests/syntax-error/leap.e:1
global function leap[integer year]
^ '(' expected"
}
4 changes: 4 additions & 0 deletions tests/syntax-error/leap.e
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global function leap[integer year]
return rmdr(year,4)=0 and (rmdr(year,100)!=0 or rmdr(year,400)=0)
end function

22 changes: 22 additions & 0 deletions tests/syntax-error/test.exw
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
include leap.e

--<do not edit>
constant canonical_data = {
{2015,false,"year not divisible by 4 in common year"},
{1970,false,"year divisible by 2, not divisible by 4 in common year"},
{1996,true,"year divisible by 4, not divisible by 100 in leap year"},
{1960,true,"year divisible by 4 and 5 is still a leap year"},
{2100,false,"year divisible by 100, not divisible by 400 in common year"},
{1900,false,"year divisible by 100 but not by 3 is still not a leap year"},
{2000,true,"year divisible by 400 is leap year"},
{2400,true,"year divisible by 400 but not by 125 is still a leap year"},
{1800,false,"year divisible by 200, not divisible by 400 in common year"},
}
--</do not edit>

set_test_verbosity(TEST_SHOW_ALL)
for test_case in canonical_data do
{integer year, bool expected, string desc} = test_case
test_equal(leap(year),expected,desc)
end for
test_summary()

0 comments on commit b3dd571

Please sign in to comment.