flake-monster 0.2.0 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flake-monster",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "description": "Source-to-source test hardener that injects async delays to surface flaky tests",
5
5
  "type": "module",
6
6
  "bin": {
@@ -43,18 +43,23 @@ export function createJavaScriptAdapter() {
43
43
  },
44
44
 
45
45
  inject(source, options) {
46
- const { ast } = parseSource(source);
47
- const { insertions, points } = computeInjections(ast, source, options);
48
- const runtimeNeeded = points.length > 0;
46
+ try {
47
+ const { ast } = parseSource(source);
48
+ const { insertions, points } = computeInjections(ast, source, options);
49
+ const runtimeNeeded = points.length > 0;
49
50
 
50
- if (runtimeNeeded) {
51
- const importPath = computeRuntimeImportPath(options.filePath);
52
- const imp = computeRuntimeImportInsertion(ast, source, importPath);
53
- if (imp) insertions.push(imp);
54
- }
51
+ if (runtimeNeeded) {
52
+ const importPath = computeRuntimeImportPath(options.filePath);
53
+ const imp = computeRuntimeImportInsertion(ast, source, importPath);
54
+ if (imp) insertions.push(imp);
55
+ }
55
56
 
56
- const output = applyInsertions(source, insertions);
57
- return { source: output, points, runtimeNeeded };
57
+ const output = applyInsertions(source, insertions);
58
+ return { source: output, points, runtimeNeeded };
59
+ } catch (err) {
60
+ console.warn(` Skipping ${options.filePath}: ${err.message}`);
61
+ return { source, points: [], runtimeNeeded: false };
62
+ }
58
63
  },
59
64
 
60
65
  remove(source) {
@@ -18,6 +18,7 @@ export function registerInjectCommand(program) {
18
18
  .option('--workspace', 'Create a workspace copy instead of modifying files in-place', false)
19
19
  .option('--min-delay <ms>', 'Minimum delay in milliseconds', '0')
20
20
  .option('--max-delay <ms>', 'Maximum delay in milliseconds', '50')
21
+ .option('-e, --exclude <patterns...>', 'Glob patterns to exclude (appends to config defaults)')
21
22
  .action(async (globs, options) => {
22
23
  try {
23
24
  const projectRoot = resolve('.');
@@ -41,7 +42,7 @@ export function registerInjectCommand(program) {
41
42
  console.log(`Workspace created: ${workspace.root}`);
42
43
  }
43
44
 
44
- const manifest = await engine.injectAll(targetDir, globs, seed);
45
+ const manifest = await engine.injectAll(targetDir, globs, seed, merged.exclude);
45
46
  const flakeDir = getFlakeMonsterDir(useWorkspace ? targetDir : projectRoot);
46
47
  await manifest.save(flakeDir);
47
48
 
@@ -45,6 +45,7 @@ export function registerTestCommand(program) {
45
45
  .option('--max-delay <ms>', 'Maximum delay in milliseconds', '50')
46
46
  .option('-f, --format <format>', 'Output format: text or json', 'text')
47
47
  .option('--runner <runner>', 'Test runner: jest, node-test, tap, or auto', 'auto')
48
+ .option('-e, --exclude <patterns...>', 'Glob patterns to exclude (appends to config defaults)')
48
49
  .argument('[globs...]', 'File patterns to process', ['src/**/*.js'])
49
50
  .action(async (globs, options) => {
50
51
  try {
@@ -94,7 +95,7 @@ export function registerTestCommand(program) {
94
95
  }
95
96
 
96
97
  // Inject directly into source
97
- const manifest = await engine.injectAll(projectRoot, globs, runSeed);
98
+ const manifest = await engine.injectAll(projectRoot, globs, runSeed, merged.exclude);
98
99
  const flakeDir = getFlakeMonsterDir(projectRoot);
99
100
  await manifest.save(flakeDir);
100
101
  lastManifest = manifest;
@@ -131,7 +132,7 @@ export function registerTestCommand(program) {
131
132
  await workspace.create();
132
133
 
133
134
  // Inject
134
- const manifest = await engine.injectAll(workspace.root, globs, runSeed);
135
+ const manifest = await engine.injectAll(workspace.root, globs, runSeed, merged.exclude);
135
136
  const flakeDir = getFlakeMonsterDir(workspace.root);
136
137
  await manifest.save(flakeDir);
137
138
 
package/src/cli/index.js CHANGED
@@ -9,7 +9,7 @@ export function createCli() {
9
9
  program
10
10
  .name('flake-monster')
11
11
  .description('Source-to-source test hardener, injects async delays to surface flaky tests')
12
- .version('0.1.0');
12
+ .version('0.3.1');
13
13
 
14
14
  registerInjectCommand(program);
15
15
  registerRestoreCommand(program);
@@ -53,5 +53,8 @@ export function mergeWithCliOptions(config, cliOptions) {
53
53
  if (cliOptions.keepOnFail) merged.keepOnFail = true;
54
54
  if (cliOptions.keepAll) merged.keepAll = true;
55
55
  if (cliOptions.skipTryCatch) merged.skipTryCatch = true;
56
+ if (cliOptions.exclude) {
57
+ merged.exclude = [...new Set([...merged.exclude, ...cliOptions.exclude])];
58
+ }
56
59
  return merged;
57
60
  }
@@ -23,15 +23,16 @@ export class InjectorEngine {
23
23
  * @param {string} rootDir - Directory to process (workspace or project root)
24
24
  * @param {string[]} globs - File patterns to process
25
25
  * @param {number} seed
26
+ * @param {string[]} [exclude=[]] - Glob patterns to exclude
26
27
  * @returns {Promise<Manifest>}
27
28
  */
28
- async injectAll(rootDir, globs, seed) {
29
+ async injectAll(rootDir, globs, seed, exclude = []) {
29
30
  const manifest = new Manifest();
30
31
  manifest.seed = seed;
31
32
  manifest.mode = this.profile.mode;
32
33
 
33
34
  // Resolve globs to file list
34
- const files = await fg(globs, { cwd: rootDir, absolute: false });
35
+ const files = await fg(globs, { cwd: rootDir, absolute: false, ignore: exclude });
35
36
 
36
37
  const adaptersUsed = new Set();
37
38
  let totalInjections = 0;