@tayo-dev/rtl 1.0.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/README.md +250 -0
- package/dist/analyzer/mocks/detector.d.ts +59 -0
- package/dist/analyzer/mocks/detector.d.ts.map +1 -0
- package/dist/analyzer/mocks/detector.js +264 -0
- package/dist/analyzer/mocks/detector.js.map +1 -0
- package/dist/analyzer/mocks/target-analyzer.d.ts +92 -0
- package/dist/analyzer/mocks/target-analyzer.d.ts.map +1 -0
- package/dist/analyzer/mocks/target-analyzer.js +305 -0
- package/dist/analyzer/mocks/target-analyzer.js.map +1 -0
- package/dist/analyzer/visual/element-analyzer.d.ts +44 -0
- package/dist/analyzer/visual/element-analyzer.d.ts.map +1 -0
- package/dist/analyzer/visual/element-analyzer.js +176 -0
- package/dist/analyzer/visual/element-analyzer.js.map +1 -0
- package/dist/analyzer/visual/inspector.d.ts +49 -0
- package/dist/analyzer/visual/inspector.d.ts.map +1 -0
- package/dist/analyzer/visual/inspector.js +109 -0
- package/dist/analyzer/visual/inspector.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +13 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +417 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/core/generator.d.ts +32 -0
- package/dist/core/generator.d.ts.map +1 -0
- package/dist/core/generator.js +173 -0
- package/dist/core/generator.js.map +1 -0
- package/dist/core/js-parser.d.ts +48 -0
- package/dist/core/js-parser.d.ts.map +1 -0
- package/dist/core/js-parser.js +244 -0
- package/dist/core/js-parser.js.map +1 -0
- package/dist/core/mock-intelligence.d.ts +14 -0
- package/dist/core/mock-intelligence.d.ts.map +1 -0
- package/dist/core/mock-intelligence.js +140 -0
- package/dist/core/mock-intelligence.js.map +1 -0
- package/dist/core/orchestrator.d.ts +49 -0
- package/dist/core/orchestrator.d.ts.map +1 -0
- package/dist/core/orchestrator.js +315 -0
- package/dist/core/orchestrator.js.map +1 -0
- package/dist/core/parser.d.ts +9 -0
- package/dist/core/parser.d.ts.map +1 -0
- package/dist/core/parser.js +120 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/recording-intelligence.d.ts +15 -0
- package/dist/core/recording-intelligence.d.ts.map +1 -0
- package/dist/core/recording-intelligence.js +178 -0
- package/dist/core/recording-intelligence.js.map +1 -0
- package/dist/core/resolver.d.ts +58 -0
- package/dist/core/resolver.d.ts.map +1 -0
- package/dist/core/resolver.js +291 -0
- package/dist/core/resolver.js.map +1 -0
- package/dist/core/scanner.d.ts +51 -0
- package/dist/core/scanner.d.ts.map +1 -0
- package/dist/core/scanner.js +310 -0
- package/dist/core/scanner.js.map +1 -0
- package/dist/core/scorer.d.ts +8 -0
- package/dist/core/scorer.d.ts.map +1 -0
- package/dist/core/scorer.js +76 -0
- package/dist/core/scorer.js.map +1 -0
- package/dist/core/validator.d.ts +134 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +44 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/core/verifier.d.ts +10 -0
- package/dist/core/verifier.d.ts.map +1 -0
- package/dist/core/verifier.js +30 -0
- package/dist/core/verifier.js.map +1 -0
- package/dist/core/writer.d.ts +15 -0
- package/dist/core/writer.d.ts.map +1 -0
- package/dist/core/writer.js +43 -0
- package/dist/core/writer.js.map +1 -0
- package/dist/generator/mocks/builder.d.ts +47 -0
- package/dist/generator/mocks/builder.d.ts.map +1 -0
- package/dist/generator/mocks/builder.js +335 -0
- package/dist/generator/mocks/builder.js.map +1 -0
- package/dist/generator/transforms/dialog-transform.d.ts +35 -0
- package/dist/generator/transforms/dialog-transform.d.ts.map +1 -0
- package/dist/generator/transforms/dialog-transform.js +293 -0
- package/dist/generator/transforms/dialog-transform.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/learner/analyzer.d.ts +13 -0
- package/dist/learner/analyzer.d.ts.map +1 -0
- package/dist/learner/analyzer.js +484 -0
- package/dist/learner/analyzer.js.map +1 -0
- package/dist/learner/index.d.ts +66 -0
- package/dist/learner/index.d.ts.map +1 -0
- package/dist/learner/index.js +247 -0
- package/dist/learner/index.js.map +1 -0
- package/dist/learner/storage.d.ts +68 -0
- package/dist/learner/storage.d.ts.map +1 -0
- package/dist/learner/storage.js +201 -0
- package/dist/learner/storage.js.map +1 -0
- package/dist/learner/types.d.ts +41 -0
- package/dist/learner/types.d.ts.map +1 -0
- package/dist/learner/types.js +31 -0
- package/dist/learner/types.js.map +1 -0
- package/dist/parser/recorder-parser.d.ts +40 -0
- package/dist/parser/recorder-parser.d.ts.map +1 -0
- package/dist/parser/recorder-parser.js +139 -0
- package/dist/parser/recorder-parser.js.map +1 -0
- package/dist/parser/steps/deduplicator.d.ts +19 -0
- package/dist/parser/steps/deduplicator.d.ts.map +1 -0
- package/dist/parser/steps/deduplicator.js +75 -0
- package/dist/parser/steps/deduplicator.js.map +1 -0
- package/dist/parser/steps/dialog-detector.d.ts +38 -0
- package/dist/parser/steps/dialog-detector.d.ts.map +1 -0
- package/dist/parser/steps/dialog-detector.js +290 -0
- package/dist/parser/steps/dialog-detector.js.map +1 -0
- package/dist/parser/steps/noise-filter.d.ts +21 -0
- package/dist/parser/steps/noise-filter.d.ts.map +1 -0
- package/dist/parser/steps/noise-filter.js +138 -0
- package/dist/parser/steps/noise-filter.js.map +1 -0
- package/dist/scorer/index.d.ts +43 -0
- package/dist/scorer/index.d.ts.map +1 -0
- package/dist/scorer/index.js +82 -0
- package/dist/scorer/index.js.map +1 -0
- package/dist/scorer/post-verify.d.ts +17 -0
- package/dist/scorer/post-verify.d.ts.map +1 -0
- package/dist/scorer/post-verify.js +163 -0
- package/dist/scorer/post-verify.js.map +1 -0
- package/dist/scorer/pre-audit.d.ts +32 -0
- package/dist/scorer/pre-audit.d.ts.map +1 -0
- package/dist/scorer/pre-audit.js +99 -0
- package/dist/scorer/pre-audit.js.map +1 -0
- package/dist/scorer/quality-gates.d.ts +17 -0
- package/dist/scorer/quality-gates.d.ts.map +1 -0
- package/dist/scorer/quality-gates.js +304 -0
- package/dist/scorer/quality-gates.js.map +1 -0
- package/dist/scorer/types.d.ts +27 -0
- package/dist/scorer/types.d.ts.map +1 -0
- package/dist/scorer/types.js +5 -0
- package/dist/scorer/types.js.map +1 -0
- package/dist/templates/test-template.d.ts +21 -0
- package/dist/templates/test-template.d.ts.map +1 -0
- package/dist/templates/test-template.js +92 -0
- package/dist/templates/test-template.js.map +1 -0
- package/dist/types/conventions.d.ts +49 -0
- package/dist/types/conventions.d.ts.map +1 -0
- package/dist/types/conventions.js +13 -0
- package/dist/types/conventions.js.map +1 -0
- package/dist/types/recording.d.ts +143 -0
- package/dist/types/recording.d.ts.map +1 -0
- package/dist/types/recording.js +5 -0
- package/dist/types/recording.js.map +1 -0
- package/dist/types/score.d.ts +18 -0
- package/dist/types/score.d.ts.map +1 -0
- package/dist/types/score.js +2 -0
- package/dist/types/score.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,484 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convention analyzer - extracts patterns from test files using AST analysis
|
|
3
|
+
*/
|
|
4
|
+
import { parse } from '@typescript-eslint/typescript-estree';
|
|
5
|
+
import * as fs from 'fs';
|
|
6
|
+
import * as path from 'path';
|
|
7
|
+
import { createEmptyConvention } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Analyze a single test file and extract conventions
|
|
10
|
+
*/
|
|
11
|
+
export function analyzeTestFile(filePath) {
|
|
12
|
+
const code = fs.readFileSync(filePath, 'utf-8');
|
|
13
|
+
let ast;
|
|
14
|
+
try {
|
|
15
|
+
ast = parse(code, {
|
|
16
|
+
loc: true,
|
|
17
|
+
range: true,
|
|
18
|
+
jsx: true,
|
|
19
|
+
ecmaVersion: 2020,
|
|
20
|
+
sourceType: 'module'
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.warn(`Failed to parse ${filePath}:`, error);
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
const naming = extractNamingPatterns(code, ast);
|
|
28
|
+
const queries = extractQueryPreferences(code);
|
|
29
|
+
const matchers = extractMatcherPatterns(ast);
|
|
30
|
+
const imports = extractImports(ast);
|
|
31
|
+
const structure = extractStructurePatterns(code, ast);
|
|
32
|
+
return {
|
|
33
|
+
naming,
|
|
34
|
+
structure,
|
|
35
|
+
queries,
|
|
36
|
+
matchers,
|
|
37
|
+
imports
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Extract naming patterns from describe blocks
|
|
42
|
+
*/
|
|
43
|
+
function extractNamingPatterns(code, ast) {
|
|
44
|
+
const describeNames = [];
|
|
45
|
+
const itNames = [];
|
|
46
|
+
function traverse(node) {
|
|
47
|
+
if (!node)
|
|
48
|
+
return;
|
|
49
|
+
if (node.type === 'CallExpression' && node.callee) {
|
|
50
|
+
const calleeName = getCalleeName(node.callee);
|
|
51
|
+
if (calleeName === 'describe' && node.arguments && node.arguments[0]) {
|
|
52
|
+
const firstArg = node.arguments[0];
|
|
53
|
+
if (firstArg.type === 'Literal' || firstArg.type === 'StringLiteral') {
|
|
54
|
+
describeNames.push(String(firstArg.value || ''));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if ((calleeName === 'it' || calleeName === 'test') && node.arguments && node.arguments[0]) {
|
|
58
|
+
const firstArg = node.arguments[0];
|
|
59
|
+
if (firstArg.type === 'Literal' || firstArg.type === 'StringLiteral') {
|
|
60
|
+
itNames.push(String(firstArg.value || ''));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
traverseArray(node.body);
|
|
65
|
+
traverseArray(node.arguments);
|
|
66
|
+
traverseArray(node.expression);
|
|
67
|
+
}
|
|
68
|
+
function traverseArray(arr) {
|
|
69
|
+
if (Array.isArray(arr)) {
|
|
70
|
+
arr.forEach(traverse);
|
|
71
|
+
}
|
|
72
|
+
else if (arr && typeof arr === 'object') {
|
|
73
|
+
traverse(arr);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
traverse(ast);
|
|
77
|
+
// Detect naming pattern from describe names
|
|
78
|
+
const pattern = detectNamingPattern(describeNames);
|
|
79
|
+
const describePrefix = extractDescribePrefix(describeNames);
|
|
80
|
+
const itTemplate = extractItTemplate(itNames);
|
|
81
|
+
return {
|
|
82
|
+
pattern,
|
|
83
|
+
describePrefix,
|
|
84
|
+
itTemplate
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Detect naming pattern (camelCase, kebab-case, snake_case)
|
|
89
|
+
*/
|
|
90
|
+
function detectNamingPattern(names) {
|
|
91
|
+
if (names.length === 0)
|
|
92
|
+
return 'camelCase';
|
|
93
|
+
const sample = names[0];
|
|
94
|
+
// Check for kebab-case (has hyphens but not underscores)
|
|
95
|
+
if (sample.includes('-') && !sample.includes('_')) {
|
|
96
|
+
return 'kebab-case';
|
|
97
|
+
}
|
|
98
|
+
// Check for snake_case (has underscores)
|
|
99
|
+
if (sample.includes('_') && !sample.includes('-')) {
|
|
100
|
+
return 'snake_case';
|
|
101
|
+
}
|
|
102
|
+
// Check for camelCase (has uppercase letters)
|
|
103
|
+
if (/[a-z][A-Z]/.test(sample)) {
|
|
104
|
+
return 'camelCase';
|
|
105
|
+
}
|
|
106
|
+
return 'camelCase';
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Extract common describe block prefix
|
|
110
|
+
*/
|
|
111
|
+
function extractDescribePrefix(names) {
|
|
112
|
+
if (names.length === 0)
|
|
113
|
+
return '';
|
|
114
|
+
// Find common prefix among all describe names
|
|
115
|
+
const sorted = [...names].sort();
|
|
116
|
+
const first = sorted[0];
|
|
117
|
+
const last = sorted[sorted.length - 1];
|
|
118
|
+
let prefix = '';
|
|
119
|
+
for (let i = 0; i < first.length; i++) {
|
|
120
|
+
if (first[i] === last[i]) {
|
|
121
|
+
prefix += first[i];
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Clean up prefix (remove trailing separators)
|
|
128
|
+
return prefix.replace(/[-_ ]+$/, '');
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Extract test template from 'it' descriptions
|
|
132
|
+
*/
|
|
133
|
+
function extractItTemplate(names) {
|
|
134
|
+
if (names.length === 0)
|
|
135
|
+
return 'should {description}';
|
|
136
|
+
// Look for common patterns like "should do X", "does Y", "renders Z"
|
|
137
|
+
const patterns = ['should', 'does', 'renders', 'shows', 'displays', 'returns'];
|
|
138
|
+
for (const name of names) {
|
|
139
|
+
for (const pattern of patterns) {
|
|
140
|
+
if (name.toLowerCase().startsWith(pattern)) {
|
|
141
|
+
const remainder = name.slice(pattern.length).trim();
|
|
142
|
+
if (remainder) {
|
|
143
|
+
return `${pattern} {description}`;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return 'should {description}';
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Extract query preferences from code
|
|
152
|
+
*/
|
|
153
|
+
function extractQueryPreferences(code) {
|
|
154
|
+
const robustQueries = [
|
|
155
|
+
'getByRole',
|
|
156
|
+
'getByLabelText',
|
|
157
|
+
'getByText',
|
|
158
|
+
'getByPlaceholderText',
|
|
159
|
+
'getByAltText',
|
|
160
|
+
'getByTitle',
|
|
161
|
+
'findByRole',
|
|
162
|
+
'findByLabelText',
|
|
163
|
+
'findByText',
|
|
164
|
+
'queryByRole',
|
|
165
|
+
'queryByLabelText'
|
|
166
|
+
];
|
|
167
|
+
const fragileQueries = [
|
|
168
|
+
'querySelector',
|
|
169
|
+
'getByTestId',
|
|
170
|
+
'queryByTestId',
|
|
171
|
+
'findByTestId'
|
|
172
|
+
];
|
|
173
|
+
const preferred = [];
|
|
174
|
+
const avoided = [];
|
|
175
|
+
robustQueries.forEach(q => {
|
|
176
|
+
if (code.includes(q))
|
|
177
|
+
preferred.push(q);
|
|
178
|
+
});
|
|
179
|
+
fragileQueries.forEach(q => {
|
|
180
|
+
if (code.includes(q))
|
|
181
|
+
avoided.push(q);
|
|
182
|
+
});
|
|
183
|
+
return { preferred, avoided };
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Extract matcher patterns from AST
|
|
187
|
+
*/
|
|
188
|
+
function extractMatcherPatterns(ast) {
|
|
189
|
+
const commonMatchers = new Set();
|
|
190
|
+
const matcherNames = [
|
|
191
|
+
'toBe',
|
|
192
|
+
'toEqual',
|
|
193
|
+
'toContain',
|
|
194
|
+
'toHaveLength',
|
|
195
|
+
'toBeTruthy',
|
|
196
|
+
'toBeFalsy',
|
|
197
|
+
'toBeInTheDocument',
|
|
198
|
+
'toBeVisible',
|
|
199
|
+
'toHaveTextContent',
|
|
200
|
+
'toHaveValue',
|
|
201
|
+
'toHaveBeenCalled',
|
|
202
|
+
'toHaveBeenCalledWith',
|
|
203
|
+
'toBeDisabled',
|
|
204
|
+
'toBeEnabled',
|
|
205
|
+
'toBeChecked',
|
|
206
|
+
'toBeRequired',
|
|
207
|
+
'not.toBe',
|
|
208
|
+
'not.toEqual',
|
|
209
|
+
'not.toContain'
|
|
210
|
+
];
|
|
211
|
+
function traverse(node) {
|
|
212
|
+
if (!node)
|
|
213
|
+
return;
|
|
214
|
+
// Check for member expressions like expect(x).toBe(y)
|
|
215
|
+
if (node.type === 'MemberExpression' && node.property) {
|
|
216
|
+
const prop = node.property;
|
|
217
|
+
const propName = typeof prop.name === 'string' ? prop.name : '';
|
|
218
|
+
// Handle "not.toBe" pattern
|
|
219
|
+
if (propName === 'not' && node.object) {
|
|
220
|
+
const obj = node.object;
|
|
221
|
+
if (obj.type === 'MemberExpression' && obj.property) {
|
|
222
|
+
const innerProp = obj.property;
|
|
223
|
+
const innerName = typeof innerProp.name === 'string' ? innerProp.name : '';
|
|
224
|
+
if (matcherNames.includes(`not.${innerName}`)) {
|
|
225
|
+
commonMatchers.add(`not.${innerName}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
else if (matcherNames.includes(propName)) {
|
|
230
|
+
commonMatchers.add(propName);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
traverseArray(node.body);
|
|
234
|
+
traverseArray(node.arguments);
|
|
235
|
+
traverseArray(node.expression);
|
|
236
|
+
}
|
|
237
|
+
function traverseArray(arr) {
|
|
238
|
+
if (Array.isArray(arr)) {
|
|
239
|
+
arr.forEach(traverse);
|
|
240
|
+
}
|
|
241
|
+
else if (arr && typeof arr === 'object') {
|
|
242
|
+
traverse(arr);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
traverse(ast);
|
|
246
|
+
return {
|
|
247
|
+
common: Array.from(commonMatchers)
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* Extract import statements from AST
|
|
252
|
+
*/
|
|
253
|
+
function extractImports(ast) {
|
|
254
|
+
const commonImports = new Set();
|
|
255
|
+
function traverse(node) {
|
|
256
|
+
if (!node)
|
|
257
|
+
return;
|
|
258
|
+
if (node.type === 'ImportDeclaration' && node.source) {
|
|
259
|
+
const source = node.source;
|
|
260
|
+
const sourceValue = source.value;
|
|
261
|
+
if (sourceValue) {
|
|
262
|
+
// Extract package name (before any / or @)
|
|
263
|
+
const packageName = sourceValue.startsWith('@')
|
|
264
|
+
? sourceValue.split('/').slice(0, 2).join('/')
|
|
265
|
+
: sourceValue.split('/')[0];
|
|
266
|
+
if (!packageName.startsWith('.') && !packageName.startsWith('/')) {
|
|
267
|
+
commonImports.add(packageName);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
traverseArray(node.body);
|
|
272
|
+
traverseArray(node.arguments);
|
|
273
|
+
}
|
|
274
|
+
function traverseArray(arr) {
|
|
275
|
+
if (Array.isArray(arr)) {
|
|
276
|
+
arr.forEach(traverse);
|
|
277
|
+
}
|
|
278
|
+
else if (arr && typeof arr === 'object') {
|
|
279
|
+
traverse(arr);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
traverse(ast);
|
|
283
|
+
return {
|
|
284
|
+
common: Array.from(commonImports)
|
|
285
|
+
};
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Extract structure patterns
|
|
289
|
+
*/
|
|
290
|
+
function extractStructurePatterns(code, ast) {
|
|
291
|
+
let hasDescribePerComponent = false;
|
|
292
|
+
let hasHelpersInDescribe = false;
|
|
293
|
+
let setupLocation = 'inside-describe';
|
|
294
|
+
const describeBlocks = [];
|
|
295
|
+
const helperFunctions = new Set();
|
|
296
|
+
const setupCalls = new Set();
|
|
297
|
+
function traverse(node, inDescribe = false) {
|
|
298
|
+
if (!node)
|
|
299
|
+
return;
|
|
300
|
+
if (node.type === 'CallExpression' && node.callee) {
|
|
301
|
+
const calleeName = getCalleeName(node.callee);
|
|
302
|
+
if (calleeName === 'describe') {
|
|
303
|
+
describeBlocks.push(node);
|
|
304
|
+
hasDescribePerComponent = true;
|
|
305
|
+
// Check what's inside the describe
|
|
306
|
+
if (node.arguments && node.arguments[1]) {
|
|
307
|
+
const body = node.arguments[1];
|
|
308
|
+
traverse(body, true);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
if ((calleeName === 'beforeEach' || calleeName === 'beforeAll' || calleeName === 'afterEach' || calleeName === 'afterAll')) {
|
|
312
|
+
setupCalls.add(calleeName);
|
|
313
|
+
if (!inDescribe) {
|
|
314
|
+
setupLocation = 'outside-describe';
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
setupLocation = 'beforeeach';
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
if (calleeName === 'it' || calleeName === 'test') {
|
|
321
|
+
if (inDescribe) {
|
|
322
|
+
setupLocation = 'inside-describe';
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
// Detect helper functions (functions defined at top level)
|
|
327
|
+
if (node.type === 'FunctionDeclaration' && node.name && !inDescribe) {
|
|
328
|
+
helperFunctions.add(node.name);
|
|
329
|
+
}
|
|
330
|
+
traverseArray(node.body, inDescribe);
|
|
331
|
+
traverseArray(node.arguments, inDescribe);
|
|
332
|
+
}
|
|
333
|
+
function traverseArray(arr, inDescribe) {
|
|
334
|
+
if (Array.isArray(arr)) {
|
|
335
|
+
arr.forEach(n => traverse(n, inDescribe));
|
|
336
|
+
}
|
|
337
|
+
else if (arr && typeof arr === 'object') {
|
|
338
|
+
traverse(arr, inDescribe);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
traverse(ast);
|
|
342
|
+
hasHelpersInDescribe = describeBlocks.length > 0 && helperFunctions.size > 0;
|
|
343
|
+
return {
|
|
344
|
+
describePerComponent: hasDescribePerComponent,
|
|
345
|
+
helpersInDescribe: hasHelpersInDescribe,
|
|
346
|
+
setupLocation
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Get the name of a callee
|
|
351
|
+
*/
|
|
352
|
+
function getCalleeName(callee) {
|
|
353
|
+
if (callee.type === 'Identifier') {
|
|
354
|
+
return callee.name || '';
|
|
355
|
+
}
|
|
356
|
+
if (callee.type === 'MemberExpression' && callee.property) {
|
|
357
|
+
const prop = callee.property;
|
|
358
|
+
return typeof prop.name === 'string' ? prop.name : '';
|
|
359
|
+
}
|
|
360
|
+
if (callee.type === 'CallExpression' && callee.callee) {
|
|
361
|
+
return getCalleeName(callee.callee);
|
|
362
|
+
}
|
|
363
|
+
return '';
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Extract conventions from all test files in a directory
|
|
367
|
+
*/
|
|
368
|
+
export function extractConventions(testDir) {
|
|
369
|
+
const convention = createEmptyConvention();
|
|
370
|
+
// Find all test files
|
|
371
|
+
const testFiles = findTestFiles(testDir);
|
|
372
|
+
if (testFiles.length === 0) {
|
|
373
|
+
console.warn(`No test files found in ${testDir}`);
|
|
374
|
+
return convention;
|
|
375
|
+
}
|
|
376
|
+
// Analyze each test file
|
|
377
|
+
const partials = testFiles.map(file => analyzeTestFile(file));
|
|
378
|
+
// Merge conventions from all files
|
|
379
|
+
return mergeConventions(partials);
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Find all test files in directory
|
|
383
|
+
*/
|
|
384
|
+
function findTestFiles(dir) {
|
|
385
|
+
const files = [];
|
|
386
|
+
if (!fs.existsSync(dir)) {
|
|
387
|
+
return files;
|
|
388
|
+
}
|
|
389
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
390
|
+
for (const entry of entries) {
|
|
391
|
+
const fullPath = path.join(dir, entry.name);
|
|
392
|
+
if (entry.isDirectory()) {
|
|
393
|
+
files.push(...findTestFiles(fullPath));
|
|
394
|
+
}
|
|
395
|
+
else if (entry.isFile()) {
|
|
396
|
+
// Match *.test.ts, *.test.tsx, *.spec.ts, *.spec.tsx
|
|
397
|
+
if (/\.(test|spec)\.(ts|tsx|js|jsx)$/.test(entry.name)) {
|
|
398
|
+
files.push(fullPath);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return files;
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Merge conventions from multiple files
|
|
406
|
+
*/
|
|
407
|
+
function mergeConventions(partials) {
|
|
408
|
+
const result = createEmptyConvention();
|
|
409
|
+
// Merge naming - take most common pattern
|
|
410
|
+
const patternCounts = {};
|
|
411
|
+
const prefixCounts = {};
|
|
412
|
+
for (const partial of partials) {
|
|
413
|
+
if (partial.naming) {
|
|
414
|
+
if (partial.naming.pattern) {
|
|
415
|
+
patternCounts[partial.naming.pattern] = (patternCounts[partial.naming.pattern] || 0) + 1;
|
|
416
|
+
}
|
|
417
|
+
if (partial.naming.describePrefix) {
|
|
418
|
+
prefixCounts[partial.naming.describePrefix] = (prefixCounts[partial.naming.describePrefix] || 0) + 1;
|
|
419
|
+
}
|
|
420
|
+
if (partial.naming.itTemplate && partial.naming.itTemplate !== 'should {description}') {
|
|
421
|
+
result.naming.itTemplate = partial.naming.itTemplate;
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
// Find most common pattern
|
|
426
|
+
let maxCount = 0;
|
|
427
|
+
for (const [pattern, count] of Object.entries(patternCounts)) {
|
|
428
|
+
if (count > maxCount) {
|
|
429
|
+
maxCount = count;
|
|
430
|
+
result.naming.pattern = pattern;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Find most common prefix
|
|
434
|
+
maxCount = 0;
|
|
435
|
+
for (const [prefix, count] of Object.entries(prefixCounts)) {
|
|
436
|
+
if (count > maxCount) {
|
|
437
|
+
maxCount = count;
|
|
438
|
+
result.naming.describePrefix = prefix;
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
// Merge structure - OR logic (if any file has it, set to true)
|
|
442
|
+
for (const partial of partials) {
|
|
443
|
+
if (partial.structure) {
|
|
444
|
+
if (partial.structure.describePerComponent) {
|
|
445
|
+
result.structure.describePerComponent = true;
|
|
446
|
+
}
|
|
447
|
+
if (partial.structure.helpersInDescribe) {
|
|
448
|
+
result.structure.helpersInDescribe = true;
|
|
449
|
+
}
|
|
450
|
+
if (partial.structure.setupLocation === 'beforeeach') {
|
|
451
|
+
result.structure.setupLocation = 'beforeeach';
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
// Merge queries - combine all preferred and avoided
|
|
456
|
+
const preferredSet = new Set();
|
|
457
|
+
const avoidedSet = new Set();
|
|
458
|
+
for (const partial of partials) {
|
|
459
|
+
if (partial.queries) {
|
|
460
|
+
partial.queries.preferred?.forEach(q => preferredSet.add(q));
|
|
461
|
+
partial.queries.avoided?.forEach(q => avoidedSet.add(q));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
result.queries.preferred = Array.from(preferredSet);
|
|
465
|
+
result.queries.avoided = Array.from(avoidedSet);
|
|
466
|
+
// Merge matchers - combine all common matchers
|
|
467
|
+
const matcherSet = new Set();
|
|
468
|
+
for (const partial of partials) {
|
|
469
|
+
if (partial.matchers) {
|
|
470
|
+
partial.matchers.common?.forEach(m => matcherSet.add(m));
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
result.matchers.common = Array.from(matcherSet);
|
|
474
|
+
// Merge imports - combine all common imports
|
|
475
|
+
const importSet = new Set();
|
|
476
|
+
for (const partial of partials) {
|
|
477
|
+
if (partial.imports) {
|
|
478
|
+
partial.imports.common?.forEach(i => importSet.add(i));
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
result.imports.common = Array.from(importSet);
|
|
482
|
+
return result;
|
|
483
|
+
}
|
|
484
|
+
//# sourceMappingURL=analyzer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyzer.js","sourceRoot":"","sources":["../../src/learner/analyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convention Learning Module
|
|
3
|
+
*
|
|
4
|
+
* Analyzes existing test patterns to derive Taro's conventions.
|
|
5
|
+
* Implements CNV-01: Taro derives conventions from observation.
|
|
6
|
+
* Implements CNV-02: Conventions persist across runs via SQLite storage.
|
|
7
|
+
* Implements CNV-03: Faster subsequent runs via caching.
|
|
8
|
+
*/
|
|
9
|
+
import { ConventionStore, createStore } from './storage.js';
|
|
10
|
+
import { TestConvention, ConventionKey, createEmptyConvention } from './types.js';
|
|
11
|
+
export type { TestConvention, ConventionKey };
|
|
12
|
+
export { createEmptyConvention, ConventionStore, createStore };
|
|
13
|
+
/**
|
|
14
|
+
* Learn conventions from test files in a project
|
|
15
|
+
*
|
|
16
|
+
* @param projectRoot - Root directory of the project
|
|
17
|
+
* @returns TestConvention object with learned patterns
|
|
18
|
+
*/
|
|
19
|
+
export declare function learnConventions(projectRoot: string): TestConvention;
|
|
20
|
+
/**
|
|
21
|
+
* Get conventions from persistent storage
|
|
22
|
+
*
|
|
23
|
+
* @param projectRoot - Root directory of the project
|
|
24
|
+
* @returns TestConvention if stored conventions exist, null otherwise
|
|
25
|
+
*/
|
|
26
|
+
export declare function getConventions(projectRoot: string): TestConvention | null;
|
|
27
|
+
/**
|
|
28
|
+
* ConventionStore - stores and manages learned conventions (in-memory)
|
|
29
|
+
*/
|
|
30
|
+
export declare class InMemoryConventionStore {
|
|
31
|
+
private conventions;
|
|
32
|
+
/**
|
|
33
|
+
* Add conventions for a specific context
|
|
34
|
+
*/
|
|
35
|
+
add(key: string, convention: TestConvention): void;
|
|
36
|
+
/**
|
|
37
|
+
* Get conventions for a specific context
|
|
38
|
+
*/
|
|
39
|
+
get(key: string): TestConvention | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Check if conventions exist for a context
|
|
42
|
+
*/
|
|
43
|
+
has(key: string): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Get all stored conventions
|
|
46
|
+
*/
|
|
47
|
+
getAll(): Map<string, TestConvention>;
|
|
48
|
+
/**
|
|
49
|
+
* Clear all stored conventions
|
|
50
|
+
*/
|
|
51
|
+
clear(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Merge multiple convention sets
|
|
54
|
+
*/
|
|
55
|
+
merge(other: InMemoryConventionStore): TestConvention;
|
|
56
|
+
private mergeInto;
|
|
57
|
+
}
|
|
58
|
+
declare const _default: {
|
|
59
|
+
learnConventions: typeof learnConventions;
|
|
60
|
+
getConventions: typeof getConventions;
|
|
61
|
+
ConventionStore: typeof ConventionStore;
|
|
62
|
+
InMemoryConventionStore: typeof InMemoryConventionStore;
|
|
63
|
+
createStore: typeof createStore;
|
|
64
|
+
};
|
|
65
|
+
export default _default;
|
|
66
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/learner/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EACL,cAAc,EACd,aAAa,EACb,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,WAAW,EAAE,CAAC;AA8D/D;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,CAoCpE;AAiDD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAqBzE;AAED;;GAEG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,WAAW,CAA0C;IAE7D;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,cAAc,GAAG,IAAI;IAIlD;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAI5C;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;OAEG;IACH,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IAIrC;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,uBAAuB,GAAG,cAAc;IAUrD,OAAO,CAAC,SAAS;CA6BlB;;;;;;;;AAED,wBAME"}
|