@mytechtoday/augment-extensions 1.3.0 → 1.4.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/LICENSE +22 -22
- package/README.md +105 -6
- package/augment-extensions/domain-rules/software-architecture/README.md +143 -143
- package/augment-extensions/domain-rules/software-architecture/examples/banking-layered.md +961 -961
- package/augment-extensions/domain-rules/software-architecture/examples/ecommerce-microservices.md +990 -990
- package/augment-extensions/domain-rules/software-architecture/examples/iot-eventdriven.md +882 -882
- package/augment-extensions/domain-rules/software-architecture/examples/monolith-to-microservices-migration.md +703 -703
- package/augment-extensions/domain-rules/software-architecture/examples/serverless-imageprocessing.md +957 -957
- package/augment-extensions/domain-rules/software-architecture/examples/trading-eventdriven.md +747 -747
- package/augment-extensions/domain-rules/software-architecture/module.json +119 -119
- package/augment-extensions/domain-rules/software-architecture/rules/challenges-solutions.md +763 -763
- package/augment-extensions/domain-rules/software-architecture/rules/definitions-terminology.md +409 -409
- package/augment-extensions/domain-rules/software-architecture/rules/design-principles.md +684 -684
- package/augment-extensions/domain-rules/software-architecture/rules/evaluation-testing.md +1381 -1381
- package/augment-extensions/domain-rules/software-architecture/rules/event-driven-architecture.md +616 -616
- package/augment-extensions/domain-rules/software-architecture/rules/fundamentals.md +306 -306
- package/augment-extensions/domain-rules/software-architecture/rules/industry-architectures.md +554 -554
- package/augment-extensions/domain-rules/software-architecture/rules/layered-architecture.md +776 -776
- package/augment-extensions/domain-rules/software-architecture/rules/microservices-architecture.md +503 -503
- package/augment-extensions/domain-rules/software-architecture/rules/modeling-documentation.md +1199 -1199
- package/augment-extensions/domain-rules/software-architecture/rules/monolithic-architecture.md +351 -351
- package/augment-extensions/domain-rules/software-architecture/rules/principles.md +556 -556
- package/augment-extensions/domain-rules/software-architecture/rules/quality-attributes.md +797 -797
- package/augment-extensions/domain-rules/software-architecture/rules/scalability-performance.md +1345 -1345
- package/augment-extensions/domain-rules/software-architecture/rules/security-architecture.md +1039 -1039
- package/augment-extensions/domain-rules/software-architecture/rules/serverless-architecture.md +711 -711
- package/augment-extensions/domain-rules/software-architecture/rules/skills-development.md +568 -568
- package/augment-extensions/domain-rules/software-architecture/rules/tools-methodologies.md +961 -961
- package/augment-extensions/visual-design/CHANGELOG.md +132 -132
- package/augment-extensions/visual-design/README.md +255 -255
- package/augment-extensions/visual-design/__tests__/README.md +119 -119
- package/augment-extensions/visual-design/__tests__/style-selector.test.ts +172 -172
- package/augment-extensions/visual-design/__tests__/vendor-styles.test.ts +214 -214
- package/augment-extensions/visual-design/domains/other/ai-prompt-helper.ts +157 -157
- package/augment-extensions/visual-design/domains/other/dotnet-application.ts +156 -156
- package/augment-extensions/visual-design/domains/other/linux-platform.ts +156 -156
- package/augment-extensions/visual-design/domains/other/mobile-application.ts +157 -157
- package/augment-extensions/visual-design/domains/other/motion-picture.ts +156 -156
- package/augment-extensions/visual-design/domains/other/os-application.ts +156 -156
- package/augment-extensions/visual-design/domains/other/print-campaigns.ts +158 -158
- package/augment-extensions/visual-design/domains/other/web-app.ts +157 -157
- package/augment-extensions/visual-design/domains/other/website.ts +161 -161
- package/augment-extensions/visual-design/domains/other/windows-platform.ts +156 -156
- package/augment-extensions/visual-design/domains/web-page-styles/amazon-cloudscape.ts +506 -506
- package/augment-extensions/visual-design/domains/web-page-styles/google-modern.ts +615 -615
- package/augment-extensions/visual-design/domains/web-page-styles/microsoft-fluent.ts +531 -531
- package/augment-extensions/visual-design/examples/README.md +97 -97
- package/augment-extensions/visual-design/examples/ai-prompt-generation.md +233 -233
- package/augment-extensions/visual-design/examples/basic-usage.md +216 -216
- package/augment-extensions/visual-design/examples/domain-workflows.md +257 -257
- package/augment-extensions/visual-design/examples/vendor-comparison.md +247 -247
- package/augment-extensions/visual-design/module.json +78 -78
- package/augment-extensions/visual-design/style-selector.ts +177 -177
- package/augment-extensions/visual-design/types.ts +302 -302
- package/augment-extensions/visual-design/visual-design-core.ts +469 -469
- package/augment-extensions/workflows/adr-support/README.md +227 -227
- package/augment-extensions/workflows/adr-support/__tests__/adr-validator.test.ts +203 -203
- package/augment-extensions/workflows/adr-support/adr-validator.ts +162 -162
- package/augment-extensions/workflows/adr-support/examples/complete-lifecycle-example.md +449 -449
- package/augment-extensions/workflows/adr-support/examples/integration-example.md +580 -580
- package/augment-extensions/workflows/adr-support/examples/superseding-example.md +436 -436
- package/augment-extensions/workflows/adr-support/module.json +112 -112
- package/augment-extensions/workflows/adr-support/rules/adr-creation.md +372 -372
- package/augment-extensions/workflows/adr-support/rules/beads-integration.md +443 -443
- package/augment-extensions/workflows/adr-support/rules/conflict-detection.md +486 -486
- package/augment-extensions/workflows/adr-support/rules/decision-detection.md +362 -362
- package/augment-extensions/workflows/adr-support/rules/lifecycle-management.md +427 -427
- package/augment-extensions/workflows/adr-support/rules/openspec-integration.md +465 -465
- package/augment-extensions/workflows/adr-support/rules/template-selection.md +405 -405
- package/augment-extensions/workflows/adr-support/rules/validation-rules.md +543 -543
- package/augment-extensions/workflows/adr-support/schemas/adr-config.json +191 -191
- package/augment-extensions/workflows/adr-support/schemas/adr-metadata.json +172 -172
- package/augment-extensions/workflows/adr-support/templates/business-case.md +235 -235
- package/augment-extensions/workflows/adr-support/templates/madr-elaborate.md +197 -197
- package/augment-extensions/workflows/adr-support/templates/madr-simple.md +68 -68
- package/augment-extensions/workflows/adr-support/templates/nygard.md +84 -84
- package/augment-extensions/writing-standards/screenplay/rules/file-organization.md +213 -213
- package/augment-extensions/writing-standards/screenplay/utils/__tests__/file-organization.test.ts +169 -169
- package/augment-extensions/writing-standards/screenplay/utils/file-organization.ts +165 -165
- package/cli/dist/commands/agent.d.ts +37 -0
- package/cli/dist/commands/agent.d.ts.map +1 -0
- package/cli/dist/commands/agent.js +222 -0
- package/cli/dist/commands/agent.js.map +1 -0
- package/cli/dist/commands/beads.d.ts +64 -0
- package/cli/dist/commands/beads.d.ts.map +1 -0
- package/cli/dist/commands/beads.js +377 -0
- package/cli/dist/commands/beads.js.map +1 -0
- package/cli/dist/commands/change.d.ts +54 -0
- package/cli/dist/commands/change.d.ts.map +1 -0
- package/cli/dist/commands/change.js +243 -0
- package/cli/dist/commands/change.js.map +1 -0
- package/cli/dist/commands/clean.d.ts +15 -0
- package/cli/dist/commands/clean.d.ts.map +1 -0
- package/cli/dist/commands/clean.js +63 -0
- package/cli/dist/commands/clean.js.map +1 -0
- package/cli/dist/commands/clone.d.ts +15 -0
- package/cli/dist/commands/clone.d.ts.map +1 -0
- package/cli/dist/commands/clone.js +49 -0
- package/cli/dist/commands/clone.js.map +1 -0
- package/cli/dist/commands/config.d.ts +33 -0
- package/cli/dist/commands/config.d.ts.map +1 -0
- package/cli/dist/commands/config.js +166 -0
- package/cli/dist/commands/config.js.map +1 -0
- package/cli/dist/commands/context.d.ts +38 -0
- package/cli/dist/commands/context.d.ts.map +1 -0
- package/cli/dist/commands/context.js +205 -0
- package/cli/dist/commands/context.js.map +1 -0
- package/cli/dist/commands/create.d.ts +18 -0
- package/cli/dist/commands/create.d.ts.map +1 -0
- package/cli/dist/commands/create.js +178 -0
- package/cli/dist/commands/create.js.map +1 -0
- package/cli/dist/commands/diff.d.ts +19 -0
- package/cli/dist/commands/diff.d.ts.map +1 -0
- package/cli/dist/commands/diff.js +104 -0
- package/cli/dist/commands/diff.js.map +1 -0
- package/cli/dist/commands/doctor.d.ts +14 -0
- package/cli/dist/commands/doctor.d.ts.map +1 -0
- package/cli/dist/commands/doctor.js +62 -0
- package/cli/dist/commands/doctor.js.map +1 -0
- package/cli/dist/commands/export.d.ts +28 -0
- package/cli/dist/commands/export.d.ts.map +1 -0
- package/cli/dist/commands/export.js +135 -0
- package/cli/dist/commands/export.js.map +1 -0
- package/cli/dist/commands/import.d.ts +23 -0
- package/cli/dist/commands/import.d.ts.map +1 -0
- package/cli/dist/commands/import.js +118 -0
- package/cli/dist/commands/import.js.map +1 -0
- package/cli/dist/commands/prompt.d.ts +45 -0
- package/cli/dist/commands/prompt.d.ts.map +1 -0
- package/cli/dist/commands/prompt.js +223 -0
- package/cli/dist/commands/prompt.js.map +1 -0
- package/cli/dist/commands/spec.d.ts +57 -0
- package/cli/dist/commands/spec.d.ts.map +1 -0
- package/cli/dist/commands/spec.js +279 -0
- package/cli/dist/commands/spec.js.map +1 -0
- package/cli/dist/commands/stats.d.ts +18 -0
- package/cli/dist/commands/stats.d.ts.map +1 -0
- package/cli/dist/commands/stats.js +85 -0
- package/cli/dist/commands/stats.js.map +1 -0
- package/cli/dist/commands/task.d.ts +65 -0
- package/cli/dist/commands/task.d.ts.map +1 -0
- package/cli/dist/commands/task.js +282 -0
- package/cli/dist/commands/task.js.map +1 -0
- package/cli/dist/commands/template.d.ts +17 -0
- package/cli/dist/commands/template.d.ts.map +1 -0
- package/cli/dist/commands/template.js +55 -0
- package/cli/dist/commands/template.js.map +1 -0
- package/cli/dist/utils/agent-config.d.ts +129 -0
- package/cli/dist/utils/agent-config.d.ts.map +1 -0
- package/cli/dist/utils/agent-config.js +297 -0
- package/cli/dist/utils/agent-config.js.map +1 -0
- package/cli/dist/utils/auto-sync.js +19 -19
- package/cli/dist/utils/beads-graph.d.ts +17 -0
- package/cli/dist/utils/beads-graph.d.ts.map +1 -0
- package/cli/dist/utils/beads-graph.js +150 -0
- package/cli/dist/utils/beads-graph.js.map +1 -0
- package/cli/dist/utils/beads-integration.d.ts +112 -0
- package/cli/dist/utils/beads-integration.d.ts.map +1 -0
- package/cli/dist/utils/beads-integration.js +312 -0
- package/cli/dist/utils/beads-integration.js.map +1 -0
- package/cli/dist/utils/beads-reporter.d.ts +17 -0
- package/cli/dist/utils/beads-reporter.d.ts.map +1 -0
- package/cli/dist/utils/beads-reporter.js +160 -0
- package/cli/dist/utils/beads-reporter.js.map +1 -0
- package/cli/dist/utils/cache-manager.d.ts +55 -0
- package/cli/dist/utils/cache-manager.d.ts.map +1 -0
- package/cli/dist/utils/cache-manager.js +150 -0
- package/cli/dist/utils/cache-manager.js.map +1 -0
- package/cli/dist/utils/change-manager.d.ts +70 -0
- package/cli/dist/utils/change-manager.d.ts.map +1 -0
- package/cli/dist/utils/change-manager.js +412 -0
- package/cli/dist/utils/change-manager.js.map +1 -0
- package/cli/dist/utils/config-manager-enhanced.d.ts +66 -0
- package/cli/dist/utils/config-manager-enhanced.d.ts.map +1 -0
- package/cli/dist/utils/config-manager-enhanced.js +77 -0
- package/cli/dist/utils/config-manager-enhanced.js.map +1 -0
- package/cli/dist/utils/context-manager.d.ts +96 -0
- package/cli/dist/utils/context-manager.d.ts.map +1 -0
- package/cli/dist/utils/context-manager.js +258 -0
- package/cli/dist/utils/context-manager.js.map +1 -0
- package/cli/dist/utils/diff-engine.d.ts +78 -0
- package/cli/dist/utils/diff-engine.d.ts.map +1 -0
- package/cli/dist/utils/diff-engine.js +233 -0
- package/cli/dist/utils/diff-engine.js.map +1 -0
- package/cli/dist/utils/export-system.d.ts +101 -0
- package/cli/dist/utils/export-system.d.ts.map +1 -0
- package/cli/dist/utils/export-system.js +289 -0
- package/cli/dist/utils/export-system.js.map +1 -0
- package/cli/dist/utils/health-checker.d.ts +66 -0
- package/cli/dist/utils/health-checker.d.ts.map +1 -0
- package/cli/dist/utils/health-checker.js +285 -0
- package/cli/dist/utils/health-checker.js.map +1 -0
- package/cli/dist/utils/import-system.d.ts +74 -0
- package/cli/dist/utils/import-system.d.ts.map +1 -0
- package/cli/dist/utils/import-system.js +317 -0
- package/cli/dist/utils/import-system.js.map +1 -0
- package/cli/dist/utils/module-cloner.d.ts +40 -0
- package/cli/dist/utils/module-cloner.d.ts.map +1 -0
- package/cli/dist/utils/module-cloner.js +136 -0
- package/cli/dist/utils/module-cloner.js.map +1 -0
- package/cli/dist/utils/prompt-manager.d.ts +90 -0
- package/cli/dist/utils/prompt-manager.d.ts.map +1 -0
- package/cli/dist/utils/prompt-manager.js +302 -0
- package/cli/dist/utils/prompt-manager.js.map +1 -0
- package/cli/dist/utils/spec-manager.d.ts +65 -0
- package/cli/dist/utils/spec-manager.d.ts.map +1 -0
- package/cli/dist/utils/spec-manager.js +329 -0
- package/cli/dist/utils/spec-manager.js.map +1 -0
- package/cli/dist/utils/stats-collector.d.ts +74 -0
- package/cli/dist/utils/stats-collector.d.ts.map +1 -0
- package/cli/dist/utils/stats-collector.js +164 -0
- package/cli/dist/utils/stats-collector.js.map +1 -0
- package/cli/dist/utils/template-engine.d.ts +47 -0
- package/cli/dist/utils/template-engine.d.ts.map +1 -0
- package/cli/dist/utils/template-engine.js +204 -0
- package/cli/dist/utils/template-engine.js.map +1 -0
- package/package.json +12 -3
- package/augment-extensions/workflows/openspec/README.md +0 -96
- package/augment-extensions/workflows/openspec/examples/complete-change-example.md +0 -244
- package/augment-extensions/workflows/openspec/module.json +0 -54
- package/augment-extensions/workflows/openspec/rules/best-practices.md +0 -272
- package/augment-extensions/workflows/openspec/rules/manual-setup.md +0 -231
- package/augment-extensions/workflows/openspec/rules/spec-format.md +0 -236
- package/augment-extensions/workflows/openspec/rules/workflow.md +0 -214
- package/cli/dist/utils/__tests__/adr-validator.example.d.ts +0 -6
- package/cli/dist/utils/__tests__/adr-validator.example.d.ts.map +0 -1
- package/cli/dist/utils/__tests__/adr-validator.example.js +0 -148
- package/cli/dist/utils/__tests__/adr-validator.example.js.map +0 -1
- package/cli/dist/utils/adr-validator.d.ts +0 -65
- package/cli/dist/utils/adr-validator.d.ts.map +0 -1
- package/cli/dist/utils/adr-validator.js +0 -203
- package/cli/dist/utils/adr-validator.js.map +0 -1
|
@@ -1,203 +1,203 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for ADR Validation Module
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import { describe, it, expect } from '@jest/globals';
|
|
6
|
-
import {
|
|
7
|
-
ADR,
|
|
8
|
-
isValidISO8601,
|
|
9
|
-
validateMetadata,
|
|
10
|
-
validateOptionalFields,
|
|
11
|
-
validateADRReferences
|
|
12
|
-
} from '../adr-validator';
|
|
13
|
-
|
|
14
|
-
describe('ADR Validator', () => {
|
|
15
|
-
describe('isValidISO8601', () => {
|
|
16
|
-
it('should accept valid ISO 8601 dates', () => {
|
|
17
|
-
expect(isValidISO8601('2026-02-06')).toBe(true);
|
|
18
|
-
expect(isValidISO8601('2024-01-01')).toBe(true);
|
|
19
|
-
expect(isValidISO8601('2024-12-31')).toBe(true);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
it('should reject invalid dates', () => {
|
|
23
|
-
expect(isValidISO8601('2024-02-30')).toBe(false); // Invalid day
|
|
24
|
-
expect(isValidISO8601('2024-13-01')).toBe(false); // Invalid month
|
|
25
|
-
expect(isValidISO8601('2024-00-01')).toBe(false); // Invalid month
|
|
26
|
-
expect(isValidISO8601('2024-01-32')).toBe(false); // Invalid day
|
|
27
|
-
expect(isValidISO8601('24-01-01')).toBe(false); // Wrong format
|
|
28
|
-
expect(isValidISO8601('2024/01/01')).toBe(false); // Wrong separator
|
|
29
|
-
expect(isValidISO8601('2024-1-1')).toBe(false); // Missing leading zeros
|
|
30
|
-
expect(isValidISO8601('not-a-date')).toBe(false);
|
|
31
|
-
expect(isValidISO8601('')).toBe(false);
|
|
32
|
-
});
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('validateMetadata', () => {
|
|
36
|
-
it('should accept valid ADR metadata', () => {
|
|
37
|
-
const validADR: ADR = {
|
|
38
|
-
id: 'adr-0001',
|
|
39
|
-
title: 'Use PostgreSQL for Primary Database',
|
|
40
|
-
status: 'approved',
|
|
41
|
-
date: '2026-02-06',
|
|
42
|
-
deciders: ['Tech Lead', 'Database Architect']
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const result = validateMetadata(validADR);
|
|
46
|
-
expect(result.valid).toBe(true);
|
|
47
|
-
expect(result.errors).toEqual([]);
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it('should reject missing required fields', () => {
|
|
51
|
-
const invalidADR = {
|
|
52
|
-
id: 'adr-0001',
|
|
53
|
-
title: 'Test',
|
|
54
|
-
status: 'approved'
|
|
55
|
-
} as ADR;
|
|
56
|
-
|
|
57
|
-
const result = validateMetadata(invalidADR);
|
|
58
|
-
expect(result.valid).toBe(false);
|
|
59
|
-
expect(result.errors).toContain('Missing required field: date');
|
|
60
|
-
expect(result.errors).toContain('At least one decider must be specified');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('should reject invalid ID format', () => {
|
|
64
|
-
const invalidADR: ADR = {
|
|
65
|
-
id: 'adr-1', // Should be adr-0001
|
|
66
|
-
title: 'Valid Title Here',
|
|
67
|
-
status: 'approved',
|
|
68
|
-
date: '2026-02-06',
|
|
69
|
-
deciders: ['Tech Lead']
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
const result = validateMetadata(invalidADR);
|
|
73
|
-
expect(result.valid).toBe(false);
|
|
74
|
-
expect(result.errors).toContain('Invalid ID format. Must be adr-NNNN (e.g., adr-0001)');
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('should reject invalid title length', () => {
|
|
78
|
-
const shortTitle: ADR = {
|
|
79
|
-
id: 'adr-0001',
|
|
80
|
-
title: 'Short', // Less than 10 characters
|
|
81
|
-
status: 'approved',
|
|
82
|
-
date: '2026-02-06',
|
|
83
|
-
deciders: ['Tech Lead']
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const result = validateMetadata(shortTitle);
|
|
87
|
-
expect(result.valid).toBe(false);
|
|
88
|
-
expect(result.errors).toContain('Title must be 10-100 characters');
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('should reject invalid status', () => {
|
|
92
|
-
const invalidStatus: ADR = {
|
|
93
|
-
id: 'adr-0001',
|
|
94
|
-
title: 'Valid Title Here',
|
|
95
|
-
status: 'invalid-status',
|
|
96
|
-
date: '2026-02-06',
|
|
97
|
-
deciders: ['Tech Lead']
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const result = validateMetadata(invalidStatus);
|
|
101
|
-
expect(result.valid).toBe(false);
|
|
102
|
-
expect(result.errors?.some(e => e.includes('Invalid status'))).toBe(true);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
it('should reject invalid date format', () => {
|
|
106
|
-
const invalidDate: ADR = {
|
|
107
|
-
id: 'adr-0001',
|
|
108
|
-
title: 'Valid Title Here',
|
|
109
|
-
status: 'approved',
|
|
110
|
-
date: '2024-02-30', // Invalid date
|
|
111
|
-
deciders: ['Tech Lead']
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const result = validateMetadata(invalidDate);
|
|
115
|
-
expect(result.valid).toBe(false);
|
|
116
|
-
expect(result.errors).toContain('Invalid date format. Must be ISO 8601 (YYYY-MM-DD)');
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
|
|
120
|
-
describe('validateOptionalFields', () => {
|
|
121
|
-
it('should accept valid optional fields', () => {
|
|
122
|
-
const adr: ADR = {
|
|
123
|
-
id: 'adr-0001',
|
|
124
|
-
title: 'Valid Title Here',
|
|
125
|
-
status: 'approved',
|
|
126
|
-
date: '2026-02-06',
|
|
127
|
-
deciders: ['Tech Lead'],
|
|
128
|
-
tags: ['database', 'postgresql'],
|
|
129
|
-
supersedes: ['adr-0002'],
|
|
130
|
-
superseded_by: 'adr-0003'
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const result = validateOptionalFields(adr);
|
|
134
|
-
expect(result.valid).toBe(true);
|
|
135
|
-
expect(result.warnings).toEqual([]);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
it('should warn about invalid supersedes format', () => {
|
|
139
|
-
const adr: ADR = {
|
|
140
|
-
id: 'adr-0001',
|
|
141
|
-
title: 'Valid Title Here',
|
|
142
|
-
status: 'approved',
|
|
143
|
-
date: '2026-02-06',
|
|
144
|
-
deciders: ['Tech Lead'],
|
|
145
|
-
supersedes: ['adr-1', 'invalid-id'] // Invalid formats
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const result = validateOptionalFields(adr);
|
|
149
|
-
expect(result.valid).toBe(false);
|
|
150
|
-
expect(result.warnings?.some(w => w.includes('Invalid ADR ID in supersedes'))).toBe(true);
|
|
151
|
-
});
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
describe('validateADRReferences', () => {
|
|
155
|
-
const existingADRs: ADR[] = [
|
|
156
|
-
{
|
|
157
|
-
id: 'adr-0001',
|
|
158
|
-
title: 'First Decision',
|
|
159
|
-
status: 'approved',
|
|
160
|
-
date: '2026-01-01',
|
|
161
|
-
deciders: ['Tech Lead']
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
id: 'adr-0002',
|
|
165
|
-
title: 'Second Decision',
|
|
166
|
-
status: 'approved',
|
|
167
|
-
date: '2026-01-02',
|
|
168
|
-
deciders: ['Tech Lead']
|
|
169
|
-
}
|
|
170
|
-
];
|
|
171
|
-
|
|
172
|
-
it('should warn when related_decisions references non-existent ADR', () => {
|
|
173
|
-
const adr: ADR = {
|
|
174
|
-
id: 'adr-0003',
|
|
175
|
-
title: 'Third Decision',
|
|
176
|
-
status: 'approved',
|
|
177
|
-
date: '2026-01-03',
|
|
178
|
-
deciders: ['Tech Lead'],
|
|
179
|
-
related_decisions: ['adr-0001', 'adr-9999'] // adr-9999 doesn't exist
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const result = validateADRReferences(adr, existingADRs);
|
|
183
|
-
expect(result.valid).toBe(false);
|
|
184
|
-
expect(result.warnings).toContain('Related ADR does not exist: adr-9999');
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
it('should pass when all references exist', () => {
|
|
188
|
-
const adr: ADR = {
|
|
189
|
-
id: 'adr-0003',
|
|
190
|
-
title: 'Third Decision',
|
|
191
|
-
status: 'approved',
|
|
192
|
-
date: '2026-01-03',
|
|
193
|
-
deciders: ['Tech Lead'],
|
|
194
|
-
related_decisions: ['adr-0001', 'adr-0002']
|
|
195
|
-
};
|
|
196
|
-
|
|
197
|
-
const result = validateADRReferences(adr, existingADRs);
|
|
198
|
-
expect(result.valid).toBe(true);
|
|
199
|
-
expect(result.warnings).toEqual([]);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ADR Validation Module
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { describe, it, expect } from '@jest/globals';
|
|
6
|
+
import {
|
|
7
|
+
ADR,
|
|
8
|
+
isValidISO8601,
|
|
9
|
+
validateMetadata,
|
|
10
|
+
validateOptionalFields,
|
|
11
|
+
validateADRReferences
|
|
12
|
+
} from '../adr-validator';
|
|
13
|
+
|
|
14
|
+
describe('ADR Validator', () => {
|
|
15
|
+
describe('isValidISO8601', () => {
|
|
16
|
+
it('should accept valid ISO 8601 dates', () => {
|
|
17
|
+
expect(isValidISO8601('2026-02-06')).toBe(true);
|
|
18
|
+
expect(isValidISO8601('2024-01-01')).toBe(true);
|
|
19
|
+
expect(isValidISO8601('2024-12-31')).toBe(true);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should reject invalid dates', () => {
|
|
23
|
+
expect(isValidISO8601('2024-02-30')).toBe(false); // Invalid day
|
|
24
|
+
expect(isValidISO8601('2024-13-01')).toBe(false); // Invalid month
|
|
25
|
+
expect(isValidISO8601('2024-00-01')).toBe(false); // Invalid month
|
|
26
|
+
expect(isValidISO8601('2024-01-32')).toBe(false); // Invalid day
|
|
27
|
+
expect(isValidISO8601('24-01-01')).toBe(false); // Wrong format
|
|
28
|
+
expect(isValidISO8601('2024/01/01')).toBe(false); // Wrong separator
|
|
29
|
+
expect(isValidISO8601('2024-1-1')).toBe(false); // Missing leading zeros
|
|
30
|
+
expect(isValidISO8601('not-a-date')).toBe(false);
|
|
31
|
+
expect(isValidISO8601('')).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('validateMetadata', () => {
|
|
36
|
+
it('should accept valid ADR metadata', () => {
|
|
37
|
+
const validADR: ADR = {
|
|
38
|
+
id: 'adr-0001',
|
|
39
|
+
title: 'Use PostgreSQL for Primary Database',
|
|
40
|
+
status: 'approved',
|
|
41
|
+
date: '2026-02-06',
|
|
42
|
+
deciders: ['Tech Lead', 'Database Architect']
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const result = validateMetadata(validADR);
|
|
46
|
+
expect(result.valid).toBe(true);
|
|
47
|
+
expect(result.errors).toEqual([]);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('should reject missing required fields', () => {
|
|
51
|
+
const invalidADR = {
|
|
52
|
+
id: 'adr-0001',
|
|
53
|
+
title: 'Test',
|
|
54
|
+
status: 'approved'
|
|
55
|
+
} as ADR;
|
|
56
|
+
|
|
57
|
+
const result = validateMetadata(invalidADR);
|
|
58
|
+
expect(result.valid).toBe(false);
|
|
59
|
+
expect(result.errors).toContain('Missing required field: date');
|
|
60
|
+
expect(result.errors).toContain('At least one decider must be specified');
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('should reject invalid ID format', () => {
|
|
64
|
+
const invalidADR: ADR = {
|
|
65
|
+
id: 'adr-1', // Should be adr-0001
|
|
66
|
+
title: 'Valid Title Here',
|
|
67
|
+
status: 'approved',
|
|
68
|
+
date: '2026-02-06',
|
|
69
|
+
deciders: ['Tech Lead']
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const result = validateMetadata(invalidADR);
|
|
73
|
+
expect(result.valid).toBe(false);
|
|
74
|
+
expect(result.errors).toContain('Invalid ID format. Must be adr-NNNN (e.g., adr-0001)');
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('should reject invalid title length', () => {
|
|
78
|
+
const shortTitle: ADR = {
|
|
79
|
+
id: 'adr-0001',
|
|
80
|
+
title: 'Short', // Less than 10 characters
|
|
81
|
+
status: 'approved',
|
|
82
|
+
date: '2026-02-06',
|
|
83
|
+
deciders: ['Tech Lead']
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const result = validateMetadata(shortTitle);
|
|
87
|
+
expect(result.valid).toBe(false);
|
|
88
|
+
expect(result.errors).toContain('Title must be 10-100 characters');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('should reject invalid status', () => {
|
|
92
|
+
const invalidStatus: ADR = {
|
|
93
|
+
id: 'adr-0001',
|
|
94
|
+
title: 'Valid Title Here',
|
|
95
|
+
status: 'invalid-status',
|
|
96
|
+
date: '2026-02-06',
|
|
97
|
+
deciders: ['Tech Lead']
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const result = validateMetadata(invalidStatus);
|
|
101
|
+
expect(result.valid).toBe(false);
|
|
102
|
+
expect(result.errors?.some(e => e.includes('Invalid status'))).toBe(true);
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
it('should reject invalid date format', () => {
|
|
106
|
+
const invalidDate: ADR = {
|
|
107
|
+
id: 'adr-0001',
|
|
108
|
+
title: 'Valid Title Here',
|
|
109
|
+
status: 'approved',
|
|
110
|
+
date: '2024-02-30', // Invalid date
|
|
111
|
+
deciders: ['Tech Lead']
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const result = validateMetadata(invalidDate);
|
|
115
|
+
expect(result.valid).toBe(false);
|
|
116
|
+
expect(result.errors).toContain('Invalid date format. Must be ISO 8601 (YYYY-MM-DD)');
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('validateOptionalFields', () => {
|
|
121
|
+
it('should accept valid optional fields', () => {
|
|
122
|
+
const adr: ADR = {
|
|
123
|
+
id: 'adr-0001',
|
|
124
|
+
title: 'Valid Title Here',
|
|
125
|
+
status: 'approved',
|
|
126
|
+
date: '2026-02-06',
|
|
127
|
+
deciders: ['Tech Lead'],
|
|
128
|
+
tags: ['database', 'postgresql'],
|
|
129
|
+
supersedes: ['adr-0002'],
|
|
130
|
+
superseded_by: 'adr-0003'
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const result = validateOptionalFields(adr);
|
|
134
|
+
expect(result.valid).toBe(true);
|
|
135
|
+
expect(result.warnings).toEqual([]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should warn about invalid supersedes format', () => {
|
|
139
|
+
const adr: ADR = {
|
|
140
|
+
id: 'adr-0001',
|
|
141
|
+
title: 'Valid Title Here',
|
|
142
|
+
status: 'approved',
|
|
143
|
+
date: '2026-02-06',
|
|
144
|
+
deciders: ['Tech Lead'],
|
|
145
|
+
supersedes: ['adr-1', 'invalid-id'] // Invalid formats
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
const result = validateOptionalFields(adr);
|
|
149
|
+
expect(result.valid).toBe(false);
|
|
150
|
+
expect(result.warnings?.some(w => w.includes('Invalid ADR ID in supersedes'))).toBe(true);
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
describe('validateADRReferences', () => {
|
|
155
|
+
const existingADRs: ADR[] = [
|
|
156
|
+
{
|
|
157
|
+
id: 'adr-0001',
|
|
158
|
+
title: 'First Decision',
|
|
159
|
+
status: 'approved',
|
|
160
|
+
date: '2026-01-01',
|
|
161
|
+
deciders: ['Tech Lead']
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
id: 'adr-0002',
|
|
165
|
+
title: 'Second Decision',
|
|
166
|
+
status: 'approved',
|
|
167
|
+
date: '2026-01-02',
|
|
168
|
+
deciders: ['Tech Lead']
|
|
169
|
+
}
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
it('should warn when related_decisions references non-existent ADR', () => {
|
|
173
|
+
const adr: ADR = {
|
|
174
|
+
id: 'adr-0003',
|
|
175
|
+
title: 'Third Decision',
|
|
176
|
+
status: 'approved',
|
|
177
|
+
date: '2026-01-03',
|
|
178
|
+
deciders: ['Tech Lead'],
|
|
179
|
+
related_decisions: ['adr-0001', 'adr-9999'] // adr-9999 doesn't exist
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
const result = validateADRReferences(adr, existingADRs);
|
|
183
|
+
expect(result.valid).toBe(false);
|
|
184
|
+
expect(result.warnings).toContain('Related ADR does not exist: adr-9999');
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
it('should pass when all references exist', () => {
|
|
188
|
+
const adr: ADR = {
|
|
189
|
+
id: 'adr-0003',
|
|
190
|
+
title: 'Third Decision',
|
|
191
|
+
status: 'approved',
|
|
192
|
+
date: '2026-01-03',
|
|
193
|
+
deciders: ['Tech Lead'],
|
|
194
|
+
related_decisions: ['adr-0001', 'adr-0002']
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
const result = validateADRReferences(adr, existingADRs);
|
|
198
|
+
expect(result.valid).toBe(true);
|
|
199
|
+
expect(result.warnings).toEqual([]);
|
|
200
|
+
});
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|