@zohodesk/codestandard-validator 1.2.4-exp-5 → 1.2.4-exp-7

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.
@@ -1,91 +1,147 @@
1
1
  "use strict";
2
2
 
3
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
4
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
3
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
5
4
  var path = require('path');
6
5
  var patternConfig = require('./mutatePattern.json');
6
+ var StrykerConfigBuilder = require('./strykerConfigBuilder');
7
7
  var DEFAULT_MUTATE_PATTERN = patternConfig.defaultPattern;
8
+
9
+ /**
10
+ * StrykerWrapper — thin wrapper around @stryker-mutator/core v5.
11
+ *
12
+ * Accepts a StrykerConfigBuilder (or a raw options hash for backwards
13
+ * compatibility) to produce the Stryker config, runs mutation testing,
14
+ * and normalizes results.
15
+ *
16
+ * Compatible with Node 16+.
17
+ */
8
18
  function StrykerWrapper(options) {
9
19
  options = options || {};
10
20
  this._strykerModule = null;
11
- this._defaultOptions = {
12
- testRunner: 'jest',
13
- coverageAnalysis: 'perTest',
14
- reporters: ['json', 'clear-text'],
15
- jsonReporter: {
16
- fileName: options.reportPath || 'reports/mutation/mutation.json'
17
- },
18
- cleanTempDir: true,
19
- concurrency: options.concurrency || Math.max(1, require('os').cpus().length - 1),
20
- timeoutMS: options.timeoutMS || 60000,
21
- timeoutFactor: options.timeoutFactor || 1.5,
22
- logLevel: options.logLevel || 'info',
23
- allowEmpty: true
24
- };
21
+ if (options instanceof StrykerConfigBuilder) {
22
+ this._configBuilder = options;
23
+ } else if (options.strykerConfigpath) {
24
+ this._configBuilder = new StrykerConfigBuilder().fromConfigFile(options.strykerConfigpath);
25
+ } else {
26
+ this._configBuilder = new StrykerConfigBuilder().setTestRunner('jest').setCoverageAnalysis('perTest').setAllowEmpty(true).setReporters(['html', 'json']).setCleanTempDir(true);
27
+ if (options.reportPath) {
28
+ this._configBuilder.setHtmlReporter({
29
+ fileName: options.reportPath
30
+ }).setJsonReporter({
31
+ fileName: options.reportPath
32
+ });
33
+ }
34
+ if (options.concurrency != null) {
35
+ this._configBuilder.setConcurrency(options.concurrency);
36
+ }
37
+ if (options.timeoutMS != null) {
38
+ this._configBuilder.setTimeoutMS(options.timeoutMS);
39
+ }
40
+ if (options.timeoutFactor != null) {
41
+ this._configBuilder.setTimeoutFactor(options.timeoutFactor);
42
+ }
43
+ if (options.logLevel) {
44
+ this._configBuilder.setLogLevel(options.logLevel);
45
+ }
46
+ }
25
47
  }
48
+
49
+ /* ------------------------------------------------------------------ */
50
+ /* Stryker loader */
51
+ /* ------------------------------------------------------------------ */
52
+
26
53
  StrykerWrapper.prototype._loadStryker = async function () {
27
- if (!this._strykerModule) {
28
- try {
29
- this._strykerModule = await Promise.resolve().then(() => _interopRequireWildcard(require('@stryker-mutator/core')));
30
- } catch (err) {
31
- throw new Error('Failed to load @stryker-mutator/core. Install it: ' + 'npm i --save-dev @stryker-mutator/core @stryker-mutator/jest-runner\n' + err.message);
32
- }
54
+ var self = this;
55
+ if (self._strykerModule) {
56
+ return Promise.resolve(self._strykerModule);
57
+ }
58
+ try {
59
+ self._strykerModule = await Promise.resolve().then(() => _interopRequireWildcard(require('@stryker-mutator/core')));
60
+ return Promise.resolve(self._strykerModule);
61
+ } catch (err) {
62
+ return Promise.reject(new Error('Failed to load @stryker-mutator/core. Install it:\n' + ' npm i --save-dev @stryker-mutator/core@5 @stryker-mutator/jest-runner@5\n' + err.message));
33
63
  }
34
- return this._strykerModule;
35
64
  };
36
- StrykerWrapper.prototype._buildMutatePatterns = function (sourceFiles) {
65
+ StrykerWrapper.prototype._buildMutatePatterns = function (sourceFiles, options) {
37
66
  if (!sourceFiles || sourceFiles.length === 0) {
38
67
  return [DEFAULT_MUTATE_PATTERN];
39
68
  }
40
- return sourceFiles.map(function (f) {
41
- return f.replace(/\\/g, '/');
69
+ options = options || {};
70
+ var rootDir = options.rootDirectory || process.cwd();
71
+ return sourceFiles.map(function (_path) {
72
+ var normalizedPath = _path && typeof _path === 'string' ? _path.replace(/\\/g, '/') : _path;
73
+ return path.resolve(rootDir, normalizedPath);
42
74
  });
43
75
  };
76
+
77
+ /**
78
+ * Build the final Stryker config by cloning the base builder and
79
+ * layering per-run overrides (mutate patterns, test files, jest, etc.).
80
+ */
44
81
  StrykerWrapper.prototype._buildStrykerConfig = function (sourceFiles, options) {
45
82
  options = options || {};
46
- var mutatePatterns = this._buildMutatePatterns(sourceFiles);
47
- var config = Object.assign({}, this._defaultOptions, {
48
- mutate: mutatePatterns
49
- });
50
- if (options.testFiles && options.testFiles.length > 0) {
51
- config.testFiles = options.testFiles.map(function (f) {
52
- return f.replace(/\\/g, '/');
83
+ var mutatePatterns = this._buildMutatePatterns(sourceFiles, options);
84
+ var builder = this._configBuilder.clone().setMutate(mutatePatterns);
85
+ if (options.testFiles) {
86
+ builder.setTestRunner('command');
87
+ var testPattern = options.testFiles.map(function (f) {
88
+ var base = path.basename(f);
89
+ return base.replace(/\.(test|spec)\.(js|ts|jsx|tsx|mjs|cjs)$/, '');
90
+ }).join('|');
91
+ var cdCmd = options.rootDirectory ? 'cd ' + options.rootDirectory + ' && ' : '';
92
+ builder.setCommandRunner({
93
+ command: 'npx ZDTestingFramework unit-test'
53
94
  });
54
95
  }
55
96
  if (options.jest) {
56
- config.jest = Object.assign({
97
+ builder.setJest(Object.assign({
57
98
  projectType: 'custom',
58
99
  enableFindRelatedTests: true
59
- }, options.jest);
100
+ }, options.jest));
60
101
  }
61
102
  if (options.configFile) {
62
- config.configFile = options.configFile;
103
+ builder.setConfigFile(options.configFile);
63
104
  }
64
105
  if (options.reportPath) {
65
- config.jsonReporter = {
106
+ builder.setJsonReporter({
66
107
  fileName: options.reportPath
67
- };
108
+ });
68
109
  }
69
110
  if (options.tempDirName) {
70
- config.tempDirName = options.tempDirName;
111
+ builder.setTempDirName(options.tempDirName);
71
112
  }
72
113
  if (options.thresholds) {
73
- config.thresholds = options.thresholds;
114
+ builder.setThresholds(options.thresholds);
74
115
  }
75
- return config;
116
+ return builder.build();
76
117
  };
77
- StrykerWrapper.prototype.run = async function (sourceFiles, options) {
118
+
119
+ /* ------------------------------------------------------------------ */
120
+ /* Runner */
121
+ /* ------------------------------------------------------------------ */
122
+
123
+ /**
124
+ * Run Stryker mutation testing on the given source files.
125
+ *
126
+ * @param {string[]} sourceFiles - files to mutate
127
+ * @param {object} [options] - testFiles, jest config, thresholds, etc.
128
+ * @returns {Promise<object>} - normalized mutation result
129
+ */
130
+ StrykerWrapper.prototype.run = function (sourceFiles, options) {
131
+ var self = this;
78
132
  options = options || {};
79
- var strykerModule = await this._loadStryker();
80
- var Stryker = strykerModule.Stryker || strykerModule.default || strykerModule;
81
- var config = this._buildStrykerConfig(sourceFiles, options);
82
- try {
133
+ return self._loadStryker().then(function (strykerModule) {
134
+ var Stryker = strykerModule.Stryker || strykerModule.default || strykerModule;
135
+ var config = self._buildStrykerConfig(sourceFiles, options);
136
+ console.log('Running Stryker with config:', JSON.stringify(config, null, 2));
83
137
  var instance = new Stryker(config);
84
- var result = await instance.runMutationTest();
85
- return this._normalizeResult(result);
86
- } catch (err) {
138
+ return instance.runMutationTest();
139
+ }).then(function (result) {
140
+ return self._normalizeResult(result);
141
+ }).catch(function (err) {
142
+ console.log(err);
87
143
  throw new Error('Stryker mutation test failed: ' + err.message);
88
- }
144
+ });
89
145
  };
90
146
  StrykerWrapper.prototype._normalizeResult = function (rawResult) {
91
147
  if (!rawResult) {
@@ -174,7 +230,7 @@ StrykerWrapper.prototype._emptyNormalizedResult = function () {
174
230
  };
175
231
  };
176
232
  StrykerWrapper.prototype.getDefaultConfig = function () {
177
- return Object.assign({}, this._defaultOptions);
233
+ return this._configBuilder.build();
178
234
  };
179
235
  module.exports = StrykerWrapper;
180
236
  module.exports.DEFAULT_MUTATE_PATTERN = DEFAULT_MUTATE_PATTERN;
@@ -10,6 +10,10 @@ function initConfig(actualConfigPath) {
10
10
  process.env.SONARQUBE = config.meticHandler_api_token;
11
11
  process.env.ZGIT_TOKEN = config.token;
12
12
  process.env.TOOL_TOKEN = config.toolToken;
13
+ process.env.PROJECT_ID = config.projectId;
14
+ process.env.GIT_END_POINT = config.gitEndPoint;
15
+ process.env.BRANCH_DIFF_PATH = config.branchDiffPath;
16
+ process.env.COMPARE_BRANCH = config.compareBranch;
13
17
  }
14
18
  function postInstallExecution() {
15
19
  const {
@@ -34,6 +34,7 @@ function getAllPlugins() {
34
34
  }
35
35
  if (!Array.isArray(commonPlugins) || !Array.isArray(serviceSpecificPlugins)) {
36
36
  Logger.log(Logger.FAILURE_TYPE, 'Plugin details should be in an array format in pluginVersion.js file');
37
+ return Object.assign([], commonPlugins.getEntries(), serviceSpecificPlugins.getEntries());
37
38
  }
38
39
  return Object.assign([], commonPlugins, serviceSpecificPlugins);
39
40
  }
package/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  const { getLintConfigurationUtil } = require("./build/utils/ConfigFileUtils/getLintConfiguration");
2
2
  const { rulesConfig, plugins, extendPlugins } = getLintConfigurationUtil();
3
+ // const Mutant = require("./build/mutation/index");
3
4
 
4
5
  module.exports = {
5
6
  rulesConfig,
6
7
  plugins,
7
- extendPlugins
8
+ extendPlugins,
8
9
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zohodesk/codestandard-validator",
3
- "version": "1.2.4-exp-5",
3
+ "version": "1.2.4-exp-7",
4
4
  "description": "library to enforce code standard using eslint",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -12,23 +12,29 @@
12
12
  "license": "ISC",
13
13
  "bin": {
14
14
  "ZDPrecommit": "./bin/cli.js",
15
- "ZDLintFramework": "./bin/cliCI.js"
15
+ "ZDLintFramework": "./bin/cliCI.js",
16
+ "zdcodequality": "./bin/zdcodequality.js"
16
17
  },
17
18
  "type": "commonjs",
18
19
  "dependencies": {
20
+ "@stryker-mutator/core": "8.7.1",
21
+ "@stryker-mutator/jest-runner": "8.7.1",
22
+ "@stryker-mutator/typescript-checker": "8.7.1",
19
23
  "@zohodesk-private/client_deployment_tool": "0.0.5",
20
24
  "@zohodesk/codestandard-analytics": "1.1.5",
21
- "@stryker-mutator/core": "5.0.0",
22
25
  "eslint": "8.26.0",
26
+ "glob": "8.1.0",
27
+ "jest": "29.7.0",
23
28
  "marked": "9.1.6",
24
29
  "marked-terminal": "6.2.0",
25
- "stylelint": "16.23.0"
30
+ "stylelint": "16.23.0",
31
+ "typescript": "5.9.3"
26
32
  },
27
33
  "devDependencies": {
34
+ "@babel/cli": "7.24.7",
28
35
  "@babel/core": "7.24.7",
29
36
  "@babel/plugin-transform-runtime": "7.24.7",
30
37
  "@babel/preset-env": "7.24.7",
31
- "husky": "7.0.4",
32
- "jest": "29.7.0"
38
+ "husky": "7.0.4"
33
39
  }
34
40
  }
@@ -1,34 +0,0 @@
1
- // Usage: node samples/sample-branch-mode.js
2
-
3
- var MutationCli = require('../src/mutation').MutationCli;
4
-
5
- var cli = new MutationCli({ cwd: process.cwd() });
6
-
7
- console.log('Running mutation testing in branch diff mode...');
8
- console.log('Diffing current branch against: main');
9
- console.log('');
10
-
11
- cli.execute(['mutate', '--branch=main']).then(function (result) {
12
- if (result.success) {
13
- console.log('=== SUCCESS ===');
14
- console.log('Report file: ', result.filePath);
15
- console.log('Score: ', result.report.summary.mutationScore + '%');
16
- console.log('Total: ', result.report.summary.totalMutants);
17
- console.log('Killed: ', result.report.summary.killed);
18
- console.log('Survived: ', result.report.summary.survived);
19
- console.log('No Coverage: ', result.report.summary.noCoverage);
20
- if (result.message) {
21
- console.log('Note: ', result.message);
22
- }
23
- console.log('');
24
- console.log('File pairs tested:');
25
- result.report.filePairs.forEach(function (pair) {
26
- console.log(' Source: ' + pair.source + ' -> Test: ' + (pair.test || 'NONE'));
27
- });
28
- } else {
29
- console.error('=== FAILED ===');
30
- console.error('Error:', result.error);
31
- }
32
- }).catch(function (err) {
33
- console.error('Unexpected error:', err);
34
- });
@@ -1,34 +0,0 @@
1
- // Usage: node samples/sample-cli-entry.js
2
- // Tests CLI argument parsing and validation only (no Stryker run)
3
-
4
- var MutationCli = require('../src/mutation').MutationCli;
5
-
6
- var testCases = [
7
- { name: 'Directory mode', args: ['mutate', '--src=src', '--test=test'] },
8
- { name: 'Branch mode', args: ['mutate', '--branch=main'] },
9
- { name: 'Missing args (should fail)', args: ['mutate'] },
10
- { name: 'Both modes (should fail)', args: ['mutate', '--branch=main', '--src=src', '--test=test'] },
11
- { name: 'Unknown command (should fail)', args: ['lint'] },
12
- { name: 'With optional flags', args: ['mutate', '--src=src', '--test=test', '--outputDir=custom-reports', '--logLevel=debug'] },
13
- { name: 'Branch with useApi', args: ['mutate', '--branch=develop', '--useApi'] },
14
- ];
15
-
16
- var cli = new MutationCli({ cwd: process.cwd() });
17
-
18
- console.log('=== CLI Argument Parsing Tests ===');
19
- console.log('');
20
-
21
- testCases.forEach(function (tc) {
22
- console.log('Test: ' + tc.name);
23
- console.log(' Args: ' + tc.args.join(' '));
24
-
25
- var parsed = cli.parseArgs(tc.args);
26
- console.log(' Parsed:', JSON.stringify(parsed));
27
-
28
- var validation = cli.validate(parsed);
29
- console.log(' Valid:', validation.valid);
30
- if (!validation.valid) {
31
- console.log(' Error:', validation.error.split('\n')[0]);
32
- }
33
- console.log('');
34
- });
@@ -1,63 +0,0 @@
1
- // Usage: node samples/sample-components.js
2
-
3
- var mutation = require('../src/mutation');
4
-
5
- console.log('=== 1. Testing BranchDiff ===');
6
- var branchDiff = new mutation.BranchDiff({ cwd: process.cwd() });
7
-
8
- branchDiff.getChangedFiles('main').then(function (changed) {
9
- console.log('Source files changed:', changed.sourceFiles);
10
- console.log('Test files changed:', changed.testFiles);
11
- console.log('');
12
-
13
- console.log('=== 2. Testing FileResolver ===');
14
- var resolver = new mutation.FileResolver({ cwd: process.cwd() });
15
- var pairs = resolver.resolveSourceTestPairs(changed.sourceFiles, changed.testFiles);
16
- console.log('Resolved pairs:');
17
- pairs.forEach(function (pair) {
18
- console.log(' ' + pair.source + ' -> ' + (pair.test || 'NO TEST'));
19
- });
20
- console.log('');
21
-
22
- console.log('=== 3. Testing StrykerWrapper config ===');
23
- var stryker = new mutation.StrykerWrapper({
24
- reportPath: 'reports/mutation/sample-report.json',
25
- });
26
- var config = stryker.getDefaultConfig();
27
- console.log('Default config:');
28
- console.log(' testRunner:', config.testRunner);
29
- console.log(' coverageAnalysis:', config.coverageAnalysis);
30
- console.log('');
31
-
32
- console.log('=== 4. Testing ReportGenerator ===');
33
- var reporter = new mutation.ReportGenerator({
34
- cwd: process.cwd(),
35
- outputDir: 'reports/mutation',
36
- outputFileName: 'sample-component-report.json',
37
- });
38
-
39
- var fakeResult = {
40
- summary: {
41
- totalMutants: 5, killed: 3, survived: 1, timeout: 0,
42
- noCoverage: 1, ignored: 0, runtimeErrors: 0, compileErrors: 0,
43
- mutationScore: 60,
44
- },
45
- files: {},
46
- mutants: [
47
- { id: '1', status: 'Killed', fileName: 'src/app.js', mutatorName: 'StringLiteral' },
48
- { id: '2', status: 'Survived', fileName: 'src/app.js', mutatorName: 'BooleanLiteral' },
49
- ],
50
- };
51
-
52
- var output = reporter.generateAndWrite(fakeResult, {
53
- command: 'sample-components test',
54
- branch: 'main',
55
- filePairs: pairs,
56
- });
57
- console.log('Report written to:', output.filePath);
58
- console.log('Report summary:', output.report.summary);
59
- console.log('');
60
- console.log('=== All component tests complete ===');
61
- }).catch(function (err) {
62
- console.error('Error:', err.message);
63
- });
@@ -1,30 +0,0 @@
1
- // Usage: node samples/sample-directory-mode.js
2
-
3
- var MutationCli = require('../src/mutation').MutationCli;
4
-
5
- var cli = new MutationCli({ cwd: process.cwd() });
6
-
7
- console.log('Running mutation testing in directory mode...');
8
- console.log('Source dir: src');
9
- console.log('Test dir: test');
10
- console.log('');
11
-
12
- cli.execute(['mutate', '--src=src', '--test=test']).then(function (result) {
13
- if (result.success) {
14
- console.log('=== SUCCESS ===');
15
- console.log('Report file: ', result.filePath);
16
- console.log('Score: ', result.report.summary.mutationScore + '%');
17
- console.log('Total: ', result.report.summary.totalMutants);
18
- console.log('Killed: ', result.report.summary.killed);
19
- console.log('Survived: ', result.report.summary.survived);
20
- console.log('No Coverage: ', result.report.summary.noCoverage);
21
- if (result.message) {
22
- console.log('Note: ', result.message);
23
- }
24
- } else {
25
- console.error('=== FAILED ===');
26
- console.error('Error:', result.error);
27
- }
28
- }).catch(function (err) {
29
- console.error('Unexpected error:', err);
30
- });
@@ -1,32 +0,0 @@
1
- // Usage: node samples/sample-runner-direct.js
2
-
3
- var MutationRunner = require('../src/mutation').MutationRunner;
4
-
5
- var runner = new MutationRunner({
6
- cwd: process.cwd(),
7
- outputDir: 'reports/mutation',
8
- outputFileName: 'direct-runner-report.json',
9
- });
10
-
11
- console.log('=== Testing runByBranch ===');
12
- runner.runByBranch('main').then(function (result) {
13
- console.log('Branch mode result:');
14
- console.log(' Report:', result.filePath);
15
- console.log(' Score:', result.report.summary.mutationScore + '%');
16
- if (result.message) {
17
- console.log(' Note:', result.message);
18
- }
19
-
20
- console.log('');
21
- console.log('=== Testing runByDirectory ===');
22
- return runner.runByDirectory('src', 'test');
23
- }).then(function (result) {
24
- console.log('Directory mode result:');
25
- console.log(' Report:', result.filePath);
26
- console.log(' Score:', result.report.summary.mutationScore + '%');
27
- if (result.message) {
28
- console.log(' Note:', result.message);
29
- }
30
- }).catch(function (err) {
31
- console.error('Error:', err.message);
32
- });
@@ -1,44 +0,0 @@
1
- // Usage: PAT_TOKEN=your_token node samples/sample-with-api.js
2
-
3
- var MutationCli = require('../src/mutation').MutationCli;
4
-
5
- var myApi = {
6
- getChangedFiles: function (targetBranch, patToken) {
7
- console.log('API called with branch:', targetBranch);
8
- console.log('PAT token provided:', patToken ? 'yes' : 'no');
9
- return Promise.resolve([
10
- 'src/services/auth.js',
11
- 'src/services/auth.test.js',
12
- 'src/utils/format.js',
13
- 'src/utils/format.test.js',
14
- 'src/config.js',
15
- ]);
16
- },
17
- };
18
-
19
- var cli = new MutationCli({
20
- cwd: process.cwd(),
21
- api: myApi,
22
- patToken: process.env.PAT_TOKEN || 'mock-token',
23
- });
24
-
25
- console.log('Running mutation testing with API-based branch diff...');
26
- console.log('');
27
-
28
- cli.execute(['mutate', '--branch=main', '--useApi']).then(function (result) {
29
- if (result.success) {
30
- console.log('=== SUCCESS ===');
31
- console.log('Report:', result.filePath);
32
- console.log('Score:', result.report.summary.mutationScore + '%');
33
- console.log('');
34
- console.log('File pairs:');
35
- result.report.filePairs.forEach(function (pair) {
36
- console.log(' ' + pair.source + ' -> ' + (pair.test || 'NO TEST'));
37
- });
38
- } else {
39
- console.error('=== FAILED ===');
40
- console.error('Error:', result.error);
41
- }
42
- }).catch(function (err) {
43
- console.error('Unexpected error:', err);
44
- });