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

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
@@ -1,3 +1,172 @@
1
1
  # Pre-commit Tool
2
2
 
3
- This Pre commit tool to identify rule violation (impact based) in development cycle
3
+ This Pre commit tool to identify rule violation (impact based) in development cycle
4
+
5
+ ---
6
+
7
+ ## Mutation Testing
8
+
9
+ The mutation module uses [Stryker Mutator](https://stryker-mutator.io/) to run mutation testing on files that changed relative to a release branch. It automatically:
10
+
11
+ 1. Detects changed source & test files via `git diff`
12
+ 2. Resolves source ↔ test file pairs (co-located, `__tests__/`, or mirrored directories)
13
+ 3. Runs Stryker on matched files
14
+ 4. Generates a **mutation summary report** (JSON) and a **SonarQube-compatible external issues report**
15
+
16
+ ### Dependencies
17
+
18
+ The following packages are **required** (already listed in `package.json`):
19
+
20
+ | Package | Version | Purpose |
21
+ |---|---|---|
22
+ | `@stryker-mutator/core` | `5.0.0` | Stryker mutation testing engine |
23
+ | `@stryker-mutator/jest-runner` | `5.0.0` | Runs Jest tests for each mutant |
24
+ | `jest` | `29.7.0` | Test runner (must already be present) |
25
+ | `glob` | `^8.1.0` | File pattern matching for test resolution |
26
+
27
+ Install all dependencies:
28
+
29
+ ```bash
30
+ npm install
31
+ ```
32
+
33
+ Or install mutation-specific packages manually:
34
+
35
+ ```bash
36
+ npm install @stryker-mutator/core@5 @stryker-mutator/jest-runner@5 glob@8
37
+ ```
38
+
39
+ ### How to Run
40
+
41
+ #### Via npx (recommended)
42
+
43
+ ```bash
44
+ # Local / pre-commit mode — uses staged files + diff vs release branch
45
+ npx ZDLintFramework mutate --mode=local --release=<branch>
46
+
47
+ # CI mode — uses diff vs release branch only
48
+ npx ZDLintFramework mutate --mode=ci --release=<branch>
49
+ ```
50
+
51
+ #### Via npm scripts
52
+
53
+ ```bash
54
+ # Local mode
55
+ npm run mutate:local -- --release=release
56
+
57
+ # CI mode
58
+ npm run mutate:ci -- --release=release
59
+ ```
60
+
61
+ #### Directly via node
62
+
63
+ ```bash
64
+ node bin/cliCI.js mutate --mode=local --release=release
65
+ node bin/cliCI.js mutate --mode=ci --release=release
66
+ ```
67
+
68
+ ### CLI Flags
69
+
70
+ | Flag | Required | Default | Description |
71
+ |---|---|---|---|
72
+ | `--mode=local\|ci` | Yes | — | `local` = staged + branch diff; `ci` = branch diff only |
73
+ | `--release=<branch>` | Yes | — | Release/target branch to diff against (e.g. `release`, `main`) |
74
+ | `--outputDir=<dir>` | No | `reports/mutation` | Directory for output reports |
75
+ | `--outputFileName=<name>` | No | `mutation-report.json` | Name of the mutation summary file |
76
+ | `--logLevel=<level>` | No | `info` | Stryker log level (`off`, `fatal`, `error`, `warn`, `info`, `debug`, `trace`) |
77
+
78
+ ### Output
79
+
80
+ Two report files are generated in the output directory (default `reports/mutation/`):
81
+
82
+ 1. **`mutation-report.json`** — Full mutation summary including mutation score, per-file breakdown, and mutant details.
83
+ 2. **`sonar-mutation-report.json`** — SonarQube generic issue import format. Survived and no-coverage mutants appear as issues.
84
+
85
+ #### Example summary output
86
+
87
+ ```json
88
+ {
89
+ "summary": {
90
+ "totalMutants": 42,
91
+ "killed": 35,
92
+ "survived": 5,
93
+ "timeout": 2,
94
+ "noCoverage": 0,
95
+ "ignored": 0,
96
+ "runtimeErrors": 0,
97
+ "compileErrors": 0,
98
+ "mutationScore": 88.10
99
+ }
100
+ }
101
+ ```
102
+
103
+ ### How It Works
104
+
105
+ | Mode | Step 1: File Collection | Step 2 | Step 3 | Step 4 |
106
+ |---|---|---|---|---|
107
+ | **local** | `git diff --staged` + `git diff <release>` | Resolve source↔test pairs | Run Stryker on matched files | Write JSON reports |
108
+ | **ci** | `git diff <release>` | Resolve source↔test pairs | Run Stryker on matched files | Write JSON reports |
109
+
110
+ ### Programmatic API
111
+
112
+ ```js
113
+ const { MutationRunner, MutationCli, StrykerWrapper } = require('./src/mutation');
114
+
115
+ // Option 1: Use MutationCli (parses CLI args)
116
+ const cli = new MutationCli();
117
+ cli.execute(['mutate', '--mode=local', '--release=release']).then(result => {
118
+ console.log(result);
119
+ });
120
+
121
+ // Option 2: Use MutationRunner directly
122
+ const runner = new MutationRunner({
123
+ outputDir: 'reports/mutation',
124
+ logLevel: 'info'
125
+ });
126
+ runner.runLocal('release').then(result => {
127
+ console.log('Score:', result.report.summary.mutationScore);
128
+ });
129
+
130
+ // Option 3: Use StrykerWrapper for full control
131
+ const stryker = new StrykerWrapper({ concurrency: 4 });
132
+ stryker.run(['src/utils/hash.js'], {
133
+ testFiles: ['src/utils/__tests__/hash.test.js']
134
+ }).then(result => {
135
+ console.log(result.summary);
136
+ });
137
+ ```
138
+
139
+ ### Default Mutate Pattern
140
+
141
+ When no specific source files are provided, Stryker uses the default pattern from `mutatePattern.json`:
142
+
143
+ ```
144
+ src/**/*.js
145
+ ```
146
+
147
+ ### File Resolution Strategies
148
+
149
+ The `FileResolver` automatically finds test files for source files using these strategies (in order):
150
+
151
+ 1. **Co-located**: `src/foo.js` → `src/foo.test.js`
152
+ 2. **`__tests__` subdir**: `src/foo.js` → `src/__tests__/foo.test.js`
153
+ 3. **Mirror structure**: `src/x/foo.js` → `test/x/foo.test.js`
154
+
155
+ Supported test suffixes: `.test.js`, `.test.ts`, `.test.jsx`, `.test.tsx`
156
+
157
+ ### SonarQube Integration
158
+
159
+ Add the sonar report path to your `sonar-project.properties`:
160
+
161
+ ```properties
162
+ sonar.externalIssuesReportPaths=reports/mutation/sonar-mutation-report.json
163
+ ```
164
+
165
+ ### Troubleshooting
166
+
167
+ | Issue | Fix |
168
+ |---|---|
169
+ | `Failed to load @stryker-mutator/core` | Run `npm install @stryker-mutator/core@5 @stryker-mutator/jest-runner@5` |
170
+ | `Branch 'X' not found` | Run `git fetch origin <branch>` first |
171
+ | No files to mutate | Ensure changed files have matching test files |
172
+ | Low mutation score | Add tests that assert specific behavior, not just "no error" |
package/bin/cliCI.js CHANGED
@@ -3,9 +3,29 @@
3
3
  /**
4
4
  * @author rajasekar 17710
5
5
  * @fileoverview This script is a Node.js executable that imports and runs the module `runner` from the `../build/lib/` directory.
6
+ * Also supports mutation testing via: npx ZDLintFramework mutate --mode=local|ci --release=<branch>
6
7
  */
7
8
 
8
9
  (async function () {
10
+ // var args = process.argv.slice(2);
11
+ // if (args.indexOf('mutate') !== -1) {
12
+ // var MutationCli = require('../build/mutation/mutationCli');
13
+ // var cli = new MutationCli();
14
+ // cli.execute(args).then(function (result) {
15
+ // if (!result.success) {
16
+ // console.error('Mutation testing failed:', result.error);
17
+ // process.exitCode = 1;
18
+ // } else {
19
+ // if (result.filePath) console.log('Mutation report written to:', result.filePath);
20
+ // if (result.message) console.log(result.message);
21
+ // }
22
+ // }).catch(function (err) {
23
+ // console.error('Mutation testing error:', err.message || err);
24
+ // process.exitCode = 1;
25
+ // });
26
+ // return;
27
+ // }
28
+
9
29
  const { initConfig, getConfigPathExecute, postInstallExecution } = require('../build/utils/General/Config');
10
30
  await initConfig(getConfigPathExecute());
11
31
  await postInstallExecution()
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * zdcodequality — mutation testing CLI.
5
+ *
6
+ * Commands:
7
+ * mutate --local [--branch=<branch>] Pre-commit: staged + branch diff (default branch: release)
8
+ * mutate --ci [--branch=<branch>] CI: branch diff only (default branch: release)
9
+ *
10
+ * Examples:
11
+ * npx zdcodequality mutate --local
12
+ * npx zdcodequality mutate --local --branch=main
13
+ * npx zdcodequality mutate --ci --branch=release
14
+ */
15
+
16
+ var args = process.argv.slice(2);
17
+
18
+ initConfig(getConfigPathExecute());
19
+
20
+ if (args.indexOf('mutate') === -1) {
21
+ console.error('Usage: npx zdcodequality mutate --local [--branch=<branch>]');
22
+ console.error(' npx zdcodequality mutate --ci [--branch=<branch>]');
23
+ console.error('Default branch: release');
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+
28
+ var MutationCli = require('../build/mutation/mutationCli');
29
+ const { initConfig } = require('../build/utils/General/Config');
30
+ var cli = new MutationCli({
31
+ token: process.env.ZGIT_TOKEN,
32
+ gitEndPoint: process.env.GIT_END_POINT,
33
+ branchDiffPath: process.env.BRANCH_DIFF_PATH,
34
+ compareBranch: process.env.COMPARE_BRANCH,
35
+ projectId: process.env.PROJECT_ID
36
+ });
37
+ console.log('cli:', cli);
38
+ cli.execute(args).then(function (result) {
39
+ if (!result.success) {
40
+ console.error('Mutation testing failed:', result.error);
41
+ process.exitCode = 1;
42
+ } else {
43
+ if (result.filePath) console.log('Mutation report written to:', result.filePath);
44
+ if (result.message) console.log(result.message);
45
+ }
46
+ }).catch(function (err) {
47
+ console.error('Mutation testing error:', err.message || err);
48
+ process.exitCode = 1;
49
+ });
@@ -0,0 +1,55 @@
1
+ // {
2
+ // "mutate": [
3
+ // "/Users/raja-17710/deskApp/desk_client_app/jsapps/supportapp/src/components/commonlist/subtab/NestedConversation/hooks/useContainerResize.js",
4
+ // "/Users/raja-17710/deskApp/desk_client_app/jsapps/supportapp/src/components/commonlist/subtab/NestedConversation/hooks/useNestedConversationActions.js",
5
+ // "/Users/raja-17710/deskApp/desk_client_app/jsapps/supportapp/src/components/commonlist/subtab/NestedConversation/hooks/useNestedConversationEditors.js",
6
+ // "/Users/raja-17710/deskApp/desk_client_app/jsapps/supportapp/src/components/commonlist/subtab/NestedConversation/hooks/useNestedConversationFetch.js",
7
+ // "/Users/raja-17710/deskApp/desk_client_app/jsapps/supportapp/src/modules/_containers/CriteriaV1/Criteria/utills/dangerAlert.js",
8
+ // "!src/**/__tests__/**",
9
+ // "!src/**/__test__/**",
10
+ // "!src/**/*.test.js",
11
+ // "!src/**/*.spec.js"
12
+ // ],
13
+ // "testRunner": "command",
14
+ // "commandRunner": {
15
+ // "command": "npm test -- --testPathPattern=\"useContainerResize|useNestedConversationActions|useNestedConversationEditors|useNestedConversationFetch|dangerAlert\""
16
+ // },
17
+ // "reporters": [
18
+ // "json",
19
+ // "clear-text"
20
+ // ],
21
+ // "coverageAnalysis": "off",
22
+ // "timeoutMS": 120000,
23
+ // "jest": {
24
+ // "projectType": "custom",
25
+ // "enableFindRelatedTests": true
26
+ // }
27
+ // }
28
+
29
+ // {
30
+ // "mutate": [
31
+ // "src/components/commonlist/subtab/NestedConversation/hooks/useNestedConversationActions.js",
32
+ // "src/components/commonlist/subtab/NestedConversation/hooks/utils/actionUtils.js",
33
+ // "!src/**/__tests__/**",
34
+ // "!src/**/__test__/**",
35
+ // "!src/**/*.test.js",
36
+ // "!src/**/*.spec.js"
37
+ // ],
38
+ // "testRunner": "command",
39
+ // "commandRunner": {
40
+ // "command": "npm test -- --testPathPattern='useNestedConversationActions|actionUtils'"
41
+ // },
42
+ // "reporters": [
43
+ // "json",
44
+ // "clear-text",
45
+ // "progress"
46
+ // ],
47
+ // "jsonReporter": {
48
+ // "fileName": "/Users/raja-17710/deskApp/desk_client_app/jsapps/supportapp/reports/mutation/mutation-report.json"
49
+ // },
50
+ // "coverageAnalysis": "off",
51
+ // "timeoutMS": 120000,
52
+ // "timeoutFactor": 1.5,
53
+ // "logLevel": "info",
54
+ // "concurrency": 2
55
+ // }