@aiready/pattern-detect 0.16.22 → 0.17.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-entry/index.mjs +3 -3
- package/dist/chunk-J2G742QF.mjs +162 -0
- package/dist/chunk-J5CW6NYY.mjs +64 -0
- package/dist/chunk-NQBYYWHJ.mjs +143 -0
- package/dist/chunk-SUUZMLPS.mjs +391 -0
- package/dist/cli.js +336 -303
- package/dist/cli.mjs +347 -303
- package/dist/context-rules-entry/index.d.mts +2 -2
- package/dist/context-rules-entry/index.d.ts +2 -2
- package/dist/context-rules-entry/index.js +2 -25
- package/dist/context-rules-entry/index.mjs +1 -1
- package/dist/detector-entry/index.mjs +2 -2
- package/dist/index-szjQDBsm.d.mts +49 -0
- package/dist/index-szjQDBsm.d.ts +49 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -25
- package/dist/index.mjs +6 -4
- package/package.json +2 -2
- package/dist/__tests__/context-rules.test.d.ts +0 -2
- package/dist/__tests__/context-rules.test.d.ts.map +0 -1
- package/dist/__tests__/context-rules.test.js +0 -189
- package/dist/__tests__/context-rules.test.js.map +0 -1
- package/dist/__tests__/detector.test.d.ts +0 -2
- package/dist/__tests__/detector.test.d.ts.map +0 -1
- package/dist/__tests__/detector.test.js +0 -259
- package/dist/__tests__/detector.test.js.map +0 -1
- package/dist/__tests__/grouping.test.d.ts +0 -2
- package/dist/__tests__/grouping.test.d.ts.map +0 -1
- package/dist/__tests__/grouping.test.js +0 -443
- package/dist/__tests__/grouping.test.js.map +0 -1
- package/dist/__tests__/scoring.test.d.ts +0 -2
- package/dist/__tests__/scoring.test.d.ts.map +0 -1
- package/dist/__tests__/scoring.test.js +0 -102
- package/dist/__tests__/scoring.test.js.map +0 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { a as ContextRule, c as calculateSeverity,
|
|
2
|
-
|
|
1
|
+
export { a as ContextRule, c as calculateSeverity, g as getSeverityThreshold } from '../index-szjQDBsm.mjs';
|
|
2
|
+
export { filterBySeverity, getSeverityLabel } from '@aiready/core';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { a as ContextRule, c as calculateSeverity,
|
|
2
|
-
|
|
1
|
+
export { a as ContextRule, c as calculateSeverity, g as getSeverityThreshold } from '../index-szjQDBsm.js';
|
|
2
|
+
export { filterBySeverity, getSeverityLabel } from '@aiready/core';
|
|
@@ -21,8 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var context_rules_entry_exports = {};
|
|
22
22
|
__export(context_rules_entry_exports, {
|
|
23
23
|
calculateSeverity: () => calculateSeverity,
|
|
24
|
-
filterBySeverity: () => filterBySeverity,
|
|
25
|
-
getSeverityLabel: () => getSeverityLabel,
|
|
24
|
+
filterBySeverity: () => import_core.filterBySeverity,
|
|
25
|
+
getSeverityLabel: () => import_core.getSeverityLabel,
|
|
26
26
|
getSeverityThreshold: () => getSeverityThreshold
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(context_rules_entry_exports);
|
|
@@ -166,29 +166,6 @@ function calculateSeverity(file1, file2, code, similarity, linesOfCode) {
|
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
168
|
}
|
|
169
|
-
function getSeverityLabel(severity) {
|
|
170
|
-
const labels = {
|
|
171
|
-
[import_core.Severity.Critical]: "\u{1F534} CRITICAL",
|
|
172
|
-
[import_core.Severity.Major]: "\u{1F7E1} MAJOR",
|
|
173
|
-
[import_core.Severity.Minor]: "\u{1F535} MINOR",
|
|
174
|
-
[import_core.Severity.Info]: "\u2139\uFE0F INFO"
|
|
175
|
-
};
|
|
176
|
-
return labels[severity];
|
|
177
|
-
}
|
|
178
|
-
function filterBySeverity(duplicates, minSeverity) {
|
|
179
|
-
const severityOrder = [
|
|
180
|
-
import_core.Severity.Info,
|
|
181
|
-
import_core.Severity.Minor,
|
|
182
|
-
import_core.Severity.Major,
|
|
183
|
-
import_core.Severity.Critical
|
|
184
|
-
];
|
|
185
|
-
const minIndex = severityOrder.indexOf(minSeverity);
|
|
186
|
-
if (minIndex === -1) return duplicates;
|
|
187
|
-
return duplicates.filter((dup) => {
|
|
188
|
-
const dupIndex = severityOrder.indexOf(dup.severity);
|
|
189
|
-
return dupIndex >= minIndex;
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
169
|
function getSeverityThreshold(severity) {
|
|
193
170
|
const thresholds = {
|
|
194
171
|
[import_core.Severity.Critical]: 0.95,
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Severity } from '@aiready/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context-aware severity detection for duplicate patterns
|
|
5
|
+
* Identifies intentional duplication patterns and adjusts severity accordingly
|
|
6
|
+
*/
|
|
7
|
+
interface ContextRule {
|
|
8
|
+
name: string;
|
|
9
|
+
detect: (file: string, code: string) => boolean;
|
|
10
|
+
severity: Severity;
|
|
11
|
+
reason: string;
|
|
12
|
+
suggestion?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Context rules for detecting intentional or acceptable duplication patterns
|
|
16
|
+
* Rules are checked in order - first match wins
|
|
17
|
+
*/
|
|
18
|
+
declare const CONTEXT_RULES: ContextRule[];
|
|
19
|
+
/**
|
|
20
|
+
* Calculate severity based on context rules and code characteristics
|
|
21
|
+
*
|
|
22
|
+
* @param file1 - First file path in the duplicate pair.
|
|
23
|
+
* @param file2 - Second file path in the duplicate pair.
|
|
24
|
+
* @param code - Snippet of the duplicated code.
|
|
25
|
+
* @param similarity - The calculated similarity score (0-1).
|
|
26
|
+
* @param linesOfCode - Number of lines in the duplicated block.
|
|
27
|
+
* @returns An object containing the severity level and reasoning.
|
|
28
|
+
*/
|
|
29
|
+
declare function calculateSeverity(file1: string, file2: string, code: string, similarity: number, linesOfCode: number): {
|
|
30
|
+
severity: Severity;
|
|
31
|
+
reason?: string;
|
|
32
|
+
suggestion?: string;
|
|
33
|
+
matchedRule?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Get a human-readable severity label with emoji
|
|
37
|
+
*
|
|
38
|
+
* @param severity - The severity level to label.
|
|
39
|
+
* @returns Formatted label string for UI display.
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Get numerical similarity threshold associated with a severity level
|
|
43
|
+
*
|
|
44
|
+
* @param severity - The severity level to look up.
|
|
45
|
+
* @returns Minimum similarity value for this severity.
|
|
46
|
+
*/
|
|
47
|
+
declare function getSeverityThreshold(severity: Severity): number;
|
|
48
|
+
|
|
49
|
+
export { CONTEXT_RULES as C, type ContextRule as a, calculateSeverity as c, getSeverityThreshold as g };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { Severity } from '@aiready/core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Context-aware severity detection for duplicate patterns
|
|
5
|
+
* Identifies intentional duplication patterns and adjusts severity accordingly
|
|
6
|
+
*/
|
|
7
|
+
interface ContextRule {
|
|
8
|
+
name: string;
|
|
9
|
+
detect: (file: string, code: string) => boolean;
|
|
10
|
+
severity: Severity;
|
|
11
|
+
reason: string;
|
|
12
|
+
suggestion?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Context rules for detecting intentional or acceptable duplication patterns
|
|
16
|
+
* Rules are checked in order - first match wins
|
|
17
|
+
*/
|
|
18
|
+
declare const CONTEXT_RULES: ContextRule[];
|
|
19
|
+
/**
|
|
20
|
+
* Calculate severity based on context rules and code characteristics
|
|
21
|
+
*
|
|
22
|
+
* @param file1 - First file path in the duplicate pair.
|
|
23
|
+
* @param file2 - Second file path in the duplicate pair.
|
|
24
|
+
* @param code - Snippet of the duplicated code.
|
|
25
|
+
* @param similarity - The calculated similarity score (0-1).
|
|
26
|
+
* @param linesOfCode - Number of lines in the duplicated block.
|
|
27
|
+
* @returns An object containing the severity level and reasoning.
|
|
28
|
+
*/
|
|
29
|
+
declare function calculateSeverity(file1: string, file2: string, code: string, similarity: number, linesOfCode: number): {
|
|
30
|
+
severity: Severity;
|
|
31
|
+
reason?: string;
|
|
32
|
+
suggestion?: string;
|
|
33
|
+
matchedRule?: string;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Get a human-readable severity label with emoji
|
|
37
|
+
*
|
|
38
|
+
* @param severity - The severity level to label.
|
|
39
|
+
* @returns Formatted label string for UI display.
|
|
40
|
+
*/
|
|
41
|
+
/**
|
|
42
|
+
* Get numerical similarity threshold associated with a severity level
|
|
43
|
+
*
|
|
44
|
+
* @param severity - The severity level to look up.
|
|
45
|
+
* @returns Minimum similarity value for this severity.
|
|
46
|
+
*/
|
|
47
|
+
declare function getSeverityThreshold(severity: Severity): number;
|
|
48
|
+
|
|
49
|
+
export { CONTEXT_RULES as C, type ContextRule as a, calculateSeverity as c, getSeverityThreshold as g };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ToolProvider } from '@aiready/core';
|
|
2
|
-
export { Severity } from '@aiready/core';
|
|
2
|
+
export { IssueType, Severity, filterBySeverity, getSeverityLabel } from '@aiready/core';
|
|
3
3
|
export { D as DuplicateGroup, P as PatternDetectOptions, a as PatternSummary, R as RefactorCluster, b as analyzePatterns, c as createRefactorClusters, f as filterClustersByImpact, g as generateSummary, d as getSmartDefaults, e as groupDuplicatesByFilePair } from './index-BVz-HnZd.mjs';
|
|
4
4
|
export { detectDuplicatePatterns } from './detector-entry/index.mjs';
|
|
5
5
|
export { calculatePatternScore } from './scoring-entry/index.mjs';
|
|
6
|
-
export { C as CONTEXT_RULES, a as ContextRule, c as calculateSeverity,
|
|
6
|
+
export { C as CONTEXT_RULES, a as ContextRule, c as calculateSeverity, g as getSeverityThreshold } from './index-szjQDBsm.mjs';
|
|
7
7
|
export { D as DuplicatePattern, P as PatternType } from './types-DU2mmhwb.mjs';
|
|
8
8
|
|
|
9
9
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ToolProvider } from '@aiready/core';
|
|
2
|
-
export { Severity } from '@aiready/core';
|
|
2
|
+
export { IssueType, Severity, filterBySeverity, getSeverityLabel } from '@aiready/core';
|
|
3
3
|
export { D as DuplicateGroup, P as PatternDetectOptions, a as PatternSummary, R as RefactorCluster, b as analyzePatterns, c as createRefactorClusters, f as filterClustersByImpact, g as generateSummary, d as getSmartDefaults, e as groupDuplicatesByFilePair } from './index-BwuoiCNm.js';
|
|
4
4
|
export { detectDuplicatePatterns } from './detector-entry/index.js';
|
|
5
5
|
export { calculatePatternScore } from './scoring-entry/index.js';
|
|
6
|
-
export { C as CONTEXT_RULES, a as ContextRule, c as calculateSeverity,
|
|
6
|
+
export { C as CONTEXT_RULES, a as ContextRule, c as calculateSeverity, g as getSeverityThreshold } from './index-szjQDBsm.js';
|
|
7
7
|
export { D as DuplicatePattern, P as PatternType } from './types-DU2mmhwb.js';
|
|
8
8
|
|
|
9
9
|
/**
|
package/dist/index.js
CHANGED
|
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
CONTEXT_RULES: () => CONTEXT_RULES,
|
|
34
|
+
IssueType: () => import_core.IssueType,
|
|
34
35
|
PatternDetectProvider: () => PatternDetectProvider,
|
|
35
36
|
Severity: () => import_core7.Severity,
|
|
36
37
|
analyzePatterns: () => analyzePatterns,
|
|
@@ -38,10 +39,10 @@ __export(index_exports, {
|
|
|
38
39
|
calculateSeverity: () => calculateSeverity,
|
|
39
40
|
createRefactorClusters: () => createRefactorClusters,
|
|
40
41
|
detectDuplicatePatterns: () => detectDuplicatePatterns,
|
|
41
|
-
filterBySeverity: () => filterBySeverity,
|
|
42
|
+
filterBySeverity: () => import_core.filterBySeverity,
|
|
42
43
|
filterClustersByImpact: () => filterClustersByImpact,
|
|
43
44
|
generateSummary: () => generateSummary,
|
|
44
|
-
getSeverityLabel: () => getSeverityLabel,
|
|
45
|
+
getSeverityLabel: () => import_core.getSeverityLabel,
|
|
45
46
|
getSeverityThreshold: () => getSeverityThreshold,
|
|
46
47
|
getSmartDefaults: () => getSmartDefaults,
|
|
47
48
|
groupDuplicatesByFilePair: () => groupDuplicatesByFilePair
|
|
@@ -197,29 +198,6 @@ function calculateSeverity(file1, file2, code, similarity, linesOfCode) {
|
|
|
197
198
|
};
|
|
198
199
|
}
|
|
199
200
|
}
|
|
200
|
-
function getSeverityLabel(severity) {
|
|
201
|
-
const labels = {
|
|
202
|
-
[import_core.Severity.Critical]: "\u{1F534} CRITICAL",
|
|
203
|
-
[import_core.Severity.Major]: "\u{1F7E1} MAJOR",
|
|
204
|
-
[import_core.Severity.Minor]: "\u{1F535} MINOR",
|
|
205
|
-
[import_core.Severity.Info]: "\u2139\uFE0F INFO"
|
|
206
|
-
};
|
|
207
|
-
return labels[severity];
|
|
208
|
-
}
|
|
209
|
-
function filterBySeverity(duplicates, minSeverity) {
|
|
210
|
-
const severityOrder = [
|
|
211
|
-
import_core.Severity.Info,
|
|
212
|
-
import_core.Severity.Minor,
|
|
213
|
-
import_core.Severity.Major,
|
|
214
|
-
import_core.Severity.Critical
|
|
215
|
-
];
|
|
216
|
-
const minIndex = severityOrder.indexOf(minSeverity);
|
|
217
|
-
if (minIndex === -1) return duplicates;
|
|
218
|
-
return duplicates.filter((dup) => {
|
|
219
|
-
const dupIndex = severityOrder.indexOf(dup.severity);
|
|
220
|
-
return dupIndex >= minIndex;
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
201
|
function getSeverityThreshold(severity) {
|
|
224
202
|
const thresholds = {
|
|
225
203
|
[import_core.Severity.Critical]: 0.95,
|
|
@@ -885,6 +863,7 @@ import_core7.ToolRegistry.register(PatternDetectProvider);
|
|
|
885
863
|
// Annotate the CommonJS export names for ESM import in node:
|
|
886
864
|
0 && (module.exports = {
|
|
887
865
|
CONTEXT_RULES,
|
|
866
|
+
IssueType,
|
|
888
867
|
PatternDetectProvider,
|
|
889
868
|
Severity,
|
|
890
869
|
analyzePatterns,
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PatternDetectProvider,
|
|
3
3
|
Severity
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-J5CW6NYY.mjs";
|
|
5
5
|
import {
|
|
6
6
|
analyzePatterns,
|
|
7
7
|
createRefactorClusters,
|
|
@@ -9,22 +9,24 @@ import {
|
|
|
9
9
|
generateSummary,
|
|
10
10
|
getSmartDefaults,
|
|
11
11
|
groupDuplicatesByFilePair
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-SUUZMLPS.mjs";
|
|
13
13
|
import {
|
|
14
14
|
detectDuplicatePatterns
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-NQBYYWHJ.mjs";
|
|
16
16
|
import {
|
|
17
17
|
CONTEXT_RULES,
|
|
18
|
+
IssueType,
|
|
18
19
|
calculateSeverity,
|
|
19
20
|
filterBySeverity,
|
|
20
21
|
getSeverityLabel,
|
|
21
22
|
getSeverityThreshold
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-J2G742QF.mjs";
|
|
23
24
|
import {
|
|
24
25
|
calculatePatternScore
|
|
25
26
|
} from "./chunk-WBBO35SC.mjs";
|
|
26
27
|
export {
|
|
27
28
|
CONTEXT_RULES,
|
|
29
|
+
IssueType,
|
|
28
30
|
PatternDetectProvider,
|
|
29
31
|
Severity,
|
|
30
32
|
analyzePatterns,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aiready/pattern-detect",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Semantic duplicate pattern detection for AI-generated code - finds similar implementations that waste AI context tokens",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"dependencies": {
|
|
66
66
|
"commander": "^14.0.0",
|
|
67
67
|
"chalk": "^5.3.0",
|
|
68
|
-
"@aiready/core": "0.
|
|
68
|
+
"@aiready/core": "0.24.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"tsup": "^8.3.5",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-rules.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/context-rules.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { calculateSeverity, filterBySeverity, getSeverityLabel } from '../context-rules';
|
|
3
|
-
describe('Context-Aware Severity', () => {
|
|
4
|
-
describe('Test Fixture Detection', () => {
|
|
5
|
-
it('should mark test fixtures as info severity', () => {
|
|
6
|
-
const file = 'src/__tests__/user.test.ts';
|
|
7
|
-
const code = `
|
|
8
|
-
beforeAll(async () => {
|
|
9
|
-
await setupDatabase();
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
afterAll(async () => {
|
|
13
|
-
await cleanupDatabase();
|
|
14
|
-
});
|
|
15
|
-
`;
|
|
16
|
-
const result = calculateSeverity(file, file, code, 1.0, 10);
|
|
17
|
-
expect(result.severity).toBe('info');
|
|
18
|
-
expect(result.reason).toContain('test isolation');
|
|
19
|
-
expect(result.matchedRule).toBe('test-fixtures');
|
|
20
|
-
});
|
|
21
|
-
it('should detect test files with spec extension', () => {
|
|
22
|
-
const file = 'src/components/Button.spec.ts';
|
|
23
|
-
const code = `
|
|
24
|
-
beforeEach(() => {
|
|
25
|
-
jest.clearAllMocks();
|
|
26
|
-
});
|
|
27
|
-
`;
|
|
28
|
-
const result = calculateSeverity(file, file, code, 0.9, 8);
|
|
29
|
-
expect(result.severity).toBe('info');
|
|
30
|
-
expect(result.matchedRule).toBe('test-fixtures');
|
|
31
|
-
});
|
|
32
|
-
});
|
|
33
|
-
describe('Template Detection', () => {
|
|
34
|
-
it('should mark email templates as low severity', () => {
|
|
35
|
-
const file = 'src/email-templates/payment-failed.ts';
|
|
36
|
-
const code = `
|
|
37
|
-
export function getEmailTemplate() {
|
|
38
|
-
return {
|
|
39
|
-
subject: 'Payment Failed',
|
|
40
|
-
html: '<div>Your payment has failed</div>',
|
|
41
|
-
body: 'Payment failed'
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
`;
|
|
45
|
-
const result = calculateSeverity(file, file, code, 0.8, 20);
|
|
46
|
-
expect(result.severity).toBe('minor');
|
|
47
|
-
expect(result.reason).toContain('branding consistency');
|
|
48
|
-
expect(result.matchedRule).toBe('templates');
|
|
49
|
-
});
|
|
50
|
-
});
|
|
51
|
-
describe('E2E Test Detection', () => {
|
|
52
|
-
it('should mark E2E page objects as low severity', () => {
|
|
53
|
-
const file = 'e2e/pages/login-page.ts';
|
|
54
|
-
const code = `
|
|
55
|
-
async function clickLoginButton() {
|
|
56
|
-
await page.click('button[type="submit"]');
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
async function fillUsername(value: string) {
|
|
60
|
-
await page.fill('input[name="username"]', value);
|
|
61
|
-
}
|
|
62
|
-
`;
|
|
63
|
-
const result = calculateSeverity(file, file, code, 0.85, 15);
|
|
64
|
-
// Debug: The detection is working now with 'await page' pattern
|
|
65
|
-
expect(result.severity).toBe('minor');
|
|
66
|
-
expect(result.reason).toContain('test independence');
|
|
67
|
-
expect(result.matchedRule).toBe('e2e-page-objects');
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
describe('Configuration Files', () => {
|
|
71
|
-
it('should mark config files as low severity', () => {
|
|
72
|
-
const file = 'packages/web/jest.config.ts';
|
|
73
|
-
const code = `
|
|
74
|
-
export default {
|
|
75
|
-
preset: 'ts-jest',
|
|
76
|
-
testEnvironment: 'node'
|
|
77
|
-
};
|
|
78
|
-
`;
|
|
79
|
-
const result = calculateSeverity(file, file, code, 0.9, 10);
|
|
80
|
-
expect(result.severity).toBe('minor');
|
|
81
|
-
expect(result.matchedRule).toBe('config-files');
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
describe('Type Definitions', () => {
|
|
85
|
-
it('should mark type definitions as info severity', () => {
|
|
86
|
-
const file = 'src/types/user.d.ts';
|
|
87
|
-
const code = `
|
|
88
|
-
interface User {
|
|
89
|
-
id: string;
|
|
90
|
-
name: string;
|
|
91
|
-
email: string;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
type UserRole = 'admin' | 'user';
|
|
95
|
-
`;
|
|
96
|
-
const result = calculateSeverity(file, file, code, 0.95, 12);
|
|
97
|
-
expect(result.severity).toBe('info');
|
|
98
|
-
expect(result.reason).toContain('type safety');
|
|
99
|
-
expect(result.matchedRule).toBe('type-definitions');
|
|
100
|
-
});
|
|
101
|
-
});
|
|
102
|
-
describe('Critical Duplication', () => {
|
|
103
|
-
it('should mark large identical code as critical', () => {
|
|
104
|
-
const file = 'src/utils/helper.ts';
|
|
105
|
-
const code = 'function compute() {\n'.repeat(35) + '}';
|
|
106
|
-
const result = calculateSeverity(file, file, code, 1.0, 35);
|
|
107
|
-
expect(result.severity).toBe('critical');
|
|
108
|
-
expect(result.reason).toContain('maintenance burden');
|
|
109
|
-
});
|
|
110
|
-
it('should mark high similarity medium-sized code as high', () => {
|
|
111
|
-
const file = 'src/services/api.ts';
|
|
112
|
-
const code = 'function fetchData() {\n'.repeat(20) + '}';
|
|
113
|
-
const result = calculateSeverity(file, file, code, 0.96, 20);
|
|
114
|
-
expect(result.severity).toBe('major');
|
|
115
|
-
expect(result.reason).toContain('consolidated');
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
describe('Severity Filtering', () => {
|
|
119
|
-
it('should filter by minimum severity', () => {
|
|
120
|
-
const duplicates = [
|
|
121
|
-
{ severity: 'critical' },
|
|
122
|
-
{ severity: 'major' },
|
|
123
|
-
{ severity: 'minor' },
|
|
124
|
-
{ severity: 'info' },
|
|
125
|
-
];
|
|
126
|
-
const filtered = filterBySeverity(duplicates, 'minor');
|
|
127
|
-
expect(filtered).toHaveLength(3);
|
|
128
|
-
expect(filtered.map(d => d.severity)).toEqual(['critical', 'major', 'minor']);
|
|
129
|
-
});
|
|
130
|
-
it('should show all severities when filtering by info', () => {
|
|
131
|
-
const duplicates = [
|
|
132
|
-
{ severity: 'critical' },
|
|
133
|
-
{ severity: 'info' },
|
|
134
|
-
];
|
|
135
|
-
const filtered = filterBySeverity(duplicates, 'info');
|
|
136
|
-
expect(filtered).toHaveLength(2);
|
|
137
|
-
});
|
|
138
|
-
it('should only show critical when filtering by critical', () => {
|
|
139
|
-
const duplicates = [
|
|
140
|
-
{ severity: 'critical' },
|
|
141
|
-
{ severity: 'major' },
|
|
142
|
-
{ severity: 'minor' },
|
|
143
|
-
];
|
|
144
|
-
const filtered = filterBySeverity(duplicates, 'critical');
|
|
145
|
-
expect(filtered).toHaveLength(1);
|
|
146
|
-
expect(filtered[0].severity).toBe('critical');
|
|
147
|
-
});
|
|
148
|
-
});
|
|
149
|
-
describe('Severity Labels', () => {
|
|
150
|
-
it('should return correct labels with emojis', () => {
|
|
151
|
-
expect(getSeverityLabel('critical')).toContain('CRITICAL');
|
|
152
|
-
expect(getSeverityLabel('major')).toContain('MAJOR');
|
|
153
|
-
expect(getSeverityLabel('minor')).toContain('MINOR');
|
|
154
|
-
expect(getSeverityLabel('info')).toContain('INFO');
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
describe('Mock Data Detection', () => {
|
|
158
|
-
it('should mark mock data as info severity', () => {
|
|
159
|
-
const file = 'src/__mocks__/user-data.ts';
|
|
160
|
-
const code = `
|
|
161
|
-
export const mockUser = {
|
|
162
|
-
id: '123',
|
|
163
|
-
name: 'Test User',
|
|
164
|
-
email: 'test@example.com'
|
|
165
|
-
};
|
|
166
|
-
`;
|
|
167
|
-
const result = calculateSeverity(file, file, code, 0.9, 10);
|
|
168
|
-
expect(result.severity).toBe('info');
|
|
169
|
-
expect(result.matchedRule).toBe('mock-data');
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
describe('Migration Scripts Detection', () => {
|
|
173
|
-
it('should mark migration scripts as info severity', () => {
|
|
174
|
-
const file = 'db/migrations/001_create_users.ts';
|
|
175
|
-
const code = `
|
|
176
|
-
export async function up(db: Database) {
|
|
177
|
-
await db.createTable('users', {
|
|
178
|
-
id: 'uuid',
|
|
179
|
-
name: 'text'
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
`;
|
|
183
|
-
const result = calculateSeverity(file, file, code, 0.95, 15);
|
|
184
|
-
expect(result.severity).toBe('info');
|
|
185
|
-
expect(result.matchedRule).toBe('migration-scripts');
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
//# sourceMappingURL=context-rules.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context-rules.test.js","sourceRoot":"","sources":["../../src/__tests__/context-rules.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detector.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/detector.test.ts"],"names":[],"mappings":""}
|