@travetto/test 8.0.0-alpha.20 → 8.0.0-alpha.21
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/README.md +14 -20
- package/__index__.ts +9 -9
- package/package.json +7 -7
- package/src/assert/capture.ts +1 -2
- package/src/assert/check.ts +52 -25
- package/src/assert/types.ts +1 -1
- package/src/assert/util.ts +16 -12
- package/src/consumer/decorator.ts +2 -2
- package/src/consumer/enhancer.ts +3 -3
- package/src/consumer/registry-adapter.ts +3 -3
- package/src/consumer/registry-index.ts +6 -5
- package/src/consumer/types/cumulative.ts +6 -6
- package/src/consumer/types/delegating.ts +2 -2
- package/src/consumer/types/event.ts +2 -2
- package/src/consumer/types/exec.ts +3 -4
- package/src/consumer/types/json.ts +3 -4
- package/src/consumer/types/noop.ts +3 -3
- package/src/consumer/types/runnable.ts +4 -6
- package/src/consumer/types/summarizer.ts +2 -3
- package/src/consumer/types/tap-summary.ts +15 -20
- package/src/consumer/types/tap.ts +57 -29
- package/src/consumer/types/util.ts +8 -5
- package/src/consumer/types/xunit.ts +7 -6
- package/src/decorator/suite.ts +3 -3
- package/src/decorator/test.ts +6 -4
- package/src/execute/barrier.ts +15 -9
- package/src/execute/console.ts +3 -4
- package/src/execute/executor.ts +29 -25
- package/src/execute/phase.ts +1 -1
- package/src/execute/run.ts +39 -39
- package/src/execute/watcher.ts +12 -19
- package/src/fixture.ts +6 -7
- package/src/model/common.ts +1 -1
- package/src/model/error.ts +2 -2
- package/src/model/event.ts +14 -9
- package/src/model/suite.ts +2 -2
- package/src/model/test.ts +8 -5
- package/src/model/util.ts +24 -14
- package/src/registry/registry-adapter.ts +10 -13
- package/src/registry/registry-index.ts +13 -11
- package/src/worker/child.ts +13 -10
- package/src/worker/standard.ts +11 -14
- package/src/worker/types.ts +3 -7
- package/support/bin/run.ts +1 -1
- package/support/cli.test.ts +16 -14
- package/support/cli.test_child.ts +2 -2
- package/support/cli.test_diff.ts +5 -6
- package/support/cli.test_digest.ts +3 -4
- package/support/cli.test_direct.ts +5 -6
- package/support/cli.test_watch.ts +2 -3
- package/support/transformer.assert.ts +40 -32
package/src/worker/standard.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { fork } from 'node:child_process';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { Env, JSONUtil, RuntimeIndex } from '@travetto/runtime';
|
|
4
4
|
import { IpcChannel } from '@travetto/worker';
|
|
5
5
|
|
|
6
|
-
import { TestWorkerEvents, type TestLogEvent } from './types.ts';
|
|
7
6
|
import type { TestConsumerShape } from '../consumer/types.ts';
|
|
8
7
|
import type { TestEvent, TestRemoveEvent } from '../model/event.ts';
|
|
9
8
|
import type { TestDiffInput, TestRun } from '../model/test.ts';
|
|
9
|
+
import { type TestLogEvent, TestWorkerEvents } from './types.ts';
|
|
10
10
|
|
|
11
11
|
const log = (message: string | TestLogEvent): void => {
|
|
12
12
|
const event: TestLogEvent = typeof message === 'string' ? { type: 'log', message } : message;
|
|
@@ -20,16 +20,13 @@ export async function buildStandardTestManager(consumer: TestConsumerShape, run:
|
|
|
20
20
|
log(`Worker Input ${JSONUtil.toUTF8(run)}`);
|
|
21
21
|
|
|
22
22
|
const channel = new IpcChannel<TestEvent & { error?: Error }>(
|
|
23
|
-
fork(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
stdio: ['ignore', 'ignore', 2, 'ipc']
|
|
31
|
-
}
|
|
32
|
-
)
|
|
23
|
+
fork(RuntimeIndex.resolveFileImport('@travetto/cli/support/entry.trv.ts'), ['test:child'], {
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
...Env.TRV_QUIET.export(true)
|
|
27
|
+
},
|
|
28
|
+
stdio: ['ignore', 'ignore', 2, 'ipc']
|
|
29
|
+
})
|
|
33
30
|
);
|
|
34
31
|
|
|
35
32
|
await channel.once(TestWorkerEvents.READY); // Wait for the child to be ready
|
|
@@ -45,7 +42,7 @@ export async function buildStandardTestManager(consumer: TestConsumerShape, run:
|
|
|
45
42
|
log(`Received remove event ${JSONUtil.toUTF8(event)}@${consumer.constructor.name}`);
|
|
46
43
|
consumer.onRemoveEvent?.(parsed); // Forward remove events
|
|
47
44
|
} else {
|
|
48
|
-
consumer.onEvent(parsed);
|
|
45
|
+
consumer.onEvent(parsed); // Forward standard events
|
|
49
46
|
}
|
|
50
47
|
} catch {
|
|
51
48
|
// Do nothing
|
|
@@ -70,4 +67,4 @@ export async function buildStandardTestManager(consumer: TestConsumerShape, run:
|
|
|
70
67
|
if (result.error) {
|
|
71
68
|
throw result.error;
|
|
72
69
|
}
|
|
73
|
-
}
|
|
70
|
+
}
|
package/src/worker/types.ts
CHANGED
|
@@ -11,16 +11,12 @@ export const TestWorkerEvents = {
|
|
|
11
11
|
READY: 'ready'
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
-
export type TestRunEvent = { type: 'runTest'
|
|
14
|
+
export type TestRunEvent = { type: 'runTest'; import: string };
|
|
15
15
|
|
|
16
16
|
export const isTestRunEvent = (event: unknown): event is TestRunEvent =>
|
|
17
17
|
typeof event === 'object' && !!event && 'type' in event && event.type === 'runTest';
|
|
18
18
|
|
|
19
19
|
export type TestReadyEvent = { type: 'ready' };
|
|
20
|
-
export type TestLogEvent = { type: 'log'
|
|
20
|
+
export type TestLogEvent = { type: 'log'; message: string };
|
|
21
21
|
|
|
22
|
-
export type TestWatchEvent =
|
|
23
|
-
TestEvent |
|
|
24
|
-
TestRemoveEvent |
|
|
25
|
-
TestReadyEvent |
|
|
26
|
-
TestLogEvent;
|
|
22
|
+
export type TestWatchEvent = TestEvent | TestRemoveEvent | TestReadyEvent | TestLogEvent;
|
package/support/bin/run.ts
CHANGED
|
@@ -17,4 +17,4 @@ export async function runTests(state: TestConsumerConfig, input: TestRunInput):
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export type TestConsumerType = 'tap' | 'tap-summary' | 'json' | 'exec' | 'event' | 'xunit' | 'custom';
|
|
20
|
+
export type TestConsumerType = 'tap' | 'tap-summary' | 'json' | 'exec' | 'event' | 'xunit' | 'custom';
|
package/support/cli.test.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
|
|
3
|
+
import { CliCommand, type CliCommandShape, CliUtil } from '@travetto/cli';
|
|
3
4
|
import { Env, RuntimeIndex } from '@travetto/runtime';
|
|
4
|
-
import { type CliCommandShape, CliCommand, CliUtil } from '@travetto/cli';
|
|
5
|
-
import { WorkPool } from '@travetto/worker';
|
|
6
5
|
import { Max, Min } from '@travetto/schema';
|
|
6
|
+
import { WorkPool } from '@travetto/worker';
|
|
7
7
|
|
|
8
8
|
import type { TestConsumerType } from './bin/run.ts';
|
|
9
9
|
|
|
@@ -15,12 +15,12 @@ import type { TestConsumerType } from './bin/run.ts';
|
|
|
15
15
|
*/
|
|
16
16
|
@CliCommand()
|
|
17
17
|
export class TestCommand implements CliCommandShape {
|
|
18
|
-
|
|
19
18
|
/** Output format for test results */
|
|
20
19
|
format: TestConsumerType = 'tap';
|
|
21
20
|
|
|
22
21
|
/** Number of tests to run concurrently */
|
|
23
|
-
@Min(1)
|
|
22
|
+
@Min(1)
|
|
23
|
+
@Max(WorkPool.MAX_SIZE)
|
|
24
24
|
concurrency: number = WorkPool.DEFAULT_SIZE;
|
|
25
25
|
|
|
26
26
|
/**
|
|
@@ -52,16 +52,18 @@ export class TestCommand implements CliCommandShape {
|
|
|
52
52
|
{
|
|
53
53
|
concurrency: this.concurrency,
|
|
54
54
|
consumer: this.format,
|
|
55
|
-
consumerOptions: CliUtil.readExtendedOptions(this.formatOptions)
|
|
55
|
+
consumerOptions: CliUtil.readExtendedOptions(this.formatOptions)
|
|
56
56
|
},
|
|
57
|
-
importPath
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
57
|
+
importPath
|
|
58
|
+
? {
|
|
59
|
+
import: importPath,
|
|
60
|
+
classId: globs[0],
|
|
61
|
+
methodNames: globs.slice(1)
|
|
62
|
+
}
|
|
63
|
+
: {
|
|
64
|
+
globs: [first, ...globs],
|
|
65
|
+
tags: this.tags
|
|
66
|
+
}
|
|
65
67
|
);
|
|
66
68
|
}
|
|
67
|
-
}
|
|
69
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
|
|
3
|
-
import { Env } from '@travetto/runtime';
|
|
4
3
|
import { CliCommand } from '@travetto/cli';
|
|
4
|
+
import { Env } from '@travetto/runtime';
|
|
5
5
|
import { IsPrivate } from '@travetto/schema';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -27,4 +27,4 @@ export class TestChildWorkerCommand {
|
|
|
27
27
|
const { TestChildWorker } = await import('../src/worker/child.ts');
|
|
28
28
|
return new TestChildWorker().activate();
|
|
29
29
|
}
|
|
30
|
-
}
|
|
30
|
+
}
|
package/support/cli.test_diff.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import fs from 'node:fs/promises';
|
|
2
2
|
|
|
3
|
-
import { Env, JSONUtil, RuntimeIndex } from '@travetto/runtime';
|
|
4
3
|
import { CliCommand, CliUtil } from '@travetto/cli';
|
|
4
|
+
import { Env, JSONUtil, RuntimeIndex } from '@travetto/runtime';
|
|
5
5
|
import { IsPrivate } from '@travetto/schema';
|
|
6
6
|
|
|
7
|
-
import { runTests, type TestConsumerType } from './bin/run.ts';
|
|
8
7
|
import type { TestDiffSource } from '../src/model/test.ts';
|
|
8
|
+
import { runTests, type TestConsumerType } from './bin/run.ts';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Run tests scoped by a precomputed diff source file.
|
|
@@ -16,7 +16,6 @@ import type { TestDiffSource } from '../src/model/test.ts';
|
|
|
16
16
|
@CliCommand()
|
|
17
17
|
@IsPrivate()
|
|
18
18
|
export class TestDiffCommand {
|
|
19
|
-
|
|
20
19
|
/** Output format for test results */
|
|
21
20
|
format: TestConsumerType = 'tap';
|
|
22
21
|
|
|
@@ -34,12 +33,12 @@ export class TestDiffCommand {
|
|
|
34
33
|
|
|
35
34
|
async main(importOrFile: string, diff: string): Promise<void> {
|
|
36
35
|
const diffSource = await fs.readFile(diff).then(JSONUtil.fromBinaryArray<TestDiffSource>);
|
|
37
|
-
const importPath = RuntimeIndex.getFromImportOrSource(importOrFile)
|
|
36
|
+
const importPath = RuntimeIndex.getFromImportOrSource(importOrFile)!.import;
|
|
38
37
|
|
|
39
38
|
return runTests(
|
|
40
39
|
{
|
|
41
40
|
consumer: this.format,
|
|
42
|
-
consumerOptions: CliUtil.readExtendedOptions(this.formatOptions)
|
|
41
|
+
consumerOptions: CliUtil.readExtendedOptions(this.formatOptions)
|
|
43
42
|
},
|
|
44
43
|
{
|
|
45
44
|
import: importPath,
|
|
@@ -47,4 +46,4 @@ export class TestDiffCommand {
|
|
|
47
46
|
}
|
|
48
47
|
);
|
|
49
48
|
}
|
|
50
|
-
}
|
|
49
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CliCommand } from '@travetto/cli';
|
|
2
|
-
import { JSONUtil, Env, Runtime, describeFunction } from '@travetto/runtime';
|
|
3
2
|
import { Registry } from '@travetto/registry';
|
|
3
|
+
import { describeFunction, Env, JSONUtil, Runtime } from '@travetto/runtime';
|
|
4
4
|
import { IsPrivate } from '@travetto/schema';
|
|
5
5
|
|
|
6
|
-
import { SuiteRegistryIndex } from '../src/registry/registry-index.ts';
|
|
7
6
|
import { RunUtil } from '../src/execute/run.ts';
|
|
7
|
+
import { SuiteRegistryIndex } from '../src/registry/registry-index.ts';
|
|
8
8
|
|
|
9
9
|
@CliCommand()
|
|
10
10
|
@IsPrivate()
|
|
@@ -15,7 +15,6 @@ import { RunUtil } from '../src/execute/run.ts';
|
|
|
15
15
|
* order for planning, sharding, or change detection workflows.
|
|
16
16
|
*/
|
|
17
17
|
export class TestDigestCommand {
|
|
18
|
-
|
|
19
18
|
/** Output mode for digest emission. */
|
|
20
19
|
output: 'json' | 'text' = 'text';
|
|
21
20
|
|
|
@@ -54,4 +53,4 @@ export class TestDigestCommand {
|
|
|
54
53
|
}
|
|
55
54
|
}
|
|
56
55
|
}
|
|
57
|
-
}
|
|
56
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Env, RuntimeIndex } from '@travetto/runtime';
|
|
2
1
|
import { CliCommand, CliUtil } from '@travetto/cli';
|
|
2
|
+
import { Env, RuntimeIndex } from '@travetto/runtime';
|
|
3
3
|
import { IsPrivate } from '@travetto/schema';
|
|
4
4
|
|
|
5
5
|
import { runTests, type TestConsumerType } from './bin/run.ts';
|
|
@@ -13,7 +13,6 @@ import { runTests, type TestConsumerType } from './bin/run.ts';
|
|
|
13
13
|
@CliCommand()
|
|
14
14
|
@IsPrivate()
|
|
15
15
|
export class TestDirectCommand {
|
|
16
|
-
|
|
17
16
|
/** Output format for test results */
|
|
18
17
|
format: TestConsumerType = 'tap';
|
|
19
18
|
|
|
@@ -31,18 +30,18 @@ export class TestDirectCommand {
|
|
|
31
30
|
|
|
32
31
|
main(importOrFile: string, clsId?: string, methodsNames: string[] = []): Promise<void> {
|
|
33
32
|
// Resolve to import
|
|
34
|
-
const importPath = RuntimeIndex.getFromImportOrSource(importOrFile)
|
|
33
|
+
const importPath = RuntimeIndex.getFromImportOrSource(importOrFile)!.import;
|
|
35
34
|
|
|
36
35
|
return runTests(
|
|
37
36
|
{
|
|
38
37
|
consumer: this.format,
|
|
39
|
-
consumerOptions: CliUtil.readExtendedOptions(this.formatOptions)
|
|
38
|
+
consumerOptions: CliUtil.readExtendedOptions(this.formatOptions)
|
|
40
39
|
},
|
|
41
40
|
{
|
|
42
41
|
import: importPath,
|
|
43
42
|
classId: clsId,
|
|
44
|
-
methodNames: methodsNames
|
|
43
|
+
methodNames: methodsNames
|
|
45
44
|
}
|
|
46
45
|
);
|
|
47
46
|
}
|
|
48
|
-
}
|
|
47
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { Env } from '@travetto/runtime';
|
|
2
1
|
import { CliCommand } from '@travetto/cli';
|
|
2
|
+
import { Env } from '@travetto/runtime';
|
|
3
3
|
|
|
4
4
|
import type { TestConsumerType } from './bin/run.ts';
|
|
5
5
|
|
|
@@ -11,7 +11,6 @@ import type { TestConsumerType } from './bin/run.ts';
|
|
|
11
11
|
*/
|
|
12
12
|
@CliCommand()
|
|
13
13
|
export class TestWatcherCommand {
|
|
14
|
-
|
|
15
14
|
/** Output format for test results */
|
|
16
15
|
format: TestConsumerType = 'tap';
|
|
17
16
|
|
|
@@ -29,4 +28,4 @@ export class TestWatcherCommand {
|
|
|
29
28
|
console.error(error);
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
|
-
}
|
|
31
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ts from 'typescript';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { CoreUtil, DeclarationUtil, TransformerHandler, type TransformerState } from '@travetto/transformer';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Which types are candidates for deep literal checking
|
|
@@ -89,7 +89,6 @@ interface Command {
|
|
|
89
89
|
* and result generation
|
|
90
90
|
*/
|
|
91
91
|
export class AssertTransformer {
|
|
92
|
-
|
|
93
92
|
static {
|
|
94
93
|
TransformerHandler(this, this.onAssertCheck, 'before', 'method', ['AssertCheck']);
|
|
95
94
|
TransformerHandler(this, this.afterAssertCheck, 'after', 'method', ['AssertCheck']);
|
|
@@ -104,8 +103,9 @@ export class AssertTransformer {
|
|
|
104
103
|
Object.keys(ts.SyntaxKind)
|
|
105
104
|
.filter(kind => !/^\d+$/.test(kind))
|
|
106
105
|
.filter((kind): kind is keyof typeof OPTOKEN_ASSERT => !/^(Last|First)/.test(kind))
|
|
107
|
-
.forEach(kind =>
|
|
108
|
-
OP_TOKEN_TO_NAME.set(ts.SyntaxKind[kind], kind)
|
|
106
|
+
.forEach(kind => {
|
|
107
|
+
OP_TOKEN_TO_NAME.set(ts.SyntaxKind[kind], kind);
|
|
108
|
+
});
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
const name = OP_TOKEN_TO_NAME.get(key)!;
|
|
@@ -120,19 +120,18 @@ export class AssertTransformer {
|
|
|
120
120
|
* Determine if element is a deep literal (should use deep comparison)
|
|
121
121
|
*/
|
|
122
122
|
static isDeepLiteral(state: TransformerState, node: ts.Expression): boolean {
|
|
123
|
-
let found =
|
|
123
|
+
let found =
|
|
124
|
+
ts.isArrayLiteralExpression(node) ||
|
|
124
125
|
ts.isObjectLiteralExpression(node) ||
|
|
125
|
-
(
|
|
126
|
-
ts.isNewExpression(node) &&
|
|
127
|
-
DEEP_LITERAL_TYPES.has(node.expression.getText())
|
|
128
|
-
);
|
|
126
|
+
(ts.isNewExpression(node) && DEEP_LITERAL_TYPES.has(node.expression.getText()));
|
|
129
127
|
|
|
130
128
|
// If looking at an identifier, see if it's in a diff file or if its const
|
|
131
129
|
if (!found && ts.isIdentifier(node)) {
|
|
132
|
-
found = !!state.getDeclarations(node).find(
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
130
|
+
found = !!state.getDeclarations(node).find(
|
|
131
|
+
declaration =>
|
|
132
|
+
// In a separate file or is const
|
|
133
|
+
declaration.getSourceFile().fileName !== state.source.fileName || DeclarationUtil.isConstantDeclaration(declaration)
|
|
134
|
+
);
|
|
136
135
|
}
|
|
137
136
|
|
|
138
137
|
return found;
|
|
@@ -148,7 +147,7 @@ export class AssertTransformer {
|
|
|
148
147
|
assert: asrt,
|
|
149
148
|
assertCheck: CoreUtil.createAccess(state.factory, asrt, ASSERT_UTIL, 'check'),
|
|
150
149
|
checkThrow: CoreUtil.createAccess(state.factory, asrt, ASSERT_UTIL, 'checkThrow'),
|
|
151
|
-
checkThrowAsync: CoreUtil.createAccess(state.factory, asrt, ASSERT_UTIL, 'checkThrowAsync')
|
|
150
|
+
checkThrowAsync: CoreUtil.createAccess(state.factory, asrt, ASSERT_UTIL, 'checkThrowAsync')
|
|
152
151
|
};
|
|
153
152
|
}
|
|
154
153
|
}
|
|
@@ -163,16 +162,20 @@ export class AssertTransformer {
|
|
|
163
162
|
const firstText = first?.getText() ?? node.getText();
|
|
164
163
|
|
|
165
164
|
cmd.args = cmd.args.filter(arg => arg !== undefined && arg !== null);
|
|
166
|
-
const check = state.factory.createCallExpression(
|
|
167
|
-
state
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
165
|
+
const check = state.factory.createCallExpression(
|
|
166
|
+
state[AssertSymbol]!.assertCheck,
|
|
167
|
+
undefined,
|
|
168
|
+
state.factory.createNodeArray([
|
|
169
|
+
state.fromLiteral({
|
|
170
|
+
module: state.getModuleIdentifier(),
|
|
171
|
+
line: state.fromLiteral(ts.getLineAndCharacterOfPosition(state.source, node.getStart()).line + 1),
|
|
172
|
+
text: state.fromLiteral(firstText),
|
|
173
|
+
operator: state.fromLiteral(cmd.fn)
|
|
174
|
+
}),
|
|
175
|
+
state.fromLiteral(!cmd.negate),
|
|
176
|
+
...cmd.args
|
|
177
|
+
])
|
|
178
|
+
);
|
|
176
179
|
|
|
177
180
|
return check;
|
|
178
181
|
}
|
|
@@ -197,7 +200,8 @@ export class AssertTransformer {
|
|
|
197
200
|
}),
|
|
198
201
|
state.fromLiteral(key.startsWith('doesNot')),
|
|
199
202
|
...args
|
|
200
|
-
])
|
|
203
|
+
])
|
|
204
|
+
);
|
|
201
205
|
}
|
|
202
206
|
|
|
203
207
|
/**
|
|
@@ -234,7 +238,6 @@ export class AssertTransformer {
|
|
|
234
238
|
* Check various `assert.*` method calls
|
|
235
239
|
*/
|
|
236
240
|
static doMethodCall(state: TransformerState, comp: ts.Expression, args: Args): Command {
|
|
237
|
-
|
|
238
241
|
if (ts.isCallExpression(comp) && ts.isPropertyAccessExpression(comp.expression)) {
|
|
239
242
|
const root = comp.expression.expression;
|
|
240
243
|
const key = comp.expression.name;
|
|
@@ -242,10 +245,13 @@ export class AssertTransformer {
|
|
|
242
245
|
const matched = METHODS[key.text!];
|
|
243
246
|
if (matched) {
|
|
244
247
|
const resolved = state.resolveType(root);
|
|
245
|
-
if (resolved.key === 'literal' && matched.find(type => resolved.ctor === type)) {
|
|
248
|
+
if (resolved.key === 'literal' && matched.find(type => resolved.ctor === type)) {
|
|
249
|
+
// Ensure method is against real type
|
|
246
250
|
switch (key.text) {
|
|
247
|
-
case 'includes':
|
|
248
|
-
|
|
251
|
+
case 'includes':
|
|
252
|
+
return { fn: key.text, args: [comp.expression.expression, comp.arguments[0], ...args.slice(1)] };
|
|
253
|
+
case 'test':
|
|
254
|
+
return { fn: key.text, args: [comp.arguments[0], comp.expression.expression, ...args.slice(1)] };
|
|
249
255
|
}
|
|
250
256
|
}
|
|
251
257
|
}
|
|
@@ -294,13 +300,15 @@ export class AssertTransformer {
|
|
|
294
300
|
const exp = node.expression;
|
|
295
301
|
|
|
296
302
|
// Determine if calling assert directly
|
|
297
|
-
if (ts.isIdentifier(exp) && exp.getSourceFile() && exp.getText() === ASSERT_CMD) {
|
|
303
|
+
if (ts.isIdentifier(exp) && exp.getSourceFile() && exp.getText() === ASSERT_CMD) {
|
|
304
|
+
// Straight assert
|
|
298
305
|
const cmd = this.getCommand(state, node.arguments);
|
|
299
306
|
if (cmd) {
|
|
300
307
|
node = this.doAssert(state, node, cmd);
|
|
301
308
|
}
|
|
302
309
|
// If calling `assert.*`
|
|
303
|
-
} else if (ts.isPropertyAccessExpression(exp) && ts.isIdentifier(exp.expression)) {
|
|
310
|
+
} else if (ts.isPropertyAccessExpression(exp) && ts.isIdentifier(exp.expression)) {
|
|
311
|
+
// Assert method call
|
|
304
312
|
const identifier = exp.expression;
|
|
305
313
|
const fn = exp.name.escapedText.toString();
|
|
306
314
|
if (identifier.escapedText === ASSERT_CMD) {
|
|
@@ -318,4 +326,4 @@ export class AssertTransformer {
|
|
|
318
326
|
|
|
319
327
|
return node;
|
|
320
328
|
}
|
|
321
|
-
}
|
|
329
|
+
}
|