as-test 0.1.3 → 0.1.5
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/.github/workflows/{nodejs.yml → as-test.yml} +10 -9
- package/.prettierrc +3 -0
- package/CHANGELOG.md +4 -1
- package/README.md +18 -65
- package/as-test.config.json +22 -0
- package/asconfig.json +30 -33
- package/assembly/__tests__/example.spec.ts +70 -0
- package/assembly/coverage.ts +15 -15
- package/assembly/index.ts +197 -135
- package/assembly/reporters/tap.ts +30 -0
- package/assembly/src/expectation.ts +302 -277
- package/assembly/src/group.ts +33 -33
- package/assembly/src/node.ts +7 -7
- package/assembly/test.ts +43 -46
- package/assembly/tsconfig.json +96 -98
- package/assembly/util.ts +90 -87
- package/bin/build.js +119 -0
- package/bin/index.js +159 -0
- package/bin/init.js +40 -0
- package/bin/package.json +3 -0
- package/bin/run.js +53 -0
- package/bin/types.js +41 -0
- package/bin/util.js +23 -0
- package/cli/build.ts +154 -0
- package/cli/index.ts +201 -0
- package/cli/init.ts +47 -0
- package/cli/run.ts +68 -0
- package/cli/tsconfig.json +8 -0
- package/cli/types.ts +34 -0
- package/cli/util.ts +30 -0
- package/index.ts +1 -1
- package/jest.test.js +44 -5
- package/package.json +19 -16
- package/tests/test.tap +14 -0
- package/transform/lib/index.js +391 -397
- package/transform/package.json +4 -4
- package/transform/src/index.ts +474 -506
- package/transform/tsconfig.json +2 -2
- package/assembly/example.spec.ts +0 -5
- package/src/cli.ts +0 -0
package/assembly/index.ts
CHANGED
|
@@ -2,17 +2,17 @@ import { rainbow } from "as-rainbow";
|
|
|
2
2
|
import { TestGroup } from "./src/group";
|
|
3
3
|
import { Expectation } from "./src/expectation";
|
|
4
4
|
import { formatTime } from "./util";
|
|
5
|
-
import { stringify } from "as-console/
|
|
6
|
-
import {
|
|
5
|
+
import { stringify } from "as-console/stringify";
|
|
6
|
+
import { __COVER, __HASHES, __POINTS } from "as-test/assembly/coverage";
|
|
7
7
|
import { createTable } from "table-as";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Enumeration representing the verdict of a test case.
|
|
11
11
|
*/
|
|
12
12
|
export enum Verdict {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
Unreachable,
|
|
14
|
+
Ok,
|
|
15
|
+
Fail,
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
// Globals
|
|
@@ -28,10 +28,10 @@ let __test_options!: RunOptions;
|
|
|
28
28
|
|
|
29
29
|
/**
|
|
30
30
|
* Creates a test group containing multiple test cases.
|
|
31
|
-
*
|
|
31
|
+
*
|
|
32
32
|
* @param {string} description - The name of the test group
|
|
33
33
|
* @param {() => void} callback - The block containing the test cases for this group
|
|
34
|
-
*
|
|
34
|
+
*
|
|
35
35
|
* @example
|
|
36
36
|
* ```ts
|
|
37
37
|
* describe("my test suite", () => {
|
|
@@ -41,20 +41,20 @@ let __test_options!: RunOptions;
|
|
|
41
41
|
* ```
|
|
42
42
|
*/
|
|
43
43
|
export function describe(description: string, callback: () => void): void {
|
|
44
|
-
|
|
44
|
+
const group = new TestGroup(description, callback);
|
|
45
45
|
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
current_group = group;
|
|
47
|
+
groups.push(group);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
51
51
|
* Creates a test group containing multiple test cases
|
|
52
|
-
*
|
|
52
|
+
*
|
|
53
53
|
* @param {string} description - The name of the test group
|
|
54
54
|
* @param {() => void} callback - The block containing the test cases for this group
|
|
55
|
-
*
|
|
55
|
+
*
|
|
56
56
|
* @example
|
|
57
|
-
*
|
|
57
|
+
*
|
|
58
58
|
* ```ts
|
|
59
59
|
* test("1 + 3 = 4", () => {
|
|
60
60
|
* expect(1 + 3).toBe(4);
|
|
@@ -62,20 +62,20 @@ export function describe(description: string, callback: () => void): void {
|
|
|
62
62
|
* ```
|
|
63
63
|
*/
|
|
64
64
|
export function test(description: string, callback: () => void): void {
|
|
65
|
-
|
|
65
|
+
const group = new TestGroup(description, callback);
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
current_group = group;
|
|
68
|
+
groups.push(group);
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
/**
|
|
72
72
|
* Creates a test group containing multiple test cases
|
|
73
|
-
*
|
|
73
|
+
*
|
|
74
74
|
* @param {string} description - The name of the test group
|
|
75
75
|
* @param {() => void} callback - The block containing the test cases for this group
|
|
76
|
-
*
|
|
76
|
+
*
|
|
77
77
|
* @example
|
|
78
|
-
*
|
|
78
|
+
*
|
|
79
79
|
* ```ts
|
|
80
80
|
* it("should perform additions", () => {
|
|
81
81
|
* expect(1 + 3).toBe(4);
|
|
@@ -83,22 +83,22 @@ export function test(description: string, callback: () => void): void {
|
|
|
83
83
|
* ```
|
|
84
84
|
*/
|
|
85
85
|
export function it(description: string, callback: () => void): void {
|
|
86
|
-
|
|
86
|
+
const group = new TestGroup(description, callback);
|
|
87
87
|
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
current_group = group;
|
|
89
|
+
groups.push(group);
|
|
90
90
|
}
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
* Creates an expectation object for making assertions within a test case.
|
|
94
|
-
*
|
|
95
|
-
* Use this function to chain assertions about a specific value.
|
|
96
|
-
* The returned expectation object provides various methods for testing
|
|
94
|
+
*
|
|
95
|
+
* Use this function to chain assertions about a specific value.
|
|
96
|
+
* The returned expectation object provides various methods for testing
|
|
97
97
|
* different properties and conditions of the value.
|
|
98
|
-
*
|
|
98
|
+
*
|
|
99
99
|
* @param {T} value - The value to be asserted against.
|
|
100
100
|
* @returns {Expectation<T>} - The expectation object for chaining assertions.
|
|
101
|
-
*
|
|
101
|
+
*
|
|
102
102
|
* @example
|
|
103
103
|
* ```ts
|
|
104
104
|
* test("number comparison", () => {
|
|
@@ -108,94 +108,93 @@ export function it(description: string, callback: () => void): void {
|
|
|
108
108
|
* ```
|
|
109
109
|
*/
|
|
110
110
|
export function expect<T>(value: T): Expectation<T> {
|
|
111
|
-
|
|
112
|
-
|
|
111
|
+
const result = new Expectation<T>(value);
|
|
112
|
+
current_group!.addExpectation(result);
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
return result;
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
/**
|
|
118
118
|
* Formats and prints content to the terminal
|
|
119
119
|
* Can be disabled like so:
|
|
120
|
-
*
|
|
120
|
+
*
|
|
121
121
|
* ```js
|
|
122
122
|
* // ...
|
|
123
|
-
*
|
|
123
|
+
*
|
|
124
124
|
* run({ log: false });
|
|
125
125
|
* ```
|
|
126
|
-
*
|
|
126
|
+
*
|
|
127
127
|
* @param {T} data - The data to format and print
|
|
128
128
|
*/
|
|
129
129
|
export function log<T>(data: T): void {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
console.log("");
|
|
130
|
+
if (!__test_options.log) return;
|
|
131
|
+
const formatted = stringify(data);
|
|
132
|
+
if (formatted) {
|
|
133
|
+
const lines = formatted.split("\n");
|
|
134
|
+
for (let i = 0; i < lines.length; i++) {
|
|
135
|
+
const line = unchecked(lines[i]);
|
|
136
|
+
console.log(" " + rainbow.bgYellow(" LOG ") + " " + line);
|
|
139
137
|
}
|
|
138
|
+
console.log("");
|
|
139
|
+
}
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
143
|
* Registers a callback function to be executed before each test group is run.
|
|
144
|
-
*
|
|
144
|
+
*
|
|
145
145
|
* @param {() => void} callback - The function to be executed before each test group.
|
|
146
146
|
*/
|
|
147
147
|
export function beforeAll(callback: () => void): void {
|
|
148
|
-
|
|
148
|
+
before_all_callback = callback;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
/**
|
|
152
152
|
* Registers a callback function to be executed after each test group is run.
|
|
153
|
-
*
|
|
153
|
+
*
|
|
154
154
|
* @param {() => void} callback - The function to be executed after each test group.
|
|
155
155
|
*/
|
|
156
156
|
export function afterAll(callback: () => void): void {
|
|
157
|
-
|
|
157
|
+
after_all_callback = callback;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
/**
|
|
161
161
|
* Registers a callback function to be executed before each test case is run.
|
|
162
|
-
*
|
|
162
|
+
*
|
|
163
163
|
* @param {() => void} callback - The function to be executed before each test case.
|
|
164
164
|
*/
|
|
165
165
|
export function beforeEach(callback: () => void): void {
|
|
166
|
-
|
|
166
|
+
before_each_callback = callback;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
/**
|
|
170
170
|
* Registers a callback function to be executed after each test case is run.
|
|
171
|
-
*
|
|
171
|
+
*
|
|
172
172
|
* @param {() => void} callback - The function to be executed after each test case.
|
|
173
173
|
*/
|
|
174
174
|
export function afterEach(callback: () => void): void {
|
|
175
|
-
|
|
175
|
+
after_each_callback = callback;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
178
|
/**
|
|
179
179
|
* Class defining options that can be passed to the `run` function.
|
|
180
|
-
*
|
|
180
|
+
*
|
|
181
181
|
* Currently, it offers a single option:
|
|
182
|
-
*
|
|
182
|
+
*
|
|
183
183
|
* - `log` (boolean, default: true): Controls whether enable the log() function
|
|
184
184
|
**/
|
|
185
185
|
class RunOptions {
|
|
186
|
-
|
|
187
|
-
coverage: boolean = false;
|
|
186
|
+
log: boolean = true;
|
|
188
187
|
}
|
|
189
188
|
|
|
190
189
|
/**
|
|
191
190
|
* Runs all the test suites defined within the current test scope.
|
|
192
|
-
*
|
|
191
|
+
*
|
|
193
192
|
* This function executes all the test cases you've defined in your test suites.
|
|
194
193
|
* It iterates through each suite, runs the tests within the suite, and tracks results.
|
|
195
194
|
* Finally, it prints a colorful summary of the test execution.
|
|
196
|
-
*
|
|
195
|
+
*
|
|
197
196
|
* @param {RunOptions} [options] - Optional options for running tests.
|
|
198
|
-
*
|
|
197
|
+
*
|
|
199
198
|
* @example
|
|
200
199
|
* ```javascript
|
|
201
200
|
* describe("Math operations", () => {
|
|
@@ -204,95 +203,158 @@ class RunOptions {
|
|
|
204
203
|
* });
|
|
205
204
|
* // ... other tests
|
|
206
205
|
* });
|
|
207
|
-
*
|
|
206
|
+
*
|
|
208
207
|
* run(); // Executes all tests in the "Math operations" suite
|
|
209
208
|
* ```
|
|
210
209
|
*/
|
|
211
210
|
export function run(options: RunOptions = new RunOptions()): void {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
211
|
+
__test_options = options;
|
|
212
|
+
console.log(
|
|
213
|
+
rainbow.boldMk(
|
|
214
|
+
rainbow.blueBright(` _____ _____ _____ _____ _____ _____ `),
|
|
215
|
+
),
|
|
216
|
+
);
|
|
217
|
+
console.log(
|
|
218
|
+
rainbow.boldMk(
|
|
219
|
+
rainbow.blueBright(`| _ || __| ___|_ _|| __|| __||_ _|`),
|
|
220
|
+
),
|
|
221
|
+
);
|
|
222
|
+
console.log(
|
|
223
|
+
rainbow.boldMk(
|
|
224
|
+
rainbow.blueBright(`| ||__ ||___| | | | __||__ | | | `),
|
|
225
|
+
),
|
|
226
|
+
);
|
|
227
|
+
console.log(
|
|
228
|
+
rainbow.boldMk(
|
|
229
|
+
rainbow.blueBright(`|__|__||_____| |_| |_____||_____| |_| `),
|
|
230
|
+
),
|
|
231
|
+
);
|
|
232
|
+
console.log(
|
|
233
|
+
rainbow.dimMk("\n------------------- v0.1.5 -------------------\n"),
|
|
234
|
+
);
|
|
235
|
+
// @ts-ignore
|
|
236
|
+
if (isDefined(COVERAGE_USE)) {
|
|
237
|
+
console.log(
|
|
238
|
+
rainbow.bgBlueBright(" PLUGIN ") +
|
|
239
|
+
" " +
|
|
240
|
+
rainbow.dimMk("Using Code Coverage") +
|
|
241
|
+
"\n",
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
const suites = groups.length;
|
|
245
|
+
let failed = 0;
|
|
246
|
+
let tests = 0;
|
|
247
|
+
let failed_tests = 0;
|
|
248
|
+
let failed_suite_logs = "";
|
|
249
|
+
const start = performance.now();
|
|
250
|
+
for (let i = 0; i < groups.length; i++) {
|
|
251
|
+
if (before_all_callback) before_all_callback();
|
|
252
|
+
const suite = unchecked(groups[i]);
|
|
253
|
+
suite.run();
|
|
254
|
+
for (let i = 0; i < suite.results.length; i++) {
|
|
255
|
+
const expectation = unchecked(suite.results[i]);
|
|
256
|
+
const verdict = expectation.verdict;
|
|
257
|
+
tests++;
|
|
258
|
+
if (verdict == Verdict.Ok) {
|
|
259
|
+
suite.passed++;
|
|
260
|
+
} else if (verdict == Verdict.Fail) {
|
|
261
|
+
suite.verdict = Verdict.Fail;
|
|
262
|
+
suite.failed++;
|
|
263
|
+
failed_tests++;
|
|
264
|
+
}
|
|
220
265
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (verdict == Verdict.Ok) {
|
|
236
|
-
suite.passed++;
|
|
237
|
-
} else if (verdict == Verdict.Fail) {
|
|
238
|
-
suite.verdict = Verdict.Fail;
|
|
239
|
-
suite.failed++;
|
|
240
|
-
failed_tests++;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
if (suite.verdict == Verdict.Unreachable) {
|
|
244
|
-
suite.verdict = Verdict.Ok;
|
|
245
|
-
console.log(rainbow.bgGreenBright(" PASS ") + " " + rainbow.dimMk(suite.description) + "\n");
|
|
246
|
-
} else {
|
|
247
|
-
failed++;
|
|
248
|
-
const txt = rainbow.bgRed(" FAIL ") + " " + rainbow.dimMk(suite.description) + "\n";
|
|
249
|
-
failed_suite_logs += txt
|
|
250
|
-
console.log(txt);
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const report = suite.getLogs();
|
|
254
|
-
if (report) {
|
|
255
|
-
if (report.passed) console.log(report.passed!);
|
|
256
|
-
if (report.failed) failed_suite_logs += report.failed!;
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
if (after_all_callback) after_all_callback();
|
|
266
|
+
if (suite.verdict == Verdict.Unreachable) {
|
|
267
|
+
suite.verdict = Verdict.Ok;
|
|
268
|
+
console.log(
|
|
269
|
+
rainbow.bgGreenBright(" PASS ") +
|
|
270
|
+
" " +
|
|
271
|
+
rainbow.dimMk(suite.description) +
|
|
272
|
+
"\n",
|
|
273
|
+
);
|
|
274
|
+
} else {
|
|
275
|
+
failed++;
|
|
276
|
+
const txt =
|
|
277
|
+
rainbow.bgRed(" FAIL ") + " " + rainbow.dimMk(suite.description) + "\n";
|
|
278
|
+
failed_suite_logs += txt;
|
|
279
|
+
console.log(txt);
|
|
260
280
|
}
|
|
261
281
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
282
|
+
const report = suite.getLogs();
|
|
283
|
+
if (report) {
|
|
284
|
+
if (report.passed) console.log(report.passed!);
|
|
285
|
+
if (report.failed) failed_suite_logs += report.failed!;
|
|
265
286
|
}
|
|
287
|
+
if (after_all_callback) after_all_callback();
|
|
288
|
+
}
|
|
266
289
|
|
|
290
|
+
if (failed) {
|
|
291
|
+
console.log(
|
|
292
|
+
rainbow.red("------------------ [FAILED] ------------------\n"),
|
|
293
|
+
);
|
|
294
|
+
console.log(failed_suite_logs);
|
|
295
|
+
}
|
|
267
296
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
297
|
+
// @ts-ignore
|
|
298
|
+
if (isDefined(COVERAGE_USE) && isDefined(COVERAGE_SHOW) && __HASHES().size) {
|
|
299
|
+
console.log(
|
|
300
|
+
rainbow.dimMk("----------------- [COVERAGE] -----------------\n"),
|
|
301
|
+
);
|
|
302
|
+
const points = __HASHES().values();
|
|
271
303
|
|
|
272
|
-
|
|
273
|
-
["Location", "Type", "Hash"]
|
|
274
|
-
];
|
|
304
|
+
const table: string[][] = [["Location", "Type", "Hash"]];
|
|
275
305
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
306
|
+
for (let i = 0; i < points.length; i++) {
|
|
307
|
+
const point = unchecked(points[i]);
|
|
308
|
+
const file = point.file;
|
|
309
|
+
const reference =
|
|
310
|
+
point.file +
|
|
311
|
+
":" +
|
|
312
|
+
point.line.toString() +
|
|
313
|
+
":" +
|
|
314
|
+
point.column.toString();
|
|
315
|
+
const type = point.type;
|
|
316
|
+
const hash = point.hash;
|
|
317
|
+
table.push([rainbow.underlineMk(reference), type, "#" + hash]);
|
|
285
318
|
}
|
|
319
|
+
console.log(rainbow.dimMk(createTable(table)) + "\n");
|
|
320
|
+
}
|
|
286
321
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
322
|
+
console.log(
|
|
323
|
+
rainbow.dimMk("----------------- [RESULTS] ------------------\n"),
|
|
324
|
+
);
|
|
325
|
+
const ms = performance.now() - start;
|
|
326
|
+
console.log(
|
|
327
|
+
rainbow.boldMk("Test Suites: ") +
|
|
328
|
+
(failed
|
|
329
|
+
? rainbow.boldMk(rainbow.red(failed.toString() + " failed"))
|
|
330
|
+
: rainbow.boldMk(rainbow.green("0 failed"))) +
|
|
331
|
+
", " +
|
|
332
|
+
suites.toString() +
|
|
333
|
+
" total",
|
|
334
|
+
);
|
|
335
|
+
console.log(
|
|
336
|
+
rainbow.boldMk("Tests: ") +
|
|
337
|
+
(failed_tests
|
|
338
|
+
? rainbow.boldMk(rainbow.red(failed_tests.toString() + " failed"))
|
|
339
|
+
: rainbow.boldMk(rainbow.green("0 failed"))) +
|
|
340
|
+
", " +
|
|
341
|
+
tests.toString() +
|
|
342
|
+
" total",
|
|
343
|
+
);
|
|
344
|
+
// @ts-ignore
|
|
345
|
+
if (isDefined(COVERAGE_USE))
|
|
346
|
+
console.log(
|
|
347
|
+
rainbow.boldMk("Coverage: ") +
|
|
348
|
+
(__HASHES().size
|
|
349
|
+
? rainbow.boldMk(rainbow.red(__HASHES().size.toString() + " failed"))
|
|
350
|
+
: rainbow.boldMk(rainbow.green("0 failed"))) +
|
|
351
|
+
", " +
|
|
352
|
+
__POINTS().toString() +
|
|
353
|
+
" total",
|
|
354
|
+
);
|
|
355
|
+
console.log(rainbow.boldMk("Snapshots: ") + "0 total");
|
|
356
|
+
console.log(rainbow.boldMk("Time: ") + formatTime(ms));
|
|
357
|
+
if (failed) {
|
|
358
|
+
process.exit(1);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Verdict } from "..";
|
|
2
|
+
import { TestGroup } from "../src/group";
|
|
3
|
+
|
|
4
|
+
export class TapReporter {
|
|
5
|
+
public groups: TestGroup[];
|
|
6
|
+
constructor(groups: TestGroup[]) {
|
|
7
|
+
this.groups = groups;
|
|
8
|
+
}
|
|
9
|
+
report(): string {
|
|
10
|
+
let out = "TAP version 14\n";
|
|
11
|
+
let totalTests: i32 = this.groups.length;
|
|
12
|
+
|
|
13
|
+
out += "1.." + totalTests.toString();
|
|
14
|
+
for (let i = 0; i < this.groups.length; i++) {
|
|
15
|
+
const group = unchecked(this.groups[i]);
|
|
16
|
+
if (group.verdict === Verdict.Ok) {
|
|
17
|
+
out += `\nok ${i} - ${group.description}`;
|
|
18
|
+
} else if (group.verdict === Verdict.Fail) {
|
|
19
|
+
out += `\nnot ok ${i} - ${group.description}`;
|
|
20
|
+
out += " ---";
|
|
21
|
+
out += ` message: '${group.description}'`;
|
|
22
|
+
out += ` severity: fail`;
|
|
23
|
+
for (let ii = 0; ii < group.results.length; ii++) {
|
|
24
|
+
const res = unchecked(group.results[ii]);
|
|
25
|
+
if (res.verdict === Verdict.Ok) continue;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|