Created
May 29, 2024 18:52
-
-
Save ghaberek/e3d312d3366b047da331283640bef3c5 to your computer and use it in GitHub Desktop.
A simple parser for Euphoria unittest.log files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- std/utparse.e | |
include std/io.e | |
include std/get.e | |
include std/error.e | |
include std/pretty.e | |
include std/sequence.e | |
include std/types.e | |
sequence PRETTY_INLINE = PRETTY_DEFAULT | |
PRETTY_INLINE[DISPLAY_ASCII] = 2 | |
PRETTY_INLINE[LINE_BREAKS] = FALSE | |
public enum | |
TEST_PASSED = 1, | |
TEST_FAILED = 0 | |
public enum | |
TEST_FILE, | |
TEST_RESULTS, | |
TEST_SUMMARY | |
public enum | |
RESULT_STATUS, | |
RESULT_NAME, | |
RESULT_EXPECTED, | |
RESULT_OUTCOME, | |
RESULT_ELAPSED | |
public enum | |
SUMMARY_TOTAL, | |
SUMMARY_FAILED, | |
SUMMARY_PASSED, | |
SUMMARY_ELAPSED, | |
SUMMARY_PERCENT | |
public function parse_unittest_log(sequence filename) | |
object content = read_file(filename) | |
if atom(content) then | |
return content | |
end if | |
-- split the content into sequence of object strings | |
sequence entries = stdseq:split(content, "entry = ", TRUE) | |
sequence unittests = {} | |
for i = 1 to length(entries) do | |
-- parse the string to an object | |
object data = stdget:value(entries[i]) | |
-- check the parsing status | |
if data[1] != GET_SUCCESS then | |
-- return error? crash? | |
error:crash("stdget:value() returned %d (i=%d)", {data[1],i}) | |
-- return {} | |
end if | |
-- get the actual object | |
data = data[2] | |
-- check the first element | |
switch data[1] do | |
case "file" then | |
-- get the file name | |
sequence file = data[2] | |
-- add new test to list | |
unittests = append(unittests, { | |
file, -- TEST_FILE | |
{}, -- TEST_RESULTS | |
{} -- TEST_SUMMARY | |
}) | |
case "passed" then | |
-- add placeholder values to result | |
data = insert(data, 0, 3) -- expected | |
data = insert(data, 0, 4) -- outcome | |
-- continue to "failed" entry below | |
fallthru | |
case "failed" then | |
-- get the test values | |
integer status = equal(data[1],"passed") | |
sequence name = data[2] | |
object expected = data[3] | |
object outcome = data[4] | |
atom elapsed = data[5] | |
-- add test result to the list | |
unittests[$][TEST_RESULTS] &= {{ | |
status, -- RESULT_STATUS | |
name, -- RESULT_NAME | |
expected, -- RESULT_EXPECTED | |
outcome, -- RESULT_OUTCOME | |
elapsed -- RESULT_ELAPSED | |
}} | |
case "summary" then | |
-- get the summary values | |
integer total = data[2] | |
integer failed = data[3] | |
integer passed = data[4] | |
atom elapsed = data[5] | |
atom percent = 0 | |
if total = passed then | |
percent = 1 | |
elsif total != 0 then | |
percent = passed / total | |
end if | |
percent = percent * 100 | |
-- store the summary in the test | |
unittests[$][TEST_SUMMARY] = { | |
total, -- SUMMARY_TOTAL | |
failed, -- SUMMARY_FAILED | |
passed, -- SUMMARY_PASSED | |
elapsed, -- SUMMARY_ELAPSED | |
percent -- SUMMARY_PERCENT | |
} | |
end switch | |
end for | |
return unittests | |
end function | |
procedure print_unittest_file(integer fn, sequence file) | |
printf(fn, "%s:\n", {file}) | |
end procedure | |
procedure print_unittest_result(integer fn, sequence result) | |
if result[RESULT_STATUS] = TEST_PASSED then | |
puts(fn, " passed:") | |
else | |
puts(fn, " failed:") | |
end if | |
printf(fn, " %s", {result[RESULT_NAME]}) | |
if result[RESULT_STATUS] = TEST_FAILED then | |
puts(fn, ", expected: ") | |
pretty_print(fn, result[RESULT_EXPECTED], PRETTY_INLINE) | |
puts(fn, " but got: ") | |
pretty_print(fn, result[RESULT_OUTCOME], PRETTY_INLINE) | |
end if | |
puts(fn, "\n") | |
end procedure | |
procedure print_unittest_summary(integer fn, sequence summary) | |
printf(fn, " %d tests run", {summary[SUMMARY_TOTAL]}) | |
printf(fn, ", %d passed", {summary[SUMMARY_PASSED]}) | |
printf(fn, ", %d failed", {summary[SUMMARY_FAILED]}) | |
printf(fn, ", %d%% success", {summary[SUMMARY_PERCENT]}) | |
puts(fn, "\n") | |
end procedure | |
public procedure print_unittest_log(integer fn=1, sequence unittests="unittest.log") | |
if string(unittests) then | |
unittests = parse_unittest_log(unittests) | |
end if | |
integer total = 0 | |
integer failed = 0 | |
integer passed = 0 | |
atom elapsed = 0 | |
for i = 1 to length(unittests) do | |
sequence file = unittests[i][TEST_FILE] | |
sequence results = unittests[i][TEST_RESULTS] | |
sequence summary = unittests[i][TEST_SUMMARY] | |
print_unittest_file(fn, file) | |
for j = 1 to length(results) do | |
print_unittest_result(fn, results[j]) | |
end for | |
print_unittest_summary(fn, summary) | |
total += summary[SUMMARY_TOTAL] | |
failed += summary[SUMMARY_FAILED] | |
passed += summary[SUMMARY_PASSED] | |
elapsed += summary[SUMMARY_ELAPSED] | |
end for | |
-- print a total summary if there are multiple files | |
if length(unittests) > 1 and total != 0 then | |
atom percent = (passed / total) * 100 | |
print_unittest_file(fn, "summary") | |
print_unittest_summary(fn, { | |
total, -- SUMMARY_TOTAL | |
failed, -- SUMMARY_FAILED | |
passed, -- SUMMARY_PASSED | |
elapsed, -- SUMMARY_ELAPSED | |
percent -- SUMMARY_PERCENT | |
}) | |
end if | |
end procedure |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment