@smartsoft001-mobilems/claude-plugins 2.85.0 → 2.86.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.
Files changed (132) hide show
  1. package/.claude-plugin/marketplace.json +2 -6
  2. package/package.json +2 -2
  3. package/plugins/mobilems/.claude-plugin/README.md +30 -0
  4. package/plugins/mobilems/.claude-plugin/plugin.json +5 -0
  5. package/plugins/mobilems/scripts/refresh-mobilems-api-spec.sh +372 -0
  6. package/plugins/mobilems/skills/mobilems-docs-reader/SKILL.md +116 -0
  7. package/plugins/flow/.claude-plugin/README.md +0 -91
  8. package/plugins/flow/.claude-plugin/merge-permissions.js +0 -97
  9. package/plugins/flow/.claude-plugin/plugin.json +0 -5
  10. package/plugins/flow/.claude-plugin/settings.template.json +0 -86
  11. package/plugins/flow/agents/angular-component-scaffolder.md +0 -175
  12. package/plugins/flow/agents/angular-directive-builder.md +0 -153
  13. package/plugins/flow/agents/angular-guard-builder.md +0 -243
  14. package/plugins/flow/agents/angular-jest-test-writer.md +0 -474
  15. package/plugins/flow/agents/angular-pipe-builder.md +0 -169
  16. package/plugins/flow/agents/angular-resolver-builder.md +0 -286
  17. package/plugins/flow/agents/angular-service-builder.md +0 -161
  18. package/plugins/flow/agents/angular-signal-state-builder.md +0 -339
  19. package/plugins/flow/agents/angular-test-diagnostician.md +0 -279
  20. package/plugins/flow/agents/angular-testbed-configurator.md +0 -315
  21. package/plugins/flow/agents/arch-scaffolder.md +0 -278
  22. package/plugins/flow/agents/e2e-data-testid-injector.md +0 -197
  23. package/plugins/flow/agents/e2e-project-scaffolder.md +0 -194
  24. package/plugins/flow/agents/e2e-test-writer.md +0 -350
  25. package/plugins/flow/agents/shared-agent-evolver.md +0 -294
  26. package/plugins/flow/agents/shared-build-verifier.md +0 -160
  27. package/plugins/flow/agents/shared-config-updater.md +0 -310
  28. package/plugins/flow/agents/shared-coverage-enforcer.md +0 -184
  29. package/plugins/flow/agents/shared-error-handler.md +0 -217
  30. package/plugins/flow/agents/shared-file-creator.md +0 -344
  31. package/plugins/flow/agents/shared-impl-orchestrator.md +0 -312
  32. package/plugins/flow/agents/shared-impl-reporter.md +0 -368
  33. package/plugins/flow/agents/shared-impl-teammate.md +0 -201
  34. package/plugins/flow/agents/shared-linear-subtask-iterator.md +0 -337
  35. package/plugins/flow/agents/shared-logic-implementer.md +0 -243
  36. package/plugins/flow/agents/shared-maia-api.md +0 -26
  37. package/plugins/flow/agents/shared-parallelization-analyzer.md +0 -343
  38. package/plugins/flow/agents/shared-performance-validator.md +0 -168
  39. package/plugins/flow/agents/shared-plan-perspective.md +0 -269
  40. package/plugins/flow/agents/shared-project-standardizer.md +0 -205
  41. package/plugins/flow/agents/shared-report-synthesizer.md +0 -188
  42. package/plugins/flow/agents/shared-review-teammate.md +0 -189
  43. package/plugins/flow/agents/shared-security-scanner.md +0 -186
  44. package/plugins/flow/agents/shared-style-enforcer.md +0 -230
  45. package/plugins/flow/agents/shared-subtask-dependency-analyzer.md +0 -188
  46. package/plugins/flow/agents/shared-tdd-developer.md +0 -350
  47. package/plugins/flow/agents/shared-team-coordinator.md +0 -189
  48. package/plugins/flow/agents/shared-test-fixer.md +0 -186
  49. package/plugins/flow/agents/shared-test-runner.md +0 -191
  50. package/plugins/flow/agents/shared-ui-classifier.md +0 -263
  51. package/plugins/flow/agents/shared-verification-orchestrator.md +0 -194
  52. package/plugins/flow/agents/shared-verification-runner.md +0 -140
  53. package/plugins/flow/agents/ui-a11y-validator.md +0 -305
  54. package/plugins/flow/agents/ui-screenshot-reporter.md +0 -329
  55. package/plugins/flow/agents/ui-web-designer.md +0 -214
  56. package/plugins/flow/scripts/compute-session-tokens.sh +0 -39
  57. package/plugins/flow/skills/a11y-audit/SKILL.md +0 -214
  58. package/plugins/flow/skills/angular-patterns/SKILL.md +0 -191
  59. package/plugins/flow/skills/browser-capture/SKILL.md +0 -238
  60. package/plugins/flow/skills/commit/SKILL.md +0 -259
  61. package/plugins/flow/skills/debug-helper/SKILL.md +0 -375
  62. package/plugins/flow/skills/impl/SKILL.md +0 -992
  63. package/plugins/flow/skills/linear-suggestion/SKILL.md +0 -132
  64. package/plugins/flow/skills/maia-files-delete/SKILL.md +0 -59
  65. package/plugins/flow/skills/maia-files-upload/SKILL.md +0 -57
  66. package/plugins/flow/skills/nx-conventions/SKILL.md +0 -326
  67. package/plugins/flow/skills/plan/SKILL.md +0 -1033
  68. package/plugins/flow/skills/push/SKILL.md +0 -759
  69. package/plugins/flow/skills/review/SKILL.md +0 -443
  70. package/plugins/flow/skills/test-e2e/SKILL.md +0 -161
  71. package/plugins/flow/skills/test-unit/SKILL.md +0 -456
  72. package/plugins/flow-external/.claude-plugin/README.md +0 -152
  73. package/plugins/flow-external/.claude-plugin/merge-permissions.js +0 -80
  74. package/plugins/flow-external/.claude-plugin/plugin.json +0 -5
  75. package/plugins/flow-external/.claude-plugin/settings.template.json +0 -78
  76. package/plugins/flow-external/agents/angular-component-scaffolder.md +0 -269
  77. package/plugins/flow-external/agents/angular-directive-builder.md +0 -130
  78. package/plugins/flow-external/agents/angular-guard-builder.md +0 -70
  79. package/plugins/flow-external/agents/angular-pipe-builder.md +0 -82
  80. package/plugins/flow-external/agents/angular-resolver-builder.md +0 -74
  81. package/plugins/flow-external/agents/angular-service-builder.md +0 -160
  82. package/plugins/flow-external/agents/angular-state-builder.md +0 -254
  83. package/plugins/flow-external/agents/shared-build-verifier.md +0 -67
  84. package/plugins/flow-external/agents/shared-impl-orchestrator.md +0 -88
  85. package/plugins/flow-external/agents/shared-impl-reporter.md +0 -135
  86. package/plugins/flow-external/agents/shared-linear-subtask-iterator.md +0 -70
  87. package/plugins/flow-external/agents/shared-ui-classifier.md +0 -38
  88. package/plugins/flow-external/agents/ui-web-designer.md +0 -179
  89. package/plugins/flow-external/scripts/compute-session-tokens.sh +0 -39
  90. package/plugins/flow-external/skills/a11y-audit/SKILL.md +0 -96
  91. package/plugins/flow-external/skills/angular-cli-conventions/SKILL.md +0 -267
  92. package/plugins/flow-external/skills/angular-patterns/SKILL.md +0 -170
  93. package/plugins/flow-external/skills/browser-capture/SKILL.md +0 -68
  94. package/plugins/flow-external/skills/commit/SKILL.md +0 -114
  95. package/plugins/flow-external/skills/debug-helper/SKILL.md +0 -131
  96. package/plugins/flow-external/skills/impl/SKILL.md +0 -217
  97. package/plugins/flow-external/skills/linear-suggestion/SKILL.md +0 -62
  98. package/plugins/flow-external/skills/maia-files-delete/SKILL.md +0 -34
  99. package/plugins/flow-external/skills/maia-files-upload/SKILL.md +0 -41
  100. package/plugins/flow-external/skills/plan/SKILL.md +0 -334
  101. package/plugins/flow-external/skills/push/SKILL.md +0 -232
  102. package/plugins/flow-legacy/.claude-plugin/README.md +0 -143
  103. package/plugins/flow-legacy/.claude-plugin/merge-permissions.js +0 -94
  104. package/plugins/flow-legacy/.claude-plugin/plugin.json +0 -5
  105. package/plugins/flow-legacy/.claude-plugin/settings.template.json +0 -79
  106. package/plugins/flow-legacy/agents/angular-component-scaffolder.md +0 -323
  107. package/plugins/flow-legacy/agents/angular-directive-builder.md +0 -258
  108. package/plugins/flow-legacy/agents/angular-guard-builder.md +0 -322
  109. package/plugins/flow-legacy/agents/angular-pipe-builder.md +0 -227
  110. package/plugins/flow-legacy/agents/angular-resolver-builder.md +0 -332
  111. package/plugins/flow-legacy/agents/angular-service-builder.md +0 -271
  112. package/plugins/flow-legacy/agents/angular-state-builder.md +0 -479
  113. package/plugins/flow-legacy/agents/shared-impl-orchestrator.md +0 -174
  114. package/plugins/flow-legacy/agents/shared-impl-reporter.md +0 -232
  115. package/plugins/flow-legacy/agents/shared-linear-subtask-iterator.md +0 -187
  116. package/plugins/flow-legacy/agents/shared-tdd-developer.md +0 -306
  117. package/plugins/flow-legacy/agents/shared-test-runner.md +0 -131
  118. package/plugins/flow-legacy/agents/shared-ui-classifier.md +0 -145
  119. package/plugins/flow-legacy/scripts/compute-session-tokens.sh +0 -39
  120. package/plugins/flow-legacy/skills/a11y-audit/SKILL.md +0 -214
  121. package/plugins/flow-legacy/skills/angular-patterns/SKILL.md +0 -346
  122. package/plugins/flow-legacy/skills/browser-capture/SKILL.md +0 -238
  123. package/plugins/flow-legacy/skills/commit/SKILL.md +0 -215
  124. package/plugins/flow-legacy/skills/debug-helper/SKILL.md +0 -395
  125. package/plugins/flow-legacy/skills/impl/SKILL.md +0 -710
  126. package/plugins/flow-legacy/skills/linear-suggestion/SKILL.md +0 -132
  127. package/plugins/flow-legacy/skills/maia-files-delete/SKILL.md +0 -59
  128. package/plugins/flow-legacy/skills/maia-files-upload/SKILL.md +0 -57
  129. package/plugins/flow-legacy/skills/nx-conventions/SKILL.md +0 -368
  130. package/plugins/flow-legacy/skills/plan/SKILL.md +0 -742
  131. package/plugins/flow-legacy/skills/push/SKILL.md +0 -645
  132. package/plugins/flow-legacy/skills/test-unit/SKILL.md +0 -500
@@ -1,500 +0,0 @@
1
- ---
2
- name: test-unit
3
- description: Write unit tests following project conventions for Angular 14 legacy projects. Generates Jest tests for components, services, and NestJS using AAA pattern.
4
- allowed-tools:
5
- - Bash
6
- - Read
7
- - Write
8
- - Edit
9
- - Glob
10
- - Grep
11
- ---
12
-
13
- # Unit Test Skill (Angular 14 Legacy)
14
-
15
- Write unit tests following project conventions using Jest framework with AAA (Arrange-Act-Assert) pattern for Angular 14 legacy projects.
16
-
17
- ## Testing Framework
18
-
19
- - **Framework**: Jest for all unit tests
20
- - **File naming**: `{name}.spec.ts` alongside source files
21
- - **Test runner**: Nx 14 (`nx test {project}`)
22
-
23
- ## Test File Location
24
-
25
- Place test files next to the source files they test:
26
-
27
- ```
28
- feature/
29
- ├── feature.service.ts
30
- ├── feature.service.spec.ts
31
- ├── feature.component.ts
32
- └── feature.component.spec.ts
33
- ```
34
-
35
- ## Naming Convention
36
-
37
- - **Describe blocks**: `@{package-name}: ClassName`
38
- - **Test format**: `it('should...')` with clear behavior description
39
-
40
- ## Test Structure (AAA Pattern)
41
-
42
- Always use Arrange-Act-Assert pattern with blank line separation (no comments):
43
-
44
- ```typescript
45
- it('should perform expected operation', () => {
46
- const input = 'test';
47
-
48
- const result = service.performOperation(input);
49
-
50
- expect(result).toBe('expected output');
51
- });
52
- ```
53
-
54
- ## Angular 14 Component Testing
55
-
56
- ### Basic Component Test (NgModule-based)
57
-
58
- ```typescript
59
- import { ComponentFixture, TestBed } from '@angular/core/testing';
60
- import { NO_ERRORS_SCHEMA } from '@angular/core';
61
-
62
- import { FeatureComponent } from './feature.component';
63
-
64
- describe('@mms/shared-angular: FeatureComponent', () => {
65
- let component: FeatureComponent;
66
- let fixture: ComponentFixture<FeatureComponent>;
67
-
68
- beforeEach(async () => {
69
- await TestBed.configureTestingModule({
70
- declarations: [FeatureComponent], // NOT imports (not standalone)
71
- schemas: [NO_ERRORS_SCHEMA],
72
- }).compileComponents();
73
-
74
- fixture = TestBed.createComponent(FeatureComponent);
75
- component = fixture.componentInstance;
76
- fixture.detectChanges();
77
- });
78
-
79
- it('should create', () => {
80
- expect(component).toBeTruthy();
81
- });
82
-
83
- it('should display expected content', () => {
84
- component.title = 'Test Title';
85
- fixture.detectChanges();
86
-
87
- const compiled = fixture.nativeElement;
88
- expect(compiled.querySelector('h1')?.textContent).toContain('Test Title');
89
- });
90
- });
91
- ```
92
-
93
- ### Testing Components with @Input/@Output
94
-
95
- ```typescript
96
- import { ComponentFixture, TestBed } from '@angular/core/testing';
97
- import { NO_ERRORS_SCHEMA } from '@angular/core';
98
-
99
- import { FormFieldComponent } from './form-field.component';
100
-
101
- describe('@mms/shared-angular: FormFieldComponent', () => {
102
- let component: FormFieldComponent;
103
- let fixture: ComponentFixture<FormFieldComponent>;
104
-
105
- beforeEach(async () => {
106
- await TestBed.configureTestingModule({
107
- declarations: [FormFieldComponent],
108
- schemas: [NO_ERRORS_SCHEMA],
109
- }).compileComponents();
110
-
111
- fixture = TestBed.createComponent(FormFieldComponent);
112
- component = fixture.componentInstance;
113
- });
114
-
115
- it('should accept input value', () => {
116
- component.label = 'Test Label';
117
- fixture.detectChanges();
118
-
119
- expect(component.label).toBe('Test Label');
120
- });
121
-
122
- it('should emit output event', () => {
123
- const spy = jest.fn();
124
- component.changed.subscribe(spy);
125
-
126
- component.onValueChange('new value');
127
-
128
- expect(spy).toHaveBeenCalledWith('new value');
129
- });
130
-
131
- it('should support two-way binding', () => {
132
- const valueChangeSpy = jest.fn();
133
- component.valueChange.subscribe(valueChangeSpy);
134
-
135
- component.value = 'initial';
136
- component.onInputChange('updated');
137
-
138
- expect(valueChangeSpy).toHaveBeenCalledWith('updated');
139
- });
140
- });
141
- ```
142
-
143
- ### Testing with BehaviorSubject State
144
-
145
- ```typescript
146
- import {
147
- ComponentFixture,
148
- TestBed,
149
- fakeAsync,
150
- tick,
151
- } from '@angular/core/testing';
152
- import { of, BehaviorSubject } from 'rxjs';
153
-
154
- import { ListComponent } from './list.component';
155
- import { StateService } from './state.service';
156
-
157
- describe('@mms/shared-angular: ListComponent', () => {
158
- let component: ListComponent;
159
- let fixture: ComponentFixture<ListComponent>;
160
- let mockStateService: {
161
- items$: BehaviorSubject<Item[]>;
162
- isLoading$: BehaviorSubject<boolean>;
163
- };
164
-
165
- beforeEach(async () => {
166
- mockStateService = {
167
- items$: new BehaviorSubject<Item[]>([]),
168
- isLoading$: new BehaviorSubject<boolean>(false),
169
- };
170
-
171
- await TestBed.configureTestingModule({
172
- declarations: [ListComponent],
173
- providers: [{ provide: StateService, useValue: mockStateService }],
174
- }).compileComponents();
175
-
176
- fixture = TestBed.createComponent(ListComponent);
177
- component = fixture.componentInstance;
178
- fixture.detectChanges();
179
- });
180
-
181
- it('should display items from state', () => {
182
- mockStateService.items$.next([
183
- { id: '1', name: 'Item 1' },
184
- { id: '2', name: 'Item 2' },
185
- ]);
186
- fixture.detectChanges();
187
-
188
- const items = fixture.nativeElement.querySelectorAll('li');
189
- expect(items.length).toBe(2);
190
- });
191
-
192
- it('should show loading spinner', () => {
193
- mockStateService.isLoading$.next(true);
194
- fixture.detectChanges();
195
-
196
- const spinner = fixture.nativeElement.querySelector('app-spinner');
197
- expect(spinner).toBeTruthy();
198
- });
199
- });
200
- ```
201
-
202
- ### Testing with Services (Constructor DI)
203
-
204
- ```typescript
205
- import { ComponentFixture, TestBed } from '@angular/core/testing';
206
- import { of } from 'rxjs';
207
-
208
- import { FeatureComponent } from './feature.component';
209
- import { DataService } from './data.service';
210
-
211
- describe('@mms/shared-angular: FeatureComponent', () => {
212
- let component: FeatureComponent;
213
- let fixture: ComponentFixture<FeatureComponent>;
214
- let mockDataService: jest.Mocked<DataService>;
215
-
216
- beforeEach(async () => {
217
- mockDataService = {
218
- getData: jest.fn().mockReturnValue(of(['item1', 'item2'])),
219
- saveData: jest.fn().mockReturnValue(of(true)),
220
- } as unknown as jest.Mocked<DataService>;
221
-
222
- await TestBed.configureTestingModule({
223
- declarations: [FeatureComponent],
224
- providers: [{ provide: DataService, useValue: mockDataService }],
225
- }).compileComponents();
226
-
227
- fixture = TestBed.createComponent(FeatureComponent);
228
- component = fixture.componentInstance;
229
- fixture.detectChanges();
230
- });
231
-
232
- it('should load data on init', () => {
233
- expect(mockDataService.getData).toHaveBeenCalled();
234
- expect(component.items).toEqual(['item1', 'item2']);
235
- });
236
- });
237
- ```
238
-
239
- ## Angular 14 Service Testing
240
-
241
- ### Service with BehaviorSubject
242
-
243
- ```typescript
244
- import { TestBed } from '@angular/core/testing';
245
- import { take } from 'rxjs/operators';
246
-
247
- import { StateService } from './state.service';
248
-
249
- describe('@mms/shared-angular: StateService', () => {
250
- let service: StateService;
251
-
252
- beforeEach(() => {
253
- TestBed.configureTestingModule({
254
- providers: [StateService],
255
- });
256
- service = TestBed.inject(StateService);
257
- });
258
-
259
- it('should be created', () => {
260
- expect(service).toBeTruthy();
261
- });
262
-
263
- it('should emit initial state', (done) => {
264
- service.items$.pipe(take(1)).subscribe((items) => {
265
- expect(items).toEqual([]);
266
- done();
267
- });
268
- });
269
-
270
- it('should update items', (done) => {
271
- const newItems = [{ id: '1', name: 'Test' }];
272
-
273
- service.setItems(newItems);
274
-
275
- service.items$.pipe(take(1)).subscribe((items) => {
276
- expect(items).toEqual(newItems);
277
- done();
278
- });
279
- });
280
-
281
- it('should return current value', () => {
282
- const items = [{ id: '1', name: 'Test' }];
283
- service.setItems(items);
284
-
285
- expect(service.currentItems).toEqual(items);
286
- });
287
- });
288
- ```
289
-
290
- ### Service with HTTP (Angular 14 HttpClientTestingModule)
291
-
292
- ```typescript
293
- import { TestBed } from '@angular/core/testing';
294
- import {
295
- HttpClientTestingModule,
296
- HttpTestingController,
297
- } from '@angular/common/http/testing';
298
-
299
- import { DataService } from './data.service';
300
-
301
- describe('@mms/shared-angular: DataService', () => {
302
- let service: DataService;
303
- let httpMock: HttpTestingController;
304
-
305
- beforeEach(() => {
306
- TestBed.configureTestingModule({
307
- imports: [HttpClientTestingModule],
308
- providers: [DataService],
309
- });
310
-
311
- service = TestBed.inject(DataService);
312
- httpMock = TestBed.inject(HttpTestingController);
313
- });
314
-
315
- afterEach(() => {
316
- httpMock.verify();
317
- });
318
-
319
- it('should be created', () => {
320
- expect(service).toBeTruthy();
321
- });
322
-
323
- it('should fetch data', () => {
324
- const mockData = [{ id: 1, name: 'Test' }];
325
-
326
- service.getData().subscribe((data) => {
327
- expect(data).toEqual(mockData);
328
- });
329
-
330
- const req = httpMock.expectOne('/api/data');
331
- expect(req.request.method).toBe('GET');
332
- req.flush(mockData);
333
- });
334
- });
335
- ```
336
-
337
- ## NestJS Service Testing
338
-
339
- ### Basic Service Test
340
-
341
- ```typescript
342
- import { TestingModule, Test } from '@nestjs/testing';
343
-
344
- import { FeatureService } from './feature.service';
345
-
346
- describe('@mms/module-name: FeatureService', () => {
347
- let service: FeatureService;
348
- let module: TestingModule;
349
-
350
- beforeEach(async () => {
351
- module = await Test.createTestingModule({
352
- providers: [FeatureService],
353
- }).compile();
354
-
355
- service = module.get<FeatureService>(FeatureService);
356
- });
357
-
358
- afterEach(async () => {
359
- await module.close();
360
- });
361
-
362
- it('should be defined', () => {
363
- expect(service).toBeDefined();
364
- });
365
-
366
- it('should perform expected operation', () => {
367
- const input = 'test';
368
-
369
- const result = service.performOperation(input);
370
-
371
- expect(result).toBe('expected output');
372
- });
373
- });
374
- ```
375
-
376
- ## Mocking Patterns
377
-
378
- ### Service Mock
379
-
380
- ```typescript
381
- const mockService = {
382
- getData: jest.fn().mockReturnValue(of(mockData)),
383
- createItem: jest.fn().mockReturnValue(of(mockItem)),
384
- updateItem: jest.fn().mockReturnValue(of(updatedMockItem)),
385
- };
386
- ```
387
-
388
- ### LocalStorage Mock
389
-
390
- ```typescript
391
- let localStorageMock: any;
392
-
393
- beforeEach(() => {
394
- localStorageMock = (() => {
395
- let store: Record<string, string> = {};
396
- return {
397
- getItem: jest.fn((key: string) => store[key] || null),
398
- setItem: jest.fn((key: string, value: string) => {
399
- store[key] = value;
400
- }),
401
- removeItem: jest.fn((key: string) => {
402
- delete store[key];
403
- }),
404
- clear: jest.fn(() => {
405
- store = {};
406
- }),
407
- };
408
- })();
409
- Object.defineProperty(window, 'localStorage', { value: localStorageMock });
410
- });
411
- ```
412
-
413
- ### Router Mock
414
-
415
- ```typescript
416
- const mockRouter = {
417
- navigate: jest.fn(),
418
- navigateByUrl: jest.fn(),
419
- createUrlTree: jest.fn(),
420
- };
421
-
422
- // In providers
423
- { provide: Router, useValue: mockRouter }
424
- ```
425
-
426
- ### ActivatedRoute Mock
427
-
428
- ```typescript
429
- const mockActivatedRoute = {
430
- params: of({ id: '123' }),
431
- queryParams: of({ filter: 'active' }),
432
- snapshot: {
433
- params: { id: '123' },
434
- queryParams: { filter: 'active' },
435
- },
436
- };
437
-
438
- // In providers
439
- { provide: ActivatedRoute, useValue: mockActivatedRoute }
440
- ```
441
-
442
- ## Test Commands (Nx 14)
443
-
444
- ```bash
445
- # Run tests for specific project
446
- nx test web
447
- nx test shared-angular
448
-
449
- # Run tests in watch mode
450
- nx test web --watch
451
-
452
- # Run tests with coverage
453
- nx test web --coverage
454
-
455
- # Run all tests
456
- nx run-many --target=test
457
-
458
- # Run specific test file
459
- nx test shared-angular --testFile=feature.service.spec.ts
460
- ```
461
-
462
- ## What to Test
463
-
464
- - Business logic in services
465
- - Component behavior and state changes
466
- - Public API contracts (@Input/@Output)
467
- - BehaviorSubject state management
468
- - Error handling scenarios
469
- - Input validation
470
- - Edge cases and boundary conditions
471
-
472
- ## What NOT to Test
473
-
474
- - Third-party libraries
475
- - Framework internals (Angular/NestJS)
476
- - Simple getters/setters without logic
477
- - Auto-generated code
478
- - Private methods directly (test through public API)
479
-
480
- ## Workflow
481
-
482
- 1. **Read source file** to understand the code being tested
483
- 2. **Create test file** with `.spec.ts` extension next to source
484
- 3. **Write describe block** with package and class name
485
- 4. **Add beforeEach** with TestBed setup (declarations, not imports)
486
- 5. **Write tests** using AAA pattern
487
- 6. **Run tests** with `nx test {project}`
488
- 7. **Fix failures** and ensure all pass
489
-
490
- ## Best Practices (Angular 14)
491
-
492
- 1. **One assertion per test** when practical
493
- 2. **Descriptive test names** that explain behavior
494
- 3. **Independent tests** - no shared state between tests
495
- 4. **Mock external dependencies** - isolate unit under test
496
- 5. **Test edge cases** - empty arrays, null values, boundaries
497
- 6. **Keep tests fast** - avoid real HTTP calls or timers
498
- 7. **Clean up** - use afterEach for cleanup when needed
499
- 8. **Use declarations** - components are NOT standalone in Angular 14
500
- 9. **Mock BehaviorSubjects** - not signals (no signals in Angular 14)