@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jterrazz/typescript",
3
- "version": "9.2.1",
3
+ "version": "9.3.0",
4
4
  "author": "Jean-Baptiste Terrazzoni <contact@jterrazz.com>",
5
5
  "repository": {
6
6
  "type": "git",
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({