@docusaurus/utils 2.0.0-beta.fc64c12e4 → 2.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 (113) hide show
  1. package/lib/constants.d.ts +73 -0
  2. package/lib/constants.d.ts.map +1 -0
  3. package/lib/constants.js +78 -0
  4. package/lib/constants.js.map +1 -0
  5. package/lib/dataFileUtils.d.ts +60 -0
  6. package/lib/dataFileUtils.d.ts.map +1 -0
  7. package/lib/dataFileUtils.js +91 -0
  8. package/lib/dataFileUtils.js.map +1 -0
  9. package/lib/emitUtils.d.ts +32 -0
  10. package/lib/emitUtils.d.ts.map +1 -0
  11. package/lib/emitUtils.js +80 -0
  12. package/lib/emitUtils.js.map +1 -0
  13. package/lib/gitUtils.d.ts +66 -0
  14. package/lib/gitUtils.d.ts.map +1 -0
  15. package/lib/gitUtils.js +63 -0
  16. package/lib/gitUtils.js.map +1 -0
  17. package/lib/globUtils.d.ts +29 -0
  18. package/lib/globUtils.d.ts.map +1 -0
  19. package/lib/globUtils.js +36 -12
  20. package/lib/globUtils.js.map +1 -0
  21. package/lib/hashUtils.d.ts +6 -4
  22. package/lib/hashUtils.d.ts.map +1 -0
  23. package/lib/hashUtils.js +13 -10
  24. package/lib/hashUtils.js.map +1 -0
  25. package/lib/i18nUtils.d.ts +53 -0
  26. package/lib/i18nUtils.d.ts.map +1 -0
  27. package/lib/i18nUtils.js +70 -0
  28. package/lib/i18nUtils.js.map +1 -0
  29. package/lib/index.d.ts +15 -75
  30. package/lib/index.d.ts.map +1 -0
  31. package/lib/index.js +86 -395
  32. package/lib/index.js.map +1 -0
  33. package/lib/jsUtils.d.ts +28 -0
  34. package/lib/jsUtils.d.ts.map +1 -0
  35. package/lib/jsUtils.js +57 -0
  36. package/lib/jsUtils.js.map +1 -0
  37. package/lib/markdownLinks.d.ts +49 -5
  38. package/lib/markdownLinks.d.ts.map +1 -0
  39. package/lib/markdownLinks.js +57 -13
  40. package/lib/markdownLinks.js.map +1 -0
  41. package/lib/markdownUtils.d.ts +112 -0
  42. package/lib/markdownUtils.d.ts.map +1 -0
  43. package/lib/markdownUtils.js +271 -0
  44. package/lib/markdownUtils.js.map +1 -0
  45. package/lib/pathUtils.d.ts +45 -1
  46. package/lib/pathUtils.d.ts.map +1 -0
  47. package/lib/pathUtils.js +92 -12
  48. package/lib/pathUtils.js.map +1 -0
  49. package/lib/shellUtils.d.ts +8 -0
  50. package/lib/shellUtils.d.ts.map +1 -0
  51. package/lib/shellUtils.js +21 -0
  52. package/lib/shellUtils.js.map +1 -0
  53. package/lib/slugger.d.ts +24 -0
  54. package/lib/slugger.d.ts.map +1 -0
  55. package/lib/slugger.js +23 -0
  56. package/lib/slugger.js.map +1 -0
  57. package/lib/tags.d.ts +59 -0
  58. package/lib/tags.d.ts.map +1 -0
  59. package/lib/tags.js +91 -0
  60. package/lib/tags.js.map +1 -0
  61. package/lib/urlUtils.d.ts +66 -0
  62. package/lib/urlUtils.d.ts.map +1 -0
  63. package/lib/urlUtils.js +207 -0
  64. package/lib/urlUtils.js.map +1 -0
  65. package/lib/webpackUtils.d.ts +35 -0
  66. package/lib/webpackUtils.d.ts.map +1 -0
  67. package/lib/webpackUtils.js +115 -0
  68. package/lib/webpackUtils.js.map +1 -0
  69. package/package.json +27 -12
  70. package/src/constants.ts +98 -0
  71. package/src/dataFileUtils.ts +122 -0
  72. package/src/deps.d.ts +10 -0
  73. package/src/emitUtils.ts +99 -0
  74. package/src/gitUtils.ts +146 -0
  75. package/src/globUtils.ts +37 -15
  76. package/src/hashUtils.ts +9 -8
  77. package/src/i18nUtils.ts +114 -0
  78. package/src/index.ts +91 -502
  79. package/src/jsUtils.ts +59 -0
  80. package/src/markdownLinks.ts +101 -30
  81. package/src/markdownUtils.ts +357 -0
  82. package/src/pathUtils.ts +93 -12
  83. package/src/shellUtils.ts +18 -0
  84. package/src/slugger.ts +36 -0
  85. package/src/tags.ts +130 -0
  86. package/src/urlUtils.ts +234 -0
  87. package/src/webpackUtils.ts +153 -0
  88. package/lib/.tsbuildinfo +0 -1
  89. package/lib/codeTranslationsUtils.d.ts +0 -11
  90. package/lib/codeTranslationsUtils.js +0 -50
  91. package/lib/escapePath.d.ts +0 -17
  92. package/lib/escapePath.js +0 -25
  93. package/lib/markdownParser.d.ts +0 -30
  94. package/lib/markdownParser.js +0 -140
  95. package/lib/posixPath.d.ts +0 -14
  96. package/lib/posixPath.js +0 -28
  97. package/src/__tests__/__fixtures__/defaultCodeTranslations/en.json +0 -4
  98. package/src/__tests__/__fixtures__/defaultCodeTranslations/fr-FR.json +0 -5
  99. package/src/__tests__/__fixtures__/defaultCodeTranslations/fr.json +0 -4
  100. package/src/__tests__/__snapshots__/index.test.ts.snap +0 -8
  101. package/src/__tests__/codeTranslationsUtils.test.ts +0 -112
  102. package/src/__tests__/escapePath.test.ts +0 -25
  103. package/src/__tests__/globUtils.test.ts +0 -109
  104. package/src/__tests__/hashUtils.test.ts +0 -51
  105. package/src/__tests__/index.test.ts +0 -631
  106. package/src/__tests__/markdownParser.test.ts +0 -817
  107. package/src/__tests__/pathUtils.test.ts +0 -63
  108. package/src/__tests__/posixPath.test.ts +0 -25
  109. package/src/codeTranslationsUtils.ts +0 -56
  110. package/src/escapePath.ts +0 -23
  111. package/src/markdownParser.ts +0 -182
  112. package/src/posixPath.ts +0 -27
  113. package/tsconfig.json +0 -9
@@ -1,631 +0,0 @@
1
- /**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- */
7
-
8
- import path from 'path';
9
- import {
10
- fileToPath,
11
- genComponentName,
12
- genChunkName,
13
- idx,
14
- getSubFolder,
15
- normalizeUrl,
16
- posixPath,
17
- objectWithKeySorted,
18
- aliasedSitePath,
19
- isValidPathname,
20
- addTrailingSlash,
21
- removeTrailingSlash,
22
- removeSuffix,
23
- removePrefix,
24
- addLeadingSlash,
25
- getElementsAround,
26
- mergeTranslations,
27
- mapAsyncSequencial,
28
- findAsyncSequential,
29
- findFolderContainingFile,
30
- getFolderContainingFile,
31
- updateTranslationFileMessages,
32
- parseMarkdownHeadingId,
33
- } from '../index';
34
- import {sum} from 'lodash';
35
-
36
- describe('load utils', () => {
37
- test('aliasedSitePath', () => {
38
- const asserts: Record<string, string> = {
39
- 'user/website/docs/asd.md': '@site/docs/asd.md',
40
- 'user/website/versioned_docs/foo/bar.md':
41
- '@site/versioned_docs/foo/bar.md',
42
- 'user/docs/test.md': '@site/../docs/test.md',
43
- };
44
- Object.keys(asserts).forEach((file) => {
45
- expect(posixPath(aliasedSitePath(file, 'user/website'))).toBe(
46
- asserts[file],
47
- );
48
- });
49
- });
50
-
51
- test('genComponentName', () => {
52
- const asserts: Record<string, string> = {
53
- '/': 'index',
54
- '/foo-bar': 'FooBar096',
55
- '/foo/bar': 'FooBar1Df',
56
- '/blog/2017/12/14/introducing-docusaurus':
57
- 'Blog20171214IntroducingDocusaurus8D2',
58
- '/blog/2017/12/14-introducing-docusaurus':
59
- 'Blog20171214IntroducingDocusaurus0Bc',
60
- '/blog/201712/14-introducing-docusaurus':
61
- 'Blog20171214IntroducingDocusaurusA93',
62
- };
63
- Object.keys(asserts).forEach((file) => {
64
- expect(genComponentName(file)).toBe(asserts[file]);
65
- });
66
- });
67
-
68
- test('fileToPath', () => {
69
- const asserts: Record<string, string> = {
70
- 'index.md': '/',
71
- 'hello/index.md': '/hello/',
72
- 'foo.md': '/foo',
73
- 'foo/bar.md': '/foo/bar',
74
- 'index.js': '/',
75
- 'hello/index.js': '/hello/',
76
- 'foo.js': '/foo',
77
- 'foo/bar.js': '/foo/bar',
78
- };
79
- Object.keys(asserts).forEach((file) => {
80
- expect(fileToPath(file)).toBe(asserts[file]);
81
- });
82
- });
83
-
84
- test('objectWithKeySorted', () => {
85
- const obj = {
86
- '/docs/adding-blog': '4',
87
- '/docs/versioning': '5',
88
- '/': '1',
89
- '/blog/2018': '3',
90
- '/youtube': '7',
91
- '/users/en/': '6',
92
- '/blog': '2',
93
- };
94
- expect(objectWithKeySorted(obj)).toMatchInlineSnapshot(`
95
- Object {
96
- "/": "1",
97
- "/blog": "2",
98
- "/blog/2018": "3",
99
- "/docs/adding-blog": "4",
100
- "/docs/versioning": "5",
101
- "/users/en/": "6",
102
- "/youtube": "7",
103
- }
104
- `);
105
- const obj2 = {
106
- b: 'foo',
107
- c: 'bar',
108
- a: 'baz',
109
- };
110
- expect(objectWithKeySorted(obj2)).toMatchInlineSnapshot(`
111
- Object {
112
- "a": "baz",
113
- "b": "foo",
114
- "c": "bar",
115
- }
116
- `);
117
- });
118
-
119
- test('genChunkName', () => {
120
- const firstAssert: Record<string, string> = {
121
- '/docs/adding-blog': 'docs-adding-blog-062',
122
- '/docs/versioning': 'docs-versioning-8a8',
123
- '/': 'index',
124
- '/blog/2018/04/30/How-I-Converted-Profilo-To-Docusaurus':
125
- 'blog-2018-04-30-how-i-converted-profilo-to-docusaurus-4f2',
126
- '/youtube': 'youtube-429',
127
- '/users/en/': 'users-en-f7a',
128
- '/blog': 'blog-c06',
129
- };
130
- Object.keys(firstAssert).forEach((str) => {
131
- expect(genChunkName(str)).toBe(firstAssert[str]);
132
- });
133
-
134
- // Don't allow different chunk name for same path.
135
- expect(genChunkName('path/is/similar', 'oldPrefix')).toEqual(
136
- genChunkName('path/is/similar', 'newPrefix'),
137
- );
138
-
139
- // Even with same preferred name, still different chunk name for different path
140
- const secondAssert: Record<string, string> = {
141
- '/blog/1': 'blog-85-f-089',
142
- '/blog/2': 'blog-353-489',
143
- };
144
- Object.keys(secondAssert).forEach((str) => {
145
- expect(genChunkName(str, undefined, 'blog')).toBe(secondAssert[str]);
146
- });
147
-
148
- // Only generate short unique id
149
- const thirdAssert: Record<string, string> = {
150
- a: '0cc175b9',
151
- b: '92eb5ffe',
152
- c: '4a8a08f0',
153
- d: '8277e091',
154
- };
155
- Object.keys(thirdAssert).forEach((str) => {
156
- expect(genChunkName(str, undefined, undefined, true)).toBe(
157
- thirdAssert[str],
158
- );
159
- });
160
- expect(genChunkName('d', undefined, undefined, true)).toBe('8277e091');
161
- });
162
-
163
- test('idx', () => {
164
- const a = {};
165
- const b = {hello: 'world'};
166
- const obj = {
167
- translation: {
168
- enabled: true,
169
- enabledLanguages: [
170
- {
171
- enabled: true,
172
- name: 'English',
173
- tag: 'en',
174
- },
175
- {
176
- enabled: true,
177
- name: '日本語',
178
- tag: 'ja',
179
- },
180
- ],
181
- },
182
- versioning: {
183
- enabled: false,
184
- versions: [],
185
- },
186
- };
187
- const test = {arr: [1, 2, 3]};
188
- const variable = 'enabledLanguages';
189
- expect(idx(a, ['b', 'c'])).toBeUndefined();
190
- expect(idx(b, ['hello'])).toEqual('world');
191
- expect(idx(b, 'hello')).toEqual('world');
192
- expect(idx(obj, 'typo')).toBeUndefined();
193
- expect(idx(obj, 'versioning')).toEqual({
194
- enabled: false,
195
- versions: [],
196
- });
197
- expect(idx(obj, ['translation', 'enabled'])).toEqual(true);
198
- expect(
199
- idx(obj, ['translation', variable]).map(
200
- (lang: {tag: string}) => lang.tag,
201
- ),
202
- ).toEqual(['en', 'ja']);
203
- expect(idx(test, ['arr', 0])).toEqual(1);
204
- expect(idx(undefined)).toBeUndefined();
205
- expect(idx(null)).toBeNull();
206
- });
207
-
208
- test('getSubFolder', () => {
209
- const testA = path.join('folder', 'en', 'test.md');
210
- const testB = path.join('folder', 'ja', 'test.md');
211
- const testC = path.join('folder', 'ja', 'en', 'test.md');
212
- const testD = path.join('docs', 'ro', 'test.md');
213
- const testE = path.join('docs', 'test.md');
214
- expect(getSubFolder(testA, 'folder')).toBe('en');
215
- expect(getSubFolder(testB, 'folder')).toBe('ja');
216
- expect(getSubFolder(testC, 'folder')).toBe('ja');
217
- expect(getSubFolder(testD, 'docs')).toBe('ro');
218
- expect(getSubFolder(testE, 'docs')).toBeNull();
219
- });
220
-
221
- test('normalizeUrl', () => {
222
- const asserts = [
223
- {
224
- input: ['/', ''],
225
- output: '/',
226
- },
227
- {
228
- input: ['', '/'],
229
- output: '/',
230
- },
231
- {
232
- input: ['/'],
233
- output: '/',
234
- },
235
- {
236
- input: [''],
237
- output: '',
238
- },
239
- {
240
- input: ['/', '/'],
241
- output: '/',
242
- },
243
- {
244
- input: ['/', 'docs'],
245
- output: '/docs',
246
- },
247
- {
248
- input: ['/', 'docs', 'en', 'next', 'blog'],
249
- output: '/docs/en/next/blog',
250
- },
251
- {
252
- input: ['/test/', '/docs', 'ro', 'doc1'],
253
- output: '/test/docs/ro/doc1',
254
- },
255
- {
256
- input: ['/test/', '/', 'ro', 'doc1'],
257
- output: '/test/ro/doc1',
258
- },
259
- {
260
- input: ['/', '/', '2020/02/29/leap-day'],
261
- output: '/2020/02/29/leap-day',
262
- },
263
- {
264
- input: ['', '/', 'ko', 'hello'],
265
- output: '/ko/hello',
266
- },
267
- {
268
- input: ['hello', 'world'],
269
- output: 'hello/world',
270
- },
271
- {
272
- input: ['http://www.google.com/', 'foo/bar', '?test=123'],
273
- output: 'http://www.google.com/foo/bar?test=123',
274
- },
275
- {
276
- input: ['http:', 'www.google.com///', 'foo/bar', '?test=123'],
277
- output: 'http://www.google.com/foo/bar?test=123',
278
- },
279
- {
280
- input: ['http://foobar.com', '', 'test'],
281
- output: 'http://foobar.com/test',
282
- },
283
- {
284
- input: ['http://foobar.com', '', 'test', '/'],
285
- output: 'http://foobar.com/test/',
286
- },
287
- {
288
- input: ['/', '', 'hello', '', '/', '/', '', '/', '/world'],
289
- output: '/hello/world',
290
- },
291
- {
292
- input: ['', '', '/tt', 'ko', 'hello'],
293
- output: '/tt/ko/hello',
294
- },
295
- {
296
- input: ['', '///hello///', '', '///world'],
297
- output: '/hello/world',
298
- },
299
- {
300
- input: ['', '/hello/', ''],
301
- output: '/hello/',
302
- },
303
- {
304
- input: ['', '/', ''],
305
- output: '/',
306
- },
307
- {
308
- input: ['///', '///'],
309
- output: '/',
310
- },
311
- {
312
- input: ['/', '/hello/world/', '///'],
313
- output: '/hello/world/',
314
- },
315
- ];
316
- asserts.forEach((testCase) => {
317
- expect(normalizeUrl(testCase.input)).toBe(testCase.output);
318
- });
319
-
320
- expect(() =>
321
- // @ts-expect-error undefined for test
322
- normalizeUrl(['http:example.com', undefined]),
323
- ).toThrowErrorMatchingInlineSnapshot(
324
- `"Url must be a string. Received undefined"`,
325
- );
326
- });
327
-
328
- test('isValidPathname', () => {
329
- expect(isValidPathname('/')).toBe(true);
330
- expect(isValidPathname('/hey')).toBe(true);
331
- expect(isValidPathname('/hey/ho')).toBe(true);
332
- expect(isValidPathname('/hey/ho/')).toBe(true);
333
- expect(isValidPathname('/hey/h%C3%B4/')).toBe(true);
334
- expect(isValidPathname('/hey///ho///')).toBe(true); // Unexpected but valid
335
- expect(isValidPathname('/hey/héllô you')).toBe(true);
336
-
337
- //
338
- expect(isValidPathname('')).toBe(false);
339
- expect(isValidPathname('hey')).toBe(false);
340
- expect(isValidPathname('/hey?qs=ho')).toBe(false);
341
- expect(isValidPathname('https://fb.com/hey')).toBe(false);
342
- expect(isValidPathname('//hey')).toBe(false);
343
- });
344
- });
345
-
346
- describe('addTrailingSlash', () => {
347
- test('should no-op', () => {
348
- expect(addTrailingSlash('/abcd/')).toEqual('/abcd/');
349
- });
350
- test('should add /', () => {
351
- expect(addTrailingSlash('/abcd')).toEqual('/abcd/');
352
- });
353
- });
354
-
355
- describe('addLeadingSlash', () => {
356
- test('should no-op', () => {
357
- expect(addLeadingSlash('/abc')).toEqual('/abc');
358
- });
359
- test('should add /', () => {
360
- expect(addLeadingSlash('abc')).toEqual('/abc');
361
- });
362
- });
363
-
364
- describe('removeTrailingSlash', () => {
365
- test('should no-op', () => {
366
- expect(removeTrailingSlash('/abcd')).toEqual('/abcd');
367
- });
368
- test('should remove /', () => {
369
- expect(removeTrailingSlash('/abcd/')).toEqual('/abcd');
370
- });
371
- });
372
-
373
- describe('removeSuffix', () => {
374
- test('should no-op 1', () => {
375
- expect(removeSuffix('abcdef', 'ijk')).toEqual('abcdef');
376
- });
377
- test('should no-op 2', () => {
378
- expect(removeSuffix('abcdef', 'abc')).toEqual('abcdef');
379
- });
380
- test('should no-op 3', () => {
381
- expect(removeSuffix('abcdef', '')).toEqual('abcdef');
382
- });
383
- test('should remove suffix', () => {
384
- expect(removeSuffix('abcdef', 'ef')).toEqual('abcd');
385
- });
386
- });
387
-
388
- describe('removePrefix', () => {
389
- test('should no-op 1', () => {
390
- expect(removePrefix('abcdef', 'ijk')).toEqual('abcdef');
391
- });
392
- test('should no-op 2', () => {
393
- expect(removePrefix('abcdef', 'def')).toEqual('abcdef');
394
- });
395
- test('should no-op 3', () => {
396
- expect(removePrefix('abcdef', '')).toEqual('abcdef');
397
- });
398
- test('should remove prefix', () => {
399
- expect(removePrefix('abcdef', 'ab')).toEqual('cdef');
400
- });
401
- });
402
-
403
- describe('getElementsAround', () => {
404
- test('can return elements around', () => {
405
- expect(getElementsAround(['a', 'b', 'c', 'd'], 0)).toEqual({
406
- previous: undefined,
407
- next: 'b',
408
- });
409
- expect(getElementsAround(['a', 'b', 'c', 'd'], 1)).toEqual({
410
- previous: 'a',
411
- next: 'c',
412
- });
413
- expect(getElementsAround(['a', 'b', 'c', 'd'], 2)).toEqual({
414
- previous: 'b',
415
- next: 'd',
416
- });
417
- expect(getElementsAround(['a', 'b', 'c', 'd'], 3)).toEqual({
418
- previous: 'c',
419
- next: undefined,
420
- });
421
- });
422
-
423
- test('throws if bad index is provided', () => {
424
- expect(() =>
425
- getElementsAround(['a', 'b', 'c', 'd'], -1),
426
- ).toThrowErrorMatchingInlineSnapshot(
427
- `"Valid \\"aroundIndex\\" for array (of size 4) are between 0 and 3, but you provided -1."`,
428
- );
429
- expect(() =>
430
- getElementsAround(['a', 'b', 'c', 'd'], 4),
431
- ).toThrowErrorMatchingInlineSnapshot(
432
- `"Valid \\"aroundIndex\\" for array (of size 4) are between 0 and 3, but you provided 4."`,
433
- );
434
- });
435
- });
436
-
437
- describe('mergeTranslations', () => {
438
- test('should merge translations', () => {
439
- expect(
440
- mergeTranslations([
441
- {
442
- T1: {message: 'T1 message', description: 'T1 desc'},
443
- T2: {message: 'T2 message', description: 'T2 desc'},
444
- T3: {message: 'T3 message', description: 'T3 desc'},
445
- },
446
- {
447
- T4: {message: 'T4 message', description: 'T4 desc'},
448
- },
449
- {T2: {message: 'T2 message 2', description: 'T2 desc 2'}},
450
- ]),
451
- ).toEqual({
452
- T1: {message: 'T1 message', description: 'T1 desc'},
453
- T2: {message: 'T2 message 2', description: 'T2 desc 2'},
454
- T3: {message: 'T3 message', description: 'T3 desc'},
455
- T4: {message: 'T4 message', description: 'T4 desc'},
456
- });
457
- });
458
- });
459
-
460
- describe('mapAsyncSequencial', () => {
461
- function sleep(timeout: number): Promise<void> {
462
- return new Promise((resolve) => setTimeout(resolve, timeout));
463
- }
464
-
465
- test('map sequentially', async () => {
466
- const itemToTimeout: Record<string, number> = {
467
- '1': 50,
468
- '2': 150,
469
- '3': 100,
470
- };
471
- const items = Object.keys(itemToTimeout);
472
-
473
- const itemMapStartsAt: Record<string, number> = {};
474
- const itemMapEndsAt: Record<string, number> = {};
475
-
476
- const timeBefore = Date.now();
477
- await expect(
478
- mapAsyncSequencial(items, async (item) => {
479
- const itemTimeout = itemToTimeout[item];
480
- itemMapStartsAt[item] = Date.now();
481
- await sleep(itemTimeout);
482
- itemMapEndsAt[item] = Date.now();
483
- return `${item} mapped`;
484
- }),
485
- ).resolves.toEqual(['1 mapped', '2 mapped', '3 mapped']);
486
- const timeAfter = Date.now();
487
-
488
- const timeTotal = timeAfter - timeBefore;
489
-
490
- const totalTimeouts = sum(Object.values(itemToTimeout));
491
- expect(timeTotal > totalTimeouts);
492
-
493
- expect(itemMapStartsAt['1'] > 0);
494
- expect(itemMapStartsAt['2'] > itemMapEndsAt['1']);
495
- expect(itemMapStartsAt['3'] > itemMapEndsAt['2']);
496
- });
497
- });
498
-
499
- describe('findAsyncSequencial', () => {
500
- function sleep(timeout: number): Promise<void> {
501
- return new Promise((resolve) => setTimeout(resolve, timeout));
502
- }
503
-
504
- test('find sequentially', async () => {
505
- const items = ['1', '2', '3'];
506
-
507
- const findFn = jest.fn(async (item: string) => {
508
- await sleep(50);
509
- return item === '2';
510
- });
511
-
512
- const timeBefore = Date.now();
513
- await expect(findAsyncSequential(items, findFn)).resolves.toEqual('2');
514
- const timeAfter = Date.now();
515
-
516
- expect(findFn).toHaveBeenCalledTimes(2);
517
- expect(findFn).toHaveBeenNthCalledWith(1, '1');
518
- expect(findFn).toHaveBeenNthCalledWith(2, '2');
519
-
520
- const timeTotal = timeAfter - timeBefore;
521
- expect(timeTotal > 100);
522
- expect(timeTotal < 150);
523
- });
524
- });
525
-
526
- describe('findFolderContainingFile', () => {
527
- test('find appropriate folder', async () => {
528
- await expect(
529
- findFolderContainingFile(
530
- ['/abcdef', '/gehij', __dirname, '/klmn'],
531
- 'index.test.ts',
532
- ),
533
- ).resolves.toEqual(__dirname);
534
- });
535
-
536
- test('return undefined if no folder contain such file', async () => {
537
- await expect(
538
- findFolderContainingFile(['/abcdef', '/gehij', '/klmn'], 'index.test.ts'),
539
- ).resolves.toBeUndefined();
540
- });
541
- });
542
-
543
- describe('getFolderContainingFile', () => {
544
- test('get appropriate folder', async () => {
545
- await expect(
546
- getFolderContainingFile(
547
- ['/abcdef', '/gehij', __dirname, '/klmn'],
548
- 'index.test.ts',
549
- ),
550
- ).resolves.toEqual(__dirname);
551
- });
552
-
553
- test('throw if no folder contain such file', async () => {
554
- await expect(
555
- getFolderContainingFile(['/abcdef', '/gehij', '/klmn'], 'index.test.ts'),
556
- ).rejects.toThrowErrorMatchingSnapshot();
557
- });
558
- });
559
-
560
- describe('updateTranslationFileMessages', () => {
561
- test('should update messages', () => {
562
- expect(
563
- updateTranslationFileMessages(
564
- {
565
- path: 'abc',
566
- content: {
567
- t1: {message: 't1 message', description: 't1 desc'},
568
- t2: {message: 't2 message', description: 't2 desc'},
569
- t3: {message: 't3 message', description: 't3 desc'},
570
- },
571
- },
572
- (message) => `prefix ${message} suffix`,
573
- ),
574
- ).toEqual({
575
- path: 'abc',
576
- content: {
577
- t1: {message: 'prefix t1 message suffix', description: 't1 desc'},
578
- t2: {message: 'prefix t2 message suffix', description: 't2 desc'},
579
- t3: {message: 'prefix t3 message suffix', description: 't3 desc'},
580
- },
581
- });
582
- });
583
- });
584
-
585
- describe('parseMarkdownHeadingId', () => {
586
- test('can parse simple heading without id', () => {
587
- expect(parseMarkdownHeadingId('## Some heading')).toEqual({
588
- text: '## Some heading',
589
- id: undefined,
590
- });
591
- });
592
-
593
- test('can parse simple heading with id', () => {
594
- expect(parseMarkdownHeadingId('## Some heading {#custom-_id}')).toEqual({
595
- text: '## Some heading',
596
- id: 'custom-_id',
597
- });
598
- });
599
-
600
- test('can parse heading not ending with the id', () => {
601
- expect(parseMarkdownHeadingId('## {#custom-_id} Some heading')).toEqual({
602
- text: '## {#custom-_id} Some heading',
603
- id: undefined,
604
- });
605
- });
606
-
607
- test('can parse heading with multiple id', () => {
608
- expect(parseMarkdownHeadingId('## Some heading {#id1} {#id2}')).toEqual({
609
- text: '## Some heading {#id1}',
610
- id: 'id2',
611
- });
612
- });
613
-
614
- test('can parse heading with link and id', () => {
615
- expect(
616
- parseMarkdownHeadingId(
617
- '## Some heading [facebook](https://facebook.com) {#id}',
618
- ),
619
- ).toEqual({
620
- text: '## Some heading [facebook](https://facebook.com)',
621
- id: 'id',
622
- });
623
- });
624
-
625
- test('can parse heading with only id', () => {
626
- expect(parseMarkdownHeadingId('## {#id}')).toEqual({
627
- text: '##',
628
- id: 'id',
629
- });
630
- });
631
- });