cursor-quality-suite 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 +155 -0
- package/bin/cli.js +303 -0
- package/commands/code-quality/churn-map.md +431 -0
- package/commands/code-quality/code-standards.md +219 -0
- package/commands/code-quality/pattern-drift.md +295 -0
- package/commands/code-quality/visualize-architecture.md +464 -0
- package/commands/testing/mutation-audit.md +229 -0
- package/commands/testing/risk-test-gen.md +232 -0
- package/commands/testing/write-unit-tests.md +42 -0
- package/package.json +36 -0
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Generate integration/contract tests for high-risk code paths
|
|
3
|
+
category: Testing
|
|
4
|
+
aliases: [gen-tests, risk-tests, test-risky]
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Risk Test Gen - Generate Tests for High-Risk Paths
|
|
8
|
+
|
|
9
|
+
Analyze code risk and generate deep integration/contract tests for critical paths.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
/risk-test-gen {FILE_PATH}
|
|
15
|
+
/risk-test-gen {PR_NUMBER}
|
|
16
|
+
/risk-test-gen --domain payments # Focus on domain
|
|
17
|
+
/risk-test-gen --coverage-gap # Find untested high-risk paths
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## What This Does
|
|
21
|
+
|
|
22
|
+
1. **Identifies high-risk paths** - Payments, auth, data mutations
|
|
23
|
+
2. **Analyzes existing coverage** - Finds gaps in critical areas
|
|
24
|
+
3. **Generates deep tests** - Integration, contract, edge cases
|
|
25
|
+
4. **Prioritizes by impact** - Business-critical first
|
|
26
|
+
|
|
27
|
+
## Risk Classification
|
|
28
|
+
|
|
29
|
+
| Risk Level | Domains | Test Depth |
|
|
30
|
+
| ----------- | ---------------------------- | ---------------------- |
|
|
31
|
+
| π΄ Critical | Payments, Auth, PII | Integration + Contract |
|
|
32
|
+
| π High | Booking mutations, API calls | Integration |
|
|
33
|
+
| π‘ Medium | State management, Forms | Unit + Edge cases |
|
|
34
|
+
| π’ Low | UI rendering, Styling | Snapshot only |
|
|
35
|
+
|
|
36
|
+
## Risk Detection Patterns
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// π΄ CRITICAL - Payment processing
|
|
40
|
+
const processPayment = async (paymentData: IPaymentData) => { ... }
|
|
41
|
+
|
|
42
|
+
// π΄ CRITICAL - Authentication
|
|
43
|
+
const validateToken = (token: string) => { ... }
|
|
44
|
+
|
|
45
|
+
// π΄ CRITICAL - PII handling
|
|
46
|
+
const updateUserProfile = (userData: IUserData) => { ... }
|
|
47
|
+
|
|
48
|
+
// π HIGH - Booking mutations
|
|
49
|
+
const createBooking = async (bookingData: IBooking) => { ... }
|
|
50
|
+
|
|
51
|
+
// π HIGH - External API calls
|
|
52
|
+
const fetchFromBackend = async (endpoint: string) => { ... }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Output Format
|
|
56
|
+
|
|
57
|
+
````
|
|
58
|
+
π Analyzing risk and generating tests for PackagesV2.tsx...
|
|
59
|
+
|
|
60
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
61
|
+
RISK ANALYSIS
|
|
62
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
63
|
+
|
|
64
|
+
## File: src/features/checkout/src/components/CoverageAndAddOns/PackagesV2.tsx
|
|
65
|
+
|
|
66
|
+
### Detected Risk Areas
|
|
67
|
+
|
|
68
|
+
| Line | Risk | Type | Coverage |
|
|
69
|
+
|------|------|------|----------|
|
|
70
|
+
| 45 | π HIGH | API call (useBookingWithFlow) | β Untested |
|
|
71
|
+
| 78 | π HIGH | State mutation (onPackageSelect) | β
Partial |
|
|
72
|
+
| 112 | π‘ MEDIUM | Price calculation | β Untested |
|
|
73
|
+
| 156 | π΄ CRITICAL | Booking modification | β Untested |
|
|
74
|
+
|
|
75
|
+
### Current Coverage
|
|
76
|
+
- Lines: 45%
|
|
77
|
+
- Branches: 32%
|
|
78
|
+
- High-risk paths: 20% β οΈ
|
|
79
|
+
|
|
80
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
81
|
+
GENERATED TESTS
|
|
82
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
83
|
+
|
|
84
|
+
## 1. Integration Test: Booking Modification (CRITICAL)
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
describe('PackagesV2 - Booking Modification', () => {
|
|
88
|
+
const mockBooking = createMockBooking({
|
|
89
|
+
packages: [{ id: 'pkg-1', name: 'Basic' }]
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('should update booking when package is selected', async () => {
|
|
93
|
+
const onPackageSelect = jest.fn();
|
|
94
|
+
|
|
95
|
+
render(
|
|
96
|
+
<BookingProvider booking={mockBooking}>
|
|
97
|
+
<PackagesV2 onPackageSelect={onPackageSelect} />
|
|
98
|
+
</BookingProvider>
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
await userEvent.click(screen.getByTestId('package-premium'));
|
|
102
|
+
|
|
103
|
+
expect(onPackageSelect).toHaveBeenCalledWith(
|
|
104
|
+
expect.objectContaining({
|
|
105
|
+
id: 'pkg-premium',
|
|
106
|
+
price: expect.any(Number)
|
|
107
|
+
})
|
|
108
|
+
);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should handle API failure gracefully', async () => {
|
|
112
|
+
server.use(
|
|
113
|
+
rest.post('/api/booking/update', (req, res, ctx) =>
|
|
114
|
+
res(ctx.status(500))
|
|
115
|
+
)
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
render(<PackagesV2 booking={mockBooking} />);
|
|
119
|
+
await userEvent.click(screen.getByTestId('package-premium'));
|
|
120
|
+
|
|
121
|
+
expect(screen.getByText(/error/i)).toBeInTheDocument();
|
|
122
|
+
expect(mockBooking.packages).toEqual([{ id: 'pkg-1' }]); // Unchanged
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should prevent double-submission', async () => {
|
|
126
|
+
const onPackageSelect = jest.fn();
|
|
127
|
+
|
|
128
|
+
render(<PackagesV2 onPackageSelect={onPackageSelect} />);
|
|
129
|
+
|
|
130
|
+
// Rapid clicks
|
|
131
|
+
await userEvent.click(screen.getByTestId('package-premium'));
|
|
132
|
+
await userEvent.click(screen.getByTestId('package-premium'));
|
|
133
|
+
|
|
134
|
+
expect(onPackageSelect).toHaveBeenCalledTimes(1);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
````
|
|
138
|
+
|
|
139
|
+
## 2. Contract Test: API Response Shape
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
describe('PackagesV2 - API Contract', () => {
|
|
143
|
+
it('should handle expected API response shape', async () => {
|
|
144
|
+
const response = await api.getPackages(bookingId);
|
|
145
|
+
|
|
146
|
+
expect(response).toMatchObject({
|
|
147
|
+
packages: expect.arrayContaining([
|
|
148
|
+
expect.objectContaining({
|
|
149
|
+
id: expect.any(String),
|
|
150
|
+
name: expect.any(String),
|
|
151
|
+
price: expect.any(Number),
|
|
152
|
+
display_name: expect.any(String).optional(),
|
|
153
|
+
line_items: expect.arrayContaining([
|
|
154
|
+
expect.objectContaining({
|
|
155
|
+
ref_id: expect.any(String),
|
|
156
|
+
name: expect.any(String),
|
|
157
|
+
display_category: expect.stringMatching(/included|excluded/)
|
|
158
|
+
})
|
|
159
|
+
])
|
|
160
|
+
})
|
|
161
|
+
])
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
it('should handle missing optional fields', async () => {
|
|
166
|
+
server.use(
|
|
167
|
+
rest.get('/api/packages', (req, res, ctx) =>
|
|
168
|
+
res(ctx.json({
|
|
169
|
+
packages: [{ id: 'pkg-1', name: 'Basic', price: 0 }]
|
|
170
|
+
// display_name intentionally missing
|
|
171
|
+
}))
|
|
172
|
+
)
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
render(<PackagesV2 />);
|
|
176
|
+
|
|
177
|
+
// Should not crash, should use fallback
|
|
178
|
+
expect(screen.getByText('Basic')).toBeInTheDocument();
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## 3. Edge Case Tests: Price Calculation
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
describe('PackagesV2 - Price Calculations', () => {
|
|
187
|
+
it.each([
|
|
188
|
+
[0, 'β¬0.00'],
|
|
189
|
+
[9.99, 'β¬9.99'],
|
|
190
|
+
[100.5, 'β¬100.50'],
|
|
191
|
+
[-10, 'β¬0.00'], // Negative should show 0
|
|
192
|
+
[undefined, 'β¬0.00'], // Missing should show 0
|
|
193
|
+
])('should format price %s as %s', (input, expected) => {
|
|
194
|
+
render(<PackagesV2 packages={[{ price: input }]} />);
|
|
195
|
+
expect(screen.getByTestId('package-price')).toHaveTextContent(expected);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('should handle currency conversion', async () => {
|
|
199
|
+
const booking = createMockBooking({ currency: 'USD' });
|
|
200
|
+
render(<PackagesV2 booking={booking} />);
|
|
201
|
+
|
|
202
|
+
expect(screen.getByTestId('package-price')).toHaveTextContent('$');
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
208
|
+
SUMMARY
|
|
209
|
+
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
210
|
+
|
|
211
|
+
Generated: 3 test suites, 8 test cases
|
|
212
|
+
Coverage improvement: +35% on high-risk paths
|
|
213
|
+
Priority: π΄ Critical paths now covered
|
|
214
|
+
|
|
215
|
+
Files created:
|
|
216
|
+
|
|
217
|
+
- PackagesV2.integration.test.tsx
|
|
218
|
+
- PackagesV2.contract.test.tsx
|
|
219
|
+
- PackagesV2.edge.test.tsx
|
|
220
|
+
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## AI Execution
|
|
224
|
+
|
|
225
|
+
When user runs `/risk-test-gen {PATH}`:
|
|
226
|
+
|
|
227
|
+
1. **Analyze file/PR** - Parse code for risk patterns
|
|
228
|
+
2. **Classify risk levels** - Map to business domains
|
|
229
|
+
3. **Check existing coverage** - Find gaps
|
|
230
|
+
4. **Generate tests** - Deep integration for critical paths
|
|
231
|
+
5. **Create test files** - Follow project conventions
|
|
232
|
+
```
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Write Unit Tests
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Guidelines for writing comprehensive unit tests for React components, React hooks, services, utilities and so on.
|
|
6
|
+
|
|
7
|
+
## Test Categories
|
|
8
|
+
|
|
9
|
+
### React component testing
|
|
10
|
+
|
|
11
|
+
- [ ] Test all component states
|
|
12
|
+
- [ ] Test user interactions
|
|
13
|
+
- [ ] Test prop variations
|
|
14
|
+
- [ ] Test side effects
|
|
15
|
+
- [ ] Test accessibility considering `axe` helper from `core-dev-testing` library
|
|
16
|
+
- [ ] Use `testing-library` best practices
|
|
17
|
+
- [ ] Consider using snapshot testing to prevent unexpected changes to the HTML output of a given component. They should only be used when other testing methods (such as asserting elements with `testing-library`) do not cover the required use case.
|
|
18
|
+
|
|
19
|
+
### Coverage
|
|
20
|
+
|
|
21
|
+
- [ ] Critical paths are tested
|
|
22
|
+
- [ ] Edge cases are covered
|
|
23
|
+
- [ ] Error scenarios are tested
|
|
24
|
+
- [ ] Mock external dependencies, dependency injections and timers
|
|
25
|
+
- [ ] Consider advanced assertions from the preinstalled `jest-extended` library
|
|
26
|
+
|
|
27
|
+
### Quality
|
|
28
|
+
|
|
29
|
+
- [ ] Design it to be short, dead-simple, flat, and delightful to work with. One should look at a test and get the intent instantly
|
|
30
|
+
- [ ] Tests are readable and maintainable
|
|
31
|
+
- [ ] Test names describe what they test
|
|
32
|
+
- [ ] Follows project's testing patterns from `testing/patterns/general-unit-testing/README.md`
|
|
33
|
+
- [ ] No flaky tests
|
|
34
|
+
|
|
35
|
+
## Best practices
|
|
36
|
+
|
|
37
|
+
- [ ] Donβt test your mock
|
|
38
|
+
- [ ] Donβt test external libraries
|
|
39
|
+
- [ ] Avoid non-deterministic specs like `Date`, `Math.random` and so on
|
|
40
|
+
- [ ] Consider using simple factory for reusing mocks
|
|
41
|
+
- [ ] Consider placing mocks in the file \*.mock.ts with the same name as the testing modules
|
|
42
|
+
- [ ] Tests are independent from each other
|
package/package.json
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "cursor-quality-suite",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Code Quality & Testing Commands for Cursor IDE - Test Generation, Mutation Testing, Architecture",
|
|
5
|
+
"bin": {
|
|
6
|
+
"cursor-quality-suite": "./bin/cli.js",
|
|
7
|
+
"quality-suite": "./bin/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"main": "./bin/cli.js",
|
|
10
|
+
"keywords": [
|
|
11
|
+
"cursor",
|
|
12
|
+
"cursor-rules",
|
|
13
|
+
"cursor-commands",
|
|
14
|
+
"testing",
|
|
15
|
+
"code-quality",
|
|
16
|
+
"mutation-testing",
|
|
17
|
+
"architecture",
|
|
18
|
+
"dev-productivity",
|
|
19
|
+
"ai-coding"
|
|
20
|
+
],
|
|
21
|
+
"author": "Sharath Chandra",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"repository": {
|
|
24
|
+
"type": "git",
|
|
25
|
+
"url": "https://github.com/sharath317/cursor-quality-suite"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/sharath317/cursor-quality-suite#readme",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"bin/",
|
|
33
|
+
"commands/"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
|