@iservu-inc/adf-cli 0.1.6 → 0.3.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/.project/chats/complete/2025-10-03_ADF-CLI-QUALITY-BASED-PROGRESS-AND-RESUME.md +399 -0
- package/.project/chats/current/2025-10-03_AGENTS-MD-AND-TOOL-GENERATORS.md +699 -0
- package/.project/docs/architecture/SYSTEM-DESIGN.md +369 -0
- package/.project/docs/frameworks/FRAMEWORK-METHODOLOGIES.md +449 -0
- package/.project/docs/goals/PROJECT-VISION.md +112 -0
- package/.project/docs/tool-integrations/IDE-CUSTOMIZATIONS.md +578 -0
- package/.project/docs/tool-integrations/RESEARCH-FINDINGS.md +828 -0
- package/CHANGELOG.md +292 -0
- package/jest.config.js +20 -0
- package/lib/commands/deploy.js +122 -3
- package/lib/commands/init.js +41 -113
- package/lib/frameworks/answer-quality-analyzer.js +216 -0
- package/lib/frameworks/interviewer.js +447 -0
- package/lib/frameworks/output-generators.js +345 -0
- package/lib/frameworks/progress-tracker.js +239 -0
- package/lib/frameworks/questions.js +664 -0
- package/lib/frameworks/session-manager.js +100 -0
- package/lib/generators/agents-md-generator.js +388 -0
- package/lib/generators/cursor-generator.js +374 -0
- package/lib/generators/index.js +98 -0
- package/lib/generators/tool-config-generator.js +188 -0
- package/lib/generators/vscode-generator.js +403 -0
- package/lib/generators/windsurf-generator.js +596 -0
- package/package.json +10 -5
- package/tests/agents-md-generator.test.js +245 -0
- package/tests/answer-quality-analyzer.test.js +173 -0
- package/tests/cursor-generator.test.js +326 -0
- package/tests/progress-tracker.test.js +205 -0
- package/tests/session-manager.test.js +162 -0
- package/tests/vscode-generator.test.js +436 -0
- package/tests/windsurf-generator.test.js +320 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
const fs = require('fs-extra');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const AgentsMdGenerator = require('../lib/generators/agents-md-generator');
|
|
4
|
+
|
|
5
|
+
const TEST_PROJECT_PATH = path.join(__dirname, 'test-project-generator');
|
|
6
|
+
const TEST_SESSION_PATH = path.join(TEST_PROJECT_PATH, '.adf', 'sessions', 'test-session');
|
|
7
|
+
|
|
8
|
+
describe('AgentsMdGenerator', () => {
|
|
9
|
+
beforeEach(async () => {
|
|
10
|
+
// Clean up test directories
|
|
11
|
+
await fs.remove(TEST_PROJECT_PATH);
|
|
12
|
+
await fs.ensureDir(TEST_PROJECT_PATH);
|
|
13
|
+
await fs.ensureDir(TEST_SESSION_PATH);
|
|
14
|
+
await fs.ensureDir(path.join(TEST_SESSION_PATH, 'outputs'));
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
afterEach(async () => {
|
|
18
|
+
// Clean up after tests
|
|
19
|
+
await fs.remove(TEST_PROJECT_PATH);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('PRP Framework', () => {
|
|
23
|
+
it('should generate AGENTS.md from PRP output', async () => {
|
|
24
|
+
// Create mock PRP output
|
|
25
|
+
const prpContent = `# Product Requirement Prompt (PRP)
|
|
26
|
+
|
|
27
|
+
## 1. Goal Definition
|
|
28
|
+
Build a React dashboard that displays real-time analytics from PostgreSQL database.
|
|
29
|
+
|
|
30
|
+
## 2. Business Justification
|
|
31
|
+
This will help users make data-driven decisions and improve productivity.
|
|
32
|
+
|
|
33
|
+
## 3. Contextual Intelligence
|
|
34
|
+
### Technology Stack
|
|
35
|
+
- Frontend: React 18, TypeScript
|
|
36
|
+
- Backend: Node.js, Express
|
|
37
|
+
- Database: PostgreSQL
|
|
38
|
+
|
|
39
|
+
## 4. Implementation Blueprint
|
|
40
|
+
### File Structure
|
|
41
|
+
- src/components/Dashboard/
|
|
42
|
+
- src/api/analytics/
|
|
43
|
+
|
|
44
|
+
### Core Logic
|
|
45
|
+
1. Fetch data from analytics API
|
|
46
|
+
2. Process and aggregate
|
|
47
|
+
3. Render charts
|
|
48
|
+
|
|
49
|
+
## 5. Validation
|
|
50
|
+
### Success Criteria
|
|
51
|
+
- Dashboard loads in <2s
|
|
52
|
+
- All charts render correctly
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
await fs.writeFile(
|
|
56
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prp.md'),
|
|
57
|
+
prpContent,
|
|
58
|
+
'utf-8'
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
// Create metadata
|
|
62
|
+
await fs.writeJson(path.join(TEST_SESSION_PATH, '_metadata.json'), {
|
|
63
|
+
framework: 'rapid',
|
|
64
|
+
projectName: 'Test Analytics Dashboard'
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// Generate AGENTS.md
|
|
68
|
+
const generator = new AgentsMdGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'rapid');
|
|
69
|
+
const generatedPath = await generator.generate();
|
|
70
|
+
|
|
71
|
+
// Verify file was created
|
|
72
|
+
expect(await fs.pathExists(generatedPath)).toBe(true);
|
|
73
|
+
|
|
74
|
+
// Verify content
|
|
75
|
+
const content = await fs.readFile(generatedPath, 'utf-8');
|
|
76
|
+
|
|
77
|
+
expect(content).toContain('# Test Analytics Dashboard');
|
|
78
|
+
expect(content).toContain('## Overview');
|
|
79
|
+
expect(content).toContain('React dashboard');
|
|
80
|
+
expect(content).toContain('## Tech Stack');
|
|
81
|
+
expect(content).toContain('## Build Commands');
|
|
82
|
+
expect(content).toContain('npm install');
|
|
83
|
+
expect(content).toContain('## AI Agent Instructions');
|
|
84
|
+
expect(content).toContain('.adf/sessions/test-session/outputs/prp.md');
|
|
85
|
+
expect(content).toContain('Generated by');
|
|
86
|
+
expect(content).toContain('ADF CLI');
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('Balanced Framework', () => {
|
|
91
|
+
it('should generate AGENTS.md from Balanced outputs', async () => {
|
|
92
|
+
// Create mock outputs
|
|
93
|
+
const constitutionContent = `# Constitution
|
|
94
|
+
|
|
95
|
+
## Core Principles
|
|
96
|
+
1. User privacy is paramount
|
|
97
|
+
2. Performance over features
|
|
98
|
+
|
|
99
|
+
## Constraints
|
|
100
|
+
- No third-party analytics
|
|
101
|
+
- WCAG 2.1 AA compliance
|
|
102
|
+
`;
|
|
103
|
+
|
|
104
|
+
const specificationContent = `# Specification
|
|
105
|
+
|
|
106
|
+
## Overview
|
|
107
|
+
A comprehensive user management system.
|
|
108
|
+
|
|
109
|
+
## Architecture
|
|
110
|
+
Microservices architecture with API gateway.
|
|
111
|
+
`;
|
|
112
|
+
|
|
113
|
+
const planContent = `# Technical Plan
|
|
114
|
+
|
|
115
|
+
## Technology Stack
|
|
116
|
+
- React 18
|
|
117
|
+
- Node.js 20
|
|
118
|
+
- PostgreSQL 15
|
|
119
|
+
`;
|
|
120
|
+
|
|
121
|
+
await fs.writeFile(
|
|
122
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'constitution.md'),
|
|
123
|
+
constitutionContent,
|
|
124
|
+
'utf-8'
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
await fs.writeFile(
|
|
128
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'specification.md'),
|
|
129
|
+
specificationContent,
|
|
130
|
+
'utf-8'
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
await fs.writeFile(
|
|
134
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'plan.md'),
|
|
135
|
+
planContent,
|
|
136
|
+
'utf-8'
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
// Generate AGENTS.md
|
|
140
|
+
const generator = new AgentsMdGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'balanced');
|
|
141
|
+
const generatedPath = await generator.generate();
|
|
142
|
+
|
|
143
|
+
// Verify content
|
|
144
|
+
const content = await fs.readFile(generatedPath, 'utf-8');
|
|
145
|
+
|
|
146
|
+
expect(content).toContain('## Constitution');
|
|
147
|
+
expect(content).toContain('User privacy is paramount');
|
|
148
|
+
expect(content).toContain('## Tech Stack');
|
|
149
|
+
expect(content).toContain('React 18');
|
|
150
|
+
expect(content).toContain('constitution.md');
|
|
151
|
+
expect(content).toContain('specification.md');
|
|
152
|
+
expect(content).toContain('plan.md');
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
describe('BMAD Framework', () => {
|
|
157
|
+
it('should generate AGENTS.md from BMAD outputs', async () => {
|
|
158
|
+
// Create mock outputs
|
|
159
|
+
const prdContent = `# Product Requirements Document
|
|
160
|
+
|
|
161
|
+
## Executive Summary
|
|
162
|
+
A complete e-commerce platform for small businesses.
|
|
163
|
+
|
|
164
|
+
## Goals and Objectives
|
|
165
|
+
- Enable online sales
|
|
166
|
+
- Provide analytics
|
|
167
|
+
|
|
168
|
+
## Technical Requirements
|
|
169
|
+
- RESTful API
|
|
170
|
+
- Payment gateway integration
|
|
171
|
+
`;
|
|
172
|
+
|
|
173
|
+
const architectureContent = `# System Architecture
|
|
174
|
+
|
|
175
|
+
## System Overview
|
|
176
|
+
Modular monolith architecture with separate domains.
|
|
177
|
+
`;
|
|
178
|
+
|
|
179
|
+
await fs.writeFile(
|
|
180
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prd.md'),
|
|
181
|
+
prdContent,
|
|
182
|
+
'utf-8'
|
|
183
|
+
);
|
|
184
|
+
|
|
185
|
+
await fs.writeFile(
|
|
186
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'architecture.md'),
|
|
187
|
+
architectureContent,
|
|
188
|
+
'utf-8'
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Generate AGENTS.md
|
|
192
|
+
const generator = new AgentsMdGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'comprehensive');
|
|
193
|
+
const generatedPath = await generator.generate();
|
|
194
|
+
|
|
195
|
+
// Verify content
|
|
196
|
+
const content = await fs.readFile(generatedPath, 'utf-8');
|
|
197
|
+
|
|
198
|
+
expect(content).toContain('## Product Overview');
|
|
199
|
+
expect(content).toContain('e-commerce platform');
|
|
200
|
+
expect(content).toContain('## Goals and Objectives');
|
|
201
|
+
expect(content).toContain('Enable online sales');
|
|
202
|
+
expect(content).toContain('## Security Notes');
|
|
203
|
+
expect(content).toContain('prd.md');
|
|
204
|
+
expect(content).toContain('architecture.md');
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
|
|
208
|
+
describe('Template Variables', () => {
|
|
209
|
+
it('should replace session ID in paths', async () => {
|
|
210
|
+
const prpContent = '# PRP\n\n## 1. Goal Definition\nTest project';
|
|
211
|
+
|
|
212
|
+
await fs.writeFile(
|
|
213
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prp.md'),
|
|
214
|
+
prpContent,
|
|
215
|
+
'utf-8'
|
|
216
|
+
);
|
|
217
|
+
|
|
218
|
+
const generator = new AgentsMdGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'rapid');
|
|
219
|
+
const generatedPath = await generator.generate();
|
|
220
|
+
|
|
221
|
+
const content = await fs.readFile(generatedPath, 'utf-8');
|
|
222
|
+
|
|
223
|
+
// Should contain the actual session ID, not a template variable
|
|
224
|
+
expect(content).toContain('test-session');
|
|
225
|
+
expect(content).not.toContain('{SESSION_ID}');
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
it('should include ADF CLI version', async () => {
|
|
229
|
+
const prpContent = '# PRP\n\n## 1. Goal Definition\nTest';
|
|
230
|
+
|
|
231
|
+
await fs.writeFile(
|
|
232
|
+
path.join(TEST_SESSION_PATH, 'outputs', 'prp.md'),
|
|
233
|
+
prpContent,
|
|
234
|
+
'utf-8'
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
const generator = new AgentsMdGenerator(TEST_SESSION_PATH, TEST_PROJECT_PATH, 'rapid');
|
|
238
|
+
const generatedPath = await generator.generate();
|
|
239
|
+
|
|
240
|
+
const content = await fs.readFile(generatedPath, 'utf-8');
|
|
241
|
+
|
|
242
|
+
expect(content).toMatch(/Generated by.*ADF CLI.*v\d+\.\d+\.\d+/);
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
});
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
const AnswerQualityAnalyzer = require('../lib/frameworks/answer-quality-analyzer');
|
|
2
|
+
|
|
3
|
+
describe('AnswerQualityAnalyzer', () => {
|
|
4
|
+
describe('analyze', () => {
|
|
5
|
+
it('should score high-quality comprehensive answer highly', () => {
|
|
6
|
+
const question = {
|
|
7
|
+
keywords: ['react', 'typescript', 'web'],
|
|
8
|
+
requiredElements: ['platform', 'technology']
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const answer = 'I am building a React 18 web dashboard using TypeScript and Node.js. ' +
|
|
12
|
+
'The platform is web-based, responsive design for desktop and mobile. ' +
|
|
13
|
+
'It will display real-time analytics data fetched from a PostgreSQL database. ' +
|
|
14
|
+
'Users can filter data by date range, export to CSV, and create custom views. ' +
|
|
15
|
+
'The tech stack includes Next.js 14 for the frontend, Express.js for the API, ' +
|
|
16
|
+
'and we will use Chart.js for data visualization. File structure will be ' +
|
|
17
|
+
'src/components/, src/api/, src/utils/. The main components are Dashboard, ' +
|
|
18
|
+
'DataTable, ChartView, and FilterPanel.';
|
|
19
|
+
|
|
20
|
+
const metrics = AnswerQualityAnalyzer.analyze(answer, question);
|
|
21
|
+
|
|
22
|
+
expect(metrics.qualityScore).toBeGreaterThan(80);
|
|
23
|
+
expect(metrics.isComprehensive).toBe(true);
|
|
24
|
+
expect(metrics.wordCount).toBeGreaterThan(50);
|
|
25
|
+
expect(metrics.hasKeywords.matched).toContain('react');
|
|
26
|
+
expect(metrics.hasKeywords.matched).toContain('typescript');
|
|
27
|
+
expect(metrics.hasRequiredElements.detected).toContain('platform');
|
|
28
|
+
expect(metrics.hasRequiredElements.detected).toContain('technology');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should score low-quality vague answer poorly', () => {
|
|
32
|
+
const question = {
|
|
33
|
+
keywords: ['react', 'typescript', 'nextjs'],
|
|
34
|
+
requiredElements: ['platform', 'technology']
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const answer = 'An app';
|
|
38
|
+
|
|
39
|
+
const metrics = AnswerQualityAnalyzer.analyze(answer, question);
|
|
40
|
+
|
|
41
|
+
expect(metrics.qualityScore).toBeLessThan(30);
|
|
42
|
+
expect(metrics.isComprehensive).toBe(false);
|
|
43
|
+
expect(metrics.wordCount).toBeLessThan(5);
|
|
44
|
+
expect(metrics.hasKeywords.matched.length).toBe(0);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('should detect bullet points and examples', () => {
|
|
48
|
+
const question = { keywords: [], requiredElements: [] };
|
|
49
|
+
|
|
50
|
+
const answer = 'The features include user authentication, dashboard, and export. ' +
|
|
51
|
+
'This allows for better security. ' +
|
|
52
|
+
'For example, users can click the export button to download CSV files.';
|
|
53
|
+
|
|
54
|
+
const metrics = AnswerQualityAnalyzer.analyze(answer, question);
|
|
55
|
+
|
|
56
|
+
expect(metrics.isDetailed.hasMultipleSentences).toBe(true);
|
|
57
|
+
expect(metrics.isDetailed.hasExamples).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should detect technical depth', () => {
|
|
61
|
+
const question = { keywords: [], requiredElements: [] };
|
|
62
|
+
|
|
63
|
+
const answer = 'Using React 18.2.0 with TypeScript. Will deploy to AWS using Docker containers. ' +
|
|
64
|
+
'Database is PostgreSQL 15. API endpoints follow REST conventions.';
|
|
65
|
+
|
|
66
|
+
const metrics = AnswerQualityAnalyzer.analyze(answer, question);
|
|
67
|
+
|
|
68
|
+
expect(metrics.hasTechnicalDepth.hasTechStack).toBe(true);
|
|
69
|
+
expect(metrics.hasTechnicalDepth.hasVersions).toBe(true);
|
|
70
|
+
expect(metrics.hasTechnicalDepth.hasSpecificTools).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should allow skipping follow-ups for excellent answers', () => {
|
|
74
|
+
const question = {
|
|
75
|
+
keywords: ['react', 'web', 'api'],
|
|
76
|
+
requiredElements: ['platform', 'technology', 'user-interaction']
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
const answer = 'Building a React web application with TypeScript and Next.js 14. ' +
|
|
80
|
+
'The platform is web-based, responsive design. Users can click buttons to submit forms, ' +
|
|
81
|
+
'search and filter data, and view real-time updates. Technology stack includes React 18, ' +
|
|
82
|
+
'TypeScript 5, Node.js 20, PostgreSQL 15, and Docker for deployment. ' +
|
|
83
|
+
'API endpoints: GET /api/users, POST /api/users, PUT /api/users/:id. ' +
|
|
84
|
+
'File structure: src/components/, src/pages/, src/api/, src/utils/. ' +
|
|
85
|
+
'Main components: UserList, UserForm, SearchBar, FilterPanel.';
|
|
86
|
+
|
|
87
|
+
const metrics = AnswerQualityAnalyzer.analyze(answer, question);
|
|
88
|
+
|
|
89
|
+
expect(metrics.canSkipFollowUps).toBe(true);
|
|
90
|
+
expect(metrics.qualityScore).toBeGreaterThanOrEqual(85);
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
describe('getFeedback', () => {
|
|
95
|
+
it('should return excellent feedback for score >= 90', () => {
|
|
96
|
+
const metrics = { qualityScore: 95 };
|
|
97
|
+
const feedback = AnswerQualityAnalyzer.getFeedback(metrics);
|
|
98
|
+
expect(feedback).toContain('Excellent');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it('should return good feedback for score >= 70', () => {
|
|
102
|
+
const metrics = { qualityScore: 75 };
|
|
103
|
+
const feedback = AnswerQualityAnalyzer.getFeedback(metrics);
|
|
104
|
+
expect(feedback).toContain('Great');
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('should return null for low scores', () => {
|
|
108
|
+
const metrics = { qualityScore: 45 };
|
|
109
|
+
const feedback = AnswerQualityAnalyzer.getFeedback(metrics);
|
|
110
|
+
expect(feedback).toBeNull();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe('getWordCount', () => {
|
|
115
|
+
it('should count words correctly', () => {
|
|
116
|
+
expect(AnswerQualityAnalyzer.getWordCount('Hello world')).toBe(2);
|
|
117
|
+
expect(AnswerQualityAnalyzer.getWordCount('This is a test sentence.')).toBe(5);
|
|
118
|
+
expect(AnswerQualityAnalyzer.getWordCount(' Multiple spaces here ')).toBe(3);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
describe('checkKeywords', () => {
|
|
123
|
+
it('should match keywords case-insensitively', () => {
|
|
124
|
+
const result = AnswerQualityAnalyzer.checkKeywords(
|
|
125
|
+
'Using React and TypeScript',
|
|
126
|
+
['react', 'typescript', 'node']
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
expect(result.matched).toContain('react');
|
|
130
|
+
expect(result.matched).toContain('typescript');
|
|
131
|
+
expect(result.count).toBe(2);
|
|
132
|
+
expect(result.total).toBe(3);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
describe('checkRequiredElements', () => {
|
|
137
|
+
it('should detect platform element', () => {
|
|
138
|
+
const result = AnswerQualityAnalyzer.checkRequiredElements(
|
|
139
|
+
'This is a web application for mobile users',
|
|
140
|
+
['platform']
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
expect(result.detected).toContain('platform');
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it('should detect technology element', () => {
|
|
147
|
+
const result = AnswerQualityAnalyzer.checkRequiredElements(
|
|
148
|
+
'Built with React and Node.js',
|
|
149
|
+
['technology']
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
expect(result.detected).toContain('technology');
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
it('should detect API endpoints', () => {
|
|
156
|
+
const result = AnswerQualityAnalyzer.checkRequiredElements(
|
|
157
|
+
'API has GET /api/users and POST /api/users endpoints',
|
|
158
|
+
['api-endpoints']
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
expect(result.detected).toContain('api-endpoints');
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it('should detect file paths', () => {
|
|
165
|
+
const result = AnswerQualityAnalyzer.checkRequiredElements(
|
|
166
|
+
'Files are in src/components/ and app/utils/helper.ts',
|
|
167
|
+
['file-paths']
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
expect(result.detected).toContain('file-paths');
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
});
|