@functional-examples/test 0.0.0-alpha.1
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/dist/commands/index.d.ts +41 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +9 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/list.d.ts +10 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +57 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/test.d.ts +19 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +110 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/integration.spec.d.ts +1 -0
- package/dist/reporters/index.d.ts +5 -0
- package/dist/reporters/index.d.ts.map +1 -0
- package/dist/reporters/index.js +4 -0
- package/dist/reporters/index.js.map +1 -0
- package/dist/reporters/pretty.d.ts +3 -0
- package/dist/reporters/pretty.d.ts.map +1 -0
- package/dist/reporters/pretty.js +58 -0
- package/dist/reporters/pretty.js.map +1 -0
- package/dist/reporters/resolve.d.ts +7 -0
- package/dist/reporters/resolve.d.ts.map +1 -0
- package/dist/reporters/resolve.js +39 -0
- package/dist/reporters/resolve.js.map +1 -0
- package/dist/reporters/tap.d.ts +3 -0
- package/dist/reporters/tap.d.ts.map +1 -0
- package/dist/reporters/tap.js +53 -0
- package/dist/reporters/tap.js.map +1 -0
- package/dist/reporters/types.d.ts +50 -0
- package/dist/reporters/types.d.ts.map +1 -0
- package/dist/reporters/types.js +2 -0
- package/dist/reporters/types.js.map +1 -0
- package/dist/runner.d.ts +15 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +232 -0
- package/dist/runner.js.map +1 -0
- package/dist/runner.spec.d.ts +1 -0
- package/dist/schema.d.ts +298 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +115 -0
- package/dist/schema.js.map +1 -0
- package/dist/schema.spec.d.ts +1 -0
- package/dist/types.d.ts +37 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ResolvedConfig } from '@functional-examples/devkit';
|
|
2
|
+
import type { ResolvedTestPluginOptions } from '../types.js';
|
|
3
|
+
export declare function createTestCommands(config: ResolvedConfig, pluginOpts: ResolvedTestPluginOptions): import("cli-forge").CLI<{
|
|
4
|
+
unmatched: string[];
|
|
5
|
+
'--'?: string[];
|
|
6
|
+
} & {
|
|
7
|
+
path?: string;
|
|
8
|
+
} & {} & {
|
|
9
|
+
filter?: string;
|
|
10
|
+
} & {} & {
|
|
11
|
+
bail?: boolean;
|
|
12
|
+
} & {} & {
|
|
13
|
+
verbose?: boolean;
|
|
14
|
+
} & {} & {
|
|
15
|
+
format?: string;
|
|
16
|
+
} & {} & {
|
|
17
|
+
timeout?: number;
|
|
18
|
+
} & {}, Promise<never>, import("cli-forge").CommandToChildEntry<import("cli-forge").CLI<{
|
|
19
|
+
unmatched: string[];
|
|
20
|
+
'--'?: string[];
|
|
21
|
+
} & {
|
|
22
|
+
path?: string;
|
|
23
|
+
} & {} & {
|
|
24
|
+
format?: "table" | "json";
|
|
25
|
+
} & {}, Promise<void>, {}, undefined>, import("cli-forge").CLI<{
|
|
26
|
+
unmatched: string[];
|
|
27
|
+
'--'?: string[];
|
|
28
|
+
} & {
|
|
29
|
+
path?: string;
|
|
30
|
+
} & {} & {
|
|
31
|
+
filter?: string;
|
|
32
|
+
} & {} & {
|
|
33
|
+
bail?: boolean;
|
|
34
|
+
} & {} & {
|
|
35
|
+
verbose?: boolean;
|
|
36
|
+
} & {} & {
|
|
37
|
+
format?: string;
|
|
38
|
+
} & {} & {
|
|
39
|
+
timeout?: number;
|
|
40
|
+
} & {}, Promise<never>, {}, undefined>>, undefined>[];
|
|
41
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAI7D,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,yBAAyB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;sDAOtC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createTestCommand } from './test.js';
|
|
2
|
+
import { createListCommand } from './list.js';
|
|
3
|
+
export function createTestCommands(config, pluginOpts) {
|
|
4
|
+
// Main test command with list as subcommand
|
|
5
|
+
const testCommand = createTestCommand(config, pluginOpts)
|
|
6
|
+
.commands(createListCommand(config));
|
|
7
|
+
return [testCommand];
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/commands/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9C,MAAM,UAAU,kBAAkB,CAChC,MAAsB,EACtB,UAAqC;IAErC,4CAA4C;IAC5C,MAAM,WAAW,GAAG,iBAAiB,CAAC,MAAM,EAAE,UAAU,CAAC;SACtD,QAAQ,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;IAEvC,OAAO,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResolvedConfig } from '@functional-examples/devkit';
|
|
2
|
+
export declare function createListCommand(config: ResolvedConfig): import("cli-forge").CLI<{
|
|
3
|
+
unmatched: string[];
|
|
4
|
+
'--'?: string[];
|
|
5
|
+
} & {
|
|
6
|
+
path?: string;
|
|
7
|
+
} & {} & {
|
|
8
|
+
format?: "table" | "json";
|
|
9
|
+
} & {}, Promise<void>, {}, undefined>;
|
|
10
|
+
//# sourceMappingURL=list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAa3E,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc;;;;;;;sCAyDvD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { cli } from 'cli-forge';
|
|
2
|
+
import { scanExamples } from 'functional-examples';
|
|
3
|
+
import { normalizeTests } from '../runner.js';
|
|
4
|
+
import { testMetadataSchema } from '../schema.js';
|
|
5
|
+
function hasTests(example) {
|
|
6
|
+
const result = testMetadataSchema.safeParse(example.metadata);
|
|
7
|
+
return result.success && result.data.test !== undefined;
|
|
8
|
+
}
|
|
9
|
+
export function createListCommand(config) {
|
|
10
|
+
return cli('list', {
|
|
11
|
+
description: 'List available tests',
|
|
12
|
+
builder: (cmd) => cmd
|
|
13
|
+
.option('path', {
|
|
14
|
+
type: 'string',
|
|
15
|
+
alias: ['p'],
|
|
16
|
+
description: 'Path to examples directory',
|
|
17
|
+
default: '.',
|
|
18
|
+
})
|
|
19
|
+
.option('format', {
|
|
20
|
+
type: 'string',
|
|
21
|
+
choices: ['table', 'json'],
|
|
22
|
+
description: 'Output format',
|
|
23
|
+
default: 'table',
|
|
24
|
+
}),
|
|
25
|
+
handler: async (args) => {
|
|
26
|
+
const { examples } = await scanExamples(config);
|
|
27
|
+
const testableExamples = examples.filter(hasTests);
|
|
28
|
+
const testList = testableExamples.flatMap((example) => {
|
|
29
|
+
const tests = normalizeTests(example.metadata.test);
|
|
30
|
+
return tests.map((t) => ({
|
|
31
|
+
example: example.id,
|
|
32
|
+
test: t.name,
|
|
33
|
+
command: 'steps' in t
|
|
34
|
+
? `${t.steps.length} step${t.steps.length > 1 ? 's' : ''}`
|
|
35
|
+
: t.options.command,
|
|
36
|
+
}));
|
|
37
|
+
});
|
|
38
|
+
if (args.format === 'json') {
|
|
39
|
+
console.log(JSON.stringify(testList, null, 2));
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
// Table format
|
|
43
|
+
if (testList.length === 0) {
|
|
44
|
+
console.log('No tests found');
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
console.log('Example'.padEnd(30) + 'Test'.padEnd(30) + 'Command');
|
|
48
|
+
console.log('-'.repeat(80));
|
|
49
|
+
for (const t of testList) {
|
|
50
|
+
console.log(t.example.slice(0, 28).padEnd(30) +
|
|
51
|
+
t.test.slice(0, 28).padEnd(30) +
|
|
52
|
+
t.command);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ResolvedConfig } from '@functional-examples/devkit';
|
|
2
|
+
import type { ResolvedTestPluginOptions } from '../types.js';
|
|
3
|
+
export declare function createTestCommand(config: ResolvedConfig, pluginOpts: ResolvedTestPluginOptions): import("cli-forge").CLI<{
|
|
4
|
+
unmatched: string[];
|
|
5
|
+
'--'?: string[];
|
|
6
|
+
} & {
|
|
7
|
+
path?: string;
|
|
8
|
+
} & {} & {
|
|
9
|
+
filter?: string;
|
|
10
|
+
} & {} & {
|
|
11
|
+
bail?: boolean;
|
|
12
|
+
} & {} & {
|
|
13
|
+
verbose?: boolean;
|
|
14
|
+
} & {} & {
|
|
15
|
+
format?: string;
|
|
16
|
+
} & {} & {
|
|
17
|
+
timeout?: number;
|
|
18
|
+
} & {}, Promise<never>, {}, undefined>;
|
|
19
|
+
//# sourceMappingURL=test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAK3E,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAoB7D,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,EACtB,UAAU,EAAE,yBAAyB;;;;;;;;;;;;;;;uCA+GtC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { cli } from 'cli-forge';
|
|
2
|
+
import { scanExamples } from 'functional-examples';
|
|
3
|
+
import { normalizeTests, runTest } from '../runner.js';
|
|
4
|
+
import { testMetadataSchema } from '../schema.js';
|
|
5
|
+
function isCI() {
|
|
6
|
+
return !!(process.env.CI ||
|
|
7
|
+
process.env.GITHUB_ACTIONS ||
|
|
8
|
+
process.env.GITLAB_CI ||
|
|
9
|
+
process.env.CIRCLECI ||
|
|
10
|
+
process.env.JENKINS_URL ||
|
|
11
|
+
process.env.TRAVIS);
|
|
12
|
+
}
|
|
13
|
+
function hasTests(example) {
|
|
14
|
+
const result = testMetadataSchema.safeParse(example.metadata);
|
|
15
|
+
return result.success && result.data.test !== undefined;
|
|
16
|
+
}
|
|
17
|
+
export function createTestCommand(config, pluginOpts) {
|
|
18
|
+
const { reporters, defaultReporter, ciReporter, timeout } = pluginOpts;
|
|
19
|
+
return cli('$0', {
|
|
20
|
+
description: 'Run tests for functional examples',
|
|
21
|
+
builder: (cmd) => cmd
|
|
22
|
+
.option('path', {
|
|
23
|
+
type: 'string',
|
|
24
|
+
alias: ['p'],
|
|
25
|
+
description: 'Path to examples directory',
|
|
26
|
+
default: '.',
|
|
27
|
+
})
|
|
28
|
+
.option('filter', {
|
|
29
|
+
type: 'string',
|
|
30
|
+
alias: ['f'],
|
|
31
|
+
description: 'Filter examples by id pattern',
|
|
32
|
+
})
|
|
33
|
+
.option('bail', {
|
|
34
|
+
type: 'boolean',
|
|
35
|
+
alias: ['b'],
|
|
36
|
+
description: 'Stop on first failure',
|
|
37
|
+
default: false,
|
|
38
|
+
})
|
|
39
|
+
.option('verbose', {
|
|
40
|
+
type: 'boolean',
|
|
41
|
+
alias: ['v'],
|
|
42
|
+
description: 'Show command output even on success',
|
|
43
|
+
default: false,
|
|
44
|
+
})
|
|
45
|
+
.option('format', {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: `Output format (default: ${defaultReporter} in TTY, ${ciReporter} in CI)`,
|
|
48
|
+
})
|
|
49
|
+
.option('timeout', {
|
|
50
|
+
type: 'number',
|
|
51
|
+
description: 'Default timeout in ms',
|
|
52
|
+
default: timeout,
|
|
53
|
+
}),
|
|
54
|
+
handler: async (args) => {
|
|
55
|
+
const formatName = args.format ?? (isCI() ? ciReporter : defaultReporter);
|
|
56
|
+
const reporterFactory = reporters[formatName];
|
|
57
|
+
if (!reporterFactory) {
|
|
58
|
+
console.error(`Unknown reporter: ${formatName}`);
|
|
59
|
+
console.error(`Available: ${Object.keys(reporters).join(', ')}`);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
const reporter = reporterFactory();
|
|
63
|
+
// Scan for examples
|
|
64
|
+
const { examples, errors } = await scanExamples(config);
|
|
65
|
+
if (errors.length) {
|
|
66
|
+
for (const error of errors) {
|
|
67
|
+
console.error(`Error in ${error}: ${error.message}`);
|
|
68
|
+
}
|
|
69
|
+
process.exit(1);
|
|
70
|
+
}
|
|
71
|
+
// Filter to examples with tests
|
|
72
|
+
let testableExamples = examples.filter(hasTests);
|
|
73
|
+
// Apply filter pattern
|
|
74
|
+
if (args.filter) {
|
|
75
|
+
const pattern = args.filter.toLowerCase();
|
|
76
|
+
testableExamples = testableExamples.filter((e) => e.id.toLowerCase().includes(pattern) ||
|
|
77
|
+
e.rootPath.toLowerCase().includes(pattern));
|
|
78
|
+
}
|
|
79
|
+
if (testableExamples.length === 0) {
|
|
80
|
+
console.log('No examples with tests found');
|
|
81
|
+
process.exit(0);
|
|
82
|
+
}
|
|
83
|
+
await reporter.start(testableExamples);
|
|
84
|
+
let passed = 0;
|
|
85
|
+
let failed = 0;
|
|
86
|
+
for (const example of testableExamples) {
|
|
87
|
+
const tests = normalizeTests(example.metadata.test);
|
|
88
|
+
for (const testCase of tests) {
|
|
89
|
+
const result = await runTest(example.id, example.rootPath, testCase, {
|
|
90
|
+
timeout: args.timeout,
|
|
91
|
+
});
|
|
92
|
+
await reporter.report(result, args.verbose);
|
|
93
|
+
if (result.passed) {
|
|
94
|
+
passed++;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
failed++;
|
|
98
|
+
if (args.bail) {
|
|
99
|
+
await reporter.finish({ passed, failed, bail: true });
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
await reporter.finish({ passed, failed });
|
|
106
|
+
process.exit(failed > 0 ? 1 : 0);
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Plugin } from '@functional-examples/devkit';
|
|
2
|
+
import type { TestMetadata } from './schema.js';
|
|
3
|
+
import type { TestPluginOptions } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Create the test plugin
|
|
6
|
+
*/
|
|
7
|
+
export declare function createTestPlugin(options?: TestPluginOptions): Plugin<TestMetadata>;
|
|
8
|
+
export type { Reporter, ReporterConfig, ReporterFactory, TestResult, TestSummary, } from './reporters/types.js';
|
|
9
|
+
export type { CommandStep, DirAssertions, FileAssertions, OptionsTestCase, StepsTestCase, TestAssertions, TestCase, TestMetadata, TestOptions, TestStep, } from './schema.js';
|
|
10
|
+
export type { TestPluginOptions } from './types.js';
|
|
11
|
+
export { createPrettyReporter } from './reporters/pretty.js';
|
|
12
|
+
export { createTapReporter } from './reporters/tap.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAoB,MAAM,6BAA6B,CAAC;AAI5E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAqDpD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CAAC,YAAY,CAAC,CAqBtB;AAGD,YAAY,EACV,QAAQ,EACR,cAAc,EACd,eAAe,EACf,UAAU,EACV,WAAW,GACZ,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,WAAW,EACX,aAAa,EACb,cAAc,EACd,eAAe,EACf,aAAa,EACb,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,WAAW,EACX,QAAQ,GACT,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAGpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createTestCommands } from './commands/index.js';
|
|
3
|
+
import { resolveReporters } from './reporters/resolve.js';
|
|
4
|
+
import { TEST_METADATA_JSON_SCHEMA, testMetadataSchema } from './schema.js';
|
|
5
|
+
function mapZodIssue(zIssue) {
|
|
6
|
+
return {
|
|
7
|
+
path: zIssue.path.join('.'),
|
|
8
|
+
message: zIssue.message,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Validate test metadata using Zod schema
|
|
13
|
+
*/
|
|
14
|
+
function validateTestMetadata(metadata) {
|
|
15
|
+
const result = testMetadataSchema.safeParse(metadata);
|
|
16
|
+
if (result.success) {
|
|
17
|
+
return { success: true, errors: [] };
|
|
18
|
+
}
|
|
19
|
+
if (result.error.issues.length === 1) {
|
|
20
|
+
const issue = result.error.issues[0];
|
|
21
|
+
if (issue.code === 'invalid_union' && issue.errors.length > 0) {
|
|
22
|
+
// Type assertion needed because Zod 4's invalid_union has errors typed as
|
|
23
|
+
// $ZodIssue[][] | [] (union with empty tuple), which confuses TypeScript
|
|
24
|
+
const unionErrors = issue.errors;
|
|
25
|
+
const issuesFromUnionMembersWithCorrectType = unionErrors.length > 1
|
|
26
|
+
? unionErrors.filter((zErr) => !zErr.find((err) => err.code === 'invalid_type'))
|
|
27
|
+
: [];
|
|
28
|
+
if (issuesFromUnionMembersWithCorrectType.length === 1) {
|
|
29
|
+
return {
|
|
30
|
+
success: false,
|
|
31
|
+
errors: issuesFromUnionMembersWithCorrectType[0].map(mapZodIssue),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
errors: [
|
|
39
|
+
{
|
|
40
|
+
path: '',
|
|
41
|
+
message: z.prettifyError(result.error),
|
|
42
|
+
...result.error,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Create the test plugin
|
|
49
|
+
*/
|
|
50
|
+
export function createTestPlugin(options = {}) {
|
|
51
|
+
return {
|
|
52
|
+
name: '@functional-examples/test',
|
|
53
|
+
schemas: {
|
|
54
|
+
metadata: JSON.stringify(TEST_METADATA_JSON_SCHEMA),
|
|
55
|
+
},
|
|
56
|
+
validators: {
|
|
57
|
+
metadata: validateTestMetadata,
|
|
58
|
+
},
|
|
59
|
+
commands: async (config) => {
|
|
60
|
+
const reporters = await resolveReporters(options.reporters);
|
|
61
|
+
return createTestCommands(config, {
|
|
62
|
+
reporters,
|
|
63
|
+
defaultReporter: options.defaultReporter ?? 'pretty',
|
|
64
|
+
ciReporter: options.ciReporter ?? 'tap',
|
|
65
|
+
timeout: options.timeout ?? 30000,
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
_options: options,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
// Re-export reporter factories for custom compositions
|
|
72
|
+
export { createPrettyReporter } from './reporters/pretty.js';
|
|
73
|
+
export { createTapReporter } from './reporters/tap.js';
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type { Reporter, ReporterFactory, ReporterConfig, TestResult, TestSummary, } from './types.js';
|
|
2
|
+
export { createPrettyReporter } from './pretty.js';
|
|
3
|
+
export { createTapReporter } from './tap.js';
|
|
4
|
+
export { resolveReporters, BUILTIN_REPORTERS } from './resolve.js';
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,eAAe,EACf,cAAc,EACd,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/reporters/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pretty.d.ts","sourceRoot":"","sources":["../../src/reporters/pretty.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAmB3C,wBAAgB,oBAAoB,IAAI,QAAQ,CAgD/C"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const PASS = '\x1b[32m PASS \x1b[0m';
|
|
2
|
+
const FAIL = '\x1b[31m FAIL \x1b[0m';
|
|
3
|
+
const DIM = '\x1b[2m';
|
|
4
|
+
const RESET = '\x1b[0m';
|
|
5
|
+
const RED = '\x1b[31m';
|
|
6
|
+
const GREEN = '\x1b[32m';
|
|
7
|
+
const YELLOW = '\x1b[33m';
|
|
8
|
+
function countTests(examples) {
|
|
9
|
+
return examples.reduce((sum, e) => {
|
|
10
|
+
const test = e.metadata?.test;
|
|
11
|
+
if (!test)
|
|
12
|
+
return sum;
|
|
13
|
+
return sum + (Array.isArray(test) ? test.length : 1);
|
|
14
|
+
}, 0);
|
|
15
|
+
}
|
|
16
|
+
export function createPrettyReporter() {
|
|
17
|
+
return {
|
|
18
|
+
start(examples) {
|
|
19
|
+
const testCount = countTests(examples);
|
|
20
|
+
console.log(`\nRunning ${testCount} test${testCount !== 1 ? 's' : ''} from ${examples.length} example${examples.length !== 1 ? 's' : ''}\n`);
|
|
21
|
+
},
|
|
22
|
+
report(result, verbose) {
|
|
23
|
+
const status = result.passed ? PASS : FAIL;
|
|
24
|
+
const duration = `${DIM}(${result.duration}ms)${RESET}`;
|
|
25
|
+
console.log(`${status} ${result.example} > ${result.test} ${duration}`);
|
|
26
|
+
if (!result.passed && result.error) {
|
|
27
|
+
const indented = result.error
|
|
28
|
+
.split('\n')
|
|
29
|
+
.map((line) => ` ${line}`)
|
|
30
|
+
.join('\n');
|
|
31
|
+
console.log(indented);
|
|
32
|
+
if (result.actual) {
|
|
33
|
+
console.log(` ${DIM}Exit code: ${result.actual.exitCode}${RESET}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (verbose && result.passed && result.actual) {
|
|
37
|
+
if (result.actual.stdout) {
|
|
38
|
+
const truncated = result.actual.stdout.slice(0, 200);
|
|
39
|
+
console.log(` ${DIM}stdout: ${truncated}${RESET}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
finish({ passed, failed, bail }) {
|
|
44
|
+
console.log('');
|
|
45
|
+
if (bail) {
|
|
46
|
+
console.log(`${YELLOW}Bailed after first failure${RESET}\n`);
|
|
47
|
+
}
|
|
48
|
+
const parts = [];
|
|
49
|
+
if (failed > 0)
|
|
50
|
+
parts.push(`${RED}${failed} failed${RESET}`);
|
|
51
|
+
if (passed > 0)
|
|
52
|
+
parts.push(`${GREEN}${passed} passed${RESET}`);
|
|
53
|
+
parts.push(`${passed + failed} total`);
|
|
54
|
+
console.log(`Tests: ${parts.join(', ')}`);
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=pretty.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pretty.js","sourceRoot":"","sources":["../../src/reporters/pretty.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReporterFactory, ReporterConfig } from './types.js';
|
|
2
|
+
export declare const BUILTIN_REPORTERS: Record<string, ReporterFactory>;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve reporter configs to factory functions
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveReporters(custom?: Record<string, ReporterConfig>): Promise<Record<string, ReporterFactory>>;
|
|
7
|
+
//# sourceMappingURL=resolve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/reporters/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIlE,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAG7D,CAAC;AAyBF;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAM,GAC1C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAY1C"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { createPrettyReporter } from './pretty.js';
|
|
2
|
+
import { createTapReporter } from './tap.js';
|
|
3
|
+
export const BUILTIN_REPORTERS = {
|
|
4
|
+
pretty: createPrettyReporter,
|
|
5
|
+
tap: createTapReporter,
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Load a reporter from a module path
|
|
9
|
+
*/
|
|
10
|
+
async function loadReporterModule(modulePath) {
|
|
11
|
+
try {
|
|
12
|
+
const mod = await import(modulePath);
|
|
13
|
+
const factory = mod.default ?? mod.reporter ?? mod.createReporter;
|
|
14
|
+
if (typeof factory !== 'function') {
|
|
15
|
+
throw new Error(`Reporter module "${modulePath}" must export a factory function ` +
|
|
16
|
+
`as default, 'reporter', or 'createReporter'`);
|
|
17
|
+
}
|
|
18
|
+
return factory;
|
|
19
|
+
}
|
|
20
|
+
catch (err) {
|
|
21
|
+
throw new Error(`Failed to load reporter from "${modulePath}": ${err instanceof Error ? err.message : err}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Resolve reporter configs to factory functions
|
|
26
|
+
*/
|
|
27
|
+
export async function resolveReporters(custom = {}) {
|
|
28
|
+
const resolved = { ...BUILTIN_REPORTERS };
|
|
29
|
+
for (const [name, config] of Object.entries(custom)) {
|
|
30
|
+
if (typeof config === 'function') {
|
|
31
|
+
resolved[name] = config;
|
|
32
|
+
}
|
|
33
|
+
else if (typeof config === 'string') {
|
|
34
|
+
resolved[name] = await loadReporterModule(config);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return resolved;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/reporters/resolve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,CAAC,MAAM,iBAAiB,GAAoC;IAChE,MAAM,EAAE,oBAAoB;IAC5B,GAAG,EAAE,iBAAiB;CACvB,CAAC;AAEF;;GAEG;AACH,KAAK,UAAU,kBAAkB,CAAC,UAAkB;IAClD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QACrC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,cAAc,CAAC;QAElE,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CACb,oBAAoB,UAAU,mCAAmC;gBAC/D,6CAA6C,CAChD,CAAC;QACJ,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,iCAAiC,UAAU,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAC5F,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAyC,EAAE;IAE3C,MAAM,QAAQ,GAAoC,EAAE,GAAG,iBAAiB,EAAE,CAAC;IAE3E,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACpD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;YACjC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC;QAC1B,CAAC;aAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,kBAAkB,CAAC,MAAM,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap.d.ts","sourceRoot":"","sources":["../../src/reporters/tap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAW3C,wBAAgB,iBAAiB,IAAI,QAAQ,CAgD5C"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
function countTests(examples) {
|
|
2
|
+
return examples.reduce((sum, e) => {
|
|
3
|
+
const test = e.metadata?.test;
|
|
4
|
+
if (!test)
|
|
5
|
+
return sum;
|
|
6
|
+
return sum + (Array.isArray(test) ? test.length : 1);
|
|
7
|
+
}, 0);
|
|
8
|
+
}
|
|
9
|
+
export function createTapReporter() {
|
|
10
|
+
let testNumber = 0;
|
|
11
|
+
return {
|
|
12
|
+
start(examples) {
|
|
13
|
+
const total = countTests(examples);
|
|
14
|
+
console.log('TAP version 14');
|
|
15
|
+
console.log(`1..${total}`);
|
|
16
|
+
},
|
|
17
|
+
report(result, _verbose) {
|
|
18
|
+
testNumber++;
|
|
19
|
+
const status = result.passed ? 'ok' : 'not ok';
|
|
20
|
+
const name = `${result.example} > ${result.test}`;
|
|
21
|
+
console.log(`${status} ${testNumber} - ${name}`);
|
|
22
|
+
if (!result.passed) {
|
|
23
|
+
console.log(' ---');
|
|
24
|
+
if (result.error) {
|
|
25
|
+
const escaped = result.error.replace(/"/g, '\\"');
|
|
26
|
+
console.log(` message: "${escaped}"`);
|
|
27
|
+
}
|
|
28
|
+
if (result.actual) {
|
|
29
|
+
console.log(` actual_exit_code: ${result.actual.exitCode}`);
|
|
30
|
+
if (result.actual.stdout) {
|
|
31
|
+
console.log(' stdout: |');
|
|
32
|
+
result.actual.stdout.split('\n').forEach((line) => {
|
|
33
|
+
console.log(` ${line}`);
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (result.actual.stderr) {
|
|
37
|
+
console.log(' stderr: |');
|
|
38
|
+
result.actual.stderr.split('\n').forEach((line) => {
|
|
39
|
+
console.log(` ${line}`);
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
console.log(' ...');
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
finish({ passed, failed }) {
|
|
47
|
+
console.log(`# tests ${passed + failed}`);
|
|
48
|
+
console.log(`# pass ${passed}`);
|
|
49
|
+
console.log(`# fail ${failed}`);
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=tap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tap.js","sourceRoot":"","sources":["../../src/reporters/tap.ts"],"names":[],"mappings":"AAGA,SAAS,UAAU,CAAC,QAAmB;IACrC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QAChC,MAAM,IAAI,GAAI,CAAC,CAAC,QAA+B,EAAE,IAAI,CAAC;QACtD,IAAI,CAAC,IAAI;YAAE,OAAO,GAAG,CAAC;QACtB,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,CAAC,EAAE,CAAC,CAAC,CAAC;AACR,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,OAAO;QACL,KAAK,CAAC,QAAQ;YACZ,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC;QAC7B,CAAC;QAED,MAAM,CAAC,MAAM,EAAE,QAAQ;YACrB,UAAU,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;YAC/C,MAAM,IAAI,GAAG,GAAG,MAAM,CAAC,OAAO,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;YAElD,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,UAAU,MAAM,IAAI,EAAE,CAAC,CAAC;YAEjD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrB,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;oBACjB,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;oBAClD,OAAO,CAAC,GAAG,CAAC,eAAe,OAAO,GAAG,CAAC,CAAC;gBACzC,CAAC;gBACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAC7D,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;wBAC3B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;4BAChD,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;wBAC7B,CAAC,CAAC,CAAC;oBACL,CAAC;oBACD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;wBACzB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;wBAC3B,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;4BAChD,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;wBAC7B,CAAC,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC;QACH,CAAC;QAED,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE;YACvB,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;YAC1C,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC;QAClC,CAAC;KACF,CAAC;AACJ,CAAC"}
|