@jterrazz/typescript 9.2.1 → 9.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/package.json +1 -1
- package/src/docs.js +10 -0
- package/src/docs.test.ts +96 -0
package/package.json
CHANGED
package/src/docs.js
CHANGED
|
@@ -324,6 +324,16 @@ function auditDecisions(report, { files, heads }) {
|
|
|
324
324
|
auditRecord(report, record, heads);
|
|
325
325
|
}
|
|
326
326
|
|
|
327
|
+
const numbers = [...new Set(records.map((record) => record.name.slice(0, 3)))].sort();
|
|
328
|
+
const sequential = numbers.every((number, index) => Number.parseInt(number, 10) === index + 1);
|
|
329
|
+
if (numbers.length > 0 && !sequential) {
|
|
330
|
+
report(
|
|
331
|
+
'docs-decision-sequence',
|
|
332
|
+
'docs/decisions/',
|
|
333
|
+
`docs/decisions/ numbers run ${numbers.join(', ')}: they run from 001 with no gap — a decision that moved folders takes the next number where it lands`,
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
|
|
327
337
|
const claimed = new Map();
|
|
328
338
|
for (const record of records) {
|
|
329
339
|
const number = record.name.slice(0, 3);
|
package/src/docs.test.ts
CHANGED
|
@@ -404,6 +404,102 @@ test('refuses a superseded status with no link naming the successor', () => {
|
|
|
404
404
|
);
|
|
405
405
|
});
|
|
406
406
|
|
|
407
|
+
test('passes an empty decisions folder', () => {
|
|
408
|
+
// Given - the folder exists but holds no record yet
|
|
409
|
+
const tree = manual({ files: [...manual().files, 'docs/decisions/'] });
|
|
410
|
+
|
|
411
|
+
// Then - a folder with nothing to number has no sequence to break
|
|
412
|
+
expect(rules(tree)).toEqual(['docs-template-missing']);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
test('passes a decisions folder holding only the template', () => {
|
|
416
|
+
// Given - the mold, and not a single record beside it
|
|
417
|
+
const tree = manual({
|
|
418
|
+
files: [...manual().files, 'docs/decisions/', 'docs/decisions/_template.md'],
|
|
419
|
+
});
|
|
420
|
+
|
|
421
|
+
// Then - nothing to say
|
|
422
|
+
expect(rules(tree)).toEqual([]);
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
test('refuses a decision sequence that skips a number', () => {
|
|
426
|
+
// Given - 001 and 003, with no record ever numbered 002
|
|
427
|
+
const tree = withDecisions({
|
|
428
|
+
files: [
|
|
429
|
+
...manual().files,
|
|
430
|
+
'docs/decisions/',
|
|
431
|
+
'docs/decisions/001-the-first-call.md',
|
|
432
|
+
'docs/decisions/003-the-third-call.md',
|
|
433
|
+
'docs/decisions/_template.md',
|
|
434
|
+
],
|
|
435
|
+
heads: {
|
|
436
|
+
'docs/decisions/001-the-first-call.md': [
|
|
437
|
+
'# ADR-001: The first call',
|
|
438
|
+
'',
|
|
439
|
+
'**Status:** Accepted',
|
|
440
|
+
],
|
|
441
|
+
'docs/decisions/003-the-third-call.md': [
|
|
442
|
+
'# ADR-003: The third call',
|
|
443
|
+
'',
|
|
444
|
+
'**Status:** Accepted',
|
|
445
|
+
],
|
|
446
|
+
},
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
// Then - the gap is named, from 001
|
|
450
|
+
expect(sentence(tree, 'docs-decision-sequence')).toBe(
|
|
451
|
+
'docs/decisions/ numbers run 001, 003: they run from 001 with no gap — a decision that moved folders takes the next number where it lands',
|
|
452
|
+
);
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
test('refuses a decision sequence that starts above 001', () => {
|
|
456
|
+
// Given - 006 and 008, with nothing numbered before them
|
|
457
|
+
const tree = withDecisions({
|
|
458
|
+
files: [
|
|
459
|
+
...manual().files,
|
|
460
|
+
'docs/decisions/',
|
|
461
|
+
'docs/decisions/006-the-sixth-call.md',
|
|
462
|
+
'docs/decisions/008-the-eighth-call.md',
|
|
463
|
+
'docs/decisions/_template.md',
|
|
464
|
+
],
|
|
465
|
+
heads: {
|
|
466
|
+
'docs/decisions/006-the-sixth-call.md': [
|
|
467
|
+
'# ADR-006: The sixth call',
|
|
468
|
+
'',
|
|
469
|
+
'**Status:** Accepted',
|
|
470
|
+
],
|
|
471
|
+
'docs/decisions/008-the-eighth-call.md': [
|
|
472
|
+
'# ADR-008: The eighth call',
|
|
473
|
+
'',
|
|
474
|
+
'**Status:** Accepted',
|
|
475
|
+
],
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
|
|
479
|
+
// Then - the same rule, from an offset start
|
|
480
|
+
expect(sentence(tree, 'docs-decision-sequence')).toBe(
|
|
481
|
+
'docs/decisions/ numbers run 006, 008: they run from 001 with no gap — a decision that moved folders takes the next number where it lands',
|
|
482
|
+
);
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
test('lets a duplicated number pass the sequence check on its own', () => {
|
|
486
|
+
// Given - two records claiming 001, and none other — the set is just {001}
|
|
487
|
+
const tree = withDecisions({
|
|
488
|
+
files: [...withDecisions().files, 'docs/decisions/001-the-same-call.md'],
|
|
489
|
+
heads: {
|
|
490
|
+
...withDecisions().heads,
|
|
491
|
+
'docs/decisions/001-the-same-call.md': [
|
|
492
|
+
'# ADR-001: The same call',
|
|
493
|
+
'',
|
|
494
|
+
'**Status:** Proposed',
|
|
495
|
+
],
|
|
496
|
+
},
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
// Then - docs-decision-number still refuses it; the sequence itself is not the gap
|
|
500
|
+
expect(rules(tree)).toEqual(['docs-decision-number']);
|
|
501
|
+
});
|
|
502
|
+
|
|
407
503
|
test('names a number two records claim', () => {
|
|
408
504
|
// Given - two records numbered 001
|
|
409
505
|
const tree = withDecisions({
|