@diplodoc/cli-tests 4.60.0 → 5.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.
Files changed (50) hide show
  1. package/e2e/__snapshots__/include-toc.test.ts.snap +106 -106
  2. package/e2e/__snapshots__/load-custom-resources.spec.ts.snap +293 -344
  3. package/e2e/__snapshots__/metadata.spec.ts.snap +119 -144
  4. package/e2e/__snapshots__/plugin-corner-cases.spec.ts.snap +0 -0
  5. package/e2e/__snapshots__/regression.test.ts.snap +904 -715
  6. package/e2e/__snapshots__/restricted-access.test.ts.snap +234 -0
  7. package/e2e/__snapshots__/rtl.spec.ts.snap +248 -302
  8. package/e2e/__snapshots__/translation.spec.ts.snap +366 -0
  9. package/e2e/errors.spec.ts +31 -0
  10. package/e2e/regression.test.ts +7 -2
  11. package/e2e/restricted-access.test.ts +21 -0
  12. package/e2e/translation.spec.ts +1 -1
  13. package/fixtures/cliAdapter.ts +41 -20
  14. package/fixtures/runners/binary.ts +18 -3
  15. package/fixtures/runners/source.ts +5 -5
  16. package/fixtures/runners/types.ts +7 -1
  17. package/fixtures/utils/file.ts +3 -3
  18. package/fixtures/utils/test.ts +6 -1
  19. package/mocks/errors/unreachable-link/input/exists.md +1 -0
  20. package/mocks/errors/unreachable-link/input/index.md +2 -0
  21. package/mocks/errors/unreachable-link/input/toc.yaml +1 -0
  22. package/mocks/include-toc/test6/input/toc.yaml +1 -0
  23. package/mocks/regression/input/1.md +2 -0
  24. package/mocks/regression/input/generic/1.md +3 -0
  25. package/mocks/regression/input/generic/2.md +3 -0
  26. package/mocks/regression/input/generic/3.md +1 -0
  27. package/mocks/regression/input/generic/Sub notes/1.md +3 -0
  28. package/mocks/regression/input/generic/Sub notes/2.md +3 -0
  29. package/mocks/regression/input/includes/deep.md +1 -0
  30. package/mocks/regression/input/includes.md +3 -0
  31. package/mocks/regression/input/redirects.yaml +6 -0
  32. package/mocks/regression/input/toc.yaml +7 -3
  33. package/mocks/restricted-access/test1/input/index.md +0 -0
  34. package/mocks/restricted-access/test1/input/plugins/index.md +0 -0
  35. package/mocks/restricted-access/test1/input/plugins/index2.md +0 -0
  36. package/mocks/restricted-access/test1/input/plugins/index3.md +0 -0
  37. package/mocks/restricted-access/test1/input/plugins/index4.md +4 -0
  38. package/mocks/restricted-access/test1/input/toc.yaml +28 -0
  39. package/mocks/restricted-access/test2/input/index.md +0 -0
  40. package/mocks/restricted-access/test2/input/plugins/index.md +0 -0
  41. package/mocks/restricted-access/test2/input/project/index.md +0 -0
  42. package/mocks/restricted-access/test2/input/toc.yaml +21 -0
  43. package/mocks/restricted-access/test3/input/a1.md +1 -0
  44. package/mocks/restricted-access/test3/input/folder1/a1.md +1 -0
  45. package/mocks/restricted-access/test3/input/folder1/folder2/a1.md +1 -0
  46. package/mocks/restricted-access/test3/input/folder1/folder2/toc.yaml +8 -0
  47. package/mocks/restricted-access/test3/input/folder1/toc.yaml +10 -0
  48. package/mocks/restricted-access/test3/input/index.md +0 -0
  49. package/mocks/restricted-access/test3/input/toc.yaml +16 -0
  50. package/package.json +1 -1
@@ -377,6 +377,372 @@ exports[`Translate command > extract yaml scheme files > filelist 1`] = `
377
377
  ]"
378
378
  `;
379
379
 
380
+ exports[`Translate command > extract yaml scheme files 1`] = `
381
+ "meta:
382
+ title: '%%%0%%%'
383
+ description: '%%%1%%%'
384
+ fullScreen: true
385
+ blocks:
386
+ - type: header-block
387
+ title: <div class="u-breadcrumbs"></div>
388
+ breadcrumbs:
389
+ items:
390
+ - text: '%%%2%%%'
391
+ url: https://site.ru/support/
392
+ - text: '%%%3%%%'
393
+ url: https://site.ru/support/adv/
394
+ - type: filter-block
395
+ centered: false
396
+ title:
397
+ text: '%%%4%%%'
398
+ tags:
399
+ - id: one
400
+ label: '%%%5%%%'
401
+ - id: two
402
+ label: '%%%6%%%'
403
+ colSizes:
404
+ all: 12
405
+ xl: 4
406
+ sm: 6
407
+ md: 4
408
+ items:
409
+ - tags:
410
+ - one
411
+ card:
412
+ type: image-card
413
+ image: https://site.ru/img/orig
414
+ title: '%%%7%%%'
415
+ text: <div>%%%8%%%</div><div class="u-card__more">%%%9%%%
416
+ margins: m
417
+ border: shadow
418
+ url: unified-performance-campaign/about.md
419
+ urlTitle: '%%%10%%%'
420
+ - tags:
421
+ - one
422
+ card:
423
+ type: image-card
424
+ image: https://site.ru/img2/orig
425
+ title: '%%%11%%%'
426
+ text: <div>%%%12%%%</div><div class="u-card__more">%%%13%%%
427
+ margins: m
428
+ border: shadow
429
+ url: campaign-master/product-campaign.md
430
+ urlTitle: '%%%14%%%'
431
+ - tags:
432
+ - one
433
+ card:
434
+ type: image-card
435
+ image: https://site.ru/img2/orig
436
+ title: '%%%15%%%'
437
+ text: <div>%%%16%%%</div><div class="u-card__more">%%%17%%%
438
+ margins: m
439
+ border: shadow
440
+ url: efficiency/telegram-ads.md
441
+ urlTitle: '%%%18%%%'
442
+ - tags:
443
+ - one
444
+ card:
445
+ type: background-card
446
+ title: '%%%19%%%'
447
+ text: ''
448
+ backgroundColor: '#F3F6FC'
449
+ border: line
450
+ links:
451
+ - text: '%%%20%%%'
452
+ url: statistics.md
453
+ arrow: true
454
+ theme: normal
455
+ - text: '%%%21%%%'
456
+ url: feeds/about.md
457
+ arrow: true
458
+ theme: normal
459
+ - tags:
460
+ - one
461
+ card:
462
+ type: background-card
463
+ title: '%%%22%%%'
464
+ text: ''
465
+ backgroundColor: '#F3F6FC'
466
+ border: line
467
+ links:
468
+ - text: '%%%23%%%'
469
+ url: moderation/adv-rules.md
470
+ arrow: true
471
+ theme: normal
472
+ - text: '%%%24%%%'
473
+ url: technologies-and-services/technologies-and-services.md
474
+ arrow: true
475
+ theme: normal
476
+ - text: '%%%25%%%'
477
+ url: troubleshooting/other.md
478
+ arrow: true
479
+ theme: normal
480
+ - tags:
481
+ - one
482
+ card:
483
+ type: background-card
484
+ title: '%%%26%%%'
485
+ text: ''
486
+ backgroundColor: '#F3F6FC'
487
+ border: line
488
+ links:
489
+ - text: '%%%27%%%'
490
+ url: glossary.md
491
+ arrow: true
492
+ theme: normal
493
+ - tags:
494
+ - two
495
+ card:
496
+ type: image-card
497
+ image: https://site.ru/img4/orig
498
+ title: '%%%28%%%'
499
+ text: <div>%%%29%%%</div><div class="u-card__more">%%%30%%%
500
+ margins: m
501
+ border: shadow
502
+ url: products-automatic/about.md
503
+ urlTitle: '%%%31%%%'
504
+ animated: false
505
+ "
506
+ `;
507
+
508
+ exports[`Translate command > extract yaml scheme files 2`] = `
509
+ "<?xml version="1.0" encoding="UTF-8"?>
510
+ <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
511
+ <file original="file.ext" source-language="ru-RU" target-language="en-US" datatype="markdown">
512
+ <header>
513
+ <skeleton>
514
+ <external-file href="file.skl"></external-file>
515
+ </skeleton>
516
+ </header>
517
+ <body>
518
+ <trans-unit id="0">
519
+ <source xml:space="preserve">Справка Сервиса</source>
520
+ </trans-unit>
521
+ <trans-unit id="1">
522
+ <source xml:space="preserve">В Справке Сервиса собрали всю необходимую информацию.</source>
523
+ </trans-unit>
524
+ <trans-unit id="2">
525
+ <source xml:space="preserve">Справка</source>
526
+ </trans-unit>
527
+ <trans-unit id="3">
528
+ <source xml:space="preserve">Реклама</source>
529
+ </trans-unit>
530
+ <trans-unit id="4">
531
+ <source xml:space="preserve">Сервис</source>
532
+ </trans-unit>
533
+ <trans-unit id="5">
534
+ <source xml:space="preserve">Для специалистов</source>
535
+ </trans-unit>
536
+ <trans-unit id="6">
537
+ <source xml:space="preserve">Для предпринимателей</source>
538
+ </trans-unit>
539
+ <trans-unit id="7">
540
+ <source xml:space="preserve">Единая перфоманс-кампания</source>
541
+ </trans-unit>
542
+ <trans-unit id="8">
543
+ <source xml:space="preserve">Комплексно решайте любые перфоманс-задачи в рамках одной кампании</source>
544
+ </trans-unit>
545
+ <trans-unit id="9">
546
+ <source xml:space="preserve">Подробнее&lt;/&gt;</source>
547
+ </trans-unit>
548
+ <trans-unit id="10">
549
+ <source xml:space="preserve">Подробнее</source>
550
+ </trans-unit>
551
+ <trans-unit id="11">
552
+ <source xml:space="preserve">Товарная кампания</source>
553
+ </trans-unit>
554
+ <trans-unit id="12">
555
+ <source xml:space="preserve">Используйте простой инструмент для продвижения товаров интернете</source>
556
+ </trans-unit>
557
+ <trans-unit id="13">
558
+ <source xml:space="preserve">Подробнее&lt;/&gt;</source>
559
+ </trans-unit>
560
+ <trans-unit id="14">
561
+ <source xml:space="preserve">Подробнее</source>
562
+ </trans-unit>
563
+ <trans-unit id="15">
564
+ <source xml:space="preserve">Реклама в Telegram</source>
565
+ </trans-unit>
566
+ <trans-unit id="16">
567
+ <source xml:space="preserve">Покажите релевантную рекламу в телеграм-каналах партнеров РСЯ</source>
568
+ </trans-unit>
569
+ <trans-unit id="17">
570
+ <source xml:space="preserve">Подробнее&lt;/&gt;</source>
571
+ </trans-unit>
572
+ <trans-unit id="18">
573
+ <source xml:space="preserve">Подробнее</source>
574
+ </trans-unit>
575
+ <trans-unit id="19">
576
+ <source xml:space="preserve">Часто ищут</source>
577
+ </trans-unit>
578
+ <trans-unit id="20">
579
+ <source xml:space="preserve">Статистика</source>
580
+ </trans-unit>
581
+ <trans-unit id="21">
582
+ <source xml:space="preserve">Управление фидами</source>
583
+ </trans-unit>
584
+ <trans-unit id="22">
585
+ <source xml:space="preserve">Сервисные функции</source>
586
+ </trans-unit>
587
+ <trans-unit id="23">
588
+ <source xml:space="preserve">Правила и модерация</source>
589
+ </trans-unit>
590
+ <trans-unit id="24">
591
+ <source xml:space="preserve">Технологии и сервисы</source>
592
+ </trans-unit>
593
+ <trans-unit id="25">
594
+ <source xml:space="preserve">Поддержка 24/7</source>
595
+ </trans-unit>
596
+ <trans-unit id="26">
597
+ <source xml:space="preserve">Полезные ссылки</source>
598
+ </trans-unit>
599
+ <trans-unit id="27">
600
+ <source xml:space="preserve">Глоссарий</source>
601
+ </trans-unit>
602
+ <trans-unit id="28">
603
+ <source xml:space="preserve">Простой старт</source>
604
+ </trans-unit>
605
+ <trans-unit id="29">
606
+ <source xml:space="preserve">Минимум ручных настроек: достаточно указать ссылку на сайт</source>
607
+ </trans-unit>
608
+ <trans-unit id="30">
609
+ <source xml:space="preserve">Подробнее&lt;/&gt;</source>
610
+ </trans-unit>
611
+ <trans-unit id="31">
612
+ <source xml:space="preserve">Подробнее</source>
613
+ </trans-unit>
614
+ </body>
615
+ </file>
616
+ </xliff>"
617
+ `;
618
+
619
+ exports[`Translate command > extract yaml scheme files 3`] = `
620
+ "blocks:
621
+ - type: content-layout-block
622
+ textWidth: l
623
+ textContent:
624
+ title: '%%%0%%%'
625
+ text: |2-
626
+ %%%1%%%
627
+ - %%%2%%%
628
+ - %%%3%%%
629
+
630
+ - type: card-layout-block
631
+ colSizes:
632
+ all: 12
633
+ lg: 4
634
+ md: 6
635
+ sm: 12
636
+ xl: 4
637
+ indent:
638
+ bottom: xs
639
+ title: '%%%4%%%'
640
+ animated: false
641
+ children:
642
+ - type: basic-card
643
+ title: '%%%5%%%'
644
+ text: '%%%6%%%'
645
+ urlTitle: '%%%7%%%'
646
+ border: shadow
647
+ controlPosition: content
648
+ url: management/index
649
+ target: ''
650
+ animated: false
651
+ "
652
+ `;
653
+
654
+ exports[`Translate command > extract yaml scheme files 4`] = `
655
+ "<?xml version="1.0" encoding="UTF-8"?>
656
+ <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
657
+ <file original="file.ext" source-language="ru-RU" target-language="en-US" datatype="markdown">
658
+ <header>
659
+ <skeleton>
660
+ <external-file href="file.skl"></external-file>
661
+ </skeleton>
662
+ </header>
663
+ <body>
664
+ <trans-unit id="0">
665
+ <source xml:space="preserve">Введение</source>
666
+ </trans-unit>
667
+ <trans-unit id="1">
668
+ <source xml:space="preserve">API сервиса: - Управлять счетчиками, их настройками и правами доступа, не используя веб-интерфейс.</source>
669
+ </trans-unit>
670
+ <trans-unit id="2">
671
+ <source xml:space="preserve">Получать информацию о посещаемости сайта и другие данные.</source>
672
+ </trans-unit>
673
+ <trans-unit id="3">
674
+ <source xml:space="preserve">Формировать отчеты, в том числе с помощью сегментации и параметризации.</source>
675
+ </trans-unit>
676
+ <trans-unit id="4">
677
+ <source xml:space="preserve">Виды API</source>
678
+ </trans-unit>
679
+ <trans-unit id="5">
680
+ <source xml:space="preserve">API управления</source>
681
+ </trans-unit>
682
+ <trans-unit id="6">
683
+ <source xml:space="preserve">Управление счетчиками, целями, фильтрами и другими объектами Сервиса (например, создать счетчик, отредактировать его настройки, создать цель, выдать права доступа).</source>
684
+ </trans-unit>
685
+ <trans-unit id="7">
686
+ <source xml:space="preserve">API управления</source>
687
+ </trans-unit>
688
+ </body>
689
+ </file>
690
+ </xliff>"
691
+ `;
692
+
693
+ exports[`Translate command > extract yaml scheme files 5`] = `
694
+ "title: '%%%0%%%'
695
+ href: index.yaml
696
+ items:
697
+ - name: '%%%4%%%'
698
+ - href: index-direct.yaml
699
+ navigation:
700
+ header:
701
+ leftItems:
702
+ - text: '%%%2%%%'
703
+ type: dropdown
704
+ items:
705
+ - text: '%%%3%%%'
706
+ type: link
707
+ href: menu/item
708
+ logo:
709
+ light:
710
+ icon: https://icon.link/logo.svg
711
+ url: https://site.ru
712
+ urlTitle: '%%%1%%%'
713
+ "
714
+ `;
715
+
716
+ exports[`Translate command > extract yaml scheme files 6`] = `
717
+ "<?xml version="1.0" encoding="UTF-8"?>
718
+ <xliff xmlns="urn:oasis:names:tc:xliff:document:1.2" version="1.2">
719
+ <file original="file.ext" source-language="ru-RU" target-language="en-US" datatype="markdown">
720
+ <header>
721
+ <skeleton>
722
+ <external-file href="file.skl"></external-file>
723
+ </skeleton>
724
+ </header>
725
+ <body>
726
+ <trans-unit id="0">
727
+ <source xml:space="preserve">Заголовок</source>
728
+ </trans-unit>
729
+ <trans-unit id="1">
730
+ <source xml:space="preserve">На сайт сервиса</source>
731
+ </trans-unit>
732
+ <trans-unit id="2">
733
+ <source xml:space="preserve">Инструменты</source>
734
+ </trans-unit>
735
+ <trans-unit id="3">
736
+ <source xml:space="preserve">Пункт меню</source>
737
+ </trans-unit>
738
+ <trans-unit id="4">
739
+ <source xml:space="preserve">Дочерняя страница</source>
740
+ </trans-unit>
741
+ </body>
742
+ </file>
743
+ </xliff>"
744
+ `;
745
+
380
746
  exports[`Translate command > filter files on extract > filelist 1`] = `
381
747
  "[
382
748
  "es/_includes/test.md.skl",
@@ -0,0 +1,31 @@
1
+ import {describe, expect, it} from 'vitest';
2
+ import {TestAdapter, getTestPaths} from '../fixtures';
3
+
4
+ function test(path: string, expect: Function) {
5
+ it(path, async () => {
6
+ const {inputPath, outputPath} = getTestPaths(path);
7
+
8
+ const md = await TestAdapter.build.run(inputPath, outputPath, ['-j2', '-f', 'md']);
9
+ const html = await TestAdapter.build.run(outputPath, outputPath + '-html', ['-j2', '-f', 'html']);
10
+
11
+ return expect({md, html});
12
+ });
13
+ }
14
+
15
+ describe('Errors', () => {
16
+ test('mocks/errors/unreachable-link', ({md, html}) => {
17
+ // console.log(md, html);
18
+ expectErrors(html, [
19
+ 'ERR index.md: 1: YFM003 / unreachable-link Link is unreachable [Context: "[Unreachable link: "exists.html"][existing file](./exists.md)"]',
20
+ 'ERR index.md: 2: YFM003 / unreachable-link Link is unreachable [Context: "[Unreachable link: "missed.html"][missed file](./missed.md)"]'
21
+ ]);
22
+ });
23
+ });
24
+
25
+ function expectErrors(report: Report, errors: string[]) {
26
+ expect(report.code).toEqual(1);
27
+
28
+ for (const error of errors) {
29
+ expect(report.errors).toContain(error);
30
+ }
31
+ }
@@ -6,15 +6,20 @@ function test(_description: string) {
6
6
  it('internal', async () => {
7
7
  const {inputPath, outputPath} = getTestPaths('mocks/regression');
8
8
 
9
- await TestAdapter.testBuildPass(inputPath, outputPath, {md2md: true, md2html: false});
9
+ await TestAdapter.testBuildPass(inputPath, outputPath, {
10
+ md2md: true,
11
+ md2html: false,
12
+ args: '-j2',
13
+ });
10
14
  await TestAdapter.testBuildPass(outputPath, outputPath + '-html', {
11
15
  md2md: false,
12
16
  md2html: true,
17
+ args: '-j2',
13
18
  });
14
19
  await TestAdapter.testBuildPass(outputPath, outputPath + '-static-html', {
15
20
  md2md: false,
16
21
  md2html: true,
17
- args: '--static-content',
22
+ args: '-j2 --static-content',
18
23
  });
19
24
  await compareDirectories(outputPath);
20
25
  await compareDirectories(outputPath + '-html');
@@ -0,0 +1,21 @@
1
+ import {describe, test} from 'vitest';
2
+ import {TestAdapter, compareDirectories, getTestPaths} from '../fixtures';
3
+
4
+ const generateFilesYamlTestTemplate = (
5
+ testTitle: string,
6
+ testRootPath: string
7
+ ) => {
8
+ test(testTitle, async () => {
9
+ const {inputPath, outputPath} = getTestPaths(testRootPath);
10
+ await TestAdapter.testBuildPass(inputPath, outputPath, {md2md:true});
11
+ await compareDirectories(outputPath);
12
+ });
13
+ };
14
+
15
+ describe('Restricted access', () => {
16
+ generateFilesYamlTestTemplate('Simple restricted access', 'mocks/restricted-access/test1');
17
+
18
+ generateFilesYamlTestTemplate('Nested restricted access', 'mocks/restricted-access/test2');
19
+
20
+ generateFilesYamlTestTemplate('Nested toc restricted access', 'mocks/restricted-access/test3');
21
+ });
@@ -6,7 +6,7 @@ const generateMapTestTemplate = (
6
6
  testRootPath: string,
7
7
  args: TranslateRunArgs,
8
8
  ) => {
9
- test(testTitle, async () => {
9
+ test.skip(testTitle, async () => {
10
10
  const {inputPath, outputPath} = getTestPaths(testRootPath);
11
11
 
12
12
  await TestAdapter.testTranslatePass(inputPath, outputPath, args);
@@ -14,8 +14,32 @@ export interface TranslateRunArgs {
14
14
  additionalArgs?: string;
15
15
  }
16
16
 
17
+ class Build {
18
+ private readonly runner: Runner;
19
+
20
+ constructor(runner: Runner) {
21
+ this.runner = runner;
22
+ }
23
+
24
+ run(input: string, output: string, args: string[]) {
25
+ return this.runner.runYfmDocs([
26
+ '--input',
27
+ input,
28
+ '--output',
29
+ output,
30
+ '--quiet',
31
+ '--allowHTML',
32
+ ...args,
33
+ '-e',
34
+ 'report-logs',
35
+ ]);
36
+ }
37
+ }
38
+
17
39
  export class CliTestAdapter {
18
- private readonly runner: Runner = createRunner();
40
+ readonly runner: Runner = createRunner();
41
+
42
+ readonly build = new Build(this.runner);
19
43
 
20
44
  async testBuildPass(
21
45
  inputPath: string,
@@ -23,30 +47,27 @@ export class CliTestAdapter {
23
47
  {md2md = true, md2html = true, args = ''}: BuildRunArgs = {},
24
48
  ): Promise<void> {
25
49
  await cleanupDirectory(outputPath);
50
+ await cleanupDirectory(`${outputPath}-md`);
51
+ await cleanupDirectory(`${outputPath}-html`);
26
52
 
27
- const baseArgs = [
28
- '--input',
29
- inputPath,
30
- '--quiet',
31
- '--allowHTML',
32
- ...args.split(' ').filter(Boolean),
33
- ];
53
+ const baseArgs = args.split(' ').filter(Boolean);
54
+
55
+ const tasks = [];
34
56
 
35
57
  if (md2md && md2html) {
36
- await cleanupDirectory(`${outputPath}-html`);
37
-
38
- await this.runner.runYfmDocs([...baseArgs, '--output', outputPath, '-f', 'md']);
39
- await this.runner.runYfmDocs([
40
- ...baseArgs,
41
- '--output',
42
- `${outputPath}-html`,
43
- '-f',
44
- 'html',
45
- ]);
58
+ tasks.push(() => this.build.run(inputPath, outputPath,[...baseArgs, '-f', 'md']));
59
+ tasks.push(() => this.build.run(inputPath, `${outputPath}-html`, [...baseArgs, '-f', 'html']));
46
60
  } else if (md2md) {
47
- await this.runner.runYfmDocs([...baseArgs, '--output', outputPath, '-f', 'md']);
61
+ tasks.push(() => this.build.run(inputPath, outputPath, [...baseArgs, '-f', 'md']));
48
62
  } else {
49
- await this.runner.runYfmDocs([...baseArgs, '--output', outputPath]);
63
+ tasks.push(() => this.build.run(inputPath, outputPath, [...baseArgs, '-f', 'html']));
64
+ }
65
+
66
+ for (const task of tasks) {
67
+ const report = await task();
68
+ if (report.code > 0) {
69
+ throw report;
70
+ }
50
71
  }
51
72
  }
52
73
 
@@ -9,9 +9,24 @@ export class BinaryRunner implements Runner {
9
9
  }
10
10
 
11
11
  async runYfmDocs(argv: string[]) {
12
- const {all} = await execa(this.binaryPath, argv, {all: true});
12
+ const {stderr, exitCode} = await execa(this.binaryPath, argv, {all: true});
13
+ const report = {
14
+ code: exitCode || 0,
15
+ warns: fillLog(/^WARN/, stderr),
16
+ errors: fillLog(/^ERR/, stderr),
17
+ };
13
18
 
14
- // eslint-disable-next-line no-console
15
- console.log(all);
19
+ const restLog = fillLog(/^(?!INFO|WARN|ERR)/, stderr);
20
+ if (restLog.length) {
21
+ for (const line of restLog) {
22
+ console.log(line);
23
+ }
24
+ }
25
+
26
+ return report;
16
27
  }
17
28
  }
29
+
30
+ function fillLog(filter: RegExp, source: string) {
31
+ return source.split('\n').filter((line) => line.match(filter));
32
+ }
@@ -1,15 +1,15 @@
1
+ import type {Report} from './types';
2
+
1
3
  export class SourceRunner {
2
4
  readonly MODULE_PATH = require.resolve('../../../');
3
5
 
4
- async runYfmDocs(argv: string[]): Promise<void> {
6
+ async runYfmDocs(argv: string[]) {
5
7
  const {run} = await import(this.MODULE_PATH);
6
8
 
7
9
  const baseArgs = ['node', this.MODULE_PATH, ...argv];
8
10
 
9
- const exitCode = await run(baseArgs);
11
+ const report = await run(baseArgs) as Report;
10
12
 
11
- if (exitCode !== 0) {
12
- throw new Error(`CLI exited with code ${exitCode}`);
13
- }
13
+ return report;
14
14
  }
15
15
  }
@@ -1,4 +1,10 @@
1
+ export type Report = {
2
+ code: number;
3
+ warns: string[];
4
+ errors: string[];
5
+ }
6
+
1
7
  export interface Runner {
2
- runYfmDocs(argv: string[]): Promise<void>;
8
+ runYfmDocs(argv: string[]): Promise<Report>;
3
9
  }
4
10
 
@@ -1,7 +1,7 @@
1
1
  import {readFileSync} from 'node:fs';
2
2
  import {join, resolve} from 'node:path';
3
3
  import {glob} from 'glob';
4
- import {bundleless, platformless} from './test';
4
+ import {bundleless, hashless, platformless} from './test';
5
5
  import {expect} from 'vitest';
6
6
  import {$} from 'execa';
7
7
 
@@ -23,12 +23,12 @@ export async function compareDirectories(outputPath: string, ignoreFileContent =
23
23
  })
24
24
  ).sort();
25
25
 
26
- expect(bundleless(JSON.stringify(filesFromOutput, null, 2))).toMatchSnapshot('filelist');
26
+ expect(hashless(bundleless(JSON.stringify(filesFromOutput, null, 2)))).toMatchSnapshot('filelist');
27
27
 
28
28
  if (!ignoreFileContent) {
29
29
  filesFromOutput.filter(uselessFile).forEach((filePath) => {
30
30
  const content = getFileContent(resolve(outputPath, filePath));
31
- expect(content).toMatchSnapshot(filePath);
31
+ expect(content).toMatchSnapshot();
32
32
  });
33
33
  }
34
34
  }
@@ -1,13 +1,18 @@
1
1
  import {readFileSync} from 'node:fs';
2
2
 
3
3
  export function platformless(text: string): string {
4
- return text
4
+ return hashless(text)
5
5
  .replace(/\r\n/g, '\n')
6
6
  .replace(/\w{8}-\w{4}-\w{4}-\w{4}-\w{12}/g, 'UUID')
7
7
  .replace(/(content"?[:=]{1}[" ]{1}Diplodoc.*? )v\d+\.\d+\.\d+(?:-[\w-]+)?/g, `$1vDIPLODOC-VERSION`)
8
8
  .replace(/(\\(?![/"'])){1,2}/g, '/');
9
9
  }
10
10
 
11
+ export function hashless(text: string): string {
12
+ return text
13
+ .replace(/-[a-z0-9]{12}\./g, '-hash.')
14
+ }
15
+
11
16
  export function bundleless(text: string): string {
12
17
  const assets = require('@diplodoc/client/manifest') as Record<string, Record<string, string[]>>;
13
18
 
@@ -0,0 +1 @@
1
+ File exists but not attached to toc
@@ -0,0 +1,2 @@
1
+ [existing file](./exists.md)
2
+ [missed file](./missed.md)
@@ -0,0 +1 @@
1
+ href: index.md
@@ -4,4 +4,5 @@ items:
4
4
  path: test
5
5
  includers:
6
6
  - name: generic
7
+ autotitle: false
7
8
  input: test
@@ -24,4 +24,6 @@ not_var{{skip()}}
24
24
 
25
25
  [](./latex.md)
26
26
 
27
+ [noext-link](./includes)
28
+
27
29
  {% include [user](includes/user.md) %}
@@ -0,0 +1,3 @@
1
+ # Note 1
2
+
3
+ Note content 1