@diplodoc/cli-tests 5.39.8 → 5.41.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 (40) hide show
  1. package/e2e/__snapshots__/build-content-map.spec.ts.snap +329 -0
  2. package/e2e/__snapshots__/include-toc.test.ts.snap +23 -50
  3. package/e2e/__snapshots__/includes-conditions.test.ts.snap +15 -29
  4. package/e2e/__snapshots__/includes.test.ts.snap +437 -148
  5. package/e2e/__snapshots__/merge-includes.spec.ts.snap +4 -4
  6. package/e2e/__snapshots__/pdf-page.spec.ts.snap +0 -1
  7. package/e2e/__snapshots__/preprocess.test.ts.snap +108 -171
  8. package/e2e/__snapshots__/regression.test.ts.snap +167 -208
  9. package/e2e/build-content-map.spec.ts +220 -0
  10. package/mocks/build-content-map/autotitle-chain/input/.yfm +0 -0
  11. package/mocks/build-content-map/autotitle-chain/input/a.md +3 -0
  12. package/mocks/build-content-map/autotitle-chain/input/b.md +3 -0
  13. package/mocks/build-content-map/autotitle-chain/input/c.md +3 -0
  14. package/mocks/build-content-map/autotitle-chain/input/toc.yaml +9 -0
  15. package/mocks/build-content-map/autotitle-target-with-include/input/.yfm +0 -0
  16. package/mocks/build-content-map/autotitle-target-with-include/input/_includes/snippet.md +3 -0
  17. package/mocks/build-content-map/autotitle-target-with-include/input/a.md +3 -0
  18. package/mocks/build-content-map/autotitle-target-with-include/input/b.md +3 -0
  19. package/mocks/build-content-map/autotitle-target-with-include/input/toc.yaml +7 -0
  20. package/mocks/build-content-map/diamond-includes/input/.yfm +0 -0
  21. package/mocks/build-content-map/diamond-includes/input/_includes/branch-a.md +5 -0
  22. package/mocks/build-content-map/diamond-includes/input/_includes/branch-b.md +5 -0
  23. package/mocks/build-content-map/diamond-includes/input/_includes/shared.md +3 -0
  24. package/mocks/build-content-map/diamond-includes/input/index.md +7 -0
  25. package/mocks/build-content-map/diamond-includes/input/toc.yaml +5 -0
  26. package/mocks/build-content-map/nested-includes/input/.yfm +0 -0
  27. package/mocks/build-content-map/nested-includes/input/_includes/level1.md +5 -0
  28. package/mocks/build-content-map/nested-includes/input/_includes/level2.md +3 -0
  29. package/mocks/build-content-map/nested-includes/input/index.md +5 -0
  30. package/mocks/build-content-map/nested-includes/input/toc.yaml +5 -0
  31. package/mocks/build-content-map/with-autotitles/input/.yfm +0 -0
  32. package/mocks/build-content-map/with-autotitles/input/index.md +3 -0
  33. package/mocks/build-content-map/with-autotitles/input/other.md +3 -0
  34. package/mocks/build-content-map/with-autotitles/input/toc.yaml +7 -0
  35. package/mocks/build-content-map/with-includes/input/.yfm +0 -0
  36. package/mocks/build-content-map/with-includes/input/_includes/snippet.md +1 -0
  37. package/mocks/build-content-map/with-includes/input/index.md +5 -0
  38. package/mocks/build-content-map/with-includes/input/logo.svg +1 -0
  39. package/mocks/build-content-map/with-includes/input/toc.yaml +5 -0
  40. package/package.json +1 -1
@@ -0,0 +1,220 @@
1
+ import {describe, expect, test} from 'vitest';
2
+ import {cp, mkdtemp, readFile, realpath, writeFile} from 'node:fs/promises';
3
+ import {tmpdir} from 'node:os';
4
+ import {join} from 'node:path';
5
+
6
+ import {TestAdapter, getTestPaths} from '../fixtures';
7
+
8
+ const buildContentTestTemplate = (testTitle: string, testRootPath: string, extraArgs = '') => {
9
+ test(testTitle, async () => {
10
+ const {inputPath, outputPath} = getTestPaths(testRootPath);
11
+
12
+ await TestAdapter.testBuildPass(inputPath, outputPath, {
13
+ md2md: true,
14
+ md2html: false,
15
+ args: `--build-content ${extraArgs}`.trim(),
16
+ });
17
+
18
+ const contentMap = await readFile(join(outputPath, 'yfm-build-content.json'), 'utf-8');
19
+
20
+ expect(JSON.parse(contentMap)).toMatchSnapshot();
21
+ });
22
+ };
23
+
24
+ describe('Build content map for', () => {
25
+ buildContentTestTemplate(
26
+ 'project with an include and a picture (mergeIncludes off)',
27
+ 'mocks/build-content-map/with-includes',
28
+ '--no-merge-includes',
29
+ );
30
+
31
+ buildContentTestTemplate(
32
+ 'project with an include and a picture (mergeIncludes on)',
33
+ 'mocks/build-content-map/with-includes',
34
+ '--merge-includes',
35
+ );
36
+
37
+ buildContentTestTemplate(
38
+ 'project with autotitle links between pages (mergeIncludes off)',
39
+ 'mocks/build-content-map/with-autotitles',
40
+ '--no-merge-includes',
41
+ );
42
+
43
+ buildContentTestTemplate(
44
+ 'project with autotitle links between pages (mergeIncludes on)',
45
+ 'mocks/build-content-map/with-autotitles',
46
+ '--merge-includes',
47
+ );
48
+
49
+ buildContentTestTemplate(
50
+ 'nested includes (hashIncludes default, mergeIncludes off)',
51
+ 'mocks/build-content-map/nested-includes',
52
+ '--no-merge-includes',
53
+ );
54
+
55
+ buildContentTestTemplate(
56
+ 'nested includes (mergeIncludes on)',
57
+ 'mocks/build-content-map/nested-includes',
58
+ '--merge-includes',
59
+ );
60
+
61
+ buildContentTestTemplate(
62
+ 'diamond includes (hashIncludes default, mergeIncludes off)',
63
+ 'mocks/build-content-map/diamond-includes',
64
+ '--no-merge-includes',
65
+ );
66
+
67
+ buildContentTestTemplate(
68
+ 'diamond includes (mergeIncludes on)',
69
+ 'mocks/build-content-map/diamond-includes',
70
+ '--merge-includes',
71
+ );
72
+
73
+ buildContentTestTemplate(
74
+ 'autotitle chain (hashIncludes default, mergeIncludes off)',
75
+ 'mocks/build-content-map/autotitle-chain',
76
+ '--no-merge-includes',
77
+ );
78
+
79
+ buildContentTestTemplate(
80
+ 'autotitle chain (mergeIncludes on)',
81
+ 'mocks/build-content-map/autotitle-chain',
82
+ '--merge-includes',
83
+ );
84
+
85
+ buildContentTestTemplate(
86
+ 'autotitle target with include (hashIncludes default, mergeIncludes off)',
87
+ 'mocks/build-content-map/autotitle-target-with-include',
88
+ '--no-merge-includes',
89
+ );
90
+
91
+ buildContentTestTemplate(
92
+ 'autotitle target with include (mergeIncludes on)',
93
+ 'mocks/build-content-map/autotitle-target-with-include',
94
+ '--merge-includes',
95
+ );
96
+ });
97
+
98
+ describe('Build content map propagation', () => {
99
+ test('mutating an include propagates to parent hashes (mergeIncludes: false, hashIncludes: true)', async () => {
100
+ const fixtureRoot = getTestPaths('mocks/build-content-map/nested-includes').inputPath;
101
+ // realpath() canonicalizes macOS /var → /private/var symlink so the
102
+ // build's scope checks (which compare against fs.realpath() results)
103
+ // line up with the configured input/output paths.
104
+ const work = await realpath(
105
+ await mkdtemp(join(tmpdir(), 'yfm-build-content-propagation-')),
106
+ );
107
+ const inputBefore = join(work, 'input-before');
108
+ const inputAfter = join(work, 'input-after');
109
+ const before = join(work, 'before');
110
+ const after = join(work, 'after');
111
+
112
+ await cp(fixtureRoot, inputBefore, {recursive: true});
113
+ await cp(fixtureRoot, inputAfter, {recursive: true});
114
+
115
+ await writeFile(
116
+ join(inputAfter, '_includes/level2.md'),
117
+ '# Level 2 mutated\n\nNew body for the deepest include.\n',
118
+ );
119
+
120
+ await TestAdapter.testBuildPass(inputBefore, before, {
121
+ md2md: true,
122
+ md2html: false,
123
+ args: '--build-content --no-merge-includes',
124
+ });
125
+ await TestAdapter.testBuildPass(inputAfter, after, {
126
+ md2md: true,
127
+ md2html: false,
128
+ args: '--build-content --no-merge-includes',
129
+ });
130
+
131
+ const beforeManifest = JSON.parse(
132
+ await readFile(join(before, 'yfm-build-content.json'), 'utf-8'),
133
+ );
134
+ const afterManifest = JSON.parse(
135
+ await readFile(join(after, 'yfm-build-content.json'), 'utf-8'),
136
+ );
137
+
138
+ // level2.md changed → its hash differs
139
+ expect(beforeManifest.contentHashes['_includes/level2.md'].hash).not.toBe(
140
+ afterManifest.contentHashes['_includes/level2.md'].hash,
141
+ );
142
+
143
+ // level1.md transitively references level2 via signlink → name change
144
+ // propagates into level1.md's body → its hash differs.
145
+ expect(beforeManifest.contentHashes['_includes/level1.md'].hash).not.toBe(
146
+ afterManifest.contentHashes['_includes/level1.md'].hash,
147
+ );
148
+
149
+ // index.md references level1 via signlink → name change cascades → its
150
+ // hash differs.
151
+ expect(beforeManifest.contentHashes['index.md'].hash).not.toBe(
152
+ afterManifest.contentHashes['index.md'].hash,
153
+ );
154
+
155
+ // toc.yaml and .yfm are untouched → identical
156
+ expect(beforeManifest.contentHashes['toc.yaml']?.hash).toBe(
157
+ afterManifest.contentHashes['toc.yaml']?.hash,
158
+ );
159
+ expect(beforeManifest.contentHashes['.yfm']?.hash).toBe(
160
+ afterManifest.contentHashes['.yfm']?.hash,
161
+ );
162
+ });
163
+
164
+ test('mutating an include propagates to parent hashes (mergeIncludes: true)', async () => {
165
+ const fixtureRoot = getTestPaths('mocks/build-content-map/nested-includes').inputPath;
166
+ const work = await realpath(
167
+ await mkdtemp(join(tmpdir(), 'yfm-build-content-propagation-merge-')),
168
+ );
169
+ const inputBefore = join(work, 'input-before');
170
+ const inputAfter = join(work, 'input-after');
171
+ const before = join(work, 'before');
172
+ const after = join(work, 'after');
173
+
174
+ await cp(fixtureRoot, inputBefore, {recursive: true});
175
+ await cp(fixtureRoot, inputAfter, {recursive: true});
176
+
177
+ await writeFile(
178
+ join(inputAfter, '_includes/level2.md'),
179
+ '# Level 2 mutated\n\nNew body for the deepest include.\n',
180
+ );
181
+
182
+ await TestAdapter.testBuildPass(inputBefore, before, {
183
+ md2md: true,
184
+ md2html: false,
185
+ args: '--build-content --merge-includes',
186
+ });
187
+ await TestAdapter.testBuildPass(inputAfter, after, {
188
+ md2md: true,
189
+ md2html: false,
190
+ args: '--build-content --merge-includes',
191
+ });
192
+
193
+ const beforeManifest = JSON.parse(
194
+ await readFile(join(before, 'yfm-build-content.json'), 'utf-8'),
195
+ );
196
+ const afterManifest = JSON.parse(
197
+ await readFile(join(after, 'yfm-build-content.json'), 'utf-8'),
198
+ );
199
+
200
+ // With merge: level2.md and level1.md don't exist in output anymore,
201
+ // their content is inlined into index.md.
202
+ expect(beforeManifest.contentHashes['_includes/level2.md']).toBeUndefined();
203
+ expect(afterManifest.contentHashes['_includes/level2.md']).toBeUndefined();
204
+ expect(beforeManifest.contentHashes['_includes/level1.md']).toBeUndefined();
205
+ expect(afterManifest.contentHashes['_includes/level1.md']).toBeUndefined();
206
+
207
+ // index.md hash differs because the inlined level2 content changed.
208
+ expect(beforeManifest.contentHashes['index.md'].hash).not.toBe(
209
+ afterManifest.contentHashes['index.md'].hash,
210
+ );
211
+
212
+ // toc.yaml and .yfm unchanged.
213
+ expect(beforeManifest.contentHashes['toc.yaml']?.hash).toBe(
214
+ afterManifest.contentHashes['toc.yaml']?.hash,
215
+ );
216
+ expect(beforeManifest.contentHashes['.yfm']?.hash).toBe(
217
+ afterManifest.contentHashes['.yfm']?.hash,
218
+ );
219
+ });
220
+ });
@@ -0,0 +1,3 @@
1
+ # A page title
2
+
3
+ See [{#T}](b.md) for the next step.
@@ -0,0 +1,3 @@
1
+ # B page title
2
+
3
+ See [{#T}](c.md) to continue the chain.
@@ -0,0 +1,3 @@
1
+ # C page title
2
+
3
+ Final page in the autotitle chain.
@@ -0,0 +1,9 @@
1
+ title: Build content map - autotitle chain
2
+ href: a.md
3
+ items:
4
+ - name: A
5
+ href: a.md
6
+ - name: B
7
+ href: b.md
8
+ - name: C
9
+ href: c.md
@@ -0,0 +1,3 @@
1
+ # Snippet heading
2
+
3
+ Reusable snippet body for the B page.
@@ -0,0 +1,3 @@
1
+ # A page title
2
+
3
+ See [{#T}](b.md) for the snippet section.
@@ -0,0 +1,3 @@
1
+ # B page title
2
+
3
+ {% include [Snippet](_includes/snippet.md) %}
@@ -0,0 +1,7 @@
1
+ title: Build content map - autotitle target with include
2
+ href: a.md
3
+ items:
4
+ - name: A
5
+ href: a.md
6
+ - name: B
7
+ href: b.md
@@ -0,0 +1,5 @@
1
+ # Branch A
2
+
3
+ First branch pulling in the shared leaf.
4
+
5
+ {% include [Shared](shared.md) %}
@@ -0,0 +1,5 @@
1
+ # Branch B
2
+
3
+ Second branch pulling in the shared leaf.
4
+
5
+ {% include [Shared](shared.md) %}
@@ -0,0 +1,3 @@
1
+ # Shared leaf
2
+
3
+ Shared content reused by both branches.
@@ -0,0 +1,7 @@
1
+ # Diamond root
2
+
3
+ Pulls in two branches that share a leaf.
4
+
5
+ {% include [Branch A](_includes/branch-a.md) %}
6
+
7
+ {% include [Branch B](_includes/branch-b.md) %}
@@ -0,0 +1,5 @@
1
+ title: Build content map - diamond includes
2
+ href: index.md
3
+ items:
4
+ - name: Index
5
+ href: index.md
@@ -0,0 +1,5 @@
1
+ # Level 1 intermediate
2
+
3
+ Intermediate snippet that pulls in a deeper one.
4
+
5
+ {% include [Level2](level2.md) %}
@@ -0,0 +1,3 @@
1
+ # Level 2 leaf
2
+
3
+ Deepest snippet with the actual leaf content.
@@ -0,0 +1,5 @@
1
+ # Nested includes root
2
+
3
+ Top-level entry page that pulls in a chained include.
4
+
5
+ {% include [Level1](_includes/level1.md) %}
@@ -0,0 +1,5 @@
1
+ title: Build content map - nested includes
2
+ href: index.md
3
+ items:
4
+ - name: Index
5
+ href: index.md
@@ -0,0 +1,3 @@
1
+ # Index page
2
+
3
+ See [{#T}](other.md) for more.
@@ -0,0 +1,3 @@
1
+ # Other page title
2
+
3
+ Body of other.
@@ -0,0 +1,7 @@
1
+ title: Build content map - autotitles
2
+ href: index.md
3
+ items:
4
+ - name: Index
5
+ href: index.md
6
+ - name: Other
7
+ href: other.md
@@ -0,0 +1 @@
1
+ Reusable snippet content.
@@ -0,0 +1,5 @@
1
+ # Index page
2
+
3
+ {% include [Snippet](_includes/snippet.md) %}
4
+
5
+ ![Diplodoc logo](logo.svg){inline=false}
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="158" height="32" fill="none"><path fill="#1D4634" fill-rule="evenodd" d="M42.03 25.795h7.225q3.25 0 5.56-1.258a8.5 8.5 0 0 0 3.55-3.61q1.24-2.352 1.24-5.624 0-3.263-1.229-5.604-1.228-2.342-3.519-3.59-2.28-1.257-5.456-1.257H42.03zm7.038-3.283h-3.176V8.134h3.29q2.166 0 3.624.798 1.468.787 2.218 2.383.75 1.584.75 3.988t-.75 4.008q-.75 1.596-2.239 2.403-1.49.798-3.717.798m12.868-12.425v15.708h3.769V10.087zm6.472 21.598V10.087h3.707v2.598h.219q.291-.573.822-1.217.531-.655 1.437-1.115.906-.47 2.311-.47 1.854 0 3.343.93 1.499.921 2.374 2.73.885 1.8.885 4.419 0 2.586-.865 4.397-.864 1.81-2.353 2.76-1.489.952-3.373.952-1.375 0-2.28-.45-.906-.45-1.458-1.084a7 7 0 0 1-.844-1.217h-.156v8.365zm3.696-13.744q0 1.524.438 2.669.447 1.145 1.28 1.79.844.633 2.041.634 1.249 0 2.093-.655.844-.664 1.27-1.81.438-1.155.438-2.628 0-1.462-.427-2.597t-1.27-1.78-2.104-.644q-1.208 0-2.051.624t-1.28 1.748q-.428 1.125-.428 2.649m17.226 7.854V4.852h-3.77v20.943zm9.68.306q-2.344 0-4.062-1.012-1.717-1.013-2.665-2.833-.937-1.82-.937-4.254t.937-4.264q.948-1.83 2.665-2.843 1.72-1.012 4.061-1.012 2.343 0 4.061 1.012t2.655 2.843q.948 1.83.947 4.264 0 2.434-.947 4.254-.937 1.82-2.655 2.833-1.719 1.012-4.06 1.012m.02-2.965q1.27 0 2.124-.685.854-.696 1.27-1.861.427-1.166.427-2.598 0-1.441-.427-2.608-.416-1.176-1.27-1.87-.853-.696-2.124-.696-1.302 0-2.166.695-.854.696-1.28 1.871-.417 1.167-.417 2.608 0 1.432.416 2.598.427 1.165 1.281 1.86.864.686 2.166.686m12.23 1.984q1.489.95 3.374.95 1.374 0 2.28-.45t1.458-1.083a6.3 6.3 0 0 0 .843-1.217h.229v2.475h3.707V4.852h-3.78v7.833h-.156a6.8 6.8 0 0 0-.823-1.217q-.531-.655-1.436-1.115-.906-.47-2.312-.47-1.844 0-3.342.93-1.5.921-2.385 2.73-.874 1.8-.874 4.419 0 2.586.864 4.397.864 1.81 2.353 2.76m6.466-2.72q-.843.633-2.041.634-1.239 0-2.093-.655-.843-.664-1.28-1.81-.427-1.155-.427-2.628 0-1.462.427-2.597t1.27-1.78 2.103-.644q1.218 0 2.051.624.844.624 1.271 1.748.437 1.125.437 2.649t-.437 2.669q-.438 1.145-1.281 1.79m15.245 3.701q-2.343 0-4.061-1.012-1.719-1.013-2.666-2.833-.936-1.82-.937-4.254 0-2.433.937-4.264.948-1.83 2.666-2.843t4.061-1.012q2.342 0 4.06 1.012 1.719 1.013 2.655 2.843.948 1.83.948 4.264t-.948 4.254q-.936 1.82-2.655 2.833-1.718 1.012-4.06 1.012m.02-2.965q1.27 0 2.124-.685.854-.696 1.271-1.861.427-1.166.427-2.598 0-1.441-.427-2.608-.417-1.176-1.271-1.87-.853-.696-2.124-.696-1.3 0-2.165.695-.854.696-1.281 1.871-.417 1.167-.417 2.608 0 1.432.417 2.598.427 1.165 1.281 1.86.864.686 2.165.686m12.533 1.933q1.718 1.032 4.112 1.032 2.01 0 3.499-.715 1.488-.726 2.353-2.005.864-1.288.999-2.955h-3.602q-.167.848-.614 1.442-.448.593-1.115.91-.656.307-1.488.307-1.178 0-2.052-.614-.864-.623-1.343-1.769-.479-1.155-.479-2.761 0-1.585.479-2.72.49-1.135 1.364-1.739.874-.613 2.031-.613 1.363 0 2.176.767a3.37 3.37 0 0 1 1.041 1.892h3.602q-.124-1.698-1.02-2.966-.896-1.278-2.405-1.974-1.5-.705-3.447-.705-2.342 0-4.06 1.033-1.708 1.022-2.645 2.863-.937 1.83-.937 4.223 0 2.383.916 4.214a6.94 6.94 0 0 0 2.635 2.853M61.912 4.856V7.63h3.797V4.856z" clip-rule="evenodd"/><path fill="#63D490" fill-rule="evenodd" d="M17.61 0h-7.157a.94.94 0 0 0-.941.942v5.717H.942A.94.94 0 0 0 0 7.6v23.457c0 .52.422.942.942.942h19.116c.52 0 .941-.422.941-.942v-5.624h8.57c.52 0 .942-.422.942-.942V12.9C30.51 5.776 24.735 0 17.61 0M21 25.434V7.6a.94.94 0 0 0-.942-.942H9.512v17.833c0 .52.421.942.941.942z" clip-rule="evenodd"/></svg>
@@ -0,0 +1,5 @@
1
+ title: Build content map - includes
2
+ href: index.md
3
+ items:
4
+ - name: Index
5
+ href: index.md
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diplodoc/cli-tests",
3
- "version": "5.39.8",
3
+ "version": "5.41.0",
4
4
  "bin": {
5
5
  "diplodoc-cli-test": "bin.mjs"
6
6
  },