Skip to content

Commit 7fdea43

Browse files
committed
Add test runner sample
1 parent 81c70c5 commit 7fdea43

File tree

1 file changed

+292
-0
lines changed

1 file changed

+292
-0
lines changed

samples/test_runner.lit

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
type TestRunner {
2+
init {
3+
self.tests = []
4+
self.current_group = nil
5+
}
6+
7+
fn test { |name, block|
8+
self.tests.push({ "name" : name, "block" : block })
9+
}
10+
11+
fn describe { |group_name, group_block|
12+
self.current_group = group_name
13+
group_block(self)
14+
self
15+
}
16+
17+
fn run {
18+
let start_time = clock()
19+
var failed_tests = []
20+
var tests_without_assertions = []
21+
22+
self.tests.each(fn { |t|
23+
let result = t[:block](Should())
24+
25+
if result && result[:ok] == false {
26+
print("F")
27+
failed_tests.push({ "name" : t[:name], "message" : result[:message] })
28+
} else {
29+
if result {
30+
print(".")
31+
} else {
32+
print("?")
33+
tests_without_assertions.push(t[:name])
34+
}
35+
}
36+
})
37+
38+
println()
39+
40+
failed_tests.each(fn { |f|
41+
println()
42+
println("{f[:name]}:")
43+
println(" {f[:message]}")
44+
})
45+
let end_time = clock()
46+
let elapsed = end_time - start_time
47+
var total_time = ""
48+
if elapsed < 1 {
49+
total_time = "{elapsed * 1000}ms"
50+
} else {
51+
total_time = "{elapsed}s"
52+
}
53+
54+
println()
55+
println("Finished in {total_time}")
56+
print("{self.tests.size()} examples, {failed_tests.size()} failures")
57+
if tests_without_assertions.size() > 0 {
58+
println(", {tests_without_assertions.size()} without assertions")
59+
} else {
60+
println()
61+
}
62+
}
63+
}
64+
65+
type Should {
66+
init {
67+
self.negated = false
68+
}
69+
70+
fn not {
71+
let s = Should()
72+
s.negated = !self.negated
73+
return s
74+
}
75+
76+
fn eq { |actual, expected|
77+
let ok = actual == expected
78+
79+
if self.negated {
80+
if ok {
81+
return self.fail("Did not expect {expected}, but got {actual}")
82+
}
83+
} else {
84+
if !ok {
85+
return self.fail("Expected {expected}, got {actual}")
86+
}
87+
}
88+
89+
return self.pass()
90+
}
91+
92+
fn greater_than { |actual, value|
93+
let ok = actual > value
94+
95+
if self.negated {
96+
if ok {
97+
return self.fail("Expected {actual} to not be greater than {value}")
98+
}
99+
} else {
100+
if !ok {
101+
return self.fail("Expected {actual} to be greater than {value}")
102+
}
103+
}
104+
105+
return self.pass()
106+
}
107+
108+
fn greater_than_or_equal { |actual, value|
109+
let ok = actual >= value
110+
111+
if self.negated {
112+
if ok {
113+
return self.fail("Expected {actual} to not be >= {value}")
114+
}
115+
} else {
116+
if !ok {
117+
return self.fail("Expected {actual} to be >= {value}")
118+
}
119+
}
120+
121+
self.pass()
122+
}
123+
124+
fn less_than { |actual, value|
125+
let ok = actual < value
126+
127+
if self.negated {
128+
if ok {
129+
return self.fail("Expected {actual} to not be less than {value}")
130+
}
131+
} else {
132+
if !ok {
133+
return self.fail("Expected {actual} to be less than {value}")
134+
}
135+
}
136+
137+
self.pass()
138+
}
139+
140+
fn less_than_or_equal { |actual, value|
141+
let ok = actual <= value
142+
143+
if self.negated {
144+
if ok {
145+
return self.fail("Expected {actual} to not be <= {value}")
146+
}
147+
} else {
148+
if !ok {
149+
return self.fail("Expected {actual} to be <= {value}")
150+
}
151+
}
152+
153+
self.pass()
154+
}
155+
156+
fn include { |actual, item|
157+
let ok = actual.includes?(item)
158+
159+
if self.negated {
160+
if ok {
161+
return self.fail("Expected {actual} to not include {item}")
162+
}
163+
} else {
164+
if !ok {
165+
return self.fail("Expected {actual} to include {item}")
166+
}
167+
}
168+
169+
self.pass()
170+
}
171+
172+
fn have_size { |actual, expected_size|
173+
let len = actual.size()
174+
let ok = len == expected_size
175+
176+
if self.negated {
177+
if ok {
178+
return self.fail("Expected size to not be {expected_size}, but got {len}")
179+
}
180+
} else {
181+
if !ok {
182+
return self.fail("Expected size {expected_size}, got {len}")
183+
}
184+
}
185+
186+
self.pass()
187+
}
188+
189+
fn be_empty { |actual|
190+
let ok = actual.size() == 0
191+
192+
if self.negated {
193+
if ok {
194+
return self.fail("Expected {inspect(actual)} not to be empty")
195+
}
196+
} else {
197+
if !ok {
198+
return self.fail("Expected {inspect(actual)} to be empty")
199+
}
200+
}
201+
202+
self.pass()
203+
}
204+
205+
fn be_of_type { |actual, expected_type|
206+
let t = typeof(actual)
207+
let ok = t == expected_type
208+
209+
if self.negated {
210+
if ok {
211+
return self.fail("Expected {actual} to not be of type {expected_type}")
212+
}
213+
} else {
214+
if !ok {
215+
return self.fail("Expected {actual} to be of type {expected_type}, but got {t}")
216+
}
217+
}
218+
219+
self.pass()
220+
}
221+
222+
fn pass do {"ok" : true, "message" : ""}
223+
224+
fn fail do {"ok" : false, "message" : it}
225+
}
226+
227+
# --------------
228+
229+
TestRunner().
230+
describe("Basic math", fn { |t|
231+
t.test("sum", fn { |should|
232+
2 + 2 |> should.eq(4)
233+
})
234+
t.test("greater than", fn { |should|
235+
10 |> should.greater_than(5)
236+
})
237+
t.test("less than or equal", fn { |should|
238+
5 |> should.less_than_or_equal(5)
239+
})
240+
}).
241+
describe("Type checks", fn { |t|
242+
t.test("bool", fn { |should|
243+
true |> should.be_of_type("Bool")
244+
})
245+
t.test("not string", fn { |should|
246+
42 |> should.not().be_of_type("String")
247+
})
248+
}).
249+
describe("Custom types", fn { |t|
250+
type Custom {
251+
fn to_s do "<custom></custom>"
252+
}
253+
254+
t.test("type", fn { |should|
255+
Custom() |> should.be_of_type("Custom")
256+
})
257+
t.test("to_s", fn { |should|
258+
"{Custom()}" |> should.eq("<custom></custom>")
259+
})
260+
}).
261+
describe("Strings", fn { |t|
262+
t.test("include", fn { |should|
263+
"hello" |> should.include("ell")
264+
})
265+
t.test("size", fn { |should|
266+
"foo" |> should.have_size(3)
267+
})
268+
t.test("empty", fn { |should|
269+
"" |> should.be_empty()
270+
})
271+
}).
272+
describe("Failures", fn { |t|
273+
t.test("equality", fn { |should|
274+
true |> should.eq(false)
275+
})
276+
t.test("comparison", fn { |should|
277+
5 |> should.greater_than(10)
278+
})
279+
t.test("empty", fn { |should|
280+
"foo" |> should.be_empty()
281+
})
282+
t.test("inclusion", fn { |should|
283+
"hello" |> should.include("foo")
284+
})
285+
t.test("type", fn { |should|
286+
42 |> should.be_of_type("String")
287+
})
288+
t.test("size", fn { |should|
289+
"foo" |> should.have_size(5)
290+
})
291+
}).
292+
run()

0 commit comments

Comments
 (0)