-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathUnitTest.Run.pq
116 lines (110 loc) · 3.53 KB
/
UnitTest.Run.pq
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
/**
Run tests from the test suite that may be passed as a record with test
functions or may be referenced by its module name
Return a table of test results
**/
(suite) =>
let
Suite = if Value.Is(suite, type text) then LibPQ(suite) else suite,
/* Load constants */
Config = LibPQ("UnitTest.Constants"),
Error.Reason = Config[Error.Reason],
Test.Prefix = Config[Test.Prefix],
/* Execute a single test case (test function or list of test functions) */
Test.Execute = (test_case as any) =>
let
Subtests =
if test_case is list
then test_case
else {test_case},
SubtestsCount = List.Count(Subtests),
Execute = List.Last(
List.Generate(
() => [
i = -1,
result = [HasError=false],
tag = null
],
each [i] < SubtestsCount,
each [
i = [i] + 1,
result =
if
not [result][HasError]
// first failed subtest fails all of them
then
try Subtests{i}()
else
[result],
tag = if [tag] is null and result[HasError]
then i + 1 // remember which subtest failed
else [tag]
]
)
),
MarkFailedSubtest =
if Execute[tag] <> null and SubtestsCount > 1
then "[" & Text.From(Execute[tag]) &
"/" & Text.From(SubtestsCount) & "] "
else "",
Return =
if Execute[result][HasError]
then Record.Combine({
Execute[result],
[
Error = Record.TransformFields(
Execute[result][Error],
{"Message", each MarkFailedSubtest & _}
)
]
})
else Execute[result]
in
Return,
/* Analyze test triage result */
Test.ReadStatus = (try_result) =>
let
Success = not try_result[HasError],
Failure =
try
try_result[Error][Reason] = Error.Reason
otherwise
false,
Error = try_result[Error],
Return =
if Success
then {"PASSED", ""}
else if Failure
then {"FAILED", Error[Reason] & ": " & Error[Message]}
else {"ERROR", Error[Reason] & ": " & Error[Message]}
in
Return,
/* Detect test functions */
Test.Names = List.Select(
Record.FieldNames(Suite),
each Text.StartsWith(_, Test.Prefix)
),
Test.Table = Table.FromColumns({Test.Names},{"Test"}),
/* Execute all tests in the suite */
Column.Factories = {
{"Result", each Test.Execute(Record.Field(Suite, [Test]))},
{"Temp", each Test.ReadStatus([Result])},
{"Status", each [Temp]{0}},
{"Description", each [Temp]{1}}
},
Test.Extra = List.Last(List.Generate(
() => [i = -1, table = Test.Table],
each [i] < List.Count(Column.Factories),
each [
i = [i] + 1,
table = Table.AddColumn(
[table],
Column.Factories{i}{0},
Column.Factories{i}{1}
)
],
each [table]
)),
Return = Table.RemoveColumns(Test.Extra, "Temp")
in
Return