feat(v2): core v2 i18n support + Docusaurus site Crowdin integration (#3325)

* docs i18n initial poc

* docs i18n initial poc

* docs i18n initial poc

* docs i18n initial poc

* crowdin-v2 attempt

* fix source

* use crowdin env variable

* try to install crowdin on netlify

* try to install crowdin on netlify

* try to use crowdin jar directly

* try to curl the crowdin jar

* add java version cmd

* try to run crowdin jar in netlify

* fix translatedDocsDirPath

* fix loadContext issue due to site baseUrl not being modified in generted config file

* real validateLocalesFile

* add locale option to deploy command

* better LocalizationFile type

* create util getPluginI18nPath

* better core localization context loading code

* More explicit VersionMetadata type for localized docs folders

* Ability to translate blog posts with Crowdin!

* blog: refactor markdown loader + report broken links + try to get linkify working better

* upgrade crowdin config to upload all docs folder files except source code related files

* try to support translated pages

* make markdown pages translation work

* add write-translations cli command template

* fix site not  reloaded with correct options

* refactor a bit the read/write of @generated/i18n.json file

* Add <Translate> + translate() API + use it on the docusaurus homepage

* watch locale translation dir

* early POC of adding babel parsing for translation extraction

* fs.stat => pathExists

* add install:fast script

* TSC: noUnusedLocals false as it's already checked  by eslint

* POC of extracting translations from source code

* minor typo

* fix extracted key to code

* initial docs extracted translations

* stable plugin translations POC

* add crowdin commands

* quickfix for i18n deployment

* POC  of themeConfig translation

* add ability to have localized site without path prefix

* sidebar typo

* refactor translation system to output multiple translation files

* translate properly  the docs plugin

* improve theme classic translation

* rework translation extractor to handle new Chrome I18n JSON format (include id/description)

* writeTranslations: allow to pass locales cli arg

* fix ThemeConfig TS issues

* fix localizePath errors

* temporary add write-translations to netlify deploy preview

* complete example of french translated folder

* update fr folder

* remove all translations from repo

* minor translation  refactors

* fix all docs-related tests

* fix blog feed tests

* fix last blog tests

* refactor i18n context a bit, extract codeTranslations in an extra generated file

* improve @generated/i18n type

* fix some i18n todos

* minor refactor

* fix logo typing issue after merge

* move i18n.json to siteConfig instead

* try to fix windows CI build

* fix config test

* attempt to fix windows non-posix path

* increase v1 minify css jest timeout due to flaky test

* proper support for localizePath on windows

* remove non-functional install:fast

* docs, fix docsDirPathLocalized

* fix Docs i18n / md linkify issues

* ensure theme-classic swizzling will use "nextjs" sources (transpiled less aggressively, to make them human readable)

* fix some snapshots

* improve themeConfig translation code

* refactor a bit getPluginI18nPath

* readTranslationFileContent => ensure files are valid, fail fast

* fix versions tests

* add extractSourceCodeAstTranslations comments/resource links

* ignore eslint: packages/docusaurus-theme-classic/lib-next/

* fix windows CI with cross-env

* crowdin ignore .DS_Store

* improve writeTranslations + add exhaustive tests for translations.ts

* remove typo

* Wire currentLocale to algolia search

* improve i18n locale error

* Add tests for translationsExtractor.ts

* better code translation extraction regarding statically evaluable code

* fix typo

* fix typo

* improve theme-classic transpilation

* refactor  +  add i18n tests

* typo

* test new utils

* add missing snapshots

* fix snapshot

* blog onBrokenMarkdownLink

* add sidebars tests

* theme-classic index should now use ES modules

* tests for theme-classic translations

* useless comment

* add more translation tests

* simplify/cleanup writeTranslations

* try to fix Netlify fr deployment

* blog: test translated md is used during feed generation

* blog: better i18n tests regarding editUrl + md translation application

* more i18n tests for docs plugin

* more i18n tests for docs plugin

* Add tests for pages i18n

* polish docusaurus build i18n logs
This commit is contained in:
Sébastien Lorber 2020-11-26 12:16:46 +01:00 committed by GitHub
parent 85fe96d112
commit 3166fab307
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
107 changed files with 5447 additions and 649 deletions

View file

@ -0,0 +1,5 @@
---
title: Team title translated
---
Team current version (translated)

View file

@ -616,18 +616,6 @@ Object {
exports[`versioned website (community) content: data 1`] = `
Object {
"site-community-team-md-9d8.json": "{
\\"unversionedId\\": \\"team\\",
\\"id\\": \\"team\\",
\\"isDocsHomePage\\": false,
\\"title\\": \\"team\\",
\\"description\\": \\"Team current version\\",
\\"source\\": \\"@site/community/team.md\\",
\\"slug\\": \\"/team\\",
\\"permalink\\": \\"/community/next/team\\",
\\"version\\": \\"current\\",
\\"sidebar\\": \\"community\\"
}",
"site-community-versioned-docs-version-1-0-0-team-md-359.json": "{
\\"unversionedId\\": \\"team\\",
\\"id\\": \\"version-1.0.0/team\\",
@ -639,6 +627,18 @@ Object {
\\"permalink\\": \\"/community/team\\",
\\"version\\": \\"1.0.0\\",
\\"sidebar\\": \\"version-1.0.0/community\\"
}",
"site-i-18-n-en-docusaurus-plugin-content-docs-community-current-team-md-7e5.json": "{
\\"unversionedId\\": \\"team\\",
\\"id\\": \\"team\\",
\\"isDocsHomePage\\": false,
\\"title\\": \\"Team title translated\\",
\\"description\\": \\"Team current version (translated)\\",
\\"source\\": \\"@site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md\\",
\\"slug\\": \\"/team\\",
\\"permalink\\": \\"/community/next/team\\",
\\"version\\": \\"current\\",
\\"sidebar\\": \\"community\\"
}",
"version-1-0-0-metadata-prop-608.json": "{
\\"pluginId\\": \\"community\\",
@ -667,7 +667,7 @@ Object {
\\"community\\": [
{
\\"type\\": \\"link\\",
\\"label\\": \\"team\\",
\\"label\\": \\"Team title translated\\",
\\"href\\": \\"/community/next/team\\"
}
]
@ -734,7 +734,7 @@ Array [
"component": "@theme/DocItem",
"exact": true,
"modules": Object {
"content": "@site/community/team.md",
"content": "@site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md",
},
"path": "/community/next/team",
},
@ -930,6 +930,22 @@ Object {
\\"slug\\": \\"/tryToEscapeSlug\\",
\\"permalink\\": \\"/docs/next/tryToEscapeSlug\\",
\\"version\\": \\"current\\"
}",
"site-i-18-n-en-docusaurus-plugin-content-docs-version-1-0-0-hello-md-fe5.json": "{
\\"unversionedId\\": \\"hello\\",
\\"id\\": \\"version-1.0.0/hello\\",
\\"isDocsHomePage\\": true,
\\"title\\": \\"hello\\",
\\"description\\": \\"Hello 1.0.0 ! (translated)\\",
\\"source\\": \\"@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md\\",
\\"slug\\": \\"/\\",
\\"permalink\\": \\"/docs/1.0.0/\\",
\\"version\\": \\"1.0.0\\",
\\"sidebar\\": \\"version-1.0.0/docs\\",
\\"previous\\": {
\\"title\\": \\"baz\\",
\\"permalink\\": \\"/docs/1.0.0/foo/baz\\"
}
}",
"site-versioned-docs-version-1-0-0-foo-bar-md-7a6.json": "{
\\"unversionedId\\": \\"foo/bar\\",
@ -966,22 +982,6 @@ Object {
\\"title\\": \\"hello\\",
\\"permalink\\": \\"/docs/1.0.0/\\"
}
}",
"site-versioned-docs-version-1-0-0-hello-md-3ef.json": "{
\\"unversionedId\\": \\"hello\\",
\\"id\\": \\"version-1.0.0/hello\\",
\\"isDocsHomePage\\": true,
\\"title\\": \\"hello\\",
\\"description\\": \\"Hello 1.0.0 !\\",
\\"source\\": \\"@site/versioned_docs/version-1.0.0/hello.md\\",
\\"slug\\": \\"/\\",
\\"permalink\\": \\"/docs/1.0.0/\\",
\\"version\\": \\"1.0.0\\",
\\"sidebar\\": \\"version-1.0.0/docs\\",
\\"previous\\": {
\\"title\\": \\"baz\\",
\\"permalink\\": \\"/docs/1.0.0/foo/baz\\"
}
}",
"site-versioned-docs-version-1-0-1-foo-bar-md-7a3.json": "{
\\"unversionedId\\": \\"foo/bar\\",
@ -1410,7 +1410,7 @@ Array [
"component": "@theme/DocItem",
"exact": true,
"modules": Object {
"content": "@site/versioned_docs/version-1.0.0/hello.md",
"content": "@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md",
},
"path": "/docs/1.0.0/",
},

View file

@ -0,0 +1,487 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`getLoadedContentTranslationFiles should return translation files matching snapshot 1`] = `
Array [
Object {
"content": Object {
"sidebar.docs.category.Getting started": Object {
"description": "The label for category Getting started in sidebar docs",
"message": "Getting started",
},
"sidebar.docs.link.Link label": Object {
"description": "The label for link Link label in sidebar docs, linking to https://facebook.com",
"message": "Link label",
},
"version.label": Object {
"description": "The label for version current",
"message": "current label",
},
},
"path": "current",
},
Object {
"content": Object {
"sidebar.docs.category.Getting started": Object {
"description": "The label for category Getting started in sidebar docs",
"message": "Getting started",
},
"sidebar.docs.link.Link label": Object {
"description": "The label for link Link label in sidebar docs, linking to https://facebook.com",
"message": "Link label",
},
"version.label": Object {
"description": "The label for version 2.0.0",
"message": "2.0.0 label",
},
},
"path": "version-2.0.0",
},
Object {
"content": Object {
"sidebar.docs.category.Getting started": Object {
"description": "The label for category Getting started in sidebar docs",
"message": "Getting started",
},
"sidebar.docs.link.Link label": Object {
"description": "The label for link Link label in sidebar docs, linking to https://facebook.com",
"message": "Link label",
},
"version.label": Object {
"description": "The label for version 1.0.0",
"message": "1.0.0 label",
},
},
"path": "version-1.0.0",
},
]
`;
exports[`translateLoadedContent should return translated loaded content matching snapshot 1`] = `
Object {
"loadedVersions": Array [
Object {
"docs": Array [
Object {
"description": "doc1 description",
"editUrl": "any",
"id": "doc1",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc1 title",
"slug": "any",
"source": "any",
"title": "doc1 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc2 description",
"editUrl": "any",
"id": "doc2",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc2 title",
"slug": "any",
"source": "any",
"title": "doc2 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc3 description",
"editUrl": "any",
"id": "doc3",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc3 title",
"slug": "any",
"source": "any",
"title": "doc3 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc4 description",
"editUrl": "any",
"id": "doc4",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc4 title",
"slug": "any",
"source": "any",
"title": "doc4 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc5 description",
"editUrl": "any",
"id": "doc5",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc5 title",
"slug": "any",
"source": "any",
"title": "doc5 title",
"unversionedId": "any",
"version": "any",
},
],
"docsDirPath": "any",
"docsDirPathLocalized": "any",
"isLast": true,
"mainDocId": "",
"permalinkToSidebar": Object {},
"routePriority": undefined,
"sidebarFilePath": "any",
"sidebars": Object {
"docs": Array [
Object {
"collapsed": false,
"items": Array [
Object {
"id": "doc1",
"type": "doc",
},
Object {
"id": "doc2",
"type": "doc",
},
Object {
"href": "https://facebook.com",
"label": "Link label (translated)",
"type": "link",
},
Object {
"id": "doc1",
"type": "ref",
},
],
"label": "Getting started (translated)",
"type": "category",
},
Object {
"id": "doc3",
"type": "doc",
},
],
"otherSidebar": Array [
Object {
"id": "doc4",
"type": "doc",
},
Object {
"id": "doc5",
"type": "doc",
},
],
},
"versionLabel": "current label (translated)",
"versionName": "current",
"versionPath": "/docs/",
},
Object {
"docs": Array [
Object {
"description": "doc1 description",
"editUrl": "any",
"id": "doc1",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc1 title",
"slug": "any",
"source": "any",
"title": "doc1 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc2 description",
"editUrl": "any",
"id": "doc2",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc2 title",
"slug": "any",
"source": "any",
"title": "doc2 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc3 description",
"editUrl": "any",
"id": "doc3",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc3 title",
"slug": "any",
"source": "any",
"title": "doc3 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc4 description",
"editUrl": "any",
"id": "doc4",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc4 title",
"slug": "any",
"source": "any",
"title": "doc4 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc5 description",
"editUrl": "any",
"id": "doc5",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc5 title",
"slug": "any",
"source": "any",
"title": "doc5 title",
"unversionedId": "any",
"version": "any",
},
],
"docsDirPath": "any",
"docsDirPathLocalized": "any",
"isLast": true,
"mainDocId": "",
"permalinkToSidebar": Object {},
"routePriority": undefined,
"sidebarFilePath": "any",
"sidebars": Object {
"docs": Array [
Object {
"collapsed": false,
"items": Array [
Object {
"id": "doc1",
"type": "doc",
},
Object {
"id": "doc2",
"type": "doc",
},
Object {
"href": "https://facebook.com",
"label": "Link label (translated)",
"type": "link",
},
Object {
"id": "doc1",
"type": "ref",
},
],
"label": "Getting started (translated)",
"type": "category",
},
Object {
"id": "doc3",
"type": "doc",
},
],
"otherSidebar": Array [
Object {
"id": "doc4",
"type": "doc",
},
Object {
"id": "doc5",
"type": "doc",
},
],
},
"versionLabel": "2.0.0 label (translated)",
"versionName": "2.0.0",
"versionPath": "/docs/",
},
Object {
"docs": Array [
Object {
"description": "doc1 description",
"editUrl": "any",
"id": "doc1",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc1 title",
"slug": "any",
"source": "any",
"title": "doc1 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc2 description",
"editUrl": "any",
"id": "doc2",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc2 title",
"slug": "any",
"source": "any",
"title": "doc2 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc3 description",
"editUrl": "any",
"id": "doc3",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc3 title",
"slug": "any",
"source": "any",
"title": "doc3 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc4 description",
"editUrl": "any",
"id": "doc4",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc4 title",
"slug": "any",
"source": "any",
"title": "doc4 title",
"unversionedId": "any",
"version": "any",
},
Object {
"description": "doc5 description",
"editUrl": "any",
"id": "doc5",
"isDocsHomePage": false,
"lastUpdatedAt": 0,
"lastUpdatedBy": "any",
"next": undefined,
"permalink": "any",
"previous": undefined,
"sidebar_label": "doc5 title",
"slug": "any",
"source": "any",
"title": "doc5 title",
"unversionedId": "any",
"version": "any",
},
],
"docsDirPath": "any",
"docsDirPathLocalized": "any",
"isLast": true,
"mainDocId": "",
"permalinkToSidebar": Object {},
"routePriority": undefined,
"sidebarFilePath": "any",
"sidebars": Object {
"docs": Array [
Object {
"collapsed": false,
"items": Array [
Object {
"id": "doc1",
"type": "doc",
},
Object {
"id": "doc2",
"type": "doc",
},
Object {
"href": "https://facebook.com",
"label": "Link label (translated)",
"type": "link",
},
Object {
"id": "doc1",
"type": "ref",
},
],
"label": "Getting started (translated)",
"type": "category",
},
Object {
"id": "doc3",
"type": "doc",
},
],
"otherSidebar": Array [
Object {
"id": "doc4",
"type": "doc",
},
Object {
"id": "doc5",
"type": "doc",
},
],
},
"versionLabel": "1.0.0 label (translated)",
"versionName": "1.0.0",
"versionPath": "/docs/",
},
],
}
`;

View file

@ -42,6 +42,7 @@ ${markdown}
source,
content,
lastUpdate: {},
filePath: source,
};
};
@ -57,7 +58,7 @@ function createTestUtils({
options: MetadataOptions;
}) {
async function readDoc(docFileSource: string) {
return readDocFile(versionMetadata.docsDirPath, docFileSource, options);
return readDocFile(versionMetadata, docFileSource, options);
}
function processDocFile(docFile: DocFile) {
return processDocMetadata({
@ -110,30 +111,41 @@ function createTestUtils({
}
describe('simple site', () => {
const siteDir = path.join(fixtureDir, 'simple-site');
const context = loadContext(siteDir);
const options = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
};
const versionsMetadata = readVersionsMetadata({
context,
options: {
async function loadSite() {
const siteDir = path.join(fixtureDir, 'simple-site');
const context = await loadContext(siteDir);
const options = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
},
});
expect(versionsMetadata.length).toEqual(1);
const [currentVersion] = versionsMetadata;
};
const versionsMetadata = readVersionsMetadata({
context,
options: {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
},
});
expect(versionsMetadata.length).toEqual(1);
const [currentVersion] = versionsMetadata;
const defaultTestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: currentVersion,
});
const defaultTestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: currentVersion,
});
return {
siteDir,
context,
options,
versionsMetadata,
defaultTestUtils,
currentVersion,
};
}
test('readVersionDocs', async () => {
const {options, currentVersion} = await loadSite();
const docs = await readVersionDocs(currentVersion, options);
expect(docs.map((doc) => doc.source).sort()).toEqual(
[
@ -155,6 +167,7 @@ describe('simple site', () => {
});
test('normal docs', async () => {
const {defaultTestUtils} = await loadSite();
await defaultTestUtils.testMeta(path.join('foo', 'bar.md'), {
version: 'current',
id: 'foo/bar',
@ -178,6 +191,8 @@ describe('simple site', () => {
});
test('homePageId doc', async () => {
const {siteDir, context, options, currentVersion} = await loadSite();
const testUtilsLocal = createTestUtils({
siteDir,
context,
@ -198,6 +213,8 @@ describe('simple site', () => {
});
test('homePageId doc nested', async () => {
const {siteDir, context, options, currentVersion} = await loadSite();
const testUtilsLocal = createTestUtils({
siteDir,
context,
@ -218,6 +235,8 @@ describe('simple site', () => {
});
test('docs with editUrl', async () => {
const {siteDir, context, options, currentVersion} = await loadSite();
const testUtilsLocal = createTestUtils({
siteDir,
context,
@ -243,6 +262,8 @@ describe('simple site', () => {
});
test('docs with custom editUrl & unrelated frontmatter', async () => {
const {defaultTestUtils} = await loadSite();
await defaultTestUtils.testMeta('lorem.md', {
version: 'current',
id: 'lorem',
@ -257,6 +278,8 @@ describe('simple site', () => {
});
test('docs with last update time and author', async () => {
const {siteDir, context, options, currentVersion} = await loadSite();
const testUtilsLocal = createTestUtils({
siteDir,
context,
@ -284,6 +307,8 @@ describe('simple site', () => {
});
test('docs with slugs', async () => {
const {defaultTestUtils} = await loadSite();
await defaultTestUtils.testSlug(
path.join('rootRelativeSlug.md'),
'/docs/rootRelativeSlug',
@ -319,7 +344,8 @@ describe('simple site', () => {
);
});
test('docs with invalid id', () => {
test('docs with invalid id', async () => {
const {defaultTestUtils} = await loadSite();
expect(() => {
defaultTestUtils.processDocFile(
createFakeDocFile({
@ -335,6 +361,8 @@ describe('simple site', () => {
});
test('docs with slug on doc home', async () => {
const {siteDir, context, options, currentVersion} = await loadSite();
const testUtilsLocal = createTestUtils({
siteDir,
context,
@ -360,55 +388,71 @@ describe('simple site', () => {
});
describe('versioned site', () => {
const siteDir = path.join(fixtureDir, 'versioned-site');
const context = loadContext(siteDir);
const options = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
};
const versionsMetadata = readVersionsMetadata({
context,
options: {
async function loadSite() {
const siteDir = path.join(fixtureDir, 'versioned-site');
const context = await loadContext(siteDir);
const options = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
},
});
expect(versionsMetadata.length).toEqual(4);
const [
currentVersion,
version101,
version100,
versionWithSlugs,
] = versionsMetadata;
};
const versionsMetadata = readVersionsMetadata({
context,
options: {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
},
});
expect(versionsMetadata.length).toEqual(4);
const [
currentVersion,
version101,
version100,
versionWithSlugs,
] = versionsMetadata;
const currentVersionTestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: currentVersion,
});
const version101TestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: version101,
});
const currentVersionTestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: currentVersion,
});
const version101TestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: version101,
});
const version100TestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: version100,
});
const version100TestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: version100,
});
const versionWithSlugsTestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: versionWithSlugs,
});
const versionWithSlugsTestUtils = createTestUtils({
siteDir,
context,
options,
versionMetadata: versionWithSlugs,
});
return {
siteDir,
context,
options,
versionsMetadata,
currentVersionTestUtils,
version101TestUtils,
version100,
version100TestUtils,
versionWithSlugsTestUtils,
};
}
test('next docs', async () => {
const {currentVersionTestUtils} = await loadSite();
await currentVersionTestUtils.testMeta(path.join('foo', 'bar.md'), {
id: 'foo/bar',
unversionedId: 'foo/bar',
@ -432,6 +476,8 @@ describe('versioned site', () => {
});
test('versioned docs', async () => {
const {version101TestUtils, version100TestUtils} = await loadSite();
await version100TestUtils.testMeta(path.join('foo', 'bar.md'), {
id: 'version-1.0.0/foo/bar',
unversionedId: 'foo/bar',
@ -449,8 +495,10 @@ describe('versioned site', () => {
permalink: '/docs/1.0.0/hello',
slug: '/hello',
title: 'hello',
description: 'Hello 1.0.0 !',
description: 'Hello 1.0.0 ! (translated)',
version: '1.0.0',
source:
'@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md',
});
await version101TestUtils.testMeta(path.join('foo', 'bar.md'), {
id: 'version-1.0.1/foo/bar',
@ -475,6 +523,8 @@ describe('versioned site', () => {
});
test('next doc slugs', async () => {
const {currentVersionTestUtils} = await loadSite();
await currentVersionTestUtils.testSlug(
path.join('slugs', 'absoluteSlug.md'),
'/docs/next/absoluteSlug',
@ -494,6 +544,8 @@ describe('versioned site', () => {
});
test('versioned doc slugs', async () => {
const {versionWithSlugsTestUtils} = await loadSite();
await versionWithSlugsTestUtils.testSlug(
path.join('rootAbsoluteSlug.md'),
'/docs/withSlugs/rootAbsoluteSlug',
@ -528,4 +580,33 @@ describe('versioned site', () => {
'/docs/withSlugs/tryToEscapeSlug',
);
});
test('translated doc with editUrl', async () => {
const {siteDir, context, options, version100} = await loadSite();
const testUtilsLocal = createTestUtils({
siteDir,
context,
options: {
...options,
editUrl: 'https://github.com/facebook/docusaurus/edit/master/website',
},
versionMetadata: version100,
});
await testUtilsLocal.testMeta(path.join('hello.md'), {
id: 'version-1.0.0/hello',
unversionedId: 'hello',
isDocsHomePage: false,
permalink: '/docs/1.0.0/hello',
slug: '/hello',
title: 'hello',
description: 'Hello 1.0.0 ! (translated)',
version: '1.0.0',
source:
'@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md',
editUrl:
'https://github.com/facebook/docusaurus/edit/master/website/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md',
});
});
});

View file

@ -106,7 +106,7 @@ Entries created:
test('site with wrong sidebar file', async () => {
const siteDir = path.join(__dirname, '__fixtures__', 'simple-site');
const context = loadContext(siteDir);
const context = await loadContext(siteDir);
const sidebarPath = path.join(siteDir, 'wrong-sidebars.json');
const plugin = pluginContentDocs(
context,
@ -119,9 +119,9 @@ test('site with wrong sidebar file', async () => {
describe('empty/no docs website', () => {
const siteDir = path.join(__dirname, '__fixtures__', 'empty-site');
const context = loadContext(siteDir);
test('no files in docs folder', async () => {
const context = await loadContext(siteDir);
await fs.ensureDir(path.join(siteDir, 'docs'));
const plugin = pluginContentDocs(
context,
@ -135,6 +135,7 @@ describe('empty/no docs website', () => {
});
test('docs folder does not exist', async () => {
const context = await loadContext(siteDir);
expect(() =>
pluginContentDocs(
context,
@ -149,20 +150,25 @@ describe('empty/no docs website', () => {
});
describe('simple website', () => {
const siteDir = path.join(__dirname, '__fixtures__', 'simple-site');
const context = loadContext(siteDir);
const sidebarPath = path.join(siteDir, 'sidebars.json');
const plugin = pluginContentDocs(
context,
normalizePluginOptions(OptionsSchema, {
path: 'docs',
sidebarPath,
homePageId: 'hello',
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
async function loadSite() {
const siteDir = path.join(__dirname, '__fixtures__', 'simple-site');
const context = await loadContext(siteDir);
const sidebarPath = path.join(siteDir, 'sidebars.json');
const plugin = pluginContentDocs(
context,
normalizePluginOptions(OptionsSchema, {
path: 'docs',
sidebarPath,
homePageId: 'hello',
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
test('extendCli - docsVersion', () => {
return {siteDir, context, sidebarPath, plugin, pluginContentDir};
}
test('extendCli - docsVersion', async () => {
const {siteDir, sidebarPath, plugin} = await loadSite();
const mock = jest
.spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation();
@ -178,7 +184,9 @@ describe('simple website', () => {
mock.mockRestore();
});
test('getPathToWatch', () => {
test('getPathToWatch', async () => {
const {siteDir, plugin} = await loadSite();
const pathToWatch = plugin.getPathsToWatch!();
const matchPattern = pathToWatch.map((filepath) =>
posixPath(path.relative(siteDir, filepath)),
@ -187,6 +195,7 @@ describe('simple website', () => {
expect(matchPattern).toMatchInlineSnapshot(`
Array [
"sidebars.json",
"i18n/en/docusaurus-plugin-content-docs/current/**/*.{md,mdx}",
"docs/**/*.{md,mdx}",
]
`);
@ -203,6 +212,8 @@ describe('simple website', () => {
});
test('configureWebpack', async () => {
const {plugin} = await loadSite();
const config = applyConfigureWebpack(
plugin.configureWebpack,
{
@ -219,6 +230,7 @@ describe('simple website', () => {
});
test('content', async () => {
const {siteDir, plugin, pluginContentDir} = await loadSite();
const content = await plugin.loadContent!();
expect(content.loadedVersions.length).toEqual(1);
const [currentVersion] = content.loadedVersions;
@ -287,22 +299,32 @@ describe('simple website', () => {
});
describe('versioned website', () => {
const siteDir = path.join(__dirname, '__fixtures__', 'versioned-site');
const context = loadContext(siteDir);
const sidebarPath = path.join(siteDir, 'sidebars.json');
const routeBasePath = 'docs';
const plugin = pluginContentDocs(
context,
normalizePluginOptions(OptionsSchema, {
async function loadSite() {
const siteDir = path.join(__dirname, '__fixtures__', 'versioned-site');
const context = await loadContext(siteDir);
const sidebarPath = path.join(siteDir, 'sidebars.json');
const routeBasePath = 'docs';
const plugin = pluginContentDocs(
context,
normalizePluginOptions(OptionsSchema, {
routeBasePath,
sidebarPath,
homePageId: 'hello',
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
return {
siteDir,
context,
routeBasePath,
sidebarPath,
homePageId: 'hello',
}),
);
plugin,
pluginContentDir,
};
}
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
test('extendCli - docsVersion', () => {
test('extendCli - docsVersion', async () => {
const {siteDir, routeBasePath, sidebarPath, plugin} = await loadSite();
const mock = jest
.spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation();
@ -318,7 +340,8 @@ describe('versioned website', () => {
mock.mockRestore();
});
test('getPathToWatch', () => {
test('getPathToWatch', async () => {
const {siteDir, plugin} = await loadSite();
const pathToWatch = plugin.getPathsToWatch!();
const matchPattern = pathToWatch.map((filepath) =>
posixPath(path.relative(siteDir, filepath)),
@ -327,12 +350,16 @@ describe('versioned website', () => {
expect(matchPattern).toMatchInlineSnapshot(`
Array [
"sidebars.json",
"i18n/en/docusaurus-plugin-content-docs/current/**/*.{md,mdx}",
"docs/**/*.{md,mdx}",
"versioned_sidebars/version-1.0.1-sidebars.json",
"i18n/en/docusaurus-plugin-content-docs/version-1.0.1/**/*.{md,mdx}",
"versioned_docs/version-1.0.1/**/*.{md,mdx}",
"versioned_sidebars/version-1.0.0-sidebars.json",
"i18n/en/docusaurus-plugin-content-docs/version-1.0.0/**/*.{md,mdx}",
"versioned_docs/version-1.0.0/**/*.{md,mdx}",
"versioned_sidebars/version-withSlugs-sidebars.json",
"i18n/en/docusaurus-plugin-content-docs/version-withSlugs/**/*.{md,mdx}",
"versioned_docs/version-withSlugs/**/*.{md,mdx}",
]
`);
@ -369,6 +396,7 @@ describe('versioned website', () => {
});
test('content', async () => {
const {siteDir, plugin, pluginContentDir} = await loadSite();
const content = await plugin.loadContent!();
expect(content.loadedVersions.length).toEqual(4);
const [
@ -499,23 +527,41 @@ describe('versioned website', () => {
});
describe('versioned website (community)', () => {
const siteDir = path.join(__dirname, '__fixtures__', 'versioned-site');
const context = loadContext(siteDir);
const sidebarPath = path.join(siteDir, 'community_sidebars.json');
const routeBasePath = 'community';
const pluginId = 'community';
const plugin = pluginContentDocs(
context,
normalizePluginOptions(OptionsSchema, {
id: 'community',
path: 'community',
async function loadSite() {
const siteDir = path.join(__dirname, '__fixtures__', 'versioned-site');
const context = await loadContext(siteDir);
const sidebarPath = path.join(siteDir, 'community_sidebars.json');
const routeBasePath = 'community';
const pluginId = 'community';
const plugin = pluginContentDocs(
context,
normalizePluginOptions(OptionsSchema, {
id: 'community',
path: 'community',
routeBasePath,
sidebarPath,
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
return {
siteDir,
context,
routeBasePath,
sidebarPath,
}),
);
const pluginContentDir = path.join(context.generatedFilesDir, plugin.name);
pluginId,
plugin,
pluginContentDir,
};
}
test('extendCli - docsVersion', () => {
test('extendCli - docsVersion', async () => {
const {
siteDir,
routeBasePath,
sidebarPath,
pluginId,
plugin,
} = await loadSite();
const mock = jest
.spyOn(cliDocs, 'cliDocsVersionCommand')
.mockImplementation();
@ -531,7 +577,8 @@ describe('versioned website (community)', () => {
mock.mockRestore();
});
test('getPathToWatch', () => {
test('getPathToWatch', async () => {
const {siteDir, plugin} = await loadSite();
const pathToWatch = plugin.getPathsToWatch!();
const matchPattern = pathToWatch.map((filepath) =>
posixPath(path.relative(siteDir, filepath)),
@ -540,8 +587,10 @@ describe('versioned website (community)', () => {
expect(matchPattern).toMatchInlineSnapshot(`
Array [
"community_sidebars.json",
"i18n/en/docusaurus-plugin-content-docs-community/current/**/*.{md,mdx}",
"community/**/*.{md,mdx}",
"community_versioned_sidebars/version-1.0.0-sidebars.json",
"i18n/en/docusaurus-plugin-content-docs-community/version-1.0.0/**/*.{md,mdx}",
"community_versioned_docs/version-1.0.0/**/*.{md,mdx}",
]
`);
@ -568,6 +617,7 @@ describe('versioned website (community)', () => {
});
test('content', async () => {
const {siteDir, plugin, pluginContentDir} = await loadSite();
const content = await plugin.loadContent!();
expect(content.loadedVersions.length).toEqual(2);
const [currentVersion, version100] = content.loadedVersions;
@ -579,13 +629,17 @@ describe('versioned website (community)', () => {
isDocsHomePage: false,
permalink: '/community/next/team',
slug: '/team',
/*
source: path.join(
'@site',
path.relative(siteDir, currentVersion.docsDirPath),
'team.md',
),
title: 'team',
description: 'Team current version',
*/
source:
'@site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md',
title: 'Team title translated',
description: 'Team current version (translated)',
version: 'current',
sidebar: 'community',
});

View file

@ -11,6 +11,9 @@ import {
collectSidebarDocItems,
collectSidebarsDocIds,
createSidebarsUtils,
collectSidebarCategories,
collectSidebarLinks,
transformSidebarItems,
} from '../sidebars';
import {Sidebar, Sidebars} from '../types';
@ -163,7 +166,7 @@ describe('loadSidebars', () => {
});
describe('collectSidebarDocItems', () => {
test('can collect recursively', async () => {
test('can collect docs', async () => {
const sidebar: Sidebar = [
{
type: 'category',
@ -213,7 +216,96 @@ describe('collectSidebarDocItems', () => {
});
});
describe('collectSidebarsDocItems', () => {
describe('collectSidebarCategories', () => {
test('can collect categories', async () => {
const sidebar: Sidebar = [
{
type: 'category',
collapsed: false,
label: 'Category1',
items: [
{
type: 'category',
collapsed: false,
label: 'Subcategory 1',
items: [{type: 'doc', id: 'doc1'}],
},
{
type: 'category',
collapsed: false,
label: 'Subcategory 2',
items: [
{type: 'doc', id: 'doc2'},
{
type: 'category',
collapsed: false,
label: 'Sub sub category 1',
items: [{type: 'doc', id: 'doc3'}],
},
],
},
],
},
{
type: 'category',
collapsed: false,
label: 'Category2',
items: [
{type: 'doc', id: 'doc4'},
{type: 'doc', id: 'doc5'},
],
},
];
expect(
collectSidebarCategories(sidebar).map((category) => category.label),
).toEqual([
'Category1',
'Subcategory 1',
'Subcategory 2',
'Sub sub category 1',
'Category2',
]);
});
});
describe('collectSidebarLinks', () => {
test('can collect links', async () => {
const sidebar: Sidebar = [
{
type: 'category',
collapsed: false,
label: 'Category1',
items: [
{
type: 'link',
href: 'https://google.com',
label: 'Google',
},
{
type: 'category',
collapsed: false,
label: 'Subcategory 2',
items: [
{
type: 'link',
href: 'https://facebook.com',
label: 'Facebook',
},
],
},
],
},
];
expect(collectSidebarLinks(sidebar).map((link) => link.href)).toEqual([
'https://google.com',
'https://facebook.com',
]);
});
});
describe('collectSidebarsDocIds', () => {
test('can collect sidebars doc items', async () => {
const sidebar1: Sidebar = [
{
@ -256,6 +348,95 @@ describe('collectSidebarsDocItems', () => {
});
});
describe('transformSidebarItems', () => {
test('can transform sidebar items', async () => {
const sidebar: Sidebar = [
{
type: 'category',
collapsed: false,
label: 'Category1',
items: [
{
type: 'category',
collapsed: false,
label: 'Subcategory 1',
items: [{type: 'doc', id: 'doc1'}],
},
{
type: 'category',
collapsed: false,
label: 'Subcategory 2',
items: [
{type: 'doc', id: 'doc2'},
{
type: 'category',
collapsed: false,
label: 'Sub sub category 1',
items: [{type: 'doc', id: 'doc3'}],
},
],
},
],
},
{
type: 'category',
collapsed: false,
label: 'Category2',
items: [
{type: 'doc', id: 'doc4'},
{type: 'doc', id: 'doc5'},
],
},
];
expect(
transformSidebarItems(sidebar, (item) => {
if (item.type === 'category') {
return {...item, label: `MODIFIED LABEL: ${item.label}`};
}
return item;
}),
).toEqual([
{
type: 'category',
collapsed: false,
label: 'MODIFIED LABEL: Category1',
items: [
{
type: 'category',
collapsed: false,
label: 'MODIFIED LABEL: Subcategory 1',
items: [{type: 'doc', id: 'doc1'}],
},
{
type: 'category',
collapsed: false,
label: 'MODIFIED LABEL: Subcategory 2',
items: [
{type: 'doc', id: 'doc2'},
{
type: 'category',
collapsed: false,
label: 'MODIFIED LABEL: Sub sub category 1',
items: [{type: 'doc', id: 'doc3'}],
},
],
},
],
},
{
type: 'category',
collapsed: false,
label: 'MODIFIED LABEL: Category2',
items: [
{type: 'doc', id: 'doc4'},
{type: 'doc', id: 'doc5'},
],
},
]);
});
});
describe('createSidebarsUtils', () => {
const sidebar1: Sidebar = [
{

View file

@ -0,0 +1,159 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {LoadedContent, DocMetadata, LoadedVersion} from '../types';
import {CURRENT_VERSION_NAME} from '../constants';
import {
getLoadedContentTranslationFiles,
translateLoadedContent,
} from '../translations';
import {updateTranslationFileMessages} from '@docusaurus/utils';
function createSampleDoc(doc: Pick<DocMetadata, 'id'>): DocMetadata {
return {
editUrl: 'any',
isDocsHomePage: false,
lastUpdatedAt: 0,
lastUpdatedBy: 'any',
next: undefined,
previous: undefined,
permalink: 'any',
slug: 'any',
source: 'any',
unversionedId: 'any',
version: 'any',
title: `${doc.id} title`,
sidebar_label: `${doc.id} title`,
description: `${doc.id} description`,
...doc,
};
}
function createSampleVersion(
version: Pick<LoadedVersion, 'versionName'>,
): LoadedVersion {
return {
versionLabel: `${version.versionName} label`,
versionPath: '/docs/',
mainDocId: '',
permalinkToSidebar: {},
routePriority: undefined,
sidebarFilePath: 'any',
isLast: true,
docsDirPath: 'any',
docsDirPathLocalized: 'any',
docs: [
createSampleDoc({
id: 'doc1',
}),
createSampleDoc({
id: 'doc2',
}),
createSampleDoc({
id: 'doc3',
}),
createSampleDoc({
id: 'doc4',
}),
createSampleDoc({
id: 'doc5',
}),
],
sidebars: {
docs: [
{
type: 'category',
label: 'Getting started',
collapsed: false,
items: [
{
type: 'doc',
id: 'doc1',
},
{
type: 'doc',
id: 'doc2',
},
{
type: 'link',
label: 'Link label',
href: 'https://facebook.com',
},
{
type: 'ref',
id: 'doc1',
},
],
},
{
type: 'doc',
id: 'doc3',
},
],
otherSidebar: [
{
type: 'doc',
id: 'doc4',
},
{
type: 'doc',
id: 'doc5',
},
],
},
...version,
};
}
const SampleLoadedContent: LoadedContent = {
loadedVersions: [
createSampleVersion({
versionName: CURRENT_VERSION_NAME,
}),
createSampleVersion({
versionName: '2.0.0',
}),
createSampleVersion({
versionName: '1.0.0',
}),
],
};
function getSampleTranslationFiles() {
return getLoadedContentTranslationFiles(SampleLoadedContent);
}
function getSampleTranslationFilesTranslated() {
const translationFiles = getSampleTranslationFiles();
return translationFiles.map((translationFile) =>
updateTranslationFileMessages(
translationFile,
(message) => `${message} (translated)`,
),
);
}
describe('getLoadedContentTranslationFiles', () => {
test('should return translation files matching snapshot', async () => {
expect(getSampleTranslationFiles()).toMatchSnapshot();
});
});
describe('translateLoadedContent', () => {
test('should not translate anything if translation files are untranslated', () => {
const translationFiles = getSampleTranslationFiles();
expect(
translateLoadedContent(SampleLoadedContent, translationFiles),
).toEqual(SampleLoadedContent);
});
test('should return translated loaded content matching snapshot', () => {
const translationFiles = getSampleTranslationFilesTranslated();
expect(
translateLoadedContent(SampleLoadedContent, translationFiles),
).toMatchSnapshot();
});
});

View file

@ -14,7 +14,14 @@ import {
} from '../versions';
import {DEFAULT_OPTIONS} from '../options';
import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
import {VersionMetadata} from '../types';
import {PluginOptions, VersionMetadata} from '../types';
import {I18n} from '@docusaurus/types';
const DefaultI18N: I18n = {
currentLocale: 'en',
locales: ['en'],
defaultLocale: 'en',
};
describe('version paths', () => {
test('getVersionedDocsDirPath', () => {
@ -46,29 +53,39 @@ describe('version paths', () => {
});
describe('simple site', () => {
const simpleSiteDir = path.resolve(
path.join(__dirname, '__fixtures__', 'simple-site'),
);
const defaultOptions = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
};
const defaultContext = {
siteDir: simpleSiteDir,
baseUrl: '/',
};
async function loadSite() {
const simpleSiteDir = path.resolve(
path.join(__dirname, '__fixtures__', 'simple-site'),
);
const defaultOptions: PluginOptions = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
};
const defaultContext = {
siteDir: simpleSiteDir,
baseUrl: '/',
i18n: DefaultI18N,
};
const vCurrent: VersionMetadata = {
docsDirPath: path.join(simpleSiteDir, 'docs'),
isLast: true,
routePriority: -1,
sidebarFilePath: path.join(simpleSiteDir, 'sidebars.json'),
versionLabel: 'Next',
versionName: 'current',
versionPath: '/docs',
};
const vCurrent: VersionMetadata = {
docsDirPath: path.join(simpleSiteDir, 'docs'),
docsDirPathLocalized: path.join(
simpleSiteDir,
'i18n/en/docusaurus-plugin-content-docs/current',
),
isLast: true,
routePriority: -1,
sidebarFilePath: path.join(simpleSiteDir, 'sidebars.json'),
versionLabel: 'Next',
versionName: 'current',
versionPath: '/docs',
};
return {simpleSiteDir, defaultOptions, defaultContext, vCurrent};
}
test('readVersionsMetadata simple site', async () => {
const {defaultOptions, defaultContext, vCurrent} = await loadSite();
test('readVersionsMetadata simple site', () => {
const versionsMetadata = readVersionsMetadata({
options: defaultOptions,
context: defaultContext,
@ -77,7 +94,9 @@ describe('simple site', () => {
expect(versionsMetadata).toEqual([vCurrent]);
});
test('readVersionsMetadata simple site with base url', () => {
test('readVersionsMetadata simple site with base url', async () => {
const {defaultOptions, defaultContext, vCurrent} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: defaultOptions,
context: {
@ -94,7 +113,9 @@ describe('simple site', () => {
]);
});
test('readVersionsMetadata simple site with current version config', () => {
test('readVersionsMetadata simple site with current version config', async () => {
const {defaultOptions, defaultContext, vCurrent} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: {
...defaultOptions,
@ -121,7 +142,9 @@ describe('simple site', () => {
]);
});
test('readVersionsMetadata simple site with unknown lastVersion should throw', () => {
test('readVersionsMetadata simple site with unknown lastVersion should throw', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {...defaultOptions, lastVersion: 'unknownVersionName'},
@ -132,7 +155,9 @@ describe('simple site', () => {
);
});
test('readVersionsMetadata simple site with unknown version configurations should throw', () => {
test('readVersionsMetadata simple site with unknown version configurations should throw', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {
@ -150,7 +175,9 @@ describe('simple site', () => {
);
});
test('readVersionsMetadata simple site with disableVersioning while single version should throw', () => {
test('readVersionsMetadata simple site with disableVersioning while single version should throw', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {...defaultOptions, disableVersioning: true},
@ -161,7 +188,9 @@ describe('simple site', () => {
);
});
test('readVersionsMetadata simple site without including current version should throw', () => {
test('readVersionsMetadata simple site without including current version should throw', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {...defaultOptions, includeCurrentVersion: false},
@ -174,71 +203,109 @@ describe('simple site', () => {
});
describe('versioned site, pluginId=default', () => {
const versionedSiteDir = path.resolve(
path.join(__dirname, '__fixtures__', 'versioned-site'),
);
const defaultOptions = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
};
const defaultContext = {
siteDir: versionedSiteDir,
baseUrl: '/',
};
async function loadSite() {
const versionedSiteDir = path.resolve(
path.join(__dirname, '__fixtures__', 'versioned-site'),
);
const defaultOptions: PluginOptions = {
id: DEFAULT_PLUGIN_ID,
...DEFAULT_OPTIONS,
};
const defaultContext = {
siteDir: versionedSiteDir,
baseUrl: '/',
i18n: DefaultI18N,
};
const vCurrent: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'docs'),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(versionedSiteDir, 'sidebars.json'),
versionLabel: 'Next',
versionName: 'current',
versionPath: '/docs/next',
};
const vCurrent: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'docs'),
docsDirPathLocalized: path.join(
versionedSiteDir,
'i18n/en/docusaurus-plugin-content-docs/current',
),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(versionedSiteDir, 'sidebars.json'),
versionLabel: 'Next',
versionName: 'current',
versionPath: '/docs/next',
};
const v101: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'versioned_docs/version-1.0.1'),
isLast: true,
routePriority: -1,
sidebarFilePath: path.join(
const v101: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'versioned_docs/version-1.0.1'),
docsDirPathLocalized: path.join(
versionedSiteDir,
'i18n/en/docusaurus-plugin-content-docs/version-1.0.1',
),
isLast: true,
routePriority: -1,
sidebarFilePath: path.join(
versionedSiteDir,
'versioned_sidebars/version-1.0.1-sidebars.json',
),
versionLabel: '1.0.1',
versionName: '1.0.1',
versionPath: '/docs',
};
const v100: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'versioned_docs/version-1.0.0'),
docsDirPathLocalized: path.join(
versionedSiteDir,
'i18n/en/docusaurus-plugin-content-docs/version-1.0.0',
),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(
versionedSiteDir,
'versioned_sidebars/version-1.0.0-sidebars.json',
),
versionLabel: '1.0.0',
versionName: '1.0.0',
versionPath: '/docs/1.0.0',
};
const vwithSlugs: VersionMetadata = {
docsDirPath: path.join(
versionedSiteDir,
'versioned_docs/version-withSlugs',
),
docsDirPathLocalized: path.join(
versionedSiteDir,
'i18n/en/docusaurus-plugin-content-docs/version-withSlugs',
),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(
versionedSiteDir,
'versioned_sidebars/version-withSlugs-sidebars.json',
),
versionLabel: 'withSlugs',
versionName: 'withSlugs',
versionPath: '/docs/withSlugs',
};
return {
versionedSiteDir,
'versioned_sidebars/version-1.0.1-sidebars.json',
),
versionLabel: '1.0.1',
versionName: '1.0.1',
versionPath: '/docs',
};
defaultOptions,
defaultContext,
vCurrent,
v101,
v100,
vwithSlugs,
};
}
const v100: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'versioned_docs/version-1.0.0'),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(
versionedSiteDir,
'versioned_sidebars/version-1.0.0-sidebars.json',
),
versionLabel: '1.0.0',
versionName: '1.0.0',
versionPath: '/docs/1.0.0',
};
test('readVersionsMetadata versioned site', async () => {
const {
defaultOptions,
defaultContext,
vCurrent,
v101,
v100,
vwithSlugs,
} = await loadSite();
const vwithSlugs: VersionMetadata = {
docsDirPath: path.join(
versionedSiteDir,
'versioned_docs/version-withSlugs',
),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(
versionedSiteDir,
'versioned_sidebars/version-withSlugs-sidebars.json',
),
versionLabel: 'withSlugs',
versionName: 'withSlugs',
versionPath: '/docs/withSlugs',
};
test('readVersionsMetadata versioned site', () => {
const versionsMetadata = readVersionsMetadata({
options: defaultOptions,
context: defaultContext,
@ -247,7 +314,15 @@ describe('versioned site, pluginId=default', () => {
expect(versionsMetadata).toEqual([vCurrent, v101, v100, vwithSlugs]);
});
test('readVersionsMetadata versioned site with includeCurrentVersion=false', () => {
test('readVersionsMetadata versioned site with includeCurrentVersion=false', async () => {
const {
defaultOptions,
defaultContext,
v101,
v100,
vwithSlugs,
} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: {...defaultOptions, includeCurrentVersion: false},
context: defaultContext,
@ -261,7 +336,16 @@ describe('versioned site, pluginId=default', () => {
]);
});
test('readVersionsMetadata versioned site with version options', () => {
test('readVersionsMetadata versioned site with version options', async () => {
const {
defaultOptions,
defaultContext,
vCurrent,
v101,
v100,
vwithSlugs,
} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: {
...defaultOptions,
@ -297,7 +381,9 @@ describe('versioned site, pluginId=default', () => {
]);
});
test('readVersionsMetadata versioned site with onlyIncludeVersions option', () => {
test('readVersionsMetadata versioned site with onlyIncludeVersions option', async () => {
const {defaultOptions, defaultContext, v101, vwithSlugs} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: {
...defaultOptions,
@ -310,7 +396,9 @@ describe('versioned site, pluginId=default', () => {
expect(versionsMetadata).toEqual([v101, vwithSlugs]);
});
test('readVersionsMetadata versioned site with disableVersioning', () => {
test('readVersionsMetadata versioned site with disableVersioning', async () => {
const {defaultOptions, defaultContext, vCurrent} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: {...defaultOptions, disableVersioning: true},
context: defaultContext,
@ -321,7 +409,9 @@ describe('versioned site, pluginId=default', () => {
]);
});
test('readVersionsMetadata versioned site with all versions disabled', () => {
test('readVersionsMetadata versioned site with all versions disabled', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {
@ -336,7 +426,9 @@ describe('versioned site, pluginId=default', () => {
);
});
test('readVersionsMetadata versioned site with empty onlyIncludeVersions', () => {
test('readVersionsMetadata versioned site with empty onlyIncludeVersions', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {
@ -350,7 +442,9 @@ describe('versioned site, pluginId=default', () => {
);
});
test('readVersionsMetadata versioned site with unknown versions in onlyIncludeVersions', () => {
test('readVersionsMetadata versioned site with unknown versions in onlyIncludeVersions', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {
@ -364,7 +458,9 @@ describe('versioned site, pluginId=default', () => {
);
});
test('readVersionsMetadata versioned site with lastVersion not in onlyIncludeVersions', () => {
test('readVersionsMetadata versioned site with lastVersion not in onlyIncludeVersions', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {
@ -379,7 +475,9 @@ describe('versioned site, pluginId=default', () => {
);
});
test('readVersionsMetadata versioned site with invalid versions.json file', () => {
test('readVersionsMetadata versioned site with invalid versions.json file', async () => {
const {defaultOptions, defaultContext} = await loadSite();
const mock = jest.spyOn(JSON, 'parse').mockImplementationOnce(() => {
return {
invalid: 'json',
@ -399,47 +497,62 @@ describe('versioned site, pluginId=default', () => {
});
describe('versioned site, pluginId=community', () => {
const versionedSiteDir = path.resolve(
path.join(__dirname, '__fixtures__', 'versioned-site'),
);
const defaultOptions = {
...DEFAULT_OPTIONS,
id: 'community',
path: 'community',
routeBasePath: 'communityBasePath',
};
const defaultContext = {
siteDir: versionedSiteDir,
baseUrl: '/',
};
async function loadSite() {
const versionedSiteDir = path.resolve(
path.join(__dirname, '__fixtures__', 'versioned-site'),
);
const defaultOptions: PluginOptions = {
...DEFAULT_OPTIONS,
id: 'community',
path: 'community',
routeBasePath: 'communityBasePath',
};
const defaultContext = {
siteDir: versionedSiteDir,
baseUrl: '/',
i18n: DefaultI18N,
};
const vCurrent: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'community'),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(versionedSiteDir, 'sidebars.json'),
versionLabel: 'Next',
versionName: 'current',
versionPath: '/communityBasePath/next',
};
const vCurrent: VersionMetadata = {
docsDirPath: path.join(versionedSiteDir, 'community'),
docsDirPathLocalized: path.join(
versionedSiteDir,
'i18n/en/docusaurus-plugin-content-docs-community/current',
),
isLast: false,
routePriority: undefined,
sidebarFilePath: path.join(versionedSiteDir, 'sidebars.json'),
versionLabel: 'Next',
versionName: 'current',
versionPath: '/communityBasePath/next',
};
const v100: VersionMetadata = {
docsDirPath: path.join(
versionedSiteDir,
'community_versioned_docs/version-1.0.0',
),
isLast: true,
routePriority: -1,
sidebarFilePath: path.join(
versionedSiteDir,
'community_versioned_sidebars/version-1.0.0-sidebars.json',
),
versionLabel: '1.0.0',
versionName: '1.0.0',
versionPath: '/communityBasePath',
};
const v100: VersionMetadata = {
docsDirPath: path.join(
versionedSiteDir,
'community_versioned_docs/version-1.0.0',
),
docsDirPathLocalized: path.join(
versionedSiteDir,
'i18n/en/docusaurus-plugin-content-docs-community/version-1.0.0',
),
isLast: true,
routePriority: -1,
sidebarFilePath: path.join(
versionedSiteDir,
'community_versioned_sidebars/version-1.0.0-sidebars.json',
),
versionLabel: '1.0.0',
versionName: '1.0.0',
versionPath: '/communityBasePath',
};
return {versionedSiteDir, defaultOptions, defaultContext, vCurrent, v100};
}
test('readVersionsMetadata versioned site (community)', async () => {
const {defaultOptions, defaultContext, vCurrent, v100} = await loadSite();
test('readVersionsMetadata versioned site (community)', () => {
const versionsMetadata = readVersionsMetadata({
options: defaultOptions,
context: defaultContext,
@ -448,7 +561,9 @@ describe('versioned site, pluginId=community', () => {
expect(versionsMetadata).toEqual([vCurrent, v100]);
});
test('readVersionsMetadata versioned site (community) with includeCurrentVersion=false', () => {
test('readVersionsMetadata versioned site (community) with includeCurrentVersion=false', async () => {
const {defaultOptions, defaultContext, v100} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: {...defaultOptions, includeCurrentVersion: false},
context: defaultContext,
@ -460,7 +575,9 @@ describe('versioned site, pluginId=community', () => {
]);
});
test('readVersionsMetadata versioned site (community) with disableVersioning', () => {
test('readVersionsMetadata versioned site (community) with disableVersioning', async () => {
const {defaultOptions, defaultContext, vCurrent} = await loadSite();
const versionsMetadata = readVersionsMetadata({
options: {...defaultOptions, disableVersioning: true},
context: defaultContext,
@ -476,7 +593,9 @@ describe('versioned site, pluginId=community', () => {
]);
});
test('readVersionsMetadata versioned site (community) with all versions disabled', () => {
test('readVersionsMetadata versioned site (community) with all versions disabled', async () => {
const {defaultOptions, defaultContext} = await loadSite();
expect(() =>
readVersionsMetadata({
options: {