@temperlang/std 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/regex.js +495 -484
- package/regex.js.map +1 -1
- package/temporal.js +39 -35
- package/temporal.js.map +1 -1
- package/testing.js +122 -122
- package/testing.js.map +1 -1
package/testing.js
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
import {
|
|
2
|
-
globalConsole as
|
|
2
|
+
globalConsole as globalConsole__232, listBuilderToList as listBuilderToList_247, pairConstructor as pairConstructor_275, listedMap as listedMap_276, listBuilderAdd as listBuilderAdd_120, listedJoin as listedJoin_99, listify as listify_69, listedGet as listedGet_159, strCat as strCat_129
|
|
3
3
|
} from "@temperlang/core";
|
|
4
4
|
import {
|
|
5
|
-
strict as
|
|
5
|
+
strict as strict__243
|
|
6
6
|
} from "assert";
|
|
7
|
-
/** @type {
|
|
8
|
-
const
|
|
7
|
+
/** @type {Console_233} */
|
|
8
|
+
const console_231 = globalConsole__232;
|
|
9
9
|
export class Test {
|
|
10
10
|
/**
|
|
11
|
-
* @param {boolean}
|
|
12
|
-
* @param {() => string}
|
|
11
|
+
* @param {boolean} success_235
|
|
12
|
+
* @param {() => string} message_236
|
|
13
13
|
*/
|
|
14
|
-
assert(
|
|
15
|
-
if (!
|
|
16
|
-
this.#
|
|
17
|
-
|
|
14
|
+
assert(success_235, message_236) {
|
|
15
|
+
if (! success_235) {
|
|
16
|
+
this.#_passing_237 = false;
|
|
17
|
+
listBuilderAdd_120(this.#_messages_238, message_236());
|
|
18
18
|
} else {
|
|
19
19
|
void 0;
|
|
20
20
|
}
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
* @param {boolean}
|
|
25
|
-
* @param {() => string}
|
|
24
|
+
* @param {boolean} success_240
|
|
25
|
+
* @param {() => string} message_241
|
|
26
26
|
* @returns {void}
|
|
27
27
|
*/
|
|
28
|
-
assertHard(
|
|
29
|
-
this.assert(
|
|
30
|
-
if (!
|
|
31
|
-
this.#
|
|
32
|
-
|
|
28
|
+
assertHard(success_240, message_241) {
|
|
29
|
+
this.assert(success_240, message_241);
|
|
30
|
+
if (! success_240) {
|
|
31
|
+
this.#_failedOnAssert_242 = true;
|
|
32
|
+
strict__243.fail(this.messagesCombined());
|
|
33
33
|
} else {
|
|
34
34
|
void 0;
|
|
35
35
|
}
|
|
@@ -38,8 +38,8 @@ export class Test {
|
|
|
38
38
|
/** @returns {void} */
|
|
39
39
|
softFailToHard() {
|
|
40
40
|
if (this.hasUnhandledFail) {
|
|
41
|
-
this.#
|
|
42
|
-
|
|
41
|
+
this.#_failedOnAssert_242 = true;
|
|
42
|
+
strict__243.fail(this.messagesCombined());
|
|
43
43
|
} else {
|
|
44
44
|
void 0;
|
|
45
45
|
}
|
|
@@ -47,177 +47,177 @@ export class Test {
|
|
|
47
47
|
}
|
|
48
48
|
/** @returns {boolean} */
|
|
49
49
|
get passing() {
|
|
50
|
-
return this.#
|
|
50
|
+
return this.#_passing_237;
|
|
51
51
|
}
|
|
52
52
|
/** @returns {Array<string>} */
|
|
53
53
|
messages() {
|
|
54
|
-
return
|
|
54
|
+
return listBuilderToList_247(this.#_messages_238);
|
|
55
55
|
}
|
|
56
56
|
/** @returns {boolean} */
|
|
57
57
|
get failedOnAssert() {
|
|
58
|
-
return this.#
|
|
58
|
+
return this.#_failedOnAssert_242;
|
|
59
59
|
}
|
|
60
60
|
/** @returns {boolean} */
|
|
61
61
|
get hasUnhandledFail() {
|
|
62
|
-
let
|
|
63
|
-
if (this.#
|
|
64
|
-
|
|
62
|
+
let t_250;
|
|
63
|
+
if (this.#_failedOnAssert_242) {
|
|
64
|
+
t_250 = true;
|
|
65
65
|
} else {
|
|
66
|
-
|
|
66
|
+
t_250 = this.#_passing_237;
|
|
67
67
|
}
|
|
68
|
-
return !
|
|
68
|
+
return ! t_250;
|
|
69
69
|
}
|
|
70
70
|
/** @returns {string | null} */
|
|
71
71
|
messagesCombined() {
|
|
72
|
-
let
|
|
73
|
-
let
|
|
74
|
-
let
|
|
75
|
-
if (! this.#
|
|
76
|
-
|
|
72
|
+
let return_252;
|
|
73
|
+
let t_253;
|
|
74
|
+
let t_254;
|
|
75
|
+
if (! this.#_messages_238.length) {
|
|
76
|
+
return_252 = null;
|
|
77
77
|
} else {
|
|
78
|
-
|
|
79
|
-
function
|
|
80
|
-
return
|
|
78
|
+
t_253 = this.#_messages_238;
|
|
79
|
+
function fn_255(it_256) {
|
|
80
|
+
return it_256;
|
|
81
81
|
}
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
t_254 = listedJoin_99(t_253, ", ", fn_255);
|
|
83
|
+
return_252 = t_254;
|
|
84
84
|
}
|
|
85
|
-
return
|
|
85
|
+
return return_252;
|
|
86
86
|
}
|
|
87
87
|
/** @type {boolean} */
|
|
88
|
-
#
|
|
88
|
+
#_failedOnAssert_242;
|
|
89
89
|
/** @type {boolean} */
|
|
90
|
-
#
|
|
90
|
+
#_passing_237;
|
|
91
91
|
/** @type {Array<string>} */
|
|
92
|
-
#
|
|
92
|
+
#_messages_238;
|
|
93
93
|
/**
|
|
94
|
-
* @param {boolean}
|
|
95
|
-
* @param {boolean}
|
|
96
|
-
* @param {Array<string>}
|
|
94
|
+
* @param {boolean} _failedOnAssert_257
|
|
95
|
+
* @param {boolean} _passing_258
|
|
96
|
+
* @param {Array<string>} _messages_259
|
|
97
97
|
*/
|
|
98
|
-
constructor(
|
|
99
|
-
let
|
|
100
|
-
if (!(
|
|
101
|
-
|
|
98
|
+
constructor(_failedOnAssert_257, _passing_258, _messages_259) {
|
|
99
|
+
let t_260;
|
|
100
|
+
if (!(_failedOnAssert_257 !== void 0)) {
|
|
101
|
+
_failedOnAssert_257 = false;
|
|
102
102
|
}
|
|
103
|
-
if (!(
|
|
104
|
-
|
|
103
|
+
if (!(_passing_258 !== void 0)) {
|
|
104
|
+
_passing_258 = true;
|
|
105
105
|
}
|
|
106
|
-
if (!(
|
|
107
|
-
|
|
108
|
-
|
|
106
|
+
if (!(_messages_259 !== void 0)) {
|
|
107
|
+
t_260 = [];
|
|
108
|
+
_messages_259 = t_260;
|
|
109
109
|
}
|
|
110
|
-
this.#
|
|
111
|
-
this.#
|
|
112
|
-
this.#
|
|
110
|
+
this.#_failedOnAssert_242 = _failedOnAssert_257;
|
|
111
|
+
this.#_passing_237 = _passing_258;
|
|
112
|
+
this.#_messages_238 = _messages_259;
|
|
113
113
|
return;
|
|
114
114
|
}
|
|
115
115
|
};
|
|
116
|
-
/** @type {
|
|
116
|
+
/** @type {Type_261} */
|
|
117
117
|
export const TestName = "String: Type";
|
|
118
|
-
/** @type {
|
|
118
|
+
/** @type {Type_261} */
|
|
119
119
|
export const TestFun = "fn (Test): (Void | Bubble): Type";
|
|
120
|
-
/** @type {
|
|
120
|
+
/** @type {Type_261} */
|
|
121
121
|
export const TestCase = "Pair\u003cString, fn (Test): (Void | Bubble)\u003e: Type";
|
|
122
|
-
/** @type {
|
|
122
|
+
/** @type {Type_261} */
|
|
123
123
|
export const TestFailureMessage = "String: Type";
|
|
124
|
-
/** @type {
|
|
124
|
+
/** @type {Type_261} */
|
|
125
125
|
export const TestResult = "Pair\u003cString, List\u003cString\u003e\u003e: Type";
|
|
126
126
|
/**
|
|
127
|
-
* @param {Array<
|
|
128
|
-
* @returns {Array<
|
|
127
|
+
* @param {Array<Pair_277<string, (arg0: Test) => void>>} testCases_262
|
|
128
|
+
* @returns {Array<Pair_277<string, Array<string>>>}
|
|
129
129
|
*/
|
|
130
|
-
export function processTestCases(
|
|
131
|
-
function
|
|
132
|
-
let t_263;
|
|
133
|
-
let t_264;
|
|
130
|
+
export function processTestCases(testCases_262) {
|
|
131
|
+
function fn_263(testCase_264) {
|
|
134
132
|
let t_265;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const
|
|
138
|
-
|
|
133
|
+
let t_266;
|
|
134
|
+
let t_267;
|
|
135
|
+
const key_268 = testCase_264.key;
|
|
136
|
+
const fun_269 = testCase_264.value;
|
|
137
|
+
const test_270 = new Test();
|
|
138
|
+
let hadBubble_271;
|
|
139
139
|
try {
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
fun_269(test_270);
|
|
141
|
+
hadBubble_271 = false;
|
|
142
142
|
} catch {
|
|
143
|
-
|
|
143
|
+
hadBubble_271 = true;
|
|
144
144
|
}
|
|
145
|
-
const
|
|
146
|
-
let
|
|
147
|
-
if (
|
|
148
|
-
|
|
145
|
+
const messages_272 = test_270.messages();
|
|
146
|
+
let failures_273;
|
|
147
|
+
if (test_270.passing) {
|
|
148
|
+
failures_273 = listify_69();
|
|
149
149
|
} else {
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
if (hadBubble_271) {
|
|
151
|
+
t_265 = test_270.failedOnAssert;
|
|
152
|
+
t_267 = ! t_265;
|
|
153
153
|
} else {
|
|
154
|
-
|
|
154
|
+
t_267 = false;
|
|
155
155
|
}
|
|
156
|
-
if (
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
156
|
+
if (t_267) {
|
|
157
|
+
const allMessages_274 = messages_272.slice();
|
|
158
|
+
listBuilderAdd_120(allMessages_274, "Bubble");
|
|
159
|
+
t_266 = listBuilderToList_247(allMessages_274);
|
|
160
|
+
failures_273 = t_266;
|
|
161
161
|
} else {
|
|
162
|
-
|
|
162
|
+
failures_273 = messages_272;
|
|
163
163
|
}
|
|
164
164
|
}
|
|
165
|
-
return
|
|
165
|
+
return pairConstructor_275(key_268, failures_273);
|
|
166
166
|
}
|
|
167
|
-
return
|
|
167
|
+
return listedMap_276(testCases_262, fn_263);
|
|
168
168
|
};
|
|
169
|
-
/** @param {Array<
|
|
170
|
-
export function reportTestResults(
|
|
171
|
-
let
|
|
172
|
-
let t_278;
|
|
173
|
-
let t_279;
|
|
169
|
+
/** @param {Array<Pair_277<string, Array<string>>>} testResults_278 */
|
|
170
|
+
export function reportTestResults(testResults_278) {
|
|
171
|
+
let return_279;
|
|
174
172
|
let t_280;
|
|
175
173
|
let t_281;
|
|
176
|
-
let
|
|
177
|
-
|
|
174
|
+
let t_282;
|
|
175
|
+
let t_283;
|
|
176
|
+
let i_284 = 0;
|
|
177
|
+
s__1288_285: {
|
|
178
178
|
while (true) {
|
|
179
|
-
|
|
180
|
-
if (
|
|
179
|
+
t_280 = testResults_278.length;
|
|
180
|
+
if (i_284 < t_280) {
|
|
181
181
|
try {
|
|
182
|
-
|
|
182
|
+
t_283 = listedGet_159(testResults_278, i_284);
|
|
183
183
|
} catch {
|
|
184
184
|
break;
|
|
185
185
|
}
|
|
186
|
-
const
|
|
187
|
-
const
|
|
188
|
-
if (!
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
const testResult_286 = t_283;
|
|
187
|
+
const failureMessages_287 = testResult_286.value;
|
|
188
|
+
if (! failureMessages_287.length) {
|
|
189
|
+
t_282 = testResult_286.key;
|
|
190
|
+
console_231.log(strCat_129(t_282, ": Passed"));
|
|
191
191
|
} else {
|
|
192
|
-
function
|
|
193
|
-
return
|
|
192
|
+
function fn_288(it_289) {
|
|
193
|
+
return it_289;
|
|
194
194
|
}
|
|
195
|
-
const
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
const message_290 = listedJoin_99(failureMessages_287, ", ", fn_288);
|
|
196
|
+
t_281 = testResult_286.key;
|
|
197
|
+
console_231.log(strCat_129(t_281, ": Failed ", message_290));
|
|
198
198
|
}
|
|
199
|
-
|
|
199
|
+
i_284 = i_284 + 1;
|
|
200
200
|
} else {
|
|
201
|
-
|
|
202
|
-
break
|
|
201
|
+
return_279 = void 0;
|
|
202
|
+
break s__1288_285;
|
|
203
203
|
}
|
|
204
204
|
}
|
|
205
205
|
throw Error();
|
|
206
206
|
}
|
|
207
|
-
return
|
|
207
|
+
return return_279;
|
|
208
208
|
};
|
|
209
|
-
/** @param {Array<
|
|
210
|
-
export function runTestCases(
|
|
211
|
-
reportTestResults(processTestCases(
|
|
209
|
+
/** @param {Array<Pair_277<string, (arg0: Test) => void>>} testCases_291 */
|
|
210
|
+
export function runTestCases(testCases_291) {
|
|
211
|
+
reportTestResults(processTestCases(testCases_291));
|
|
212
212
|
return;
|
|
213
213
|
};
|
|
214
214
|
/**
|
|
215
|
-
* @param {(arg0: Test) => void}
|
|
215
|
+
* @param {(arg0: Test) => void} testFun_292
|
|
216
216
|
* @returns {void}
|
|
217
217
|
*/
|
|
218
|
-
export function runTest(
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
218
|
+
export function runTest(testFun_292) {
|
|
219
|
+
const test_293 = new Test();
|
|
220
|
+
testFun_292(test_293);
|
|
221
|
+
test_293.softFailToHard();
|
|
222
222
|
return;
|
|
223
223
|
};
|
package/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "version": 3, "file": "js/std/testing.js", "sources": [ "std/testing.temper.md" ], "sourcesContent": [ "# Temper test framework\n\n## Test instance\n\nWe currently convert assert and check macro calls into method calls on a `Test`\ninstance.\n\n export class Test {\n\nRecommended default Temper assert is soft, meaning that it records failures for\nreporting but doesn't immediately end test execution on a false value. This lets\nyou check multiple conditions more easily.\n\n @connected(\u0022Test::assert\u0022)\n public assert(success: Boolean, message: fn (): String): Void {\n if (!success) {\n _passing = false;\n _messages.add(message());\n }\n }\n\nTypical hard asserts that end the test on false condition also are available.\n\n @connected(\u0022Test::assertHard\u0022)\n public assertHard(\n success: Boolean,\n message: fn (): String,\n ): Void | Bubble {\n assert(success, message);\n if (!success) {\n // Attempt to distinguish assert fails from others.\n // Sadly, they can still orelse an assert failure, so this isn't\n // flawless.\n _failedOnAssert = true;\n bail();\n }\n }\n\nHarden and end current test on any pending failure if not previously hardened.\nBackends typically insert calls to this if needed, but you can also call it\nmanually at any desired point in your test.\n\n public softFailToHard(): Void | Bubble {\n if (hasUnhandledFail) {\n _failedOnAssert = true;\n bail();\n }\n }\n\nProvide a bailing `Bubble` method here that enables backends to customize\nmessage delivery on failure.\n\n @connected(\u0022Test::bail\u0022)\n bail(): Bubble {\n bubble()\n }\n\nYou can check the current passing state of the test at any time. A test is\ncurrently passing if all soft checks and hard asserts have been succesful.\n\nTODO Does this need to be function call syntax for macro purposes?\n\n @connected(\u0022Test::passing\u0022)\n public get passing(): Boolean { _passing }\n\nMessages access is presented as a function because it likely allocates. Also,\nmessages might be automatically constructed in some cases, so it's possibly\nunwise to depend on their exact formatting.\n\n @connected(\u0022Test::messages\u0022)\n public messages(): List\u003cString\u003e { _messages.toList() }\n\n### Backend helper methods\n\nAvoid using backend helper methods in user code. Their behavior might be\nunreliable on some backends and/or have high risk of changing in future releases\nof Temper.\n\n @connected(\u0022Test::failedOnAssert\u0022)\n public get failedOnAssert(): Boolean { _failedOnAssert }\n\nAdditional helper methods to simplify backend code generation in some contexts.\n\n public get hasUnhandledFail(): Boolean { !(_failedOnAssert || _passing) }\n\nSimple helper to get multiple messages combined for now. We probably want to do\nfancier things in the future, but this can simplify backends for now.\n\n public messagesCombined(): String | Null {\n if (_messages.isEmpty) {\n // Unexpected, but most backends can do something with null.\n null\n } else {\n _messages.join(\u0022, \u0022) { (it);; it }\n }\n }\n\n private var _failedOnAssert: Boolean = false;\n private var _passing: Boolean = true;\n private _messages: ListBuilder\u003cString\u003e = new ListBuilder\u003cString\u003e();\n }\n\n## Interpreter testing support\n\nNOTICE: Don't directly anything in this section. It just exists for the\nimplementation of testing within the interpreter.\n\n export let TestCase = Pair\u003cTestName, TestFun\u003e;\n export let TestFailureMessage = String;\n export let TestFun = fn (Test): Void | Bubble;\n export let TestName = String;\n export let TestResult = Pair\u003cTestName, List\u003cTestFailureMessage\u003e\u003e;\n\n @connected(\u0022::processTestCases\u0022)\n export let processTestCases(testCases: List\u003cTestCase\u003e): List\u003cTestResult\u003e {\n testCases.map { (testCase): TestResult;;\n let { key, value as fun } = testCase;\n let test = new Test();\n // Actually call the test.\n let hadBubble = do {\n fun(test);\n false\n } orelse true;\n // Now get the messages.\n let messages = test.messages();\n let failures: List\u003cTestFailureMessage\u003e = if (test.passing) {\n []\n } else if (hadBubble \u0026\u0026 !test.failedOnAssert) {\n // Despite having 1+ failure messages, we seem to have failed on some\n // Bubble separate from asserts, so add that on.\n let allMessages = messages.toListBuilder();\n allMessages.add(\u0022Bubble\u0022);\n allMessages.toList()\n } else {\n messages\n };\n // Package up with test name.\n new Pair(key, failures)\n }\n }\n\n @connected(\u0022::reportTestResults\u0022)\n export let reportTestResults(testResults: List\u003cTestResult\u003e): Void {\n // TODO Write as junit xml (or tap if we switch to that).\n for (var i = 0; i \u003c testResults.length; i += 1) {\n let testResult = testResults[i];\n let failureMessages = testResult.value;\n if (failureMessages.isEmpty) {\n console.log(\u0022\u0024{testResult.key}: Passed\u0022);\n } else {\n let message = failureMessages.join(\u0022, \u0022) { (it);; it };\n console.log(\u0022\u0024{testResult.key}: Failed \u0024{message}\u0022);\n }\n }\n }\n\n @connected(\u0022::runTestCases\u0022)\n export let runTestCases(testCases: List\u003cTestCase\u003e): Void {\n reportTestResults(processTestCases(testCases));\n }\n\nTODO Is this a better idea than inlining each case? We'd need to generate\n`fun testFunction() { runTest(originalFunctionAsCallback) }` or some such.\n\n export let runTest(testFun: TestFun): Void | Bubble {\n let test = new Test();\n testFun(test);\n test.softFailToHard();\n }\n" ], "names": [ "Test", "success", "message", "_passing", "_messages", "_failedOnAssert", "return", "fn", "it", "TestName", "TestFun", "TestCase", "TestFailureMessage", "TestResult", "processTestCases", "testCases", "testCase", "key", "fun", "test", "hadBubble", "messages", "failures", "allMessages", "reportTestResults", "testResults", "i", "testResult", "failureMessages", "runTestCases", "runTest", "testFun" ], "mappings": "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" }
|
|
1
|
+
{ "version": 3, "file": "js/std/testing.js", "sources": [ "std/testing.temper.md" ], "sourcesContent": [ "# Temper test framework\n\n## Test instance\n\nWe currently convert assert and check macro calls into method calls on a `Test`\ninstance.\n\n export class Test {\n\nRecommended default Temper assert is soft, meaning that it records failures for\nreporting but doesn't immediately end test execution on a false value. This lets\nyou check multiple conditions more easily.\n\n @connected(\u0022Test::assert\u0022)\n public assert(success: Boolean, message: fn (): String): Void {\n if (!success) {\n _passing = false;\n _messages.add(message());\n }\n }\n\nTypical hard asserts that end the test on false condition also are available.\n\n @connected(\u0022Test::assertHard\u0022)\n public assertHard(\n success: Boolean,\n message: fn (): String,\n ): Void | Bubble {\n assert(success, message);\n if (!success) {\n // Attempt to distinguish assert fails from others.\n // Sadly, they can still orelse an assert failure, so this isn't\n // flawless.\n _failedOnAssert = true;\n bail();\n }\n }\n\nHarden and end current test on any pending failure if not previously hardened.\nBackends typically insert calls to this if needed, but you can also call it\nmanually at any desired point in your test.\n\n public softFailToHard(): Void | Bubble {\n if (hasUnhandledFail) {\n _failedOnAssert = true;\n bail();\n }\n }\n\nProvide a bailing `Bubble` method here that enables backends to customize\nmessage delivery on failure.\n\n @connected(\u0022Test::bail\u0022)\n bail(): Bubble {\n bubble()\n }\n\nYou can check the current passing state of the test at any time. A test is\ncurrently passing if all soft checks and hard asserts have been succesful.\n\nTODO Does this need to be function call syntax for macro purposes?\n\n @connected(\u0022Test::passing\u0022)\n public get passing(): Boolean { _passing }\n\nMessages access is presented as a function because it likely allocates. Also,\nmessages might be automatically constructed in some cases, so it's possibly\nunwise to depend on their exact formatting.\n\n @connected(\u0022Test::messages\u0022)\n public messages(): List\u003cString\u003e { _messages.toList() }\n\n### Backend helper methods\n\nAvoid using backend helper methods in user code. Their behavior might be\nunreliable on some backends and/or have high risk of changing in future releases\nof Temper.\n\n @connected(\u0022Test::failedOnAssert\u0022)\n public get failedOnAssert(): Boolean { _failedOnAssert }\n\nAdditional helper methods to simplify backend code generation in some contexts.\n\n public get hasUnhandledFail(): Boolean { !(_failedOnAssert || _passing) }\n\nSimple helper to get multiple messages combined for now. We probably want to do\nfancier things in the future, but this can simplify backends for now.\n\n public messagesCombined(): String | Null {\n if (_messages.isEmpty) {\n // Unexpected, but most backends can do something with null.\n null\n } else {\n _messages.join(\u0022, \u0022) { (it);; it }\n }\n }\n\n private var _failedOnAssert: Boolean = false;\n private var _passing: Boolean = true;\n private _messages: ListBuilder\u003cString\u003e = new ListBuilder\u003cString\u003e();\n }\n\n## Interpreter testing support\n\nNOTICE: Don't directly anything in this section. It just exists for the\nimplementation of testing within the interpreter.\n\n export let TestCase = Pair\u003cTestName, TestFun\u003e;\n export let TestFailureMessage = String;\n export let TestFun = fn (Test): Void | Bubble;\n export let TestName = String;\n export let TestResult = Pair\u003cTestName, List\u003cTestFailureMessage\u003e\u003e;\n\n @connected(\u0022::processTestCases\u0022)\n export let processTestCases(testCases: List\u003cTestCase\u003e): List\u003cTestResult\u003e {\n testCases.map { (testCase): TestResult;;\n let { key, value as fun } = testCase;\n let test = new Test();\n // Actually call the test.\n let hadBubble = do {\n fun(test);\n false\n } orelse true;\n // Now get the messages.\n let messages = test.messages();\n let failures: List\u003cTestFailureMessage\u003e = if (test.passing) {\n []\n } else if (hadBubble \u0026\u0026 !test.failedOnAssert) {\n // Despite having 1+ failure messages, we seem to have failed on some\n // Bubble separate from asserts, so add that on.\n let allMessages = messages.toListBuilder();\n allMessages.add(\u0022Bubble\u0022);\n allMessages.toList()\n } else {\n messages\n };\n // Package up with test name.\n new Pair(key, failures)\n }\n }\n\n @connected(\u0022::reportTestResults\u0022)\n export let reportTestResults(testResults: List\u003cTestResult\u003e): Void {\n // TODO Write as junit xml (or tap if we switch to that).\n for (var i = 0; i \u003c testResults.length; i += 1) {\n let testResult = testResults[i];\n let failureMessages = testResult.value;\n if (failureMessages.isEmpty) {\n console.log(\u0022\u0024{testResult.key}: Passed\u0022);\n } else {\n let message = failureMessages.join(\u0022, \u0022) { (it);; it };\n console.log(\u0022\u0024{testResult.key}: Failed \u0024{message}\u0022);\n }\n }\n }\n\n @connected(\u0022::runTestCases\u0022)\n export let runTestCases(testCases: List\u003cTestCase\u003e): Void {\n reportTestResults(processTestCases(testCases));\n }\n\nTODO Is this a better idea than inlining each case? We'd need to generate\n`fun testFunction() { runTest(originalFunctionAsCallback) }` or some such.\n\n export let runTest(testFun: TestFun): Void | Bubble {\n let test = new Test();\n testFun(test);\n test.softFailToHard();\n }\n" ], "names": [ "Test", "success", "message", "_passing", "_messages", "_failedOnAssert", "return", "fn", "it", "TestName", "TestFun", "TestCase", "TestFailureMessage", "TestResult", "processTestCases", "testCases", "testCase", "key", "fun", "test", "hadBubble", "messages", "failures", "allMessages", "reportTestResults", "testResults", "i", "testResult", "failureMessages", "runTestCases", "runTest", "testFun" ], "mappings": "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" }
|