testgen-ts 1.0.0
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/analyzer.d.ts +33 -0
- package/dist/analyzer.js +154 -0
- package/dist/analyzer.js.map +1 -0
- package/dist/bootstrap.d.ts +16 -0
- package/dist/bootstrap.js +227 -0
- package/dist/bootstrap.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +70 -0
- package/dist/cli.js.map +1 -0
- package/dist/configManager.d.ts +15 -0
- package/dist/configManager.js +94 -0
- package/dist/configManager.js.map +1 -0
- package/dist/formatter.d.ts +5 -0
- package/dist/formatter.js +67 -0
- package/dist/formatter.js.map +1 -0
- package/dist/generator.d.ts +10 -0
- package/dist/generator.js +446 -0
- package/dist/generator.js.map +1 -0
- package/dist/mockGenerator.d.ts +61 -0
- package/dist/mockGenerator.js +305 -0
- package/dist/mockGenerator.js.map +1 -0
- package/dist/scenarioEngine.d.ts +39 -0
- package/dist/scenarioEngine.js +138 -0
- package/dist/scenarioEngine.js.map +1 -0
- package/dist/utils.d.ts +27 -0
- package/dist/utils.js +110 -0
- package/dist/utils.js.map +1 -0
- package/dist/watcher.d.ts +13 -0
- package/dist/watcher.js +148 -0
- package/dist/watcher.js.map +1 -0
- package/package.json +44 -0
package/dist/watcher.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.startWatcher = startWatcher;
|
|
37
|
+
exports.processFile = processFile;
|
|
38
|
+
const chokidar = __importStar(require("chokidar"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const analyzer_1 = require("./analyzer");
|
|
41
|
+
const scenarioEngine_1 = require("./scenarioEngine");
|
|
42
|
+
const mockGenerator_1 = require("./mockGenerator");
|
|
43
|
+
const generator_1 = require("./generator");
|
|
44
|
+
const configManager_1 = require("./configManager");
|
|
45
|
+
const utils_1 = require("./utils");
|
|
46
|
+
/**
|
|
47
|
+
* Start the file watcher.
|
|
48
|
+
*
|
|
49
|
+
* Watches the src directory for .ts file changes and runs the
|
|
50
|
+
* analyze → scenario → mock → test pipeline on each changed file.
|
|
51
|
+
*/
|
|
52
|
+
function startWatcher() {
|
|
53
|
+
const projectRoot = (0, utils_1.getProjectRoot)();
|
|
54
|
+
const config = (0, configManager_1.loadConfig)(projectRoot);
|
|
55
|
+
// Resolve the src directory as an absolute path
|
|
56
|
+
const srcAbsolute = path.resolve(projectRoot, config.srcDir);
|
|
57
|
+
(0, utils_1.log)("Starting testgen watcher…", "info");
|
|
58
|
+
(0, utils_1.log)(`Project root: ${projectRoot}`, "info");
|
|
59
|
+
(0, utils_1.log)(`Watching directory: ${srcAbsolute}`, "info");
|
|
60
|
+
(0, utils_1.log)("", "info");
|
|
61
|
+
const debounceTimers = new Map();
|
|
62
|
+
const DEBOUNCE_MS = 500;
|
|
63
|
+
// Watch the src directory directly — NOT a glob pattern.
|
|
64
|
+
// Globs resolved to absolute Windows paths (C:\...) cause unreliable
|
|
65
|
+
// matching in chokidar on Windows.
|
|
66
|
+
const watcher = chokidar.watch(srcAbsolute, {
|
|
67
|
+
persistent: true,
|
|
68
|
+
ignoreInitial: true,
|
|
69
|
+
// Use polling for reliable cross-platform detection
|
|
70
|
+
usePolling: true,
|
|
71
|
+
interval: 300,
|
|
72
|
+
binaryInterval: 600,
|
|
73
|
+
// Only ignore known non-source directories by path.
|
|
74
|
+
// IMPORTANT: Do NOT filter by extension here — chokidar calls ignored()
|
|
75
|
+
// on directories too, and without stats they'd be blocked.
|
|
76
|
+
ignored: /(^|[\/\\])(node_modules|testgen|dist|\.git)([\/\\]|$)/,
|
|
77
|
+
});
|
|
78
|
+
const handleFile = (filePath) => {
|
|
79
|
+
// Extra safety: skip non-.ts files
|
|
80
|
+
if (!filePath.endsWith(".ts"))
|
|
81
|
+
return;
|
|
82
|
+
if (filePath.endsWith(".test.ts") || filePath.endsWith(".spec.ts"))
|
|
83
|
+
return;
|
|
84
|
+
if (filePath.endsWith(".d.ts"))
|
|
85
|
+
return;
|
|
86
|
+
// Clear existing timer for this file
|
|
87
|
+
const existing = debounceTimers.get(filePath);
|
|
88
|
+
if (existing)
|
|
89
|
+
clearTimeout(existing);
|
|
90
|
+
debounceTimers.set(filePath, setTimeout(async () => {
|
|
91
|
+
debounceTimers.delete(filePath);
|
|
92
|
+
await processFile(filePath, projectRoot, config);
|
|
93
|
+
}, DEBOUNCE_MS));
|
|
94
|
+
};
|
|
95
|
+
watcher
|
|
96
|
+
.on("add", (fp) => {
|
|
97
|
+
(0, utils_1.log)(`File added: ${path.relative(projectRoot, fp)}`, "info");
|
|
98
|
+
handleFile(fp);
|
|
99
|
+
})
|
|
100
|
+
.on("change", (fp) => {
|
|
101
|
+
(0, utils_1.log)(`File changed: ${path.relative(projectRoot, fp)}`, "info");
|
|
102
|
+
handleFile(fp);
|
|
103
|
+
})
|
|
104
|
+
.on("error", (err) => {
|
|
105
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
106
|
+
(0, utils_1.log)(`Watcher error: ${message}`, "error");
|
|
107
|
+
})
|
|
108
|
+
.on("ready", () => {
|
|
109
|
+
(0, utils_1.log)("Watcher ready — waiting for file changes…\n", "success");
|
|
110
|
+
});
|
|
111
|
+
// Keep the Node.js event loop alive.
|
|
112
|
+
// chokidar v5 on Windows may not hold the event loop by itself.
|
|
113
|
+
const keepalive = setInterval(() => { }, 60000);
|
|
114
|
+
// Graceful shutdown
|
|
115
|
+
const shutdown = () => {
|
|
116
|
+
clearInterval(keepalive);
|
|
117
|
+
(0, utils_1.log)("\nShutting down watcher…", "info");
|
|
118
|
+
watcher.close().then(() => process.exit(0));
|
|
119
|
+
};
|
|
120
|
+
process.on("SIGINT", shutdown);
|
|
121
|
+
process.on("SIGTERM", shutdown);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Process a single TypeScript file through the full pipeline:
|
|
125
|
+
* analyze → scenarios → mock file → test file
|
|
126
|
+
*/
|
|
127
|
+
async function processFile(filePath, projectRoot, config) {
|
|
128
|
+
try {
|
|
129
|
+
(0, utils_1.log)(`Analyzing: ${path.relative(projectRoot, filePath)}`, "info");
|
|
130
|
+
// 1. Analyse the file
|
|
131
|
+
const functions = (0, analyzer_1.analyzeFile)(filePath);
|
|
132
|
+
if (functions.length === 0) {
|
|
133
|
+
(0, utils_1.log)(" No exported functions or class methods found — skipping.", "warn");
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
(0, utils_1.log)(` Found ${functions.length} exported function(s) / method(s).`, "info");
|
|
137
|
+
// 2. Generate scenarios
|
|
138
|
+
const scenarios = (0, scenarioEngine_1.generateScenarios)(functions, config);
|
|
139
|
+
// 3. Generate the mock file (first!)
|
|
140
|
+
const mockResult = await (0, mockGenerator_1.generateMockFile)(filePath, scenarios, projectRoot, config.srcDir, config.mockDir);
|
|
141
|
+
// 4. Generate the test file (with mock import)
|
|
142
|
+
await (0, generator_1.generateTestFile)(filePath, scenarios, projectRoot, config.srcDir, config.testDir, mockResult);
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
(0, utils_1.log)(` Error processing file: ${err.message}`, "error");
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../src/watcher.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "testgen-ts",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Developer CLI tool that bootstraps testing environments and auto-generates unit test skeletons for TypeScript functions",
|
|
5
|
+
"main": "dist/cli.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"testgen": "./dist/cli.js",
|
|
8
|
+
"testgen-ts": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/cli.js",
|
|
13
|
+
"dev": "ts-node src/cli.ts",
|
|
14
|
+
"test": "jest --config ./testgen/jest.config.ts"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"testing",
|
|
18
|
+
"typescript",
|
|
19
|
+
"cli",
|
|
20
|
+
"code-generation",
|
|
21
|
+
"jest"
|
|
22
|
+
],
|
|
23
|
+
"author": "",
|
|
24
|
+
"license": "ISC",
|
|
25
|
+
"files": [
|
|
26
|
+
"dist/**/*"
|
|
27
|
+
],
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"chokidar": "^5.0.0",
|
|
30
|
+
"commander": "^14.0.3",
|
|
31
|
+
"crypto-js": "^4.2.0",
|
|
32
|
+
"prettier": "^3.8.1",
|
|
33
|
+
"ts-morph": "^27.0.2"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/crypto-js": "^4.2.2",
|
|
37
|
+
"@types/jest": "^30.0.0",
|
|
38
|
+
"@types/node": "^25.3.3",
|
|
39
|
+
"jest": "^30.2.0",
|
|
40
|
+
"ts-jest": "^29.4.6",
|
|
41
|
+
"ts-node": "^10.9.2",
|
|
42
|
+
"typescript": "^5.9.3"
|
|
43
|
+
}
|
|
44
|
+
}
|