mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-30 10:48:05 +02:00
fix(types): fix type of PluginModule (#10420)
This commit is contained in:
parent
0b640ca3e2
commit
2d55ca474e
3 changed files with 445 additions and 366 deletions
3
packages/docusaurus-types/src/plugin.d.ts
vendored
3
packages/docusaurus-types/src/plugin.d.ts
vendored
|
@ -191,9 +191,8 @@ export type LoadedPlugin = InitializedPlugin & {
|
||||||
export type PluginModule<Content = unknown> = {
|
export type PluginModule<Content = unknown> = {
|
||||||
(context: LoadContext, options: unknown):
|
(context: LoadContext, options: unknown):
|
||||||
| Plugin<Content>
|
| Plugin<Content>
|
||||||
| Promise<Plugin<Content>>
|
|
||||||
| null
|
| null
|
||||||
| Promise<null>;
|
| Promise<Plugin<Content> | null>;
|
||||||
|
|
||||||
validateOptions?: <T, U>(data: OptionValidationContext<T, U>) => U;
|
validateOptions?: <T, U>(data: OptionValidationContext<T, U>) => U;
|
||||||
validateThemeConfig?: <T>(data: ThemeConfigValidationContext<T>) => T;
|
validateThemeConfig?: <T>(data: ThemeConfigValidationContext<T>) => T;
|
||||||
|
|
|
@ -1,143 +1,5 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if plugins is not a string and it's not an array #1 for the input of: [123] 1`] = `
|
|
||||||
" => Bad Docusaurus plugin value plugins[0].
|
|
||||||
Example valid plugin config:
|
|
||||||
{
|
|
||||||
plugins: [
|
|
||||||
["@docusaurus/plugin-content-docs",options],
|
|
||||||
"./myPlugin",
|
|
||||||
["./myPlugin",{someOption: 42}],
|
|
||||||
function myPlugin() { },
|
|
||||||
[function myPlugin() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if plugins is not an array of [string, object][] #1 for the input of: [[Array]] 1`] = `
|
|
||||||
" => Bad Docusaurus plugin value plugins[0].
|
|
||||||
Example valid plugin config:
|
|
||||||
{
|
|
||||||
plugins: [
|
|
||||||
["@docusaurus/plugin-content-docs",options],
|
|
||||||
"./myPlugin",
|
|
||||||
["./myPlugin",{someOption: 42}],
|
|
||||||
function myPlugin() { },
|
|
||||||
[function myPlugin() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if plugins is not an array of [string, object][] #2 for the input of: [[Array]] 1`] = `
|
|
||||||
" => Bad Docusaurus plugin value plugins[0].
|
|
||||||
Example valid plugin config:
|
|
||||||
{
|
|
||||||
plugins: [
|
|
||||||
["@docusaurus/plugin-content-docs",options],
|
|
||||||
"./myPlugin",
|
|
||||||
["./myPlugin",{someOption: 42}],
|
|
||||||
function myPlugin() { },
|
|
||||||
[function myPlugin() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if plugins is not an array of [string, object][] #3 for the input of: [[Array]] 1`] = `
|
|
||||||
" => Bad Docusaurus plugin value plugins[0].
|
|
||||||
Example valid plugin config:
|
|
||||||
{
|
|
||||||
plugins: [
|
|
||||||
["@docusaurus/plugin-content-docs",options],
|
|
||||||
"./myPlugin",
|
|
||||||
["./myPlugin",{someOption: 42}],
|
|
||||||
function myPlugin() { },
|
|
||||||
[function myPlugin() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if plugins is not array for the input of: {} 1`] = `
|
|
||||||
""plugins" must be an array
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if themes is not a string and it's not an array #1 for the input of: [123] 1`] = `
|
|
||||||
" => Bad Docusaurus theme value themes[0].
|
|
||||||
Example valid theme config:
|
|
||||||
{
|
|
||||||
themes: [
|
|
||||||
["@docusaurus/theme-classic",options],
|
|
||||||
"./myTheme",
|
|
||||||
["./myTheme",{someOption: 42}],
|
|
||||||
function myTheme() { },
|
|
||||||
[function myTheme() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #1 for the input of: [[Array]] 1`] = `
|
|
||||||
" => Bad Docusaurus theme value themes[0].
|
|
||||||
Example valid theme config:
|
|
||||||
{
|
|
||||||
themes: [
|
|
||||||
["@docusaurus/theme-classic",options],
|
|
||||||
"./myTheme",
|
|
||||||
["./myTheme",{someOption: 42}],
|
|
||||||
function myTheme() { },
|
|
||||||
[function myTheme() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #2 for the input of: [[Array]] 1`] = `
|
|
||||||
" => Bad Docusaurus theme value themes[0].
|
|
||||||
Example valid theme config:
|
|
||||||
{
|
|
||||||
themes: [
|
|
||||||
["@docusaurus/theme-classic",options],
|
|
||||||
"./myTheme",
|
|
||||||
["./myTheme",{someOption: 42}],
|
|
||||||
function myTheme() { },
|
|
||||||
[function myTheme() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if themes is not an array of [string, object][] #3 for the input of: [[Array]] 1`] = `
|
|
||||||
" => Bad Docusaurus theme value themes[0].
|
|
||||||
Example valid theme config:
|
|
||||||
{
|
|
||||||
themes: [
|
|
||||||
["@docusaurus/theme-classic",options],
|
|
||||||
"./myTheme",
|
|
||||||
["./myTheme",{someOption: 42}],
|
|
||||||
function myTheme() { },
|
|
||||||
[function myTheme() { },options]
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig should throw error if themes is not array for the input of: {} 1`] = `
|
|
||||||
""themes" must be an array
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`normalizeConfig throws error for required fields 1`] = `
|
exports[`normalizeConfig throws error for required fields 1`] = `
|
||||||
""baseUrl" is required
|
""baseUrl" is required
|
||||||
"title" is required
|
"title" is required
|
||||||
|
@ -157,7 +19,145 @@ If you still want these fields to be in your configuration, put them in the "cus
|
||||||
See https://docusaurus.io/docs/api/docusaurus-config/#customfields"
|
See https://docusaurus.io/docs/api/docusaurus-config/#customfields"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`normalizeConfig throws for "error" reporting severity 1`] = `
|
exports[`onBrokenLinks throws for "error" reporting severity 1`] = `
|
||||||
""onBrokenLinks" must be one of [ignore, log, warn, throw]
|
""onBrokenLinks" must be one of [ignore, log, warn, throw]
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`plugins should throw error if plugins is not a string and it's not an array #1 for the input of: [123] 1`] = `
|
||||||
|
" => Bad Docusaurus plugin value plugins[0].
|
||||||
|
Example valid plugin config:
|
||||||
|
{
|
||||||
|
plugins: [
|
||||||
|
["@docusaurus/plugin-content-docs",options],
|
||||||
|
"./myPlugin",
|
||||||
|
["./myPlugin",{someOption: 42}],
|
||||||
|
function myPlugin() { },
|
||||||
|
[function myPlugin() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`plugins should throw error if plugins is not an array of [string, object][] #1 for the input of: [[Array]] 1`] = `
|
||||||
|
" => Bad Docusaurus plugin value plugins[0].
|
||||||
|
Example valid plugin config:
|
||||||
|
{
|
||||||
|
plugins: [
|
||||||
|
["@docusaurus/plugin-content-docs",options],
|
||||||
|
"./myPlugin",
|
||||||
|
["./myPlugin",{someOption: 42}],
|
||||||
|
function myPlugin() { },
|
||||||
|
[function myPlugin() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`plugins should throw error if plugins is not an array of [string, object][] #2 for the input of: [[Array]] 1`] = `
|
||||||
|
" => Bad Docusaurus plugin value plugins[0].
|
||||||
|
Example valid plugin config:
|
||||||
|
{
|
||||||
|
plugins: [
|
||||||
|
["@docusaurus/plugin-content-docs",options],
|
||||||
|
"./myPlugin",
|
||||||
|
["./myPlugin",{someOption: 42}],
|
||||||
|
function myPlugin() { },
|
||||||
|
[function myPlugin() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`plugins should throw error if plugins is not an array of [string, object][] #3 for the input of: [[Array]] 1`] = `
|
||||||
|
" => Bad Docusaurus plugin value plugins[0].
|
||||||
|
Example valid plugin config:
|
||||||
|
{
|
||||||
|
plugins: [
|
||||||
|
["@docusaurus/plugin-content-docs",options],
|
||||||
|
"./myPlugin",
|
||||||
|
["./myPlugin",{someOption: 42}],
|
||||||
|
function myPlugin() { },
|
||||||
|
[function myPlugin() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`plugins should throw error if plugins is not array for the input of: {} 1`] = `
|
||||||
|
""plugins" must be an array
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`themes should throw error if themes is not a string and it's not an array #1 for the input of: [123] 1`] = `
|
||||||
|
" => Bad Docusaurus theme value themes[0].
|
||||||
|
Example valid theme config:
|
||||||
|
{
|
||||||
|
themes: [
|
||||||
|
["@docusaurus/theme-classic",options],
|
||||||
|
"./myTheme",
|
||||||
|
["./myTheme",{someOption: 42}],
|
||||||
|
function myTheme() { },
|
||||||
|
[function myTheme() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`themes should throw error if themes is not an array of [string, object][] #1 for the input of: [[Array]] 1`] = `
|
||||||
|
" => Bad Docusaurus theme value themes[0].
|
||||||
|
Example valid theme config:
|
||||||
|
{
|
||||||
|
themes: [
|
||||||
|
["@docusaurus/theme-classic",options],
|
||||||
|
"./myTheme",
|
||||||
|
["./myTheme",{someOption: 42}],
|
||||||
|
function myTheme() { },
|
||||||
|
[function myTheme() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`themes should throw error if themes is not an array of [string, object][] #2 for the input of: [[Array]] 1`] = `
|
||||||
|
" => Bad Docusaurus theme value themes[0].
|
||||||
|
Example valid theme config:
|
||||||
|
{
|
||||||
|
themes: [
|
||||||
|
["@docusaurus/theme-classic",options],
|
||||||
|
"./myTheme",
|
||||||
|
["./myTheme",{someOption: 42}],
|
||||||
|
function myTheme() { },
|
||||||
|
[function myTheme() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`themes should throw error if themes is not an array of [string, object][] #3 for the input of: [[Array]] 1`] = `
|
||||||
|
" => Bad Docusaurus theme value themes[0].
|
||||||
|
Example valid theme config:
|
||||||
|
{
|
||||||
|
themes: [
|
||||||
|
["@docusaurus/theme-classic",options],
|
||||||
|
"./myTheme",
|
||||||
|
["./myTheme",{someOption: 42}],
|
||||||
|
function myTheme() { },
|
||||||
|
[function myTheme() { },options]
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`themes should throw error if themes is not array for the input of: {} 1`] = `
|
||||||
|
""themes" must be an array
|
||||||
|
"
|
||||||
|
`;
|
||||||
|
|
|
@ -12,7 +12,7 @@ import {
|
||||||
validateConfig,
|
validateConfig,
|
||||||
} from '../configValidation';
|
} from '../configValidation';
|
||||||
import type {StorageConfig} from '@docusaurus/types/src/config';
|
import type {StorageConfig} from '@docusaurus/types/src/config';
|
||||||
import type {Config, DocusaurusConfig} from '@docusaurus/types';
|
import type {Config, DocusaurusConfig, PluginConfig} from '@docusaurus/types';
|
||||||
import type {DeepPartial} from 'utility-types';
|
import type {DeepPartial} from 'utility-types';
|
||||||
|
|
||||||
const baseConfig = {
|
const baseConfig = {
|
||||||
|
@ -114,6 +114,34 @@ describe('normalizeConfig', () => {
|
||||||
}).toThrowErrorMatchingSnapshot();
|
}).toThrowErrorMatchingSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('throws error for required fields', () => {
|
||||||
|
expect(() =>
|
||||||
|
validateConfig(
|
||||||
|
{
|
||||||
|
invalidField: true,
|
||||||
|
presets: {},
|
||||||
|
stylesheets: {},
|
||||||
|
themes: {},
|
||||||
|
scripts: {},
|
||||||
|
},
|
||||||
|
'docusaurus.config.js',
|
||||||
|
),
|
||||||
|
).toThrowErrorMatchingSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('config warning and error', () => {
|
||||||
|
function getWarning(config: unknown) {
|
||||||
|
return ConfigSchema.validate(config).warning;
|
||||||
|
}
|
||||||
|
|
||||||
|
it('baseConfig has no warning', () => {
|
||||||
|
const warning = getWarning(baseConfig);
|
||||||
|
expect(warning).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('url', () => {
|
||||||
it('throws for non-string URLs', () => {
|
it('throws for non-string URLs', () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
normalizeConfig({
|
normalizeConfig({
|
||||||
|
@ -180,195 +208,19 @@ describe('normalizeConfig', () => {
|
||||||
).toBe('/noSlash/foo/');
|
).toBe('/noSlash/foo/');
|
||||||
});
|
});
|
||||||
|
|
||||||
it.each([
|
it('site url fails validation when using subpath', () => {
|
||||||
['should throw error if plugins is not array', {}],
|
const {error} = ConfigSchema.validate({
|
||||||
[
|
...baseConfig,
|
||||||
"should throw error if plugins is not a string and it's not an array #1",
|
url: 'https://mysite.com/someSubpath',
|
||||||
[123],
|
});
|
||||||
],
|
expect(error).toBeDefined();
|
||||||
[
|
expect(error?.message).toBe(
|
||||||
'should throw error if plugins is not an array of [string, object][] #1',
|
'The url is not supposed to contain a sub-path like "/someSubpath". Please use the baseUrl field for sub-paths.',
|
||||||
[['example/path', 'wrong parameter here']],
|
);
|
||||||
],
|
|
||||||
[
|
|
||||||
'should throw error if plugins is not an array of [string, object][] #2',
|
|
||||||
[[{}, 'example/path']],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should throw error if plugins is not an array of [string, object][] #3',
|
|
||||||
[[{}, {}]],
|
|
||||||
],
|
|
||||||
])(`%s for the input of: %p`, (_message, plugins) => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
// @ts-expect-error: test
|
|
||||||
plugins,
|
|
||||||
});
|
});
|
||||||
}).toThrowErrorMatchingSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each([
|
|
||||||
['should throw error if themes is not array', {}],
|
|
||||||
[
|
|
||||||
"should throw error if themes is not a string and it's not an array #1",
|
|
||||||
[123],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should throw error if themes is not an array of [string, object][] #1',
|
|
||||||
[['example/path', 'wrong parameter here']],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should throw error if themes is not an array of [string, object][] #2',
|
|
||||||
[[{}, 'example/path']],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should throw error if themes is not an array of [string, object][] #3',
|
|
||||||
[[{}, {}]],
|
|
||||||
],
|
|
||||||
])(`%s for the input of: %p`, (_message, themes) => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
// @ts-expect-error: test
|
|
||||||
themes,
|
|
||||||
});
|
|
||||||
}).toThrowErrorMatchingSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each([
|
|
||||||
['should accept [string] for plugins', ['plain/string']],
|
|
||||||
[
|
|
||||||
'should accept string[] for plugins',
|
|
||||||
['plain/string', 'another/plain/string/path'],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should accept [string, object] for plugins',
|
|
||||||
[['plain/string', {it: 'should work'}]],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should accept [string, object][] for plugins',
|
|
||||||
[
|
|
||||||
['plain/string', {it: 'should work'}],
|
|
||||||
['this/should/work', {too: 'yes'}],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should accept ([string, object]|string)[] for plugins',
|
|
||||||
[
|
|
||||||
'plain/string',
|
|
||||||
['plain', {it: 'should work'}],
|
|
||||||
['this/should/work', {too: 'yes'}],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['should accept function for plugin', [function plugin() {}]],
|
|
||||||
[
|
|
||||||
'should accept [function, object] for plugin',
|
|
||||||
[[() => {}, {it: 'should work'}]],
|
|
||||||
],
|
|
||||||
['should accept false/null for plugin', [false as const, null, 'classic']],
|
|
||||||
])(`%s for the input of: %p`, (_message, plugins) => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
plugins,
|
|
||||||
} as Config);
|
|
||||||
}).not.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it.each([
|
|
||||||
['should accept [string] for themes', ['plain/string']],
|
|
||||||
[
|
|
||||||
'should accept string[] for themes',
|
|
||||||
['plain/string', 'another/plain/string/path'],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should accept [string, object] for themes',
|
|
||||||
[['plain/string', {it: 'should work'}]],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should accept [string, object][] for themes',
|
|
||||||
[
|
|
||||||
['plain/string', {it: 'should work'}],
|
|
||||||
['this/should/work', {too: 'yes'}],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'should accept ([string, object]|string)[] for themes',
|
|
||||||
[
|
|
||||||
'plain/string',
|
|
||||||
['plain', {it: 'should work'}],
|
|
||||||
['this/should/work', {too: 'yes'}],
|
|
||||||
],
|
|
||||||
],
|
|
||||||
['should accept function for theme', [function theme() {}]],
|
|
||||||
[
|
|
||||||
'should accept [function, object] for theme',
|
|
||||||
[[function theme() {}, {it: 'should work'}]],
|
|
||||||
],
|
|
||||||
['should accept false/null for themes', [false, null, 'classic']],
|
|
||||||
])(`%s for the input of: %p`, (_message, themes) => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
themes,
|
|
||||||
} as Config);
|
|
||||||
}).not.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error if themes is not array', () => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
// @ts-expect-error: test
|
|
||||||
themes: {},
|
|
||||||
});
|
|
||||||
}).toThrowErrorMatchingInlineSnapshot(`
|
|
||||||
""themes" must be an array
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error if presets is not array', () => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
// @ts-expect-error: test
|
|
||||||
presets: {},
|
|
||||||
});
|
|
||||||
}).toThrowErrorMatchingInlineSnapshot(`
|
|
||||||
""presets" must be an array
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('throws error if presets looks invalid', () => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
// @ts-expect-error: test
|
|
||||||
presets: [() => {}],
|
|
||||||
});
|
|
||||||
}).toThrowErrorMatchingInlineSnapshot(`
|
|
||||||
""presets[0]" does not look like a valid preset config. A preset config entry should be one of:
|
|
||||||
- A tuple of [presetName, options], like \`["classic", { blog: false }]\`, or
|
|
||||||
- A simple string, like \`"classic"\`
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('accepts presets as false / null', () => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
presets: [false, null, 'classic'],
|
|
||||||
});
|
|
||||||
}).not.toThrow();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("throws error if scripts doesn't have src", () => {
|
|
||||||
expect(() => {
|
|
||||||
normalizeConfig({
|
|
||||||
scripts: ['https://some.com', {}],
|
|
||||||
});
|
|
||||||
}).toThrowErrorMatchingInlineSnapshot(`
|
|
||||||
""scripts[1]" is invalid. A script must be a plain string (the src), or an object with at least a "src" property.
|
|
||||||
"
|
|
||||||
`);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('headTags', () => {
|
||||||
it('accepts headTags with tagName and attributes', () => {
|
it('accepts headTags with tagName and attributes', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
normalizeConfig({
|
normalizeConfig({
|
||||||
|
@ -436,7 +288,9 @@ describe('normalizeConfig', () => {
|
||||||
"
|
"
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('css', () => {
|
||||||
it("throws error if css doesn't have href", () => {
|
it("throws error if css doesn't have href", () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
normalizeConfig({
|
normalizeConfig({
|
||||||
|
@ -447,22 +301,22 @@ describe('normalizeConfig', () => {
|
||||||
"
|
"
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throws error for required fields', () => {
|
|
||||||
expect(() =>
|
|
||||||
validateConfig(
|
|
||||||
{
|
|
||||||
invalidField: true,
|
|
||||||
presets: {},
|
|
||||||
stylesheets: {},
|
|
||||||
themes: {},
|
|
||||||
scripts: {},
|
|
||||||
},
|
|
||||||
'docusaurus.config.js',
|
|
||||||
),
|
|
||||||
).toThrowErrorMatchingSnapshot();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('scripts', () => {
|
||||||
|
it("throws error if scripts doesn't have src", () => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
scripts: ['https://some.com', {}],
|
||||||
|
});
|
||||||
|
}).toThrowErrorMatchingInlineSnapshot(`
|
||||||
|
""scripts[1]" is invalid. A script must be a plain string (the src), or an object with at least a "src" property.
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onBrokenLinks', () => {
|
||||||
it('throws for "error" reporting severity', () => {
|
it('throws for "error" reporting severity', () => {
|
||||||
expect(() =>
|
expect(() =>
|
||||||
validateConfig(
|
validateConfig(
|
||||||
|
@ -478,28 +332,6 @@ describe('normalizeConfig', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('config warning and error', () => {
|
|
||||||
function getWarning(config: unknown) {
|
|
||||||
return ConfigSchema.validate(config).warning;
|
|
||||||
}
|
|
||||||
|
|
||||||
it('baseConfig has no warning', () => {
|
|
||||||
const warning = getWarning(baseConfig);
|
|
||||||
expect(warning).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('site url fails validation when using subpath', () => {
|
|
||||||
const {error} = ConfigSchema.validate({
|
|
||||||
...baseConfig,
|
|
||||||
url: 'https://mysite.com/someSubpath',
|
|
||||||
});
|
|
||||||
expect(error).toBeDefined();
|
|
||||||
expect(error?.message).toBe(
|
|
||||||
'The url is not supposed to contain a sub-path like "/someSubpath". Please use the baseUrl field for sub-paths.',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('markdown', () => {
|
describe('markdown', () => {
|
||||||
it('accepts undefined object', () => {
|
it('accepts undefined object', () => {
|
||||||
expect(
|
expect(
|
||||||
|
@ -597,8 +429,14 @@ describe('markdown', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('throw for bad markdown format', () => {
|
it('throw for bad markdown format', () => {
|
||||||
expect(() => normalizeConfig({markdown: {format: null}}))
|
expect(() =>
|
||||||
.toThrowErrorMatchingInlineSnapshot(`
|
normalizeConfig({
|
||||||
|
markdown: {
|
||||||
|
// @ts-expect-error: bad value
|
||||||
|
format: null,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
).toThrowErrorMatchingInlineSnapshot(`
|
||||||
""markdown.format" must be one of [mdx, md, detect]
|
""markdown.format" must be one of [mdx, md, detect]
|
||||||
"markdown.format" must be a string
|
"markdown.format" must be a string
|
||||||
"
|
"
|
||||||
|
@ -617,6 +455,7 @@ describe('markdown', () => {
|
||||||
it('throw for null object', () => {
|
it('throw for null object', () => {
|
||||||
expect(() => {
|
expect(() => {
|
||||||
normalizeConfig({
|
normalizeConfig({
|
||||||
|
// @ts-expect-error: bad value
|
||||||
markdown: null,
|
markdown: null,
|
||||||
});
|
});
|
||||||
}).toThrowErrorMatchingInlineSnapshot(`
|
}).toThrowErrorMatchingInlineSnapshot(`
|
||||||
|
@ -626,6 +465,245 @@ describe('markdown', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('plugins', () => {
|
||||||
|
// Only here to verify typing
|
||||||
|
function ensurePlugins(plugins: PluginConfig[]): PluginConfig[] {
|
||||||
|
return plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['should throw error if plugins is not array', {}],
|
||||||
|
[
|
||||||
|
"should throw error if plugins is not a string and it's not an array #1",
|
||||||
|
[123],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should throw error if plugins is not an array of [string, object][] #1',
|
||||||
|
[['example/path', 'wrong parameter here']],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should throw error if plugins is not an array of [string, object][] #2',
|
||||||
|
[[{}, 'example/path']],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should throw error if plugins is not an array of [string, object][] #3',
|
||||||
|
[[{}, {}]],
|
||||||
|
],
|
||||||
|
])(`%s for the input of: %p`, (_message, plugins) => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
// @ts-expect-error: test
|
||||||
|
plugins,
|
||||||
|
});
|
||||||
|
}).toThrowErrorMatchingSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['should accept [string] for plugins', ensurePlugins(['plain/string'])],
|
||||||
|
[
|
||||||
|
'should accept string[] for plugins',
|
||||||
|
ensurePlugins(['plain/string', 'another/plain/string/path']),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept [string, object] for plugins',
|
||||||
|
ensurePlugins([['plain/string', {it: 'should work'}]]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept [string, object][] for plugins',
|
||||||
|
ensurePlugins([
|
||||||
|
['plain/string', {it: 'should work'}],
|
||||||
|
['this/should/work', {too: 'yes'}],
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept ([string, object]|string)[] for plugins',
|
||||||
|
ensurePlugins([
|
||||||
|
'plain/string',
|
||||||
|
['plain', {it: 'should work'}],
|
||||||
|
['this/should/work', {too: 'yes'}],
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept function returning null',
|
||||||
|
ensurePlugins([
|
||||||
|
function plugin() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept function returning plugin',
|
||||||
|
ensurePlugins([
|
||||||
|
function plugin() {
|
||||||
|
return {name: 'plugin'};
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept function returning plugin or null',
|
||||||
|
ensurePlugins([
|
||||||
|
function plugin() {
|
||||||
|
return Math.random() > 0.5 ? null : {name: 'plugin'};
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept async function returning null',
|
||||||
|
ensurePlugins([
|
||||||
|
async function plugin() {
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept async function returning plugin',
|
||||||
|
ensurePlugins([
|
||||||
|
async function plugin() {
|
||||||
|
return {name: 'plugin'};
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept function returning plugin or null',
|
||||||
|
ensurePlugins([
|
||||||
|
async function plugin() {
|
||||||
|
return Math.random() > 0.5 ? null : {name: 'plugin'};
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept [function, object] for plugin',
|
||||||
|
[[() => {}, {it: 'should work'}]],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept false/null for plugin',
|
||||||
|
ensurePlugins([false as const, null, 'classic']),
|
||||||
|
],
|
||||||
|
])(`%s for the input of: %p`, (_message, plugins) => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
plugins,
|
||||||
|
} as Config);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('themes', () => {
|
||||||
|
it.each([
|
||||||
|
['should throw error if themes is not array', {}],
|
||||||
|
[
|
||||||
|
"should throw error if themes is not a string and it's not an array #1",
|
||||||
|
[123],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should throw error if themes is not an array of [string, object][] #1',
|
||||||
|
[['example/path', 'wrong parameter here']],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should throw error if themes is not an array of [string, object][] #2',
|
||||||
|
[[{}, 'example/path']],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should throw error if themes is not an array of [string, object][] #3',
|
||||||
|
[[{}, {}]],
|
||||||
|
],
|
||||||
|
])(`%s for the input of: %p`, (_message, themes) => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
// @ts-expect-error: test
|
||||||
|
themes,
|
||||||
|
});
|
||||||
|
}).toThrowErrorMatchingSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each([
|
||||||
|
['should accept [string] for themes', ['plain/string']],
|
||||||
|
[
|
||||||
|
'should accept string[] for themes',
|
||||||
|
['plain/string', 'another/plain/string/path'],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept [string, object] for themes',
|
||||||
|
[['plain/string', {it: 'should work'}]],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept [string, object][] for themes',
|
||||||
|
[
|
||||||
|
['plain/string', {it: 'should work'}],
|
||||||
|
['this/should/work', {too: 'yes'}],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'should accept ([string, object]|string)[] for themes',
|
||||||
|
[
|
||||||
|
'plain/string',
|
||||||
|
['plain', {it: 'should work'}],
|
||||||
|
['this/should/work', {too: 'yes'}],
|
||||||
|
],
|
||||||
|
],
|
||||||
|
['should accept function for theme', [function theme() {}]],
|
||||||
|
[
|
||||||
|
'should accept [function, object] for theme',
|
||||||
|
[[function theme() {}, {it: 'should work'}]],
|
||||||
|
],
|
||||||
|
['should accept false/null for themes', [false, null, 'classic']],
|
||||||
|
])(`%s for the input of: %p`, (_message, themes) => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
themes,
|
||||||
|
} as Config);
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws error if themes is not array', () => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
// @ts-expect-error: test
|
||||||
|
themes: {},
|
||||||
|
});
|
||||||
|
}).toThrowErrorMatchingInlineSnapshot(`
|
||||||
|
""themes" must be an array
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('presets', () => {
|
||||||
|
it('throws error if presets is not array', () => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
// @ts-expect-error: test
|
||||||
|
presets: {},
|
||||||
|
});
|
||||||
|
}).toThrowErrorMatchingInlineSnapshot(`
|
||||||
|
""presets" must be an array
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('throws error if presets looks invalid', () => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
// @ts-expect-error: test
|
||||||
|
presets: [() => {}],
|
||||||
|
});
|
||||||
|
}).toThrowErrorMatchingInlineSnapshot(`
|
||||||
|
""presets[0]" does not look like a valid preset config. A preset config entry should be one of:
|
||||||
|
- A tuple of [presetName, options], like \`["classic", { blog: false }]\`, or
|
||||||
|
- A simple string, like \`"classic"\`
|
||||||
|
"
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts presets as false / null', () => {
|
||||||
|
expect(() => {
|
||||||
|
normalizeConfig({
|
||||||
|
presets: [false, null, 'classic'],
|
||||||
|
});
|
||||||
|
}).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('future', () => {
|
describe('future', () => {
|
||||||
it('accepts future - undefined', () => {
|
it('accepts future - undefined', () => {
|
||||||
expect(
|
expect(
|
||||||
|
@ -737,6 +815,7 @@ describe('future', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects router - null', () => {
|
it('rejects router - null', () => {
|
||||||
|
// @ts-expect-error: bad value
|
||||||
const router: DocusaurusConfig['future']['experimental_router'] = null;
|
const router: DocusaurusConfig['future']['experimental_router'] = null;
|
||||||
expect(() =>
|
expect(() =>
|
||||||
normalizeConfig({
|
normalizeConfig({
|
||||||
|
@ -976,6 +1055,7 @@ describe('future', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('rejects namespace - null', () => {
|
it('rejects namespace - null', () => {
|
||||||
|
// @ts-expect-error: bad value
|
||||||
const storage: Partial<StorageConfig> = {namespace: null};
|
const storage: Partial<StorageConfig> = {namespace: null};
|
||||||
expect(() =>
|
expect(() =>
|
||||||
normalizeConfig({
|
normalizeConfig({
|
||||||
|
|
Loading…
Add table
Reference in a new issue