Skip to content

Commit

Permalink
Merge pull request #101
Browse files Browse the repository at this point in the history
  • Loading branch information
delasy authored Jan 5, 2024
2 parents b0fd20e + 05e993c commit 7f9fe16
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 67 deletions.
70 changes: 4 additions & 66 deletions packages/testing/src/main
Original file line number Diff line number Diff line change
Expand Up @@ -11,75 +11,13 @@ import
EXPECT_TRUE
from "./expects"
import FAIL_TEST, TEST_FAILED from "./matchers"
import Test from "./test"
import Tests from "./tests"

export EXPECT_EQ
export EXPECT_FALSE
export EXPECT_NO_THROW
export EXPECT_THROW_WITH_MESSAGE
export EXPECT_TRUE

export obj Test {
name: str
body: () -> void
}

export obj Tests {
mut _tests: Test[]

fn register (mut self: ref Self, name: str, body: () -> void) ref Self {
self._tests.push(Test{name: name, body: body})
return self
}

fn run (mut self: ref Self, args: str[]) ref Self {
mut totalTime := 0
mut failedTests: str[]

print("[==========] Running", self._tests.len, self._word(self._tests.len), to: "stderr")

loop i := 0; i < self._tests.len; i++ {
test := self._tests[i]

print("[ RUN ]", test.name, to: "stderr")
timeStart := date_now()
test.body()
timeDelta := date_now() - timeStart
testStatus := TEST_FAILED ? "[ FAILED ]" : "[ OK ]"
print(testStatus, test.name, "(" + timeDelta.str() + " ms)", to: "stderr")

if TEST_FAILED {
failedTests.push(test.name)
}

totalTime += timeDelta
TEST_FAILED = false
}

print(
"[==========]",
self._tests.len,
self._word(self._tests.len) + " ran (" + totalTime.str() + " ms total)",
to: "stderr"
)

passedTestsNum := self._tests.len - failedTests.len
print("[ PASSED ]", passedTestsNum, self._word(passedTestsNum), to: "stderr")

if !failedTests.empty {
print("[ FAILED ]", failedTests.len, self._word(failedTests.len) + ", listed below:", to: "stderr")

loop i := 0; i < failedTests.len; i++ {
failedTest: str = failedTests[i]
print("[ FAILED ]", failedTest, to: "stderr")
}

print(to: "stderr")
print(" " + failedTests.len.str() + " FAILED", self._word(failedTests.len).upper, to: "stderr")
process_exit(1)
}
}

fn _word (n: int) str {
return n == 1 ? "test" : "tests"
}
}
export Test
export Tests
15 changes: 14 additions & 1 deletion packages/testing/src/matchers
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export mut TEST_FAILED := false

export fn FAIL_TEST (message: str) {
TEST_FAILED = true
print("Failure: " + message, to: "stderr")
print(getLocation() + ": Failure" + os_EOL + message, to: "stderr")
}

export fn MATCH_ANY (a: any, b: any) {
Expand Down Expand Up @@ -447,3 +447,16 @@ fn MATCH_REF_STR (a: ref str, b: ref str) {
)
}
}

fn getLocation () str {
mut stack := ""

try {
throw error_NewError("")
} catch err: error_Error {
stack = err.stack
}

stackLines := stack.lines()
return stackLines[6].trim().slice(3)
}
9 changes: 9 additions & 0 deletions packages/testing/src/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*!
* Copyright (c) Aaron Delasy
* Licensed under the MIT License
*/

export obj Test {
name: str
body: () -> void
}
117 changes: 117 additions & 0 deletions packages/testing/src/tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*!
* Copyright (c) Aaron Delasy
* Licensed under the MIT License
*/

import TEST_FAILED from "./matchers"
import Test from "./test"

export obj Tests {
mut _tests: Test[]

fn register (mut self: ref Self, name: str, body: () -> void) ref Self {
self._tests.push(Test{name: name, body: body})
return self
}

fn run (mut self: ref Self, args: str[]) ref Self {
mut filters: str[]

loop i := 0; i < args.len; i++ {
arg := args[i]

if arg.slice(0, 9) == "--filter=" {
filters = arg.slice(9).split(",")
}
}

mut filtersAreInclusive := false

loop i := filters.len - 1; i >= 0; i-- {
mut filter := filters[i]
filter = filter.trim()

if filter.empty {
filters.remove(i)
} elif filter[0] != '!' {
filtersAreInclusive = true
}
}

mut allTests: (ref Test)[]

loop i := 0; i < self._tests.len; i++ {
mut test := self._tests[i]
mut shouldInclude := false

loop j := 0; j < filters.len; j++ {
exclude := filters[j][0] == '!'
filterValue := exclude ? filters[j].slice(1) : filters[j]

if filtersAreInclusive {
if !exclude && test.name == filterValue {
shouldInclude = true
break
}
} elif !(exclude && test.name == filterValue) {
shouldInclude = true
break
}
}

if shouldInclude || filters.len == 0 {
allTests.push(test)
}
}

mut totalTime := 0
mut failedTests: str[]

print("[==========] Running", allTests.len, self._word(allTests.len), to: "stderr")

loop i := 0; i < allTests.len; i++ {
test := allTests[i]

print("[ RUN ]", test.name, to: "stderr")
timeStart := date_now()
test.body()
timeDelta := date_now() - timeStart
testStatus := TEST_FAILED ? "[ FAILED ]" : "[ OK ]"
print(testStatus, test.name, "(" + timeDelta.str() + " ms)", to: "stderr")

if TEST_FAILED {
failedTests.push(test.name)
}

totalTime += timeDelta
TEST_FAILED = false
}

print(
"[==========]",
allTests.len,
self._word(allTests.len) + " ran (" + totalTime.str() + " ms total)",
to: "stderr"
)

passedTestsNum := allTests.len - failedTests.len
print("[ PASSED ]", passedTestsNum, self._word(passedTestsNum), to: "stderr")

if !failedTests.empty {
print("[ FAILED ]", failedTests.len, self._word(failedTests.len) + ", listed below:", to: "stderr")

loop i := 0; i < failedTests.len; i++ {
failedTest: str = failedTests[i]
print("[ FAILED ]", failedTest, to: "stderr")
}

print(to: "stderr")
print(" " + failedTests.len.str() + " FAILED", self._word(failedTests.len).upper, to: "stderr")
process_exit(1)
}
}

fn _word (n: int) str {
return n == 1 ? "test" : "tests"
}
}

0 comments on commit 7f9fe16

Please sign in to comment.