jest-test-lineage-reporter 2.1.0 → 2.1.2

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 CHANGED
@@ -20,29 +20,58 @@ A comprehensive test analytics platform that provides line-by-line test coverage
20
20
 
21
21
  ## šŸš€ CLI Usage (New!)
22
22
 
23
- Jest Test Lineage Reporter now includes a powerful CLI tool!
23
+ Jest Test Lineage Reporter now includes a powerful CLI tool with automatic configuration!
24
24
 
25
25
  ### Quick Start with CLI
26
26
 
27
27
  ```bash
28
- # Run tests with lineage tracking
29
- jest-lineage test
28
+ # 1. Install the package
29
+ npm install --save-dev jest-test-lineage-reporter jest babel-jest @babel/core @babel/preset-env
30
30
 
31
- # Run mutation testing on existing data
32
- jest-lineage mutate --threshold 85
31
+ # 2. Initialize configuration (creates jest.config.js and babel.config.js)
32
+ npx jest-lineage init
33
33
 
34
- # Generate HTML report
35
- jest-lineage report --open
34
+ # 3. Run tests with lineage tracking
35
+ npx jest-lineage test
36
36
 
37
- # Query which tests cover a specific line
38
- jest-lineage query src/calculator.ts 42
37
+ # 4. Generate HTML report
38
+ npx jest-lineage report --open
39
39
 
40
- # Full analysis workflow (test + mutate + report)
41
- jest-lineage analyze --open
40
+ # 5. Run mutation testing
41
+ npx jest-lineage mutate --threshold 85
42
+
43
+ # 6. Query which tests cover a specific line
44
+ npx jest-lineage query src/calculator.ts 42
45
+
46
+ # 7. Full analysis workflow (test + mutate + report)
47
+ npx jest-lineage analyze --open
42
48
  ```
43
49
 
44
50
  ### CLI Commands
45
51
 
52
+ #### `jest-lineage init` ⭐ NEW
53
+ Initialize project configuration automatically.
54
+
55
+ ```bash
56
+ # Create jest.config.js and babel.config.js with all required settings
57
+ npx jest-lineage init
58
+
59
+ # Force overwrite existing config files
60
+ npx jest-lineage init --force
61
+
62
+ # Configure for TypeScript project
63
+ npx jest-lineage init --typescript
64
+ ```
65
+
66
+ **What it does:**
67
+ - āœ… Checks for required dependencies
68
+ - āœ… Creates `jest.config.js` with lineage reporter configured
69
+ - āœ… Creates `babel.config.js` with instrumentation plugin
70
+ - āœ… Detects TypeScript and configures accordingly
71
+ - āœ… Shows clear next steps
72
+
73
+
74
+
46
75
  #### `jest-lineage test [jest-args...]`
47
76
  Run Jest tests with lineage tracking enabled.
48
77
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jest-test-lineage-reporter",
3
- "version": "2.1.0",
3
+ "version": "2.1.2",
4
4
  "main": "src/TestCoverageReporter.js",
5
5
  "bin": {
6
6
  "jest-lineage": "./bin/jest-lineage.js"
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Init Command
3
+ * Initialize jest-test-lineage-reporter in a project
4
+ */
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+ const { success, error, info, warning } = require('../utils/output-formatter');
9
+
10
+ async function initCommand(options) {
11
+ try {
12
+ const cwd = process.cwd();
13
+ const jestConfigPath = path.join(cwd, 'jest.config.js');
14
+ const babelConfigPath = path.join(cwd, 'babel.config.js');
15
+ const packageJsonPath = path.join(cwd, 'package.json');
16
+
17
+ console.log('\nšŸš€ Initializing jest-test-lineage-reporter...\n');
18
+
19
+ // Check if package.json exists
20
+ if (!fs.existsSync(packageJsonPath)) {
21
+ error('No package.json found. Please run "npm init" first.');
22
+ process.exit(1);
23
+ }
24
+
25
+ // Detect if jest-test-lineage-reporter is installed locally or globally
26
+ const isLocalInstall = isInstalledLocally(cwd);
27
+
28
+ if (!isLocalInstall) {
29
+ warning('jest-test-lineage-reporter is installed globally.');
30
+ warning('For best results, install it locally in your project:\n');
31
+ console.log(' npm install --save-dev jest-test-lineage-reporter\n');
32
+
33
+ if (!options.force) {
34
+ error('Global installation detected. Use --force to continue with absolute paths.');
35
+ process.exit(1);
36
+ }
37
+ }
38
+
39
+ // Read package.json to check dependencies
40
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
41
+ const allDeps = {
42
+ ...(packageJson.dependencies || {}),
43
+ ...(packageJson.devDependencies || {}),
44
+ };
45
+
46
+ // Check for required dependencies
47
+ const requiredDeps = ['jest', 'babel-jest', '@babel/core', '@babel/preset-env'];
48
+ const missingDeps = requiredDeps.filter(dep => !allDeps[dep]);
49
+
50
+ if (missingDeps.length > 0) {
51
+ warning('Missing required dependencies:');
52
+ missingDeps.forEach(dep => console.log(` - ${dep}`));
53
+ console.log('\nšŸ’” Install them with:');
54
+ console.log(` npm install --save-dev ${missingDeps.join(' ')}\n`);
55
+
56
+ if (!options.force) {
57
+ error('Please install missing dependencies first, or use --force to continue anyway.');
58
+ process.exit(1);
59
+ }
60
+ }
61
+
62
+ // Create or update Jest config
63
+ let jestConfigCreated = false;
64
+ if (fs.existsSync(jestConfigPath)) {
65
+ if (!options.force) {
66
+ warning(`jest.config.js already exists. Use --force to overwrite.`);
67
+ info('Please manually add the following to your jest.config.js:');
68
+ const setupPath = isLocalInstall
69
+ ? 'jest-test-lineage-reporter/src/testSetup.js'
70
+ : getGlobalPackagePath('testSetup.js');
71
+ console.log(`
72
+ setupFilesAfterEnv: ['${setupPath}'],
73
+
74
+ reporters: [
75
+ 'default',
76
+ ['jest-test-lineage-reporter', {
77
+ outputFile: '.jest-lineage-data.json',
78
+ enableMutationTesting: false,
79
+ }]
80
+ ],
81
+
82
+ collectCoverage: true,
83
+ collectCoverageFrom: ['src/**/*.{js,ts}', '!src/**/*.test.{js,ts}'],
84
+
85
+ transform: {
86
+ '^.+\\\\.(js|jsx|ts|tsx)$': 'babel-jest',
87
+ },
88
+ `);
89
+ } else {
90
+ createJestConfig(jestConfigPath, options, isLocalInstall);
91
+ jestConfigCreated = true;
92
+ }
93
+ } else {
94
+ createJestConfig(jestConfigPath, options, isLocalInstall);
95
+ jestConfigCreated = true;
96
+ }
97
+
98
+ // Create or update Babel config
99
+ let babelConfigCreated = false;
100
+ if (fs.existsSync(babelConfigPath)) {
101
+ if (!options.force) {
102
+ warning(`babel.config.js already exists. Use --force to overwrite.`);
103
+ info('Please manually add the lineage tracker plugin to your babel.config.js:');
104
+ const pluginPath = isLocalInstall
105
+ ? 'jest-test-lineage-reporter/src/babel-plugin-lineage-tracker.js'
106
+ : getGlobalPackagePath('babel-plugin-lineage-tracker.js');
107
+ console.log(`
108
+ plugins: [
109
+ '${pluginPath}',
110
+ ],
111
+ `);
112
+ } else {
113
+ createBabelConfig(babelConfigPath, options, isLocalInstall);
114
+ babelConfigCreated = true;
115
+ }
116
+ } else {
117
+ createBabelConfig(babelConfigPath, options, isLocalInstall);
118
+ babelConfigCreated = true;
119
+ }
120
+
121
+ // Summary
122
+ console.log('\n' + '═'.repeat(50));
123
+ if (jestConfigCreated && babelConfigCreated) {
124
+ success('Configuration complete! ✨\n');
125
+ console.log('āœ… Created jest.config.js');
126
+ console.log('āœ… Created babel.config.js\n');
127
+ } else if (!jestConfigCreated && !babelConfigCreated) {
128
+ info('Configuration files already exist.');
129
+ info('Use --force to overwrite, or manually update the files.\n');
130
+ } else {
131
+ info('Partial configuration completed.');
132
+ if (jestConfigCreated) console.log('āœ… Created jest.config.js');
133
+ if (babelConfigCreated) console.log('āœ… Created babel.config.js');
134
+ console.log('');
135
+ }
136
+
137
+ // Show next steps
138
+ console.log('šŸ“‹ Next steps:\n');
139
+ if (missingDeps.length > 0) {
140
+ console.log('1. Install missing dependencies:');
141
+ console.log(` npm install --save-dev ${missingDeps.join(' ')}\n`);
142
+ }
143
+ console.log(`${missingDeps.length > 0 ? '2' : '1'}. Run your tests with lineage tracking:`);
144
+ console.log(' npx jest-lineage test\n');
145
+ console.log(`${missingDeps.length > 0 ? '3' : '2'}. Query coverage data:`);
146
+ console.log(' npx jest-lineage query src/yourfile.js\n');
147
+ console.log(`${missingDeps.length > 0 ? '4' : '3'}. Generate HTML report:`);
148
+ console.log(' npx jest-lineage report --open\n');
149
+ console.log('═'.repeat(50) + '\n');
150
+
151
+ } catch (err) {
152
+ error(`Failed to initialize: ${err.message}`);
153
+ if (options.verbose) {
154
+ console.error(err.stack);
155
+ }
156
+ process.exit(1);
157
+ }
158
+ }
159
+
160
+ function createJestConfig(filePath, options, isLocalInstall) {
161
+ const isTypeScript = options.typescript || hasTypeScriptFiles();
162
+ const setupPath = isLocalInstall
163
+ ? 'jest-test-lineage-reporter/src/testSetup.js'
164
+ : getGlobalPackagePath('testSetup.js');
165
+
166
+ const config = `module.exports = {
167
+ testEnvironment: 'node',
168
+
169
+ // Required: Setup file for lineage tracking
170
+ setupFilesAfterEnv: ['${setupPath}'],
171
+
172
+ // Add the lineage reporter
173
+ reporters: [
174
+ 'default',
175
+ [
176
+ 'jest-test-lineage-reporter',
177
+ {
178
+ outputFile: '.jest-lineage-data.json',
179
+ enableMutationTesting: false,
180
+ }
181
+ ]
182
+ ],
183
+
184
+ // Enable coverage
185
+ collectCoverage: true,
186
+ collectCoverageFrom: [
187
+ 'src/**/*.{js${isTypeScript ? ',ts' : ''}}',
188
+ '!src/**/*.test.{js${isTypeScript ? ',ts' : ''}}',
189
+ '!src/**/*.d.ts',
190
+ ],
191
+
192
+ // Use babel-jest for transformation
193
+ transform: {
194
+ '^.+\\\\.(js|jsx${isTypeScript ? '|ts|tsx' : ''})$': 'babel-jest',
195
+ },
196
+
197
+ // File extensions
198
+ moduleFileExtensions: ['js', 'jsx'${isTypeScript ? ", 'ts', 'tsx'" : ''}, 'json'],
199
+ };
200
+ `;
201
+
202
+ fs.writeFileSync(filePath, config, 'utf8');
203
+ }
204
+
205
+ function createBabelConfig(filePath, options, isLocalInstall) {
206
+ const isTypeScript = options.typescript || hasTypeScriptFiles();
207
+ const pluginPath = isLocalInstall
208
+ ? 'jest-test-lineage-reporter/src/babel-plugin-lineage-tracker.js'
209
+ : getGlobalPackagePath('babel-plugin-lineage-tracker.js');
210
+
211
+ const config = `module.exports = {
212
+ presets: [
213
+ ['@babel/preset-env', { targets: { node: 'current' } }],${isTypeScript ? `
214
+ '@babel/preset-typescript',` : ''}
215
+ ],
216
+ plugins: [
217
+ // Required: Lineage tracker plugin for instrumentation
218
+ '${pluginPath}',
219
+ ],
220
+ };
221
+ `;
222
+
223
+ fs.writeFileSync(filePath, config, 'utf8');
224
+ }
225
+
226
+ function hasTypeScriptFiles() {
227
+ const cwd = process.cwd();
228
+ const srcDir = path.join(cwd, 'src');
229
+
230
+ if (!fs.existsSync(srcDir)) return false;
231
+
232
+ try {
233
+ const files = fs.readdirSync(srcDir);
234
+ return files.some(file => file.endsWith('.ts') || file.endsWith('.tsx'));
235
+ } catch {
236
+ return false;
237
+ }
238
+ }
239
+
240
+ function isInstalledLocally(cwd) {
241
+ const localPath = path.join(cwd, 'node_modules', 'jest-test-lineage-reporter');
242
+ return fs.existsSync(localPath);
243
+ }
244
+
245
+ function getGlobalPackagePath(filename) {
246
+ // Get the directory where this script is running from
247
+ const scriptDir = path.dirname(path.dirname(path.dirname(__dirname)));
248
+ const srcPath = path.join(scriptDir, 'src', filename);
249
+
250
+ // Return absolute path
251
+ return srcPath;
252
+ }
253
+
254
+ module.exports = initCommand;
package/src/cli/index.js CHANGED
@@ -4,6 +4,7 @@
4
4
  */
5
5
 
6
6
  const { Command } = require('commander');
7
+ const initCommand = require('./commands/init');
7
8
  const testCommand = require('./commands/test');
8
9
  const mutateCommand = require('./commands/mutate');
9
10
  const reportCommand = require('./commands/report');
@@ -19,6 +20,15 @@ async function run(argv) {
19
20
  .description('Comprehensive test analytics with lineage tracking and mutation testing')
20
21
  .version(pkg.version, '-v, --version', 'Display version number');
21
22
 
23
+ // Init command - Initialize project configuration
24
+ program
25
+ .command('init')
26
+ .description('Initialize jest-test-lineage-reporter configuration')
27
+ .option('--force', 'Overwrite existing configuration files')
28
+ .option('--typescript', 'Configure for TypeScript project')
29
+ .option('--verbose', 'Show detailed error messages')
30
+ .action(initCommand);
31
+
22
32
  // Test command - Run Jest with lineage tracking
23
33
  program
24
34
  .command('test [jest-args...]')