as-test 0.5.1 → 0.5.3

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.
@@ -12,7 +12,36 @@ const COVERAGE_IGNORED_CALLS = new Set([
12
12
  "beforeAll",
13
13
  "afterAll",
14
14
  "mockFn",
15
+ "unmockFn",
15
16
  "mockImport",
17
+ "unmockImport",
18
+ "snapshotImport",
19
+ "restoreImport",
20
+ ]);
21
+ const COVERAGE_IGNORED_BUILTINS = new Set([
22
+ "alignof",
23
+ "changetype",
24
+ "idof",
25
+ "isArray",
26
+ "isArrayLike",
27
+ "isBoolean",
28
+ "isConstant",
29
+ "isDefined",
30
+ "isFloat",
31
+ "isFunction",
32
+ "isInteger",
33
+ "isManaged",
34
+ "isNullable",
35
+ "isReference",
36
+ "isSigned",
37
+ "isString",
38
+ "isUnsigned",
39
+ "load",
40
+ "nameof",
41
+ "offsetof",
42
+ "sizeof",
43
+ "store",
44
+ "unchecked",
16
45
  ]);
17
46
  class CoverPoint {
18
47
  file = "";
@@ -40,6 +69,7 @@ export class CoverageTransform extends Visitor {
40
69
  }
41
70
  super.visitCallExpression(node);
42
71
  }
72
+ visitDecoratorNode(_node, _ref) { }
43
73
  visitBinaryExpression(node) {
44
74
  super.visitBinaryExpression(node);
45
75
  if (node.visited)
@@ -50,6 +80,8 @@ export class CoverageTransform extends Visitor {
50
80
  case 98:
51
81
  case 97: {
52
82
  const right = node.right;
83
+ if (isBuiltinCallExpression(right))
84
+ break;
53
85
  const rightLc = getLineCol(node);
54
86
  const point = new CoverPoint();
55
87
  point.line = rightLc?.line;
@@ -58,18 +90,10 @@ export class CoverageTransform extends Visitor {
58
90
  point.type = CoverType.Expression;
59
91
  point.hash = hash(point);
60
92
  const replacer = new RangeTransform(node);
61
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
62
- file: "${point.file}",
63
- hash: "${point.hash}",
64
- line: ${point.line},
65
- column: ${point.column},
66
- type: "Expression",
67
- executed: false
68
- });`);
93
+ const registerStmt = createRegisterStatement(point);
69
94
  replacer.visit(registerStmt);
70
- const coverExpression = SimpleParser.parseExpression(`(__COVER("${point.hash}"), $$REPLACE_ME)`);
95
+ const coverExpression = createCoverExpression(point.hash, right, node);
71
96
  replacer.visit(coverExpression);
72
- coverExpression.expression.expressions[1] = right;
73
97
  node.right = coverExpression;
74
98
  this.globalStatements.push(registerStmt);
75
99
  break;
@@ -94,16 +118,9 @@ export class CoverageTransform extends Visitor {
94
118
  point.type = CoverType.Function;
95
119
  point.hash = hash(point);
96
120
  const replacer = new RangeTransform(node);
97
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
98
- file: "${point.file}",
99
- hash: "${point.hash}",
100
- line: ${point.line},
101
- column: ${point.column},
102
- type: "Function",
103
- executed: false
104
- })`);
121
+ const registerStmt = createRegisterStatement(point);
105
122
  replacer.visit(registerStmt);
106
- const coverStmt = SimpleParser.parseStatement(`__COVER("${point.hash}")`, true);
123
+ const coverStmt = createCoverStatement(point.hash, node);
107
124
  replacer.visit(coverStmt);
108
125
  const bodyBlock = node.body;
109
126
  bodyBlock.statements.unshift(coverStmt);
@@ -120,6 +137,8 @@ export class CoverageTransform extends Visitor {
120
137
  return;
121
138
  node.initializer.visited = true;
122
139
  super.visitParameter(node);
140
+ if (isBuiltinCallExpression(node.initializer))
141
+ return;
123
142
  const paramLc = getLineCol(node.initializer);
124
143
  const point = new CoverPoint();
125
144
  point.line = paramLc?.line;
@@ -128,19 +147,10 @@ export class CoverageTransform extends Visitor {
128
147
  point.type = CoverType.Expression;
129
148
  point.hash = hash(point);
130
149
  const replacer = new RangeTransform(node);
131
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
132
- file: "${point.file}",
133
- hash: "${point.hash}",
134
- line: ${point.line},
135
- column: ${point.column},
136
- type: "Expression",
137
- executed: false
138
- })`);
150
+ const registerStmt = createRegisterStatement(point);
139
151
  replacer.visit(registerStmt);
140
- const coverExpression = SimpleParser.parseExpression(`(__COVER("${point.hash}"), $$REPLACE_ME)`);
152
+ const coverExpression = createCoverExpression(point.hash, node.initializer, node);
141
153
  replacer.visit(coverExpression);
142
- coverExpression.expression.expressions[1] =
143
- node.initializer;
144
154
  node.initializer = coverExpression;
145
155
  this.globalStatements.push(registerStmt);
146
156
  }
@@ -163,14 +173,7 @@ export class CoverageTransform extends Visitor {
163
173
  point.type = CoverType.Function;
164
174
  point.hash = hash(point);
165
175
  const replacer = new RangeTransform(node);
166
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
167
- file: "${point.file}",
168
- hash: "${point.hash}",
169
- line: ${point.line},
170
- column: ${point.column},
171
- type: "Function",
172
- executed: false
173
- })`);
176
+ const registerStmt = createRegisterStatement(point);
174
177
  replacer.visit(registerStmt);
175
178
  this.globalStatements.push(registerStmt);
176
179
  if (node.body.kind === 35) {
@@ -186,7 +189,7 @@ export class CoverageTransform extends Visitor {
186
189
  node.body = body;
187
190
  }
188
191
  else {
189
- const coverStmt = SimpleParser.parseStatement(`__COVER("${point.hash}")`, true);
192
+ const coverStmt = createCoverStatement(point.hash, node);
190
193
  replacer.visit(coverStmt);
191
194
  if (node.body instanceof BlockStatement) {
192
195
  node.body.statements.unshift(coverStmt);
@@ -209,7 +212,7 @@ export class CoverageTransform extends Visitor {
209
212
  const ifTrue = node.ifTrue;
210
213
  const ifFalse = node.ifFalse;
211
214
  const path = node.range.source.normalizedPath;
212
- if (ifTrue.kind !== 30) {
215
+ if (ifTrue.kind !== 30 && !isBuiltinStatement(ifTrue)) {
213
216
  const trueLc = getLineCol(ifTrue);
214
217
  const point = new CoverPoint();
215
218
  point.line = trueLc?.line;
@@ -218,16 +221,9 @@ export class CoverageTransform extends Visitor {
218
221
  point.type = CoverType.Expression;
219
222
  point.hash = hash(point);
220
223
  const replacer = new RangeTransform(ifTrue);
221
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
222
- file: "${point.file}",
223
- hash: "${point.hash}",
224
- line: ${point.line},
225
- column: ${point.column},
226
- type: "Expression",
227
- executed: false
228
- })`);
224
+ const registerStmt = createRegisterStatement(point);
229
225
  replacer.visit(registerStmt);
230
- const coverStmt = SimpleParser.parseStatement(`{__COVER("${point.hash}")};`, true);
226
+ const coverStmt = Node.createBlockStatement([createCoverStatement(point.hash, ifTrue)], ifTrue.range);
231
227
  replacer.visit(coverStmt);
232
228
  coverStmt.statements.push(ifTrue);
233
229
  node.ifTrue = coverStmt;
@@ -235,7 +231,9 @@ export class CoverageTransform extends Visitor {
235
231
  visitIfTrue = true;
236
232
  visitIfFalse = !!ifFalse;
237
233
  }
238
- if (ifFalse && ifFalse.kind !== 30) {
234
+ if (ifFalse &&
235
+ ifFalse.kind !== 30 &&
236
+ !isBuiltinStatement(ifFalse)) {
239
237
  const falseLc = getLineCol(ifFalse);
240
238
  const point = new CoverPoint();
241
239
  point.line = falseLc?.line;
@@ -243,17 +241,10 @@ export class CoverageTransform extends Visitor {
243
241
  point.file = path;
244
242
  point.type = CoverType.Expression;
245
243
  point.hash = hash(point);
246
- const replacer = new RangeTransform(ifTrue);
247
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
248
- file: "${point.file}",
249
- hash: "${point.hash}",
250
- line: ${point.line},
251
- column: ${point.column},
252
- type: "Expression",
253
- executed: false
254
- })`);
244
+ const replacer = new RangeTransform(ifFalse);
245
+ const registerStmt = createRegisterStatement(point);
255
246
  replacer.visit(registerStmt);
256
- const coverStmt = SimpleParser.parseStatement(`{__COVER("${point.hash}")};`, true);
247
+ const coverStmt = Node.createBlockStatement([createCoverStatement(point.hash, ifFalse)], ifFalse.range);
257
248
  replacer.visit(coverStmt);
258
249
  coverStmt.statements.push(ifFalse);
259
250
  node.ifFalse = coverStmt;
@@ -288,54 +279,40 @@ export class CoverageTransform extends Visitor {
288
279
  const falseExpression = node.ifElse;
289
280
  const path = node.range.source.normalizedPath;
290
281
  {
291
- const trueLc = getLineCol(trueExpression);
292
- const point = new CoverPoint();
293
- point.line = trueLc?.line;
294
- point.column = trueLc?.column;
295
- point.file = path;
296
- point.type = CoverType.Expression;
297
- point.hash = hash(point);
298
- const replacer = new RangeTransform(trueExpression);
299
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
300
- file: "${point.file}",
301
- hash: "${point.hash}",
302
- line: ${point.line},
303
- column: ${point.column},
304
- type: "Expression",
305
- executed: false
306
- })`);
307
- replacer.visit(registerStmt);
308
- const coverExpression = SimpleParser.parseExpression(`(__COVER("${point.hash}"), $$REPLACE_ME)`);
309
- replacer.visit(coverExpression);
310
- coverExpression.expression.expressions[1] =
311
- trueExpression;
312
- node.ifThen = coverExpression;
313
- this.globalStatements.push(registerStmt);
282
+ if (!isBuiltinCallExpression(trueExpression)) {
283
+ const trueLc = getLineCol(trueExpression);
284
+ const point = new CoverPoint();
285
+ point.line = trueLc?.line;
286
+ point.column = trueLc?.column;
287
+ point.file = path;
288
+ point.type = CoverType.Expression;
289
+ point.hash = hash(point);
290
+ const replacer = new RangeTransform(trueExpression);
291
+ const registerStmt = createRegisterStatement(point);
292
+ replacer.visit(registerStmt);
293
+ const coverExpression = createCoverExpression(point.hash, trueExpression, trueExpression);
294
+ replacer.visit(coverExpression);
295
+ node.ifThen = coverExpression;
296
+ this.globalStatements.push(registerStmt);
297
+ }
314
298
  }
315
299
  {
316
- const falseLc = getLineCol(falseExpression);
317
- const point = new CoverPoint();
318
- point.line = falseLc?.line;
319
- point.column = falseLc?.column;
320
- point.file = path;
321
- point.type = CoverType.Expression;
322
- point.hash = hash(point);
323
- const replacer = new RangeTransform(falseExpression);
324
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
325
- file: "${point.file}",
326
- hash: "${point.hash}",
327
- line: ${point.line},
328
- column: ${point.column},
329
- type: "Expression",
330
- executed: false
331
- })`);
332
- replacer.visit(registerStmt);
333
- const coverExpression = SimpleParser.parseExpression(`(__COVER("${point.hash}"), $$REPLACE_ME)`);
334
- replacer.visit(coverExpression);
335
- coverExpression.expression.expressions[1] =
336
- falseExpression;
337
- node.ifElse = coverExpression;
338
- this.globalStatements.push(registerStmt);
300
+ if (!isBuiltinCallExpression(falseExpression)) {
301
+ const falseLc = getLineCol(falseExpression);
302
+ const point = new CoverPoint();
303
+ point.line = falseLc?.line;
304
+ point.column = falseLc?.column;
305
+ point.file = path;
306
+ point.type = CoverType.Expression;
307
+ point.hash = hash(point);
308
+ const replacer = new RangeTransform(falseExpression);
309
+ const registerStmt = createRegisterStatement(point);
310
+ replacer.visit(registerStmt);
311
+ const coverExpression = createCoverExpression(point.hash, falseExpression, falseExpression);
312
+ replacer.visit(coverExpression);
313
+ node.ifElse = coverExpression;
314
+ this.globalStatements.push(registerStmt);
315
+ }
339
316
  }
340
317
  }
341
318
  visitSwitchCase(node) {
@@ -351,16 +328,9 @@ export class CoverageTransform extends Visitor {
351
328
  point.type = CoverType.Block;
352
329
  point.hash = hash(point);
353
330
  const replacer = new RangeTransform(node);
354
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
355
- file: "${point.file}",
356
- hash: "${point.hash}",
357
- line: ${point.line},
358
- column: ${point.column},
359
- type: "Block",
360
- executed: false
361
- })`);
331
+ const registerStmt = createRegisterStatement(point);
362
332
  replacer.visit(registerStmt);
363
- const coverStmt = SimpleParser.parseStatement(`__COVER("${point.hash}")`);
333
+ const coverStmt = createCoverStatement(point.hash, node);
364
334
  replacer.visit(coverStmt);
365
335
  this.globalStatements.push(registerStmt);
366
336
  super.visitSwitchCase(node);
@@ -383,16 +353,9 @@ export class CoverageTransform extends Visitor {
383
353
  point.type = CoverType.Block;
384
354
  point.hash = hash(point);
385
355
  const replacer = new RangeTransform(node);
386
- const registerStmt = SimpleParser.parseTopLevelStatement(`__REGISTER({
387
- file: "${point.file}",
388
- hash: "${point.hash}",
389
- line: ${point.line},
390
- column: ${point.column},
391
- type: "Block",
392
- executed: false
393
- })`);
356
+ const registerStmt = createRegisterStatement(point);
394
357
  replacer.visit(registerStmt);
395
- const coverStmt = SimpleParser.parseStatement(`__COVER("${point.hash}")`);
358
+ const coverStmt = createCoverStatement(point.hash, node);
396
359
  replacer.visit(coverStmt);
397
360
  this.globalStatements.push(registerStmt);
398
361
  super.visitBlockStatement(node);
@@ -411,6 +374,29 @@ export class CoverageTransform extends Visitor {
411
374
  function getCallName(node) {
412
375
  return getExpressionName(node.expression);
413
376
  }
377
+ function isBuiltinStatement(node) {
378
+ if (node.kind !== 38)
379
+ return false;
380
+ return isBuiltinCallExpression(node.expression);
381
+ }
382
+ function isBuiltinCallExpression(node) {
383
+ const unwrapped = unwrapParenthesized(node);
384
+ if (unwrapped.kind !== 9)
385
+ return false;
386
+ const call = unwrapped;
387
+ const expression = unwrapParenthesized(call.expression);
388
+ if (expression.kind !== 6)
389
+ return false;
390
+ const name = expression.text;
391
+ return COVERAGE_IGNORED_BUILTINS.has(name);
392
+ }
393
+ function unwrapParenthesized(node) {
394
+ let current = node;
395
+ while (current.kind === 20) {
396
+ current = current.expression;
397
+ }
398
+ return current;
399
+ }
414
400
  function getExpressionName(node) {
415
401
  switch (node.kind) {
416
402
  case 6:
@@ -453,6 +439,31 @@ function getLineCol(node) {
453
439
  column: node.range.source.columnAt(),
454
440
  };
455
441
  }
442
+ function createRegisterStatement(point) {
443
+ return SimpleParser.parseTopLevelStatement(`__REGISTER_RAW(${asStringLiteral(point.file)}, ${asStringLiteral(point.hash)}, ${point.line}, ${point.column}, ${asStringLiteral(coverTypeToString(point.type))})`);
444
+ }
445
+ function createCoverStatement(hashValue, ref) {
446
+ return Node.createExpressionStatement(createCoverCallExpression(hashValue, ref));
447
+ }
448
+ function createCoverExpression(hashValue, replacement, ref) {
449
+ return Node.createParenthesizedExpression(Node.createCommaExpression([createCoverCallExpression(hashValue, ref), replacement], ref.range), ref.range);
450
+ }
451
+ function createCoverCallExpression(hashValue, ref) {
452
+ return Node.createCallExpression(Node.createIdentifierExpression("__COVER", ref.range), null, [Node.createStringLiteralExpression(hashValue, ref.range)], ref.range);
453
+ }
454
+ function coverTypeToString(type) {
455
+ switch (type) {
456
+ case CoverType.Function:
457
+ return "Function";
458
+ case CoverType.Expression:
459
+ return "Expression";
460
+ default:
461
+ return "Block";
462
+ }
463
+ }
464
+ function asStringLiteral(value) {
465
+ return JSON.stringify(value);
466
+ }
456
467
  function isConcreteSourceBlock(node) {
457
468
  const source = node.range.source;
458
469
  const start = node.range.start;
@@ -8,9 +8,9 @@ import { isStdlib } from "./util.js";
8
8
  export default class Transformer extends Transform {
9
9
  afterParse(parser) {
10
10
  const mock = new MockTransform();
11
- const coverage = new CoverageTransform();
12
11
  const location = new LocationTransform();
13
12
  const log = new LogTransform(parser);
13
+ const coverage = isCoverageEnabled() ? new CoverageTransform() : null;
14
14
  const sources = parser.sources
15
15
  .filter((source) => !isStdlib(source))
16
16
  .sort((_a, _b) => {
@@ -27,19 +27,31 @@ export default class Transformer extends Transform {
27
27
  }
28
28
  });
29
29
  const entryFile = sources.find((v) => v.sourceKind == 1).simplePath;
30
+ const mockedImportTargets = collectMockImportTargets(sources);
31
+ for (const target of mockedImportTargets) {
32
+ mock.importMocked.add(target);
33
+ }
30
34
  for (const source of sources) {
35
+ const sourceInfo = analyzeSourceText(source.text);
31
36
  const shouldInjectRunCall = source.sourceKind == 1 &&
32
- shouldAutoInjectRun(source.text);
37
+ sourceInfo.hasSuiteCalls &&
38
+ !sourceInfo.hasRunCall;
33
39
  const node = Node.createVariableStatement(null, [
34
40
  Node.createVariableDeclaration(Node.createIdentifierExpression("ENTRY_FILE", source.range), null, 8, null, Node.createStringLiteralExpression(entryFile + ".ts", source.range), source.range),
35
41
  ], source.range);
36
42
  source.statements.unshift(node);
37
43
  mock.visit(source);
38
- coverage.visit(source);
39
- location.visit(source);
40
- log.visit(source);
44
+ if (coverage) {
45
+ coverage.visit(source);
46
+ }
47
+ if (sourceInfo.hasExpectCall) {
48
+ location.visit(source);
49
+ }
50
+ if (sourceInfo.hasLogCall) {
51
+ log.visit(source);
52
+ }
41
53
  if (shouldInjectRunCall) {
42
- const runImportPath = detectRunImportPath(source.text);
54
+ const runImportPath = sourceInfo.runImportPath;
43
55
  let runCall = "run();";
44
56
  if (runImportPath) {
45
57
  const autoImport = new Tokenizer(new Source(0, source.normalizedPath, `import { run as __as_test_auto_run } from "${runImportPath}";`));
@@ -52,31 +64,51 @@ export default class Transformer extends Transform {
52
64
  source.statements.push(parser.parseTopLevelStatement(autoCall));
53
65
  parser.currentSource = source;
54
66
  }
55
- if (coverage.globalStatements.length) {
67
+ if (coverage && coverage.globalStatements.length) {
56
68
  source.statements.unshift(...coverage.globalStatements);
57
- const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, 'import { __REGISTER, __COVER } from "as-test/assembly/coverage";'));
69
+ const tokenizer = new Tokenizer(new Source(0, source.normalizedPath, 'import { __REGISTER_RAW, __COVER } from "as-test/assembly/coverage";'));
58
70
  parser.currentSource = tokenizer.source;
59
71
  source.statements.unshift(parser.parseTopLevelStatement(tokenizer));
60
72
  parser.currentSource = source;
73
+ coverage.globalStatements = [];
61
74
  }
62
75
  }
63
- coverage.globalStatements = [];
76
+ if (coverage) {
77
+ coverage.globalStatements = [];
78
+ }
64
79
  }
65
80
  }
66
- function shouldAutoInjectRun(sourceText) {
67
- const text = stripComments(sourceText);
68
- const hasSuiteCalls = /\b(?:describe|test|it)\s*\(/.test(text);
69
- if (!hasSuiteCalls)
70
- return false;
71
- const runAlias = detectRunAlias(text);
72
- if (runAlias && new RegExp(`\\b${escapeRegex(runAlias)}\\s*\\(`).test(text)) {
73
- return false;
81
+ function collectMockImportTargets(sources) {
82
+ const out = new Set();
83
+ const pattern = /\bmockImport\s*\(\s*["']([^"']+)["']/g;
84
+ for (const source of sources) {
85
+ const text = stripComments(source.text);
86
+ for (const match of text.matchAll(pattern)) {
87
+ const target = (match[1] ?? "").trim();
88
+ if (!target.length)
89
+ continue;
90
+ out.add(target);
91
+ }
74
92
  }
75
- const hasRunCall = /\brun\s*\(/.test(text);
76
- return !hasRunCall;
93
+ return out;
77
94
  }
78
- function detectRunImportPath(sourceText) {
95
+ function analyzeSourceText(sourceText) {
79
96
  const text = stripComments(sourceText);
97
+ const runImportPath = detectRunImportPath(text);
98
+ const runAlias = detectRunAlias(text);
99
+ const hasRunCall = runAlias
100
+ ? new RegExp(`\\b${escapeRegex(runAlias)}\\s*\\(`).test(text)
101
+ : /\brun\s*\(/.test(text);
102
+ return {
103
+ hasSuiteCalls: /\b(?:describe|test|it)\s*\(/.test(text),
104
+ hasRunCall,
105
+ runImportPath,
106
+ hasMockCalls: /\b(?:mockFn|unmockFn|mockImport|unmockImport)\s*\(/.test(text),
107
+ hasLogCall: /\blog\s*\(/.test(text),
108
+ hasExpectCall: /\bexpect\s*\(/.test(text),
109
+ };
110
+ }
111
+ function detectRunImportPath(text) {
80
112
  const imports = text.matchAll(/import\s*\{([^}]+)\}\s*from\s*["']([^"']+)["']/g);
81
113
  for (const match of imports) {
82
114
  const specifiers = match[1] ?? "";
@@ -88,8 +120,7 @@ function detectRunImportPath(sourceText) {
88
120
  }
89
121
  return null;
90
122
  }
91
- function detectRunAlias(sourceText) {
92
- const text = stripComments(sourceText);
123
+ function detectRunAlias(text) {
93
124
  const imports = text.matchAll(/import\s*\{([^}]+)\}\s*from\s*["']([^"']+)["']/g);
94
125
  for (const match of imports) {
95
126
  const specifiers = match[1] ?? "";
@@ -103,7 +134,7 @@ function detectRunAlias(sourceText) {
103
134
  return null;
104
135
  }
105
136
  function looksLikeAsTestImport(specifiers) {
106
- return /\b(?:describe|test|it|expect|beforeAll|afterAll|beforeEach|afterEach|mockFn|mockImport|log|run)\b/.test(specifiers);
137
+ return /\b(?:describe|test|it|expect|beforeAll|afterAll|beforeEach|afterEach|mockFn|unmockFn|mockImport|unmockImport|snapshotImport|restoreImport|log|run)\b/.test(specifiers);
107
138
  }
108
139
  function stripComments(sourceText) {
109
140
  return sourceText.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
@@ -111,4 +142,7 @@ function stripComments(sourceText) {
111
142
  function escapeRegex(value) {
112
143
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
113
144
  }
145
+ function isCoverageEnabled() {
146
+ return process.env.AS_TEST_COVERAGE_ENABLED !== "0";
147
+ }
114
148
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,6 @@
1
1
  import { Node, Source, Tokenizer, } from "assemblyscript/dist/assemblyscript.js";
2
2
  import { Visitor } from "./visitor.js";
3
3
  import { toString } from "./util.js";
4
- const LOG_VALUE_FN = "__as_test_log_value";
5
4
  const LOG_CALL_FN = "__as_test_log_call";
6
5
  const LOG_ENABLED_IMPORT = "__as_test_log_is_enabled_internal";
7
6
  const LOG_SERIALIZED_IMPORT = "__as_test_log_serialized_internal";
@@ -11,7 +10,6 @@ export class LogTransform extends Visitor {
11
10
  activeSource = null;
12
11
  touchedSource = null;
13
12
  hasLogCalls = false;
14
- classNames = [];
15
13
  constructor(parser) {
16
14
  super();
17
15
  this.parser = parser;
@@ -22,7 +20,6 @@ export class LogTransform extends Visitor {
22
20
  this.activeSource = node;
23
21
  this.touchedSource = node;
24
22
  this.hasLogCalls = false;
25
- this.classNames = [];
26
23
  super.visitSource(node);
27
24
  if (!this.hasLogCalls) {
28
25
  this.activeSource = null;
@@ -34,18 +31,7 @@ export class LogTransform extends Visitor {
34
31
  this.parser.currentSource = tokenizer.source;
35
32
  node.statements.unshift(this.parser.parseTopLevelStatement(tokenizer));
36
33
  this.parser.currentSource = node;
37
- const jsonTokenizer = new Tokenizer(new Source(0, node.normalizedPath, `import { JSON } from "json-as";`));
38
- this.parser.currentSource = jsonTokenizer.source;
39
- node.statements.unshift(this.parser.parseTopLevelStatement(jsonTokenizer));
40
- this.parser.currentSource = node;
41
- const classFallbackLines = this.classNames
42
- .map((className) => `if (idof<nonnull<T>>() == idof<${className}>()) return JSON.stringify<${className}>(changetype<${className}>(value));`)
43
- .join(" ");
44
- const genericTokenizer = new Tokenizer(new Source(0, node.normalizedPath, `function ${LOG_VALUE_FN}<T>(value: T): string { const formatted = ${LOG_DEFAULT_IMPORT}<T>(value); if (formatted != "none") return formatted; if (isReference<T>()) { ${classFallbackLines} } return formatted; }`));
45
- this.parser.currentSource = genericTokenizer.source;
46
- node.statements.push(this.parser.parseTopLevelStatement(genericTokenizer));
47
- this.parser.currentSource = node;
48
- const callTokenizer = new Tokenizer(new Source(0, node.normalizedPath, `function ${LOG_CALL_FN}<T>(value: T): void { if (!${LOG_ENABLED_IMPORT}()) return; ${LOG_SERIALIZED_IMPORT}(${LOG_VALUE_FN}(value)); }`));
34
+ const callTokenizer = new Tokenizer(new Source(0, node.normalizedPath, `function ${LOG_CALL_FN}<T>(value: T): void { if (!${LOG_ENABLED_IMPORT}()) return; ${LOG_SERIALIZED_IMPORT}(${LOG_DEFAULT_IMPORT}<T>(value)); }`));
49
35
  this.parser.currentSource = callTokenizer.source;
50
36
  node.statements.push(this.parser.parseTopLevelStatement(callTokenizer));
51
37
  this.parser.currentSource = node;
@@ -65,34 +51,11 @@ export class LogTransform extends Visitor {
65
51
  node.args[0] = arg;
66
52
  this.hasLogCalls = true;
67
53
  }
68
- visitClassDeclaration(node, isDefault = false) {
69
- super.visitClassDeclaration(node, isDefault);
70
- if (!this.activeSource || this.touchedSource !== this.activeSource)
71
- return;
72
- if (!node.name)
73
- return;
74
- if (node.flags & 32768)
75
- return;
76
- if (node.decorators?.some((decorator) => isDecoratorNamed(decorator, "json")))
77
- return;
78
- if (node.decorators?.some((decorator) => isDecoratorNamed(decorator, "unmanaged")))
79
- return;
80
- const className = node.name.text;
81
- if (!this.classNames.includes(className)) {
82
- this.classNames.push(className);
83
- }
84
- const decorators = node.decorators ? [...node.decorators] : [];
85
- decorators.unshift(Node.createDecorator(Node.createIdentifierExpression("json", node.range), [], node.range));
86
- node.decorators = decorators;
87
- }
88
54
  }
89
55
  function isUserSource(source) {
90
56
  return (source.sourceKind === 0 ||
91
57
  source.sourceKind === 1);
92
58
  }
93
- function isDecoratorNamed(node, name) {
94
- return toString(node.name) === name;
95
- }
96
59
  function detectAsTestImportPath(sourceText) {
97
60
  const text = stripComments(sourceText);
98
61
  const imports = text.matchAll(/import\s*\{([^}]+)\}\s*from\s*["']([^"']+)["']/g);
@@ -110,7 +73,7 @@ function detectAsTestImportPath(sourceText) {
110
73
  function looksLikeAsTestImport(specifiers, modulePath) {
111
74
  if (modulePath === "as-test" || modulePath.endsWith("/as-test"))
112
75
  return true;
113
- return /\b(?:describe|test|it|expect|beforeAll|afterAll|beforeEach|afterEach|mockFn|mockImport|log|run)\b/.test(specifiers);
76
+ return /\b(?:describe|test|it|expect|beforeAll|afterAll|beforeEach|afterEach|mockFn|unmockFn|mockImport|unmockImport|snapshotImport|restoreImport|log|run)\b/.test(specifiers);
114
77
  }
115
78
  function stripComments(sourceText) {
116
79
  return sourceText.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");