From f763ac13a92f6828ee15f2676274a4d846efa1e1 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Sun, 6 Mar 2022 17:55:21 +0800 Subject: [PATCH] test: improve test coverage (#6857) --- .../__snapshots__/translations.test.ts.snap | 41 +++ .../src/__tests__/translations.test.ts | 6 + .../src/translations.ts | 3 - .../src/categoryGeneratedIndex.ts | 6 +- .../sidebars/invalid-docs/foo/_category_.json | 3 + .../sidebars/invalid-docs/foo/_category_.yml} | 0 .../__snapshots__/generator.test.ts.snap | 255 ++++++++++++++++++ .../src/sidebars/__tests__/generator.test.ts | 185 ++++--------- .../src/sidebars/__tests__/index.test.ts | 37 ++- .../src/sidebars/generator.ts | 6 +- .../src/sidebars/utils.ts | 6 +- packages/docusaurus-types/src/index.d.ts | 8 +- .../docusaurus/src/server/configValidation.ts | 4 +- .../__fixtures__/site-with-plugin/plugin3.js | 4 + .../src/server/plugins/__tests__/init.test.ts | 1 + .../docusaurus/src/server/plugins/index.ts | 6 +- .../docusaurus/src/server/plugins/init.ts | 67 ++--- .../docusaurus/src/server/presets/index.ts | 4 +- .../__tests__/__fixtures__/dummy-plugin.js | 0 .../{ => __tests__}/__fixtures__/package.json | 0 .../server/versions/__tests__/index.test.ts | 6 +- .../docusaurus/src/server/versions/index.ts | 7 +- 22 files changed, 435 insertions(+), 220 deletions(-) create mode 100644 packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__fixtures__/sidebars/invalid-docs/foo/_category_.json rename packages/{docusaurus/src/server/versions/__fixtures__/dummy-plugin.js => docusaurus-plugin-content-docs/src/sidebars/__tests__/__fixtures__/sidebars/invalid-docs/foo/_category_.yml} (100%) create mode 100644 packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap create mode 100644 packages/docusaurus/src/server/versions/__tests__/__fixtures__/dummy-plugin.js rename packages/docusaurus/src/server/versions/{ => __tests__}/__fixtures__/package.json (100%) diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap index ba9ff2b59b..d2cb32ded0 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/__snapshots__/translations.test.ts.snap @@ -22,6 +22,47 @@ Array [ ] `; +exports[`translateContent should fallback when translation is incomplete 1`] = ` +Object { + "blogListPaginated": Array [ + Object { + "items": Array [ + "hello", + ], + "metadata": Object { + "blogDescription": "Someone's random blog", + "blogTitle": "My blog", + "nextPage": null, + "page": 1, + "permalink": "/", + "postsPerPage": 10, + "previousPage": null, + "totalCount": 1, + "totalPages": 1, + }, + }, + ], + "blogPosts": Array [ + Object { + "id": "hello", + "metadata": Object { + "date": 2021-07-19T00:00:00.000Z, + "description": "/blog/2021/06/19/hello", + "formattedDate": "June 19, 2021", + "permalink": "/blog/2021/06/19/hello", + "source": "/blog/2021/06/19/hello", + "tags": Array [], + "title": "Hello", + "truncated": true, + }, + }, + ], + "blogSidebarTitle": "All my posts", + "blogTags": Object {}, + "blogTagsListPath": "/tags", +} +`; + exports[`translateContent should return translated loaded content matching snapshot 1`] = ` Object { "blogListPaginated": Array [ diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts index 9844c4cab9..71cdd42af2 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/translations.test.ts @@ -77,6 +77,12 @@ describe('getContentTranslationFiles', () => { }); describe('translateContent', () => { + test('should fallback when translation is incomplete', () => { + expect( + translateContent(sampleBlogContent, [{path: 'foo', content: {}}]), + ).toMatchSnapshot(); + }); + test('should not translate anything if translation files are untranslated', () => { const translationFiles = getSampleTranslationFiles(); expect(translateContent(sampleBlogContent, translationFiles)).toEqual( diff --git a/packages/docusaurus-plugin-content-blog/src/translations.ts b/packages/docusaurus-plugin-content-blog/src/translations.ts index 6459fec598..460e24a624 100644 --- a/packages/docusaurus-plugin-content-blog/src/translations.ts +++ b/packages/docusaurus-plugin-content-blog/src/translations.ts @@ -53,9 +53,6 @@ export function translateContent( content: BlogContent, translationFiles: TranslationFiles, ): BlogContent { - if (translationFiles.length === 0) { - return content; - } const {content: optionsTranslations} = translationFiles[0]!; return { ...content, diff --git a/packages/docusaurus-plugin-content-docs/src/categoryGeneratedIndex.ts b/packages/docusaurus-plugin-content-docs/src/categoryGeneratedIndex.ts index ac2cb55e1e..522ae14556 100644 --- a/packages/docusaurus-plugin-content-docs/src/categoryGeneratedIndex.ts +++ b/packages/docusaurus-plugin-content-docs/src/categoryGeneratedIndex.ts @@ -21,10 +21,6 @@ function getCategoryGeneratedIndexMetadata({ }): CategoryGeneratedIndexMetadata { const {sidebarName, previous, next} = sidebarsUtils.getCategoryGeneratedIndexNavigation(category.link.permalink); - if (!sidebarName) { - throw new Error('unexpected'); - } - return { title: category.link.title ?? category.label, description: category.link.description, @@ -32,7 +28,7 @@ function getCategoryGeneratedIndexMetadata({ keywords: category.link.keywords, slug: category.link.slug, permalink: category.link.permalink, - sidebar: sidebarName, + sidebar: sidebarName!, previous: toNavigationLink(previous, docsById), next: toNavigationLink(next, docsById), }; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__fixtures__/sidebars/invalid-docs/foo/_category_.json b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__fixtures__/sidebars/invalid-docs/foo/_category_.json new file mode 100644 index 0000000000..c8c4105eb5 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__fixtures__/sidebars/invalid-docs/foo/_category_.json @@ -0,0 +1,3 @@ +{ + "foo": "bar" +} diff --git a/packages/docusaurus/src/server/versions/__fixtures__/dummy-plugin.js b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__fixtures__/sidebars/invalid-docs/foo/_category_.yml similarity index 100% rename from packages/docusaurus/src/server/versions/__fixtures__/dummy-plugin.js rename to packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__fixtures__/sidebars/invalid-docs/foo/_category_.yml diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap new file mode 100644 index 0000000000..3338aa1cd5 --- /dev/null +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/__snapshots__/generator.test.ts.snap @@ -0,0 +1,255 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`DefaultSidebarItemsGenerator generates complex nested sidebar 1`] = ` +Array [ + Object { + "id": "intro", + "type": "doc", + }, + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "tutorial1", + "type": "doc", + }, + Object { + "id": "tutorial2", + "type": "doc", + }, + ], + "label": "Tutorials", + "link": Object { + "id": "tutorials-index", + "type": "doc", + }, + "type": "category", + }, + Object { + "collapsed": false, + "collapsible": undefined, + "customProps": Object { + "description": "foo", + }, + "items": Array [ + Object { + "className": "foo", + "id": "guide1", + "type": "doc", + }, + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "nested-guide", + "type": "doc", + }, + ], + "label": "SubGuides (metadata file label)", + "link": Object { + "description": "subguides-description", + "slug": "subguides-generated-index-slug", + "title": "subguides-title", + "type": "generated-index", + }, + "type": "category", + }, + Object { + "id": "guide2", + "type": "doc", + }, + ], + "label": "Guides", + "link": Object { + "id": "guides-index", + "type": "doc", + }, + "type": "category", + }, + Object { + "id": "end", + "type": "doc", + }, +] +`; + +exports[`DefaultSidebarItemsGenerator generates simple flat sidebar 1`] = ` +Array [ + Object { + "id": "doc3", + "type": "doc", + }, + Object { + "id": "doc4", + "type": "doc", + }, + Object { + "id": "doc1", + "label": "doc1 sidebar label", + "type": "doc", + }, + Object { + "id": "doc2", + "type": "doc", + }, + Object { + "id": "doc5", + "type": "doc", + }, +] +`; + +exports[`DefaultSidebarItemsGenerator generates subfolder sidebar 1`] = ` +Array [ + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "doc8", + "type": "doc", + }, + Object { + "id": "doc7", + "type": "doc", + }, + ], + "label": "subsubsubfolder3 (_category_.json label)", + "link": Object { + "id": "doc1", + "type": "doc", + }, + "type": "category", + }, + Object { + "className": "bar", + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "doc6", + "type": "doc", + }, + ], + "label": "subsubsubfolder2 (_category_.yml label)", + "type": "category", + }, + Object { + "id": "doc1", + "type": "doc", + }, + Object { + "id": "doc4", + "type": "doc", + }, + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "doc5", + "type": "doc", + }, + ], + "label": "subsubsubfolder", + "type": "category", + }, +] +`; + +exports[`DefaultSidebarItemsGenerator respects custom isCategoryIndex 1`] = ` +Array [ + Object { + "id": "intro", + "type": "doc", + }, + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "tutorial1", + "type": "doc", + }, + Object { + "id": "tutorial2", + "type": "doc", + }, + ], + "label": "Tutorials", + "link": Object { + "id": "tutorials-index", + "type": "doc", + }, + "type": "category", + }, + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "className": "foo", + "id": "guide1", + "type": "doc", + }, + Object { + "id": "guide2", + "type": "doc", + }, + Object { + "id": "not-guides-index", + "type": "doc", + }, + ], + "label": "Guides", + "type": "category", + }, +] +`; + +exports[`DefaultSidebarItemsGenerator uses explicit link over the index/readme.{md,mdx} naming convention 1`] = ` +Array [ + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "parent/doc2", + "type": "doc", + }, + Object { + "id": "parent/doc1", + "type": "doc", + }, + ], + "label": "Category label", + "link": Object { + "id": "parent/doc3", + "type": "doc", + }, + "type": "category", + }, + Object { + "collapsed": undefined, + "collapsible": undefined, + "items": Array [ + Object { + "id": "parent/doc4", + "type": "doc", + }, + Object { + "id": "parent/doc6", + "type": "doc", + }, + Object { + "id": "parent/doc5", + "type": "doc", + }, + ], + "label": "Category 2 label", + "type": "category", + }, +] +`; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts index d45cdc8425..73c2357cd9 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/generator.test.ts @@ -6,7 +6,7 @@ */ import {DefaultSidebarItemsGenerator} from '../generator'; -import type {Sidebar, SidebarItemsGenerator} from '../types'; +import type {SidebarItemsGenerator} from '../types'; import {DefaultNumberPrefixParser} from '../../numberPrefix'; import {isCategoryIndex} from '../../docs'; @@ -104,13 +104,7 @@ describe('DefaultSidebarItemsGenerator', () => { }, }); - expect(sidebarSlice).toEqual([ - {type: 'doc', id: 'doc3'}, - {type: 'doc', id: 'doc4'}, - {type: 'doc', id: 'doc1', label: 'doc1 sidebar label'}, - {type: 'doc', id: 'doc2'}, - {type: 'doc', id: 'doc5'}, - ] as Sidebar); + expect(sidebarSlice).toMatchSnapshot(); }); test('generates complex nested sidebar', async () => { @@ -214,49 +208,7 @@ describe('DefaultSidebarItemsGenerator', () => { }, }); - expect(sidebarSlice).toEqual([ - {type: 'doc', id: 'intro'}, - { - type: 'category', - label: 'Tutorials', - link: { - type: 'doc', - id: 'tutorials-index', - }, - items: [ - {type: 'doc', id: 'tutorial1'}, - {type: 'doc', id: 'tutorial2'}, - ], - }, - { - type: 'category', - label: 'Guides', - link: { - type: 'doc', - id: 'guides-index', - }, - customProps: { - description: 'foo', - }, - collapsed: false, - items: [ - {type: 'doc', id: 'guide1', className: 'foo'}, - { - type: 'category', - label: 'SubGuides (metadata file label)', - items: [{type: 'doc', id: 'nested-guide'}], - link: { - type: 'generated-index', - slug: 'subguides-generated-index-slug', - title: 'subguides-title', - description: 'subguides-description', - }, - }, - {type: 'doc', id: 'guide2'}, - ], - }, - {type: 'doc', id: 'end'}, - ] as Sidebar); + expect(sidebarSlice).toMatchSnapshot(); }); test('generates subfolder sidebar', async () => { @@ -352,33 +304,7 @@ describe('DefaultSidebarItemsGenerator', () => { }, }); - expect(sidebarSlice).toEqual([ - { - type: 'category', - label: 'subsubsubfolder3 (_category_.json label)', - link: { - id: 'doc1', - type: 'doc', - }, - items: [ - {type: 'doc', id: 'doc8'}, - {type: 'doc', id: 'doc7'}, - ], - }, - { - type: 'category', - label: 'subsubsubfolder2 (_category_.yml label)', - className: 'bar', - items: [{type: 'doc', id: 'doc6'}], - }, - {type: 'doc', id: 'doc1'}, - {type: 'doc', id: 'doc4'}, - { - type: 'category', - label: 'subsubsubfolder', - items: [{type: 'doc', id: 'doc5'}], - }, - ] as Sidebar); + expect(sidebarSlice).toMatchSnapshot(); }); test('uses explicit link over the index/readme.{md,mdx} naming convention', async () => { @@ -449,45 +375,7 @@ describe('DefaultSidebarItemsGenerator', () => { }, }); - expect(sidebarSlice).toEqual([ - { - type: 'category', - label: 'Category label', - link: { - id: 'parent/doc3', - type: 'doc', - }, - items: [ - { - id: 'parent/doc2', - type: 'doc', - }, - // doc1 is below doc2, because its file name is index.md - { - id: 'parent/doc1', - type: 'doc', - }, - ], - }, - { - type: 'category', - label: 'Category 2 label', - items: [ - { - id: 'parent/doc4', - type: 'doc', - }, - { - id: 'parent/doc6', - type: 'doc', - }, - { - id: 'parent/doc5', - type: 'doc', - }, - ], - }, - ] as Sidebar); + expect(sidebarSlice).toMatchSnapshot(); }); test('respects custom isCategoryIndex', async () => { @@ -570,32 +458,49 @@ describe('DefaultSidebarItemsGenerator', () => { }, }); - expect(sidebarSlice).toEqual([ - {type: 'doc', id: 'intro'}, - { - type: 'category', - label: 'Tutorials', - link: { - type: 'doc', - id: 'tutorials-index', + expect(sidebarSlice).toMatchSnapshot(); + }); + + test('throws for unknown index link', async () => { + const generateSidebar = () => + DefaultSidebarItemsGenerator({ + numberPrefixParser: DefaultNumberPrefixParser, + isCategoryIndex, + item: { + type: 'autogenerated', + dirName: '.', }, - items: [ - {type: 'doc', id: 'tutorial1'}, - {type: 'doc', id: 'tutorial2'}, - ], - }, - { - type: 'category', - label: 'Guides', - items: [ - {type: 'doc', id: 'guide1', className: 'foo'}, - {type: 'doc', id: 'guide2'}, + version: { + versionName: 'current', + contentPath: '', + }, + categoriesMetadata: { + category: { + link: { + type: 'doc', + id: 'foo', + }, + }, + }, + docs: [ { - type: 'doc', - id: 'not-guides-index', + id: 'intro', + unversionedId: 'intro', + source: '@site/docs/category/intro.md', + sourceDirName: 'category', + frontMatter: {}, }, ], - }, - ] as Sidebar); + options: { + sidebarCollapsed: true, + sidebarCollapsible: true, + }, + }); + + await expect(generateSidebar).rejects.toThrowErrorMatchingInlineSnapshot(` + "Can't find any doc with ID foo. + Available doc IDs: + - intro" + `); }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts index d165ae6673..ad30c2177c 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/__tests__/index.test.ts @@ -23,7 +23,10 @@ describe('loadSidebars', () => { frontMatter: {}, }, ], - version: {contentPath: 'docs/foo', contentPathLocalized: 'docs/foo'}, + version: { + contentPath: path.join(fixtureDir, 'docs'), + contentPathLocalized: path.join(fixtureDir, 'docs'), + }, categoryLabelSlugger: null, sidebarOptions: {sidebarCollapsed: true, sidebarCollapsible: true}, }; @@ -107,4 +110,36 @@ describe('loadSidebars', () => { const result = await loadSidebars(sidebarPath, params); expect(result).toMatchSnapshot(); }); + + test('duplicate category metadata files', async () => { + const sidebarPath = path.join( + fixtureDir, + 'sidebars-collapsed-first-level.json', + ); + const consoleWarnMock = jest + .spyOn(console, 'warn') + .mockImplementation(() => {}); + const consoleErrorMock = jest + .spyOn(console, 'error') + .mockImplementation(() => {}); + await expect(() => + loadSidebars(sidebarPath, { + ...params, + version: { + contentPath: path.join(fixtureDir, 'invalid-docs'), + contentPathLocalized: path.join(fixtureDir, 'invalid-docs'), + }, + }), + ).rejects.toThrowErrorMatchingInlineSnapshot(`"\\"foo\\" is not allowed"`); + expect(consoleWarnMock).toBeCalledWith( + expect.stringMatching( + /.*\[WARNING].* There are more than one category metadata files for .*foo.*: foo\/_category_.json, foo\/_category_.yml. The behavior is undetermined./, + ), + ); + expect(consoleErrorMock).toBeCalledWith( + expect.stringMatching( + /.*\[ERROR].* The docs sidebar category metadata file .*foo\/_category_.json.* looks invalid!/, + ), + ); + }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts index 9d6b4c3d39..5e266bc005 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/generator.ts @@ -60,9 +60,9 @@ export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async ({ const doc = findDoc(docId); if (!doc) { throw new Error( - `Can't find any doc with id=${docId}.\nAvailable doc ids:\n- ${Object.keys( - docsById, - ).join('\n- ')}`, + `Can't find any doc with ID ${docId}. +Available doc IDs: +- ${Object.keys(docsById).join('\n- ')}`, ); } return doc; diff --git a/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts b/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts index 1da2c7aee0..20013e5208 100644 --- a/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts +++ b/packages/docusaurus-plugin-content-docs/src/sidebars/utils.ts @@ -258,11 +258,7 @@ export function createSidebarsUtils(sidebars: Sidebars): SidebarsUtils { const sidebarName = Object.entries(sidebarNameToNavigationItems).find( ([, navigationItems]) => navigationItems.find(isCurrentCategoryGeneratedIndexItem), - )?.[0]; - - if (!sidebarName) { - return emptySidebarNavigation(); - } + )![0]; const navigationItems = sidebarNameToNavigationItems[sidebarName]!; const currentItemIndex = navigationItems.findIndex( isCurrentCategoryGeneratedIndexItem, diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index 9b6ef14bc3..d9047970a4 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -161,10 +161,7 @@ export type ImportedPresetModule = PresetModule & { default?: PresetModule; }; -export type PresetConfig = - | [string, Record] - | [string] - | string; +export type PresetConfig = string | [string, Record]; export type HostPortCLIOptions = { host?: string; @@ -356,9 +353,8 @@ export type ConfigurePostCssFn = Plugin['configurePostCss']; export type PluginOptions = {id?: string} & Record; export type PluginConfig = - | [string, PluginOptions] - | [string] | string + | [string, PluginOptions] | [PluginModule, PluginOptions] | PluginModule; diff --git a/packages/docusaurus/src/server/configValidation.ts b/packages/docusaurus/src/server/configValidation.ts index aa81707a77..78dee2de68 100644 --- a/packages/docusaurus/src/server/configValidation.ts +++ b/packages/docusaurus/src/server/configValidation.ts @@ -55,7 +55,9 @@ function createPluginSchema(theme: boolean = false) { Joi.alternatives() .try( Joi.function(), - Joi.array().ordered(Joi.function().required(), Joi.object().required()), + Joi.array() + .ordered(Joi.function().required(), Joi.object().required()) + .length(2), Joi.string(), Joi.array() .ordered(Joi.string().required(), Joi.object().required()) diff --git a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js index b220cc30b7..4e49b55a82 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js +++ b/packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/plugin3.js @@ -3,3 +3,7 @@ module.exports = function (context, options) { name: 'third-plugin', }; }; + +module.exports.validateThemeConfig = function ({validate, themeConfig}) { + return {a: 1}; +}; diff --git a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts index 2cde3a7a58..78d670c5b0 100644 --- a/packages/docusaurus/src/server/plugins/__tests__/init.test.ts +++ b/packages/docusaurus/src/server/plugins/__tests__/init.test.ts @@ -38,6 +38,7 @@ describe('initPlugins', () => { expect(plugins[1].name).toBe('second-plugin'); expect(plugins[2].name).toBe('third-plugin'); expect(plugins[3].name).toBe('fourth-plugin'); + expect(context.siteConfig.themeConfig).toEqual({a: 1}); }); test('plugins with bad values throw user-friendly error message', async () => { diff --git a/packages/docusaurus/src/server/plugins/index.ts b/packages/docusaurus/src/server/plugins/index.ts index ef63e6bee9..c7983f16cf 100644 --- a/packages/docusaurus/src/server/plugins/index.ts +++ b/packages/docusaurus/src/server/plugins/index.ts @@ -89,7 +89,7 @@ export async function loadPlugins({ // need to run in certain order or depend on others for data. const loadedPlugins: LoadedPlugin[] = await Promise.all( plugins.map(async (plugin) => { - const content = plugin.loadContent ? await plugin.loadContent() : null; + const content = await plugin.loadContent?.(); return {...plugin, content}; }), ); @@ -205,7 +205,7 @@ export async function loadPlugins({ await Promise.all( contentLoadedTranslatedPlugins.map(async (plugin) => { if (!plugin.routesLoaded) { - return null; + return; } // TODO remove this deprecated lifecycle soon @@ -213,7 +213,7 @@ export async function loadPlugins({ // TODO, 1 user reported usage of this lifecycle! https://github.com/facebook/docusaurus/issues/3918 logger.error`Plugin code=${'routesLoaded'} lifecycle is deprecated. If you think we should keep this lifecycle, please report here: path=${'https://github.com/facebook/docusaurus/issues/3918'}`; - return plugin.routesLoaded(pluginsRouteConfigs); + await plugin.routesLoaded(pluginsRouteConfigs); }), ); diff --git a/packages/docusaurus/src/server/plugins/init.ts b/packages/docusaurus/src/server/plugins/init.ts index a6d6e04459..6e4a600386 100644 --- a/packages/docusaurus/src/server/plugins/init.ts +++ b/packages/docusaurus/src/server/plugins/init.ts @@ -61,39 +61,29 @@ async function normalizePluginConfig( }; } - if (Array.isArray(pluginConfig)) { - // plugins: [ - // ['./plugin',options], - // ] - if (typeof pluginConfig[0] === 'string') { - const pluginModuleImport = pluginConfig[0]; - const pluginPath = pluginRequire.resolve(pluginModuleImport); - const pluginModule = importFresh(pluginPath); - return { - plugin: pluginModule?.default ?? pluginModule, - options: pluginConfig[1] ?? {}, - pluginModule: { - path: pluginModuleImport, - module: pluginModule, - }, - }; - } - // plugins: [ - // [function plugin() { },options], - // ] - if (typeof pluginConfig[0] === 'function') { - return { - plugin: pluginConfig[0], - options: pluginConfig[1] ?? {}, - }; - } + // plugins: [ + // ['./plugin',options], + // ] + if (typeof pluginConfig[0] === 'string') { + const pluginModuleImport = pluginConfig[0]; + const pluginPath = pluginRequire.resolve(pluginModuleImport); + const pluginModule = importFresh(pluginPath); + return { + plugin: pluginModule?.default ?? pluginModule, + options: pluginConfig[1], + pluginModule: { + path: pluginModuleImport, + module: pluginModule, + }, + }; } - - throw new Error( - `Unexpected: can't load plugin for following plugin config.\n${JSON.stringify( - pluginConfig, - )}`, - ); + // plugins: [ + // [function plugin() { },options], + // ] + return { + plugin: pluginConfig[0], + options: pluginConfig[1], + }; } export async function normalizePluginConfigs( @@ -219,16 +209,9 @@ export default async function initPlugins({ }; } - const plugins: InitializedPlugin[] = ( - await Promise.all( - pluginConfigsNormalized.map((pluginConfig) => { - if (!pluginConfig) { - return null; - } - return initializePlugin(pluginConfig); - }), - ) - ).filter((item: T): item is Exclude => Boolean(item)); + const plugins: InitializedPlugin[] = await Promise.all( + pluginConfigsNormalized.map(initializePlugin), + ); ensureUniquePluginInstanceIds(plugins); diff --git a/packages/docusaurus/src/server/presets/index.ts b/packages/docusaurus/src/server/presets/index.ts index b811343540..235493e044 100644 --- a/packages/docusaurus/src/server/presets/index.ts +++ b/packages/docusaurus/src/server/presets/index.ts @@ -32,10 +32,8 @@ export default async function loadPresets(context: LoadContext): Promise<{ let presetOptions = {}; if (typeof presetItem === 'string') { presetModuleImport = presetItem; - } else if (Array.isArray(presetItem)) { - [presetModuleImport, presetOptions = {}] = presetItem; } else { - throw new Error('Invalid presets format detected in config.'); + [presetModuleImport, presetOptions] = presetItem; } const presetName = resolveModuleName( presetModuleImport, diff --git a/packages/docusaurus/src/server/versions/__tests__/__fixtures__/dummy-plugin.js b/packages/docusaurus/src/server/versions/__tests__/__fixtures__/dummy-plugin.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/docusaurus/src/server/versions/__fixtures__/package.json b/packages/docusaurus/src/server/versions/__tests__/__fixtures__/package.json similarity index 100% rename from packages/docusaurus/src/server/versions/__fixtures__/package.json rename to packages/docusaurus/src/server/versions/__tests__/__fixtures__/package.json diff --git a/packages/docusaurus/src/server/versions/__tests__/index.test.ts b/packages/docusaurus/src/server/versions/__tests__/index.test.ts index 377cb6f2ab..e5542ffbfb 100644 --- a/packages/docusaurus/src/server/versions/__tests__/index.test.ts +++ b/packages/docusaurus/src/server/versions/__tests__/index.test.ts @@ -12,7 +12,7 @@ describe('getPluginVersion', () => { it('Can detect external packages plugins versions of correctly.', async () => { await expect( getPluginVersion( - path.join(__dirname, '..', '__fixtures__', 'dummy-plugin.js'), + path.join(__dirname, '__fixtures__/dummy-plugin.js'), // Make the plugin appear external. path.join(__dirname, '..', '..', '..', '..', '..', '..', 'website'), ), @@ -22,9 +22,9 @@ describe('getPluginVersion', () => { it('Can detect project plugins versions correctly.', async () => { await expect( getPluginVersion( - path.join(__dirname, '..', '__fixtures__', 'dummy-plugin.js'), + path.join(__dirname, '__fixtures__/dummy-plugin.js'), // Make the plugin appear project local. - path.join(__dirname, '..', '__fixtures__'), + path.join(__dirname, '__fixtures__'), ), ).resolves.toEqual({type: 'project'}); }); diff --git a/packages/docusaurus/src/server/versions/index.ts b/packages/docusaurus/src/server/versions/index.ts index 2b95a36db4..e2f717419b 100644 --- a/packages/docusaurus/src/server/versions/index.ts +++ b/packages/docusaurus/src/server/versions/index.ts @@ -22,11 +22,8 @@ export async function getPackageJsonVersion( async function getPackageJsonName( packageJsonPath: string, ): Promise { - if (await fs.pathExists(packageJsonPath)) { - // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require - return require(packageJsonPath).name; - } - return undefined; + // eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-dynamic-require, global-require + return require(packageJsonPath).name; } export async function getPluginVersion(