test: improve test coverage (#7113)

This commit is contained in:
Joshua Chen 2022-04-05 14:09:19 +08:00 committed by GitHub
parent 4194925da9
commit e610a4ac00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 235 additions and 61 deletions

View file

@ -25,6 +25,7 @@ const ignorePatterns = [
'/packages/docusaurus-theme-classic/lib-next', '/packages/docusaurus-theme-classic/lib-next',
'/packages/docusaurus-theme-common/lib', '/packages/docusaurus-theme-common/lib',
'/packages/docusaurus-migrate/lib', '/packages/docusaurus-migrate/lib',
'/jest',
]; ];
export default { export default {

View file

@ -74,7 +74,20 @@ bbbbb",
} }
`; `;
exports[`parseLines respects language 1`] = ` exports[`parseLines respects language: html 1`] = `
{
"code": "aaaa
{/* highlight-next-line */}
bbbbb
dddd",
"highlightLines": [
0,
3,
],
}
`;
exports[`parseLines respects language: js 1`] = `
{ {
"code": "# highlight-next-line "code": "# highlight-next-line
aaaaa aaaaa
@ -83,31 +96,47 @@ bbbbb",
} }
`; `;
exports[`parseLines respects language 2`] = ` exports[`parseLines respects language: jsx 1`] = `
{ {
"code": "/* highlight-next-line */ "code": "aaaa
aaaaa
bbbbb",
"highlightLines": [],
}
`;
exports[`parseLines respects language 3`] = `
{
"code": "// highlight-next-line
aaaa
/* highlight-next-line */
bbbbb bbbbb
ccccc
<!-- highlight-next-line --> <!-- highlight-next-line -->
dddd", dddd",
"highlightLines": [ "highlightLines": [
4, 0,
1,
], ],
} }
`; `;
exports[`parseLines respects language 4`] = ` exports[`parseLines respects language: md 1`] = `
{
"code": "---
aaa: boo
---
aaaa
<div>
foo
</div>
bbbbb
dddd
\`\`\`js
// highlight-next-line
console.log(\\"preserved\\");
\`\`\`",
"highlightLines": [
1,
7,
11,
],
}
`;
exports[`parseLines respects language: none 1`] = `
{ {
"code": "aaaa "code": "aaaa
bbbbb bbbbb
@ -121,3 +150,27 @@ dddd",
], ],
} }
`; `;
exports[`parseLines respects language: py 1`] = `
{
"code": "/* highlight-next-line */
aaaaa
bbbbb",
"highlightLines": [],
}
`;
exports[`parseLines respects language: py 2`] = `
{
"code": "// highlight-next-line
aaaa
/* highlight-next-line */
bbbbb
ccccc
<!-- highlight-next-line -->
dddd",
"highlightLines": [
4,
],
}
`;

View file

@ -140,7 +140,7 @@ bbbbb`,
'', '',
'js', 'js',
), ),
).toMatchSnapshot(); ).toMatchSnapshot('js');
expect( expect(
parseLines( parseLines(
`/* highlight-next-line */ `/* highlight-next-line */
@ -149,7 +149,7 @@ bbbbb`,
'', '',
'py', 'py',
), ),
).toMatchSnapshot(); ).toMatchSnapshot('py');
expect( expect(
parseLines( parseLines(
`// highlight-next-line `// highlight-next-line
@ -163,7 +163,7 @@ dddd`,
'', '',
'py', 'py',
), ),
).toMatchSnapshot(); ).toMatchSnapshot('py');
expect( expect(
parseLines( parseLines(
`// highlight-next-line `// highlight-next-line
@ -177,6 +177,57 @@ dddd`,
'', '',
'', '',
), ),
).toMatchSnapshot(); ).toMatchSnapshot('none');
expect(
parseLines(
`// highlight-next-line
aaaa
{/* highlight-next-line */}
bbbbb
<!-- highlight-next-line -->
dddd`,
'',
'jsx',
),
).toMatchSnapshot('jsx');
expect(
parseLines(
`// highlight-next-line
aaaa
{/* highlight-next-line */}
bbbbb
<!-- highlight-next-line -->
dddd`,
'',
'html',
),
).toMatchSnapshot('html');
expect(
parseLines(
`---
# highlight-next-line
aaa: boo
---
aaaa
<div>
{/* highlight-next-line */}
foo
</div>
bbbbb
<!-- highlight-next-line -->
dddd
\`\`\`js
// highlight-next-line
console.log("preserved");
\`\`\`
`,
'',
'md',
),
).toMatchSnapshot('md');
}); });
}); });

View file

@ -141,29 +141,29 @@ export function parseLines(
for (let lineNumber = 0; lineNumber < lines.length; ) { for (let lineNumber = 0; lineNumber < lines.length; ) {
const line = lines[lineNumber]!; const line = lines[lineNumber]!;
const match = line.match(directiveRegex); const match = line.match(directiveRegex);
if (match !== null) { if (!match) {
const directive = match.slice(1).find((item) => item !== undefined);
switch (directive) {
case 'highlight-next-line':
highlightRange += `${lineNumber},`;
break;
case 'highlight-start':
highlightBlockStart = lineNumber;
break;
case 'highlight-end':
highlightRange += `${highlightBlockStart!}-${lineNumber - 1},`;
break;
default:
break;
}
lines.splice(lineNumber, 1);
} else {
// lines without directives are unchanged // lines without directives are unchanged
lineNumber += 1; lineNumber += 1;
continue;
} }
const directive = match.slice(1).find((item) => item !== undefined);
switch (directive) {
case 'highlight-next-line':
highlightRange += `${lineNumber},`;
break;
case 'highlight-start':
highlightBlockStart = lineNumber;
break;
case 'highlight-end':
highlightRange += `${highlightBlockStart!}-${lineNumber - 1},`;
break;
default:
break;
}
lines.splice(lineNumber, 1);
} }
const highlightLines = rangeParser(highlightRange); const highlightLines = rangeParser(highlightRange);
code = lines.join('\n'); code = lines.join('\n');

View file

@ -11,7 +11,7 @@ import path from 'path';
import fs from 'fs-extra'; import fs from 'fs-extra';
describe('readOutputHTMLFile', () => { describe('readOutputHTMLFile', () => {
it('trailing slash undefined', async () => { it('reads both files with trailing slash undefined', async () => {
await expect( await expect(
readOutputHTMLFile( readOutputHTMLFile(
'/file', '/file',
@ -41,7 +41,7 @@ describe('readOutputHTMLFile', () => {
).then(String), ).then(String),
).resolves.toBe('folder\n'); ).resolves.toBe('folder\n');
}); });
it('trailing slash true', async () => { it('reads only folder with trailing slash true', async () => {
await expect( await expect(
readOutputHTMLFile( readOutputHTMLFile(
'/folder', '/folder',
@ -57,7 +57,7 @@ describe('readOutputHTMLFile', () => {
).then(String), ).then(String),
).resolves.toBe('folder\n'); ).resolves.toBe('folder\n');
}); });
it('trailing slash false', async () => { it('reads only file trailing slash false', async () => {
await expect( await expect(
readOutputHTMLFile( readOutputHTMLFile(
'/file', '/file',
@ -73,6 +73,18 @@ describe('readOutputHTMLFile', () => {
).then(String), ).then(String),
).resolves.toBe('file\n'); ).resolves.toBe('file\n');
}); });
// Can it ever happen?
it('throws if file does not exist', async () => {
await expect(
readOutputHTMLFile(
'/nonExistent',
path.join(__dirname, '__fixtures__/build-snap'),
undefined,
).then(String),
).rejects.toThrowErrorMatchingInlineSnapshot(
`"Expected output HTML file to be found at <PROJECT_ROOT>/packages/docusaurus-utils/src/__tests__/__fixtures__/build-snap/nonExistent/index.html."`,
);
});
}); });
describe('generate', () => { describe('generate', () => {

View file

@ -83,18 +83,16 @@ export async function readOutputHTMLFile(
outDir, outDir,
`${permalink.replace(/\/$/, '')}.html`, `${permalink.replace(/\/$/, '')}.html`,
); );
if (trailingSlash) {
return fs.readFile(withTrailingSlashPath);
} else if (trailingSlash === false) {
return fs.readFile(withoutTrailingSlashPath);
}
const HTMLPath = await findAsyncSequential( const HTMLPath = await findAsyncSequential(
[withTrailingSlashPath, withoutTrailingSlashPath], [
trailingSlash !== false && withTrailingSlashPath,
trailingSlash !== true && withoutTrailingSlashPath,
].filter((p): p is string => Boolean(p)),
fs.pathExists, fs.pathExists,
); );
if (!HTMLPath) { if (!HTMLPath) {
throw new Error( throw new Error(
`Expected output HTML file to be found at ${withTrailingSlashPath}`, `Expected output HTML file to be found at ${withTrailingSlashPath}.`,
); );
} }
return fs.readFile(HTMLPath); return fs.readFile(HTMLPath);

View file

@ -22,4 +22,7 @@ module.exports = {
], ],
'@docusaurus/plugin-content-pages', '@docusaurus/plugin-content-pages',
], ],
clientModules: [
'foo.js'
]
}; };

View file

@ -0,0 +1,6 @@
{
"foo": {
"message": "bar",
"description": "foo for bar"
}
}

View file

@ -34,7 +34,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
"titleDelimiter": "|", "titleDelimiter": "|",
"url": "https://docusaurus.io", "url": "https://docusaurus.io",
}, },
"siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/configs/configAsync.config.js", "siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/config/configAsync.config.js",
} }
`; `;
@ -72,7 +72,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
"titleDelimiter": "|", "titleDelimiter": "|",
"url": "https://docusaurus.io", "url": "https://docusaurus.io",
}, },
"siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/configs/createConfigAsync.config.js", "siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/config/createConfigAsync.config.js",
} }
`; `;
@ -110,7 +110,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
"titleDelimiter": "|", "titleDelimiter": "|",
"url": "https://docusaurus.io", "url": "https://docusaurus.io",
}, },
"siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/configs/createConfig.config.js", "siteConfigPath": "<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/config/createConfig.config.js",
} }
`; `;
@ -119,7 +119,9 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
"siteConfig": { "siteConfig": {
"baseUrl": "/", "baseUrl": "/",
"baseUrlIssueBanner": true, "baseUrlIssueBanner": true,
"clientModules": [], "clientModules": [
"foo.js",
],
"customFields": {}, "customFields": {},
"favicon": "img/docusaurus.ico", "favicon": "img/docusaurus.ico",
"i18n": { "i18n": {

View file

@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`loadSiteMetadata warns about plugin version mismatch 1`] = `
{
"docusaurusVersion": "<CURRENT_VERSION>",
"pluginVersions": {
"docusaurus-plugin-content-docs": {
"name": "@docusaurus/plugin-content-docs",
"type": "package",
"version": "1.0.0",
},
},
"siteVersion": "random-version",
}
`;

View file

@ -9,7 +9,7 @@ import path from 'path';
import {loadSiteConfig} from '../config'; import {loadSiteConfig} from '../config';
describe('loadSiteConfig', () => { describe('loadSiteConfig', () => {
const siteDir = path.join(__dirname, '__fixtures__', 'configs'); const siteDir = path.join(__dirname, '__fixtures__', 'config');
it('website with valid siteConfig', async () => { it('website with valid siteConfig', async () => {
const config = await loadSiteConfig({ const config = await loadSiteConfig({
@ -49,7 +49,8 @@ describe('loadSiteConfig', () => {
it('website with incomplete siteConfig', async () => { it('website with incomplete siteConfig', async () => {
await expect( await expect(
loadSiteConfig({ loadSiteConfig({
siteDir: path.join(__dirname, '__fixtures__', 'bad-site'), siteDir,
customConfigFilePath: 'incomplete.config.js',
}), }),
).rejects.toThrowErrorMatchingInlineSnapshot(` ).rejects.toThrowErrorMatchingInlineSnapshot(`
"\\"url\\" is required "\\"url\\" is required
@ -60,7 +61,8 @@ describe('loadSiteConfig', () => {
it('website with useless field (wrong field) in siteConfig', async () => { it('website with useless field (wrong field) in siteConfig', async () => {
await expect( await expect(
loadSiteConfig({ loadSiteConfig({
siteDir: path.join(__dirname, '__fixtures__', 'wrong-site'), siteDir,
customConfigFilePath: 'wrong.config.js',
}), }),
).rejects.toThrowErrorMatchingInlineSnapshot(` ).rejects.toThrowErrorMatchingInlineSnapshot(`
"These field(s) (\\"useLessField\\",) are not recognized in docusaurus.config.js. "These field(s) (\\"useLessField\\",) are not recognized in docusaurus.config.js.
@ -72,10 +74,11 @@ describe('loadSiteConfig', () => {
it('website with no siteConfig', async () => { it('website with no siteConfig', async () => {
await expect( await expect(
loadSiteConfig({ loadSiteConfig({
siteDir: path.join(__dirname, '__fixtures__', 'nonExisting'), siteDir,
customConfigFilePath: 'nonExistent.config.js',
}), }),
).rejects.toThrowErrorMatchingInlineSnapshot( ).rejects.toThrowErrorMatchingInlineSnapshot(
`"Config file at \\"<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/nonExisting/docusaurus.config.js\\" not found."`, `"Config file at \\"<PROJECT_ROOT>/packages/docusaurus/src/server/__tests__/__fixtures__/config/nonExistent.config.js\\" not found."`,
); );
}); });
}); });

View file

@ -5,7 +5,8 @@
* LICENSE file in the root directory of this source tree. * LICENSE file in the root directory of this source tree.
*/ */
import {getPluginVersion} from '../siteMetadata'; import {jest} from '@jest/globals';
import {getPluginVersion, loadSiteMetadata} from '../siteMetadata';
import path from 'path'; import path from 'path';
describe('getPluginVersion', () => { describe('getPluginVersion', () => {
@ -33,3 +34,32 @@ describe('getPluginVersion', () => {
await expect(getPluginVersion('/', '/')).resolves.toEqual({type: 'local'}); await expect(getPluginVersion('/', '/')).resolves.toEqual({type: 'local'});
}); });
}); });
describe('loadSiteMetadata', () => {
it('warns about plugin version mismatch', async () => {
const consoleMock = jest
.spyOn(console, 'error')
.mockImplementation(() => {});
await expect(
loadSiteMetadata({
plugins: [
{
name: 'docusaurus-plugin-content-docs',
version: {
type: 'package',
version: '1.0.0',
name: '@docusaurus/plugin-content-docs',
},
},
],
siteDir: path.join(__dirname, '__fixtures__/siteMetadata'),
}),
).resolves.toMatchSnapshot();
// cSpell:ignore mdocusaurus
expect(consoleMock.mock.calls[0][0]).toMatchInlineSnapshot(`
"[ERROR] Invalid docusaurus-plugin-content-docs version 1.0.0.
All official @docusaurus/* packages should have the exact same version as @docusaurus/core (<CURRENT_VERSION>).
Maybe you want to check, or regenerate your yarn.lock or package-lock.json file?"
`);
});
});