@aigne/test-utils 0.5.69-beta.18 → 0.5.69-beta.19

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/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.69-beta.19](https://github.com/AIGNE-io/aigne-framework/compare/test-utils-v0.5.69-beta.18...test-utils-v0.5.69-beta.19) (2026-01-14)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * improve test coverage tracking and reporting ([#903](https://github.com/AIGNE-io/aigne-framework/issues/903)) ([031144e](https://github.com/AIGNE-io/aigne-framework/commit/031144e74f29e882cffe52ffda8f7a18c76ace7f))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @aigne/core bumped to 1.72.0-beta.19
16
+
3
17
  ## [0.5.69-beta.18](https://github.com/AIGNE-io/aigne-framework/compare/test-utils-v0.5.69-beta.17...test-utils-v0.5.69-beta.18) (2026-01-13)
4
18
 
5
19
 
@@ -0,0 +1,38 @@
1
+ export interface ImportAllModulesOptions {
2
+ /**
3
+ * The root directory to scan for source files
4
+ */
5
+ sourceDir: string;
6
+ /**
7
+ * Patterns to exclude from import (default: test files, type definitions, build artifacts)
8
+ */
9
+ exclude?: string[];
10
+ /**
11
+ * File extensions to include (default: ts, tsx, js, jsx, mjs, cjs)
12
+ */
13
+ extensions?: string[];
14
+ /**
15
+ * Whether to show verbose logging (default: false)
16
+ */
17
+ verbose?: boolean;
18
+ }
19
+ /**
20
+ * Import all modules in a directory for coverage tracking.
21
+ *
22
+ * This utility dynamically imports all source files in a package to ensure
23
+ * Bun's coverage reporter includes them in coverage metrics, even if they
24
+ * aren't directly imported by any tests.
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * import { test } from 'bun:test';
29
+ * import { importAllModules } from '@aigne/test-utils/utils/import-all-modules';
30
+ *
31
+ * test('import all modules for coverage tracking', async () => {
32
+ * await importAllModules({
33
+ * sourceDir: '../src',
34
+ * });
35
+ * });
36
+ * ```
37
+ */
38
+ export declare function importAllModules(options: ImportAllModulesOptions): Promise<void>;
@@ -0,0 +1,84 @@
1
+ import { join, resolve } from "node:path";
2
+ import { Glob } from "bun";
3
+ /**
4
+ * Import all modules in a directory for coverage tracking.
5
+ *
6
+ * This utility dynamically imports all source files in a package to ensure
7
+ * Bun's coverage reporter includes them in coverage metrics, even if they
8
+ * aren't directly imported by any tests.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * import { test } from 'bun:test';
13
+ * import { importAllModules } from '@aigne/test-utils/utils/import-all-modules';
14
+ *
15
+ * test('import all modules for coverage tracking', async () => {
16
+ * await importAllModules({
17
+ * sourceDir: '../src',
18
+ * });
19
+ * });
20
+ * ```
21
+ */
22
+ export async function importAllModules(options) {
23
+ const { sourceDir, exclude = [
24
+ "**/*.test.*",
25
+ "**/*.spec.*",
26
+ "**/__tests__/**",
27
+ "**/__mocks__/**",
28
+ "**/*.d.ts",
29
+ "**/node_modules/**",
30
+ "**/lib/**",
31
+ "**/dist/**",
32
+ "**/coverage/**",
33
+ ], extensions = ["ts", "tsx", "js", "jsx", "mjs", "cjs"], verbose = false, } = options;
34
+ // Resolve sourceDir to absolute path from current working directory
35
+ const absoluteSourceDir = resolve(sourceDir);
36
+ // Build the glob pattern for matching files
37
+ const pattern = extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(",")}}`;
38
+ const glob = new Glob(pattern);
39
+ // Scan for files
40
+ const files = [];
41
+ for await (const file of glob.scan({
42
+ cwd: absoluteSourceDir,
43
+ onlyFiles: true,
44
+ })) {
45
+ // Check if file should be excluded
46
+ const shouldExclude = exclude.some((pattern) => {
47
+ // Simple pattern matching (supports ** and * wildcards)
48
+ const regexPattern = pattern
49
+ .replace(/\*\*/g, ".*")
50
+ .replace(/\*/g, "[^/]*")
51
+ .replace(/\./g, "\\.");
52
+ return new RegExp(regexPattern).test(file);
53
+ });
54
+ if (!shouldExclude) {
55
+ files.push(file);
56
+ }
57
+ }
58
+ if (verbose) {
59
+ console.log(`[coverage] Found ${files.length} source files to import`);
60
+ }
61
+ // Import all files in parallel
62
+ const imports = files.map(async (file) => {
63
+ const absoluteFilePath = join(absoluteSourceDir, file);
64
+ try {
65
+ // Use file:// URL for reliable imports across different CWDs
66
+ const fileUrl = `file://${absoluteFilePath}`;
67
+ await import(fileUrl);
68
+ if (verbose) {
69
+ console.log(`[coverage] ✓ Imported: ${file}`);
70
+ }
71
+ }
72
+ catch (error) {
73
+ // Some files may fail to import (e.g., templates, type-only files)
74
+ // This is expected and should not fail the test
75
+ if (verbose) {
76
+ console.warn(`[coverage] ⚠ Failed to import ${file}:`, error);
77
+ }
78
+ }
79
+ });
80
+ await Promise.allSettled(imports);
81
+ if (verbose) {
82
+ console.log(`[coverage] Completed importing ${files.length} modules`);
83
+ }
84
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/test-utils",
3
- "version": "0.5.69-beta.18",
3
+ "version": "0.5.69-beta.19",
4
4
  "description": "Test utils for AIGNE framework",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -27,7 +27,7 @@
27
27
  }
28
28
  },
29
29
  "dependencies": {
30
- "@aigne/core": "^1.72.0-beta.18"
30
+ "@aigne/core": "^1.72.0-beta.19"
31
31
  },
32
32
  "devDependencies": {
33
33
  "@types/bun": "^1.2.22",
@@ -0,0 +1,121 @@
1
+ import { join, resolve } from "node:path";
2
+ import { Glob } from "bun";
3
+
4
+ export interface ImportAllModulesOptions {
5
+ /**
6
+ * The root directory to scan for source files
7
+ */
8
+ sourceDir: string;
9
+
10
+ /**
11
+ * Patterns to exclude from import (default: test files, type definitions, build artifacts)
12
+ */
13
+ exclude?: string[];
14
+
15
+ /**
16
+ * File extensions to include (default: ts, tsx, js, jsx, mjs, cjs)
17
+ */
18
+ extensions?: string[];
19
+
20
+ /**
21
+ * Whether to show verbose logging (default: false)
22
+ */
23
+ verbose?: boolean;
24
+ }
25
+
26
+ /**
27
+ * Import all modules in a directory for coverage tracking.
28
+ *
29
+ * This utility dynamically imports all source files in a package to ensure
30
+ * Bun's coverage reporter includes them in coverage metrics, even if they
31
+ * aren't directly imported by any tests.
32
+ *
33
+ * @example
34
+ * ```typescript
35
+ * import { test } from 'bun:test';
36
+ * import { importAllModules } from '@aigne/test-utils/utils/import-all-modules';
37
+ *
38
+ * test('import all modules for coverage tracking', async () => {
39
+ * await importAllModules({
40
+ * sourceDir: '../src',
41
+ * });
42
+ * });
43
+ * ```
44
+ */
45
+ export async function importAllModules(options: ImportAllModulesOptions): Promise<void> {
46
+ const {
47
+ sourceDir,
48
+ exclude = [
49
+ "**/*.test.*",
50
+ "**/*.spec.*",
51
+ "**/__tests__/**",
52
+ "**/__mocks__/**",
53
+ "**/*.d.ts",
54
+ "**/node_modules/**",
55
+ "**/lib/**",
56
+ "**/dist/**",
57
+ "**/coverage/**",
58
+ ],
59
+ extensions = ["ts", "tsx", "js", "jsx", "mjs", "cjs"],
60
+ verbose = false,
61
+ } = options;
62
+
63
+ // Resolve sourceDir to absolute path from current working directory
64
+ const absoluteSourceDir = resolve(sourceDir);
65
+
66
+ // Build the glob pattern for matching files
67
+ const pattern =
68
+ extensions.length === 1 ? `**/*.${extensions[0]}` : `**/*.{${extensions.join(",")}}`;
69
+
70
+ const glob = new Glob(pattern);
71
+
72
+ // Scan for files
73
+ const files: string[] = [];
74
+ for await (const file of glob.scan({
75
+ cwd: absoluteSourceDir,
76
+ onlyFiles: true,
77
+ })) {
78
+ // Check if file should be excluded
79
+ const shouldExclude = exclude.some((pattern) => {
80
+ // Simple pattern matching (supports ** and * wildcards)
81
+ const regexPattern = pattern
82
+ .replace(/\*\*/g, ".*")
83
+ .replace(/\*/g, "[^/]*")
84
+ .replace(/\./g, "\\.");
85
+ return new RegExp(regexPattern).test(file);
86
+ });
87
+
88
+ if (!shouldExclude) {
89
+ files.push(file);
90
+ }
91
+ }
92
+
93
+ if (verbose) {
94
+ console.log(`[coverage] Found ${files.length} source files to import`);
95
+ }
96
+
97
+ // Import all files in parallel
98
+ const imports = files.map(async (file) => {
99
+ const absoluteFilePath = join(absoluteSourceDir, file);
100
+ try {
101
+ // Use file:// URL for reliable imports across different CWDs
102
+ const fileUrl = `file://${absoluteFilePath}`;
103
+ await import(fileUrl);
104
+ if (verbose) {
105
+ console.log(`[coverage] ✓ Imported: ${file}`);
106
+ }
107
+ } catch (error) {
108
+ // Some files may fail to import (e.g., templates, type-only files)
109
+ // This is expected and should not fail the test
110
+ if (verbose) {
111
+ console.warn(`[coverage] ⚠ Failed to import ${file}:`, error);
112
+ }
113
+ }
114
+ });
115
+
116
+ await Promise.allSettled(imports);
117
+
118
+ if (verbose) {
119
+ console.log(`[coverage] Completed importing ${files.length} modules`);
120
+ }
121
+ }
@@ -4,6 +4,7 @@
4
4
  "rootDir": "./src",
5
5
  "outDir": "./lib",
6
6
  "noEmit": false,
7
+ "allowImportingTsExtensions": false,
7
8
  "declaration": true
8
9
  },
9
10
  "include": ["./src"]
@@ -1 +1 @@
1
- {"root":["./src/run-example-test.ts","./src/utils/agent-response.ts","./src/utils/event-stream.ts","./src/utils/openai-like-utils.ts","./src/utils/with-env.ts"],"version":"5.9.2"}
1
+ {"root":["./src/run-example-test.ts","./src/utils/agent-response.ts","./src/utils/event-stream.ts","./src/utils/import-all-modules.ts","./src/utils/openai-like-utils.ts","./src/utils/with-env.ts"],"version":"5.9.2"}