@docusaurus/utils 2.0.0-beta.8bda3b2db → 2.0.0-beta.9
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/lib/.tsbuildinfo +1 -1
- package/lib/codeTranslationsUtils.js +2 -2
- package/lib/globUtils.d.ts +11 -0
- package/lib/globUtils.js +47 -0
- package/lib/{docuHash.d.ts → hashUtils.d.ts} +2 -0
- package/lib/{docuHash.js → hashUtils.js} +15 -5
- package/lib/index.d.ts +5 -4
- package/lib/index.js +38 -88
- package/lib/markdownLinks.js +19 -6
- package/lib/markdownParser.js +20 -12
- package/lib/mdxUtils.d.ts +16 -0
- package/lib/mdxUtils.js +30 -0
- package/lib/{getFilePathForRoutePath.d.ts → normalizeUrl.d.ts} +1 -1
- package/lib/normalizeUrl.js +66 -0
- package/lib/pathUtils.d.ts +0 -1
- package/lib/pathUtils.js +1 -6
- package/lib/tags.d.ts +18 -0
- package/lib/tags.js +72 -0
- package/package.json +17 -6
- package/src/__tests__/globUtils.test.ts +109 -0
- package/src/__tests__/{docuHash.test.ts → hashUtils.test.ts} +22 -1
- package/src/__tests__/index.test.ts +0 -108
- package/src/__tests__/markdownParser.test.ts +13 -0
- package/src/__tests__/mdxUtils.test.ts +133 -0
- package/src/__tests__/normalizeUrl.test.ts +117 -0
- package/src/__tests__/pathUtils.test.ts +5 -22
- package/src/__tests__/tags.test.ts +183 -0
- package/src/dependencies.d.ts +12 -0
- package/src/globUtils.ts +63 -0
- package/src/{docuHash.ts → hashUtils.ts} +10 -1
- package/src/index.ts +14 -83
- package/src/markdownLinks.ts +19 -8
- package/src/markdownParser.ts +24 -17
- package/src/mdxUtils.ts +32 -0
- package/src/normalizeUrl.ts +80 -0
- package/src/pathUtils.ts +0 -6
- package/src/tags.ts +100 -0
- package/src/types.d.ts +10 -0
- package/yarn-error.log +17862 -0
- package/lib/getFilePathForRoutePath.js +0 -40
- package/src/__tests__/getFilePathForRoutePath.test.ts +0 -87
- package/src/getFilePathForRoutePath.ts +0 -43
|
@@ -0,0 +1,109 @@
|
|
|
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 {
|
|
9
|
+
GlobExcludeDefault,
|
|
10
|
+
createMatcher,
|
|
11
|
+
createAbsoluteFilePathMatcher,
|
|
12
|
+
} from '../globUtils';
|
|
13
|
+
|
|
14
|
+
describe('createMatcher', () => {
|
|
15
|
+
const matcher = createMatcher(GlobExcludeDefault);
|
|
16
|
+
|
|
17
|
+
test('match default exclude MD/MDX partials correctly', () => {
|
|
18
|
+
expect(matcher('doc.md')).toEqual(false);
|
|
19
|
+
expect(matcher('category/doc.md')).toEqual(false);
|
|
20
|
+
expect(matcher('category/subcategory/doc.md')).toEqual(false);
|
|
21
|
+
//
|
|
22
|
+
expect(matcher('doc.mdx')).toEqual(false);
|
|
23
|
+
expect(matcher('category/doc.mdx')).toEqual(false);
|
|
24
|
+
expect(matcher('category/subcategory/doc.mdx')).toEqual(false);
|
|
25
|
+
//
|
|
26
|
+
expect(matcher('_doc.md')).toEqual(true);
|
|
27
|
+
expect(matcher('category/_doc.md')).toEqual(true);
|
|
28
|
+
expect(matcher('category/subcategory/_doc.md')).toEqual(true);
|
|
29
|
+
expect(matcher('_category/doc.md')).toEqual(true);
|
|
30
|
+
expect(matcher('_category/subcategory/doc.md')).toEqual(true);
|
|
31
|
+
expect(matcher('category/_subcategory/doc.md')).toEqual(true);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('match default exclude tests correctly', () => {
|
|
35
|
+
expect(matcher('xyz.js')).toEqual(false);
|
|
36
|
+
expect(matcher('xyz.ts')).toEqual(false);
|
|
37
|
+
expect(matcher('xyz.jsx')).toEqual(false);
|
|
38
|
+
expect(matcher('xyz.tsx')).toEqual(false);
|
|
39
|
+
expect(matcher('folder/xyz.js')).toEqual(false);
|
|
40
|
+
expect(matcher('folder/xyz.ts')).toEqual(false);
|
|
41
|
+
expect(matcher('folder/xyz.jsx')).toEqual(false);
|
|
42
|
+
expect(matcher('folder/xyz.tsx')).toEqual(false);
|
|
43
|
+
//
|
|
44
|
+
expect(matcher('xyz.test.js')).toEqual(true);
|
|
45
|
+
expect(matcher('xyz.test.ts')).toEqual(true);
|
|
46
|
+
expect(matcher('xyz.test.jsx')).toEqual(true);
|
|
47
|
+
expect(matcher('xyz.test.tsx')).toEqual(true);
|
|
48
|
+
expect(matcher('folder/xyz.test.js')).toEqual(true);
|
|
49
|
+
expect(matcher('folder/xyz.test.ts')).toEqual(true);
|
|
50
|
+
expect(matcher('folder/xyz.test.jsx')).toEqual(true);
|
|
51
|
+
expect(matcher('folder/xyz.test.tsx')).toEqual(true);
|
|
52
|
+
expect(matcher('folder/subfolder/xyz.test.js')).toEqual(true);
|
|
53
|
+
expect(matcher('folder/subfolder/xyz.test.ts')).toEqual(true);
|
|
54
|
+
expect(matcher('folder/subfolder/xyz.test.jsx')).toEqual(true);
|
|
55
|
+
expect(matcher('folder/subfolder/xyz.test.tsx')).toEqual(true);
|
|
56
|
+
//
|
|
57
|
+
expect(matcher('__tests__/subfolder/xyz.js')).toEqual(true);
|
|
58
|
+
expect(matcher('__tests__/subfolder/xyz.ts')).toEqual(true);
|
|
59
|
+
expect(matcher('__tests__/subfolder/xyz.jsx')).toEqual(true);
|
|
60
|
+
expect(matcher('__tests__/subfolder/xyz.tsx')).toEqual(true);
|
|
61
|
+
expect(matcher('folder/__tests__/xyz.js')).toEqual(true);
|
|
62
|
+
expect(matcher('folder/__tests__/xyz.ts')).toEqual(true);
|
|
63
|
+
expect(matcher('folder/__tests__/xyz.jsx')).toEqual(true);
|
|
64
|
+
expect(matcher('folder/__tests__/xyz.tsx')).toEqual(true);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('createAbsoluteFilePathMatcher', () => {
|
|
69
|
+
const rootFolders = ['/_root/docs', '/root/_docs/', '/__test__/website/src'];
|
|
70
|
+
|
|
71
|
+
const matcher = createAbsoluteFilePathMatcher(
|
|
72
|
+
GlobExcludeDefault,
|
|
73
|
+
rootFolders,
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
test('match default exclude MD/MDX partials correctly', () => {
|
|
77
|
+
expect(matcher('/_root/docs/myDoc.md')).toEqual(false);
|
|
78
|
+
expect(matcher('/_root/docs/myDoc.mdx')).toEqual(false);
|
|
79
|
+
expect(matcher('/root/_docs/myDoc.md')).toEqual(false);
|
|
80
|
+
expect(matcher('/root/_docs/myDoc.mdx')).toEqual(false);
|
|
81
|
+
expect(matcher('/_root/docs/category/myDoc.md')).toEqual(false);
|
|
82
|
+
expect(matcher('/_root/docs/category/myDoc.mdx')).toEqual(false);
|
|
83
|
+
expect(matcher('/root/_docs/category/myDoc.md')).toEqual(false);
|
|
84
|
+
expect(matcher('/root/_docs/category/myDoc.mdx')).toEqual(false);
|
|
85
|
+
//
|
|
86
|
+
expect(matcher('/_root/docs/_myDoc.md')).toEqual(true);
|
|
87
|
+
expect(matcher('/_root/docs/_myDoc.mdx')).toEqual(true);
|
|
88
|
+
expect(matcher('/root/_docs/_myDoc.md')).toEqual(true);
|
|
89
|
+
expect(matcher('/root/_docs/_myDoc.mdx')).toEqual(true);
|
|
90
|
+
expect(matcher('/_root/docs/_category/myDoc.md')).toEqual(true);
|
|
91
|
+
expect(matcher('/_root/docs/_category/myDoc.mdx')).toEqual(true);
|
|
92
|
+
expect(matcher('/root/_docs/_category/myDoc.md')).toEqual(true);
|
|
93
|
+
expect(matcher('/root/_docs/_category/myDoc.mdx')).toEqual(true);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('match default exclude tests correctly', () => {
|
|
97
|
+
expect(matcher('/__test__/website/src/xyz.js')).toEqual(false);
|
|
98
|
+
expect(matcher('/__test__/website/src/__test__/xyz.js')).toEqual(true);
|
|
99
|
+
expect(matcher('/__test__/website/src/xyz.test.js')).toEqual(true);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
test('throw if file is not contained in any root doc', () => {
|
|
103
|
+
expect(() =>
|
|
104
|
+
matcher('/bad/path/myDoc.md'),
|
|
105
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
106
|
+
`"createAbsoluteFilePathMatcher unexpected error, absoluteFilePath=/bad/path/myDoc.md was not contained in any of the root folders [\\"/_root/docs\\",\\"/root/_docs/\\",\\"/__test__/website/src\\"]"`,
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
@@ -5,7 +5,28 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {docuHash} from '../
|
|
8
|
+
import {simpleHash, docuHash} from '../hashUtils';
|
|
9
|
+
|
|
10
|
+
describe('hashUtils', () => {
|
|
11
|
+
test('simpleHash', () => {
|
|
12
|
+
const asserts: Record<string, string> = {
|
|
13
|
+
'': 'd41',
|
|
14
|
+
'/foo-bar': '096',
|
|
15
|
+
'/foo/bar': '1df',
|
|
16
|
+
'/endi/lie': '9fa',
|
|
17
|
+
'/endi-lie': 'fd3',
|
|
18
|
+
'/yangshun/tay': '48d',
|
|
19
|
+
'/yangshun-tay': 'f3b',
|
|
20
|
+
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar':
|
|
21
|
+
'd46',
|
|
22
|
+
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/test1-test2':
|
|
23
|
+
'787',
|
|
24
|
+
};
|
|
25
|
+
Object.keys(asserts).forEach((str) => {
|
|
26
|
+
expect(simpleHash(str, 3)).toBe(asserts[str]);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
9
30
|
|
|
10
31
|
describe('docuHash', () => {
|
|
11
32
|
test('docuHash works', () => {
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
genChunkName,
|
|
13
13
|
idx,
|
|
14
14
|
getSubFolder,
|
|
15
|
-
normalizeUrl,
|
|
16
15
|
posixPath,
|
|
17
16
|
objectWithKeySorted,
|
|
18
17
|
aliasedSitePath,
|
|
@@ -218,113 +217,6 @@ describe('load utils', () => {
|
|
|
218
217
|
expect(getSubFolder(testE, 'docs')).toBeNull();
|
|
219
218
|
});
|
|
220
219
|
|
|
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
220
|
test('isValidPathname', () => {
|
|
329
221
|
expect(isValidPathname('/')).toBe(true);
|
|
330
222
|
expect(isValidPathname('/hey')).toBe(true);
|
|
@@ -129,6 +129,19 @@ describe('createExcerpt', () => {
|
|
|
129
129
|
`),
|
|
130
130
|
).toEqual('Markdown title');
|
|
131
131
|
});
|
|
132
|
+
|
|
133
|
+
test('should create excerpt for content with various code blocks', () => {
|
|
134
|
+
expect(
|
|
135
|
+
createExcerpt(dedent`
|
|
136
|
+
\`\`\`jsx
|
|
137
|
+
import React from 'react';
|
|
138
|
+
import Layout from '@theme/Layout';
|
|
139
|
+
\`\`\`
|
|
140
|
+
|
|
141
|
+
Lorem \`ipsum\` dolor sit amet, consectetur \`adipiscing elit\`.
|
|
142
|
+
`),
|
|
143
|
+
).toEqual('Lorem ipsum dolor sit amet, consectetur adipiscing elit.');
|
|
144
|
+
});
|
|
132
145
|
});
|
|
133
146
|
|
|
134
147
|
describe('parseMarkdownContentTitle', () => {
|
|
@@ -0,0 +1,133 @@
|
|
|
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 {mdxToHtml} from '../mdxUtils';
|
|
9
|
+
|
|
10
|
+
describe('mdxToHtml', () => {
|
|
11
|
+
test('work with simple markdown', () => {
|
|
12
|
+
const mdxString = `
|
|
13
|
+
# title
|
|
14
|
+
|
|
15
|
+
title text **bold**
|
|
16
|
+
|
|
17
|
+
## subtitle
|
|
18
|
+
|
|
19
|
+
subtitle text *italic*
|
|
20
|
+
|
|
21
|
+
> Quote
|
|
22
|
+
|
|
23
|
+
`;
|
|
24
|
+
|
|
25
|
+
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
|
26
|
+
`"<h1>title</h1><p>title text <strong>bold</strong></p><h2>subtitle</h2><p>subtitle text <em>italic</em></p><blockquote><p>Quote</p></blockquote>"`,
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('work with MDX imports', () => {
|
|
31
|
+
const mdxString = `
|
|
32
|
+
# title
|
|
33
|
+
|
|
34
|
+
import Tabs from '@theme/Tabs';
|
|
35
|
+
import TabItem from '@theme/TabItem';
|
|
36
|
+
|
|
37
|
+
text
|
|
38
|
+
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
|
42
|
+
`"<h1>title</h1><p>text</p>"`,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('work with MDX exports', () => {
|
|
47
|
+
const mdxString = `
|
|
48
|
+
# title
|
|
49
|
+
|
|
50
|
+
export const someExport = 42
|
|
51
|
+
|
|
52
|
+
export const MyLocalComponent = () => "result"
|
|
53
|
+
|
|
54
|
+
export const toc = [
|
|
55
|
+
{id: "title",label: "title"}
|
|
56
|
+
]
|
|
57
|
+
|
|
58
|
+
text
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
|
64
|
+
`"<h1>title</h1><p>text</p>"`,
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('work with MDX Tabs', () => {
|
|
69
|
+
const mdxString = `
|
|
70
|
+
# title
|
|
71
|
+
|
|
72
|
+
import Tabs from '@theme/Tabs';
|
|
73
|
+
import TabItem from '@theme/TabItem';
|
|
74
|
+
|
|
75
|
+
<Tabs>
|
|
76
|
+
<TabItem value="apple" label="Apple">
|
|
77
|
+
This is an apple 🍎
|
|
78
|
+
</TabItem>
|
|
79
|
+
<TabItem value="orange" label="Orange">
|
|
80
|
+
This is an orange 🍊
|
|
81
|
+
</TabItem>
|
|
82
|
+
</Tabs>
|
|
83
|
+
|
|
84
|
+
text
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
`;
|
|
88
|
+
|
|
89
|
+
// TODO this is not an ideal behavior!
|
|
90
|
+
// There is a warning "Component TabItem was not imported, exported, or provided by MDXProvider as global scope"
|
|
91
|
+
// Theme + MDX config should provide a list of React components to put in MDX scope
|
|
92
|
+
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
|
|
93
|
+
`"<h1>title</h1><div><div value=\\"apple\\" label=\\"Apple\\">This is an apple 🍎</div><div value=\\"orange\\" label=\\"Orange\\">This is an orange 🍊</div></div><p>text</p>"`,
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('work with MDX Tabs with ```mdx-code-block', () => {
|
|
98
|
+
const mdxString = `
|
|
99
|
+
# title
|
|
100
|
+
|
|
101
|
+
import Tabs from '@theme/Tabs';
|
|
102
|
+
import TabItem from '@theme/TabItem';
|
|
103
|
+
|
|
104
|
+
\`\`\`mdx-code-block
|
|
105
|
+
<Tabs>
|
|
106
|
+
<TabItem value="apple" label="Apple">
|
|
107
|
+
This is an apple 🍎
|
|
108
|
+
</TabItem>
|
|
109
|
+
<TabItem value="orange" label="Orange">
|
|
110
|
+
This is an orange 🍊
|
|
111
|
+
</TabItem>
|
|
112
|
+
</Tabs>
|
|
113
|
+
\`\`\`
|
|
114
|
+
|
|
115
|
+
text
|
|
116
|
+
|
|
117
|
+
`;
|
|
118
|
+
|
|
119
|
+
// TODO bad behavior!
|
|
120
|
+
// ```mdx-code-block should be unwrapped and inner MDX content should be evaluated
|
|
121
|
+
expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(`
|
|
122
|
+
"<h1>title</h1><pre><code class=\\"language-mdx-code-block\\"><Tabs>
|
|
123
|
+
<TabItem value="apple" label="Apple">
|
|
124
|
+
This is an apple 🍎
|
|
125
|
+
</TabItem>
|
|
126
|
+
<TabItem value="orange" label="Orange">
|
|
127
|
+
This is an orange 🍊
|
|
128
|
+
</TabItem>
|
|
129
|
+
</Tabs>
|
|
130
|
+
</code></pre><p>text</p>"
|
|
131
|
+
`);
|
|
132
|
+
});
|
|
133
|
+
});
|
|
@@ -0,0 +1,117 @@
|
|
|
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 {normalizeUrl} from '../normalizeUrl';
|
|
9
|
+
|
|
10
|
+
describe('normalizeUrl', () => {
|
|
11
|
+
test('should normalize urls correctly', () => {
|
|
12
|
+
const asserts = [
|
|
13
|
+
{
|
|
14
|
+
input: ['/', ''],
|
|
15
|
+
output: '/',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
input: ['', '/'],
|
|
19
|
+
output: '/',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
input: ['/'],
|
|
23
|
+
output: '/',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
input: [''],
|
|
27
|
+
output: '',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
input: ['/', '/'],
|
|
31
|
+
output: '/',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
input: ['/', 'docs'],
|
|
35
|
+
output: '/docs',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
input: ['/', 'docs', 'en', 'next', 'blog'],
|
|
39
|
+
output: '/docs/en/next/blog',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
input: ['/test/', '/docs', 'ro', 'doc1'],
|
|
43
|
+
output: '/test/docs/ro/doc1',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
input: ['/test/', '/', 'ro', 'doc1'],
|
|
47
|
+
output: '/test/ro/doc1',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
input: ['/', '/', '2020/02/29/leap-day'],
|
|
51
|
+
output: '/2020/02/29/leap-day',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
input: ['', '/', 'ko', 'hello'],
|
|
55
|
+
output: '/ko/hello',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
input: ['hello', 'world'],
|
|
59
|
+
output: 'hello/world',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
input: ['http://www.google.com/', 'foo/bar', '?test=123'],
|
|
63
|
+
output: 'http://www.google.com/foo/bar?test=123',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
input: ['http:', 'www.google.com///', 'foo/bar', '?test=123'],
|
|
67
|
+
output: 'http://www.google.com/foo/bar?test=123',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
input: ['http://foobar.com', '', 'test'],
|
|
71
|
+
output: 'http://foobar.com/test',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
input: ['http://foobar.com', '', 'test', '/'],
|
|
75
|
+
output: 'http://foobar.com/test/',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
input: ['/', '', 'hello', '', '/', '/', '', '/', '/world'],
|
|
79
|
+
output: '/hello/world',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
input: ['', '', '/tt', 'ko', 'hello'],
|
|
83
|
+
output: '/tt/ko/hello',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
input: ['', '///hello///', '', '///world'],
|
|
87
|
+
output: '/hello/world',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
input: ['', '/hello/', ''],
|
|
91
|
+
output: '/hello/',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
input: ['', '/', ''],
|
|
95
|
+
output: '/',
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
input: ['///', '///'],
|
|
99
|
+
output: '/',
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
input: ['/', '/hello/world/', '///'],
|
|
103
|
+
output: '/hello/world/',
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
asserts.forEach((testCase) => {
|
|
107
|
+
expect(normalizeUrl(testCase.input)).toBe(testCase.output);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
expect(() =>
|
|
111
|
+
// @ts-expect-error undefined for test
|
|
112
|
+
normalizeUrl(['http:example.com', undefined]),
|
|
113
|
+
).toThrowErrorMatchingInlineSnapshot(
|
|
114
|
+
`"Url must be a string. Received undefined"`,
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
@@ -5,28 +5,9 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import {isNameTooLong, shortName} from '../pathUtils';
|
|
9
9
|
|
|
10
10
|
describe('pathUtils', () => {
|
|
11
|
-
test('simpleHash', () => {
|
|
12
|
-
const asserts: Record<string, string> = {
|
|
13
|
-
'': 'd41',
|
|
14
|
-
'/foo-bar': '096',
|
|
15
|
-
'/foo/bar': '1df',
|
|
16
|
-
'/endi/lie': '9fa',
|
|
17
|
-
'/endi-lie': 'fd3',
|
|
18
|
-
'/yangshun/tay': '48d',
|
|
19
|
-
'/yangshun-tay': 'f3b',
|
|
20
|
-
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar':
|
|
21
|
-
'd46',
|
|
22
|
-
'/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/test1-test2':
|
|
23
|
-
'787',
|
|
24
|
-
};
|
|
25
|
-
Object.keys(asserts).forEach((file) => {
|
|
26
|
-
expect(simpleHash(file, 3)).toBe(asserts[file]);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
11
|
test('isNameTooLong', () => {
|
|
31
12
|
const asserts: Record<string, boolean> = {
|
|
32
13
|
'': false,
|
|
@@ -36,8 +17,10 @@ describe('pathUtils', () => {
|
|
|
36
17
|
'endi-lie-fd3': false,
|
|
37
18
|
'yangshun-tay-48d': false,
|
|
38
19
|
'yangshun-tay-f3b': false,
|
|
39
|
-
'foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-d46':
|
|
40
|
-
|
|
20
|
+
'foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-d46':
|
|
21
|
+
true,
|
|
22
|
+
'foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-test-1-test-2-787':
|
|
23
|
+
true,
|
|
41
24
|
};
|
|
42
25
|
Object.keys(asserts).forEach((path) => {
|
|
43
26
|
expect(isNameTooLong(path)).toBe(asserts[path]);
|