test: improve test coverage (#6857)

This commit is contained in:
Joshua Chen 2022-03-06 17:55:21 +08:00 committed by GitHub
parent edb4d00096
commit f763ac13a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 435 additions and 220 deletions

View file

@ -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),
};

View file

@ -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",
},
]
`;

View file

@ -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"
`);
});
});

View file

@ -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!/,
),
);
});
});

View file

@ -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;

View file

@ -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,