mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-24 21:48:02 +02:00
test: improve test coverage (#6857)
This commit is contained in:
parent
edb4d00096
commit
f763ac13a9
22 changed files with 435 additions and 220 deletions
|
@ -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),
|
||||
};
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"foo": "bar"
|
||||
}
|
|
@ -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",
|
||||
},
|
||||
]
|
||||
`;
|
|
@ -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"
|
||||
`);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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!/,
|
||||
),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue