From 141d062c3b4742ef9c9e74eafc5a30adafd58f1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Lorber?= Date: Mon, 28 Dec 2020 19:50:12 +0100 Subject: [PATCH] chore(v2): fix windows Jest tests (#3959) * test(v2): Fix docusaurus-utils tests for windows * test(v2): Fix plugin-client-redirects test - add the posixPath in writeRedirectsFiles.ts * test(v2): Fix plugin-content-pages test add posixPath in test and index * test(v2): add window test configuration - add the window test configuration in nodejs-windows.yml * test(v2): revert plugin-content-pages test fix * test(v2): Fix mdx-loader/transformImage test * test(v2): add cleanPath in transformImage test * fix version path tests for windows * make versionMetadata test work on Windows * try to fix posix/win32 path issues * attempt to fix windows test * try to make source alias less win32 sensitive * try to make source alias less win32 sensitive * try to make source alias less win32 sensitive * try to make source alias less win32 sensitive * try to make source alias less win32 sensitive * try to make source alias less win32 sensitive * specific jest config for windows * attempt to fix windows testing issue * attempt to fix windows testing issue * attempt to fix windows testing issue * attempt to fix windows testing issue * attempt to fix windows testing issue * attempt to fix windows testing issue * attempt to fix windows testing issue * remove bad cleanPath fn * try to fix windows tests * try to fix windows tests * blog: try to fix windows tests by using same logic as on docs plugin * try to fix windows tests * try to fix windows tests * try to fix windows tests * try to fix windows tests * improve the Github CI setup for windows: make jobs run in parallel * revert GH action change Co-authored-by: Sachin Kumar Rajput --- .github/workflows/nodejs-windows.yml | 2 + jest.config.js | 10 ++++- .../src/remark/transformImage/index.js | 18 +++----- .../src/remark/transformLinks/index.js | 16 +++---- .../src/__tests__/index.test.ts | 12 ++--- .../src/__tests__/linkify.test.ts | 2 +- .../src/blogUtils.ts | 16 ++++--- .../src/index.ts | 3 +- .../src/__tests__/docs.test.ts | 7 +-- .../src/__tests__/index.test.ts | 45 +++++++++---------- .../src/__tests__/versions.test.ts | 14 +++--- .../src/index.ts | 3 +- .../src/markdown/linkify.ts | 4 +- .../src/versions.ts | 22 ++++++--- .../src/__tests__/index.test.ts | 40 ++++++++++------- packages/docusaurus-plugin-debug/src/index.ts | 4 +- .../README.md | 18 +++++--- .../src/__tests__/index.test.ts | 10 +++-- packages/docusaurus-utils/src/index.ts | 13 +++++- .../src/server/__tests__/i18n.test.ts | 2 +- packages/docusaurus/src/server/config.ts | 4 +- .../__tests__/translations.test.ts | 14 +++--- .../src/server/translations/translations.ts | 8 ++-- .../translations/translationsExtractor.ts | 9 +++- .../src/webpack/__tests__/base.test.ts | 3 +- .../src/webpack/__tests__/utils.test.ts | 2 +- .../stylelint-copyright/__tests__/index.js | 3 +- website/docs/deployment.mdx | 14 +++--- website/docs/sidebar.md | 2 + 29 files changed, 189 insertions(+), 131 deletions(-) diff --git a/.github/workflows/nodejs-windows.yml b/.github/workflows/nodejs-windows.yml index 85c91ad573..d2bb701d35 100644 --- a/.github/workflows/nodejs-windows.yml +++ b/.github/workflows/nodejs-windows.yml @@ -29,6 +29,8 @@ jobs: - name: Docusaurus 1 Build if: steps.filter.outputs.v1 == 'true' run: yarn build:v1 + - name: Docusaurus Jest Tests + run: yarn test - name: Docusaurus 2 Build run: yarn build:v2 env: diff --git a/jest.config.js b/jest.config.js index 4a7d7d20fe..810caed743 100644 --- a/jest.config.js +++ b/jest.config.js @@ -7,6 +7,14 @@ const path = require('path'); +const isWin = process.platform === 'win32'; + +const windowsSpecificIgnorePatterns = [ + // v1 is legacy, not really worth it to invest in making its tests work on Windows + '/packages/docusaurus-1.x', + '/packages/docusaurus-init-1.x', +]; + const ignorePatterns = [ '/node_modules/', '__fixtures__', @@ -19,7 +27,7 @@ const ignorePatterns = [ '/packages/docusaurus-theme-classic/lib', '/packages/docusaurus-theme-classic/lib-next', '/packages/docusaurus-migrate/lib', -]; +].concat(isWin ? windowsSpecificIgnorePatterns : []); module.exports = { rootDir: path.resolve(__dirname), diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js index e7e178e59d..e65f072201 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js +++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.js @@ -11,7 +11,7 @@ const url = require('url'); const fs = require('fs-extra'); const escapeHtml = require('escape-html'); const {getFileLoaderUtils} = require('@docusaurus/core/lib/webpack/utils'); -const {posixPath} = require('@docusaurus/utils'); +const {posixPath, toMessageRelativeFilePath} = require('@docusaurus/utils'); const { loaders: {inlineMarkdownImageFileLoader}, @@ -37,19 +37,13 @@ const createJSX = (node, pathUrl) => { } }; -// Needed to throw errors with computer-agnostic path messages -// Absolute paths are too dependant of user FS -function toRelativePath(filePath) { - return path.relative(process.cwd(), filePath); -} - async function ensureImageFileExist(imagePath, sourceFilePath) { const imageExists = await fs.exists(imagePath); if (!imageExists) { throw new Error( - `Image ${toRelativePath(imagePath)} used in ${toRelativePath( - sourceFilePath, - )} not found.`, + `Image ${toMessageRelativeFilePath( + imagePath, + )} used in ${toMessageRelativeFilePath(sourceFilePath)} not found.`, ); } } @@ -57,7 +51,9 @@ async function ensureImageFileExist(imagePath, sourceFilePath) { async function processImageNode(node, {filePath, staticDir}) { if (!node.url) { throw new Error( - `Markdown image url is mandatory. filePath=${toRelativePath(filePath)}`, + `Markdown image url is mandatory. filePath=${toMessageRelativeFilePath( + filePath, + )}`, ); } diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js index 5295acc2ae..5dd09d2e75 100644 --- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js +++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -const {posixPath} = require('@docusaurus/utils'); +const {toMessageRelativeFilePath, posixPath} = require('@docusaurus/utils'); const visit = require('unist-util-visit'); const path = require('path'); @@ -19,19 +19,13 @@ const { loaders: {inlineMarkdownLinkFileLoader}, } = getFileLoaderUtils(); -// Needed to throw errors with computer-agnostic path messages -// Absolute paths are too dependant of user FS -function toRelativePath(filePath) { - return path.relative(process.cwd(), filePath); -} - async function ensureAssetFileExist(fileSystemAssetPath, sourceFilePath) { const assetExists = await fs.exists(fileSystemAssetPath); if (!assetExists) { throw new Error( - `Asset ${toRelativePath(fileSystemAssetPath)} used in ${toRelativePath( - sourceFilePath, - )} not found.`, + `Asset ${toMessageRelativeFilePath( + fileSystemAssetPath, + )} used in ${toMessageRelativeFilePath(sourceFilePath)} not found.`, ); } } @@ -111,7 +105,7 @@ async function processLinkNode({node, _index, _parent, filePath, staticDir}) { const line = (node.position && node.position.start && node.position.start.line) || '?'; throw new Error( - `Markdown link url is mandatory. filePath=${toRelativePath( + `Markdown link url is mandatory. filePath=${toMessageRelativeFilePath( filePath, )}, title=${title}, line=${line}`, ); diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts index a26442d6d4..937a556949 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -65,7 +65,7 @@ describe('loadBlog', () => { 'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/date-matter.md', permalink: '/blog/date-matter', readingTime: 0.02, - source: path.join('@site', pluginPath, 'date-matter.md'), + source: path.posix.join('@site', pluginPath, 'date-matter.md'), title: 'date-matter', description: `date inside front matter`, date: new Date('2019-01-01'), @@ -87,10 +87,10 @@ describe('loadBlog', () => { 'https://github.com/facebook/docusaurus/edit/master/website-1x/i18n/en/docusaurus-plugin-content-blog/2018-12-14-Happy-First-Birthday-Slash.md', permalink: '/blog/2018/12/14/Happy-First-Birthday-Slash', readingTime: 0.015, - source: path.join( + source: path.posix.join( '@site', // pluginPath, - path.join('i18n', 'en', 'docusaurus-plugin-content-blog'), + path.posix.join('i18n', 'en', 'docusaurus-plugin-content-blog'), '2018-12-14-Happy-First-Birthday-Slash.md', ), title: 'Happy 1st Birthday Slash! (translated)', @@ -112,7 +112,7 @@ describe('loadBlog', () => { 'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/complex-slug.md', permalink: '/blog/hey/my super path/héllô', readingTime: 0.015, - source: path.join('@site', pluginPath, 'complex-slug.md'), + source: path.posix.join('@site', pluginPath, 'complex-slug.md'), title: 'Complex Slug', description: `complex url slug`, prevItem: undefined, @@ -133,7 +133,7 @@ describe('loadBlog', () => { 'https://github.com/facebook/docusaurus/edit/master/website-1x/blog/simple-slug.md', permalink: '/blog/simple/slug', readingTime: 0.015, - source: path.join('@site', pluginPath, 'simple-slug.md'), + source: path.posix.join('@site', pluginPath, 'simple-slug.md'), title: 'Simple Slug', description: `simple url slug`, prevItem: undefined, @@ -162,7 +162,7 @@ describe('loadBlog', () => { 'website-blog-without-date', ); const blogPosts = await getBlogPosts(siteDir); - const noDateSource = path.join('@site', pluginPath, 'no date.md'); + const noDateSource = path.posix.join('@site', pluginPath, 'no date.md'); const noDateSourceBirthTime = ( await fs.stat(noDateSource.replace('@site', siteDir)) ).birthtime; diff --git a/packages/docusaurus-plugin-content-blog/src/__tests__/linkify.test.ts b/packages/docusaurus-plugin-content-blog/src/__tests__/linkify.test.ts index 3b30ba1e39..6923c1d633 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/linkify.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/linkify.test.ts @@ -21,7 +21,7 @@ const blogPosts: BlogPost[] = [ id: 'Happy 1st Birthday Slash!', metadata: { permalink: '/blog/2018/12/14/Happy-First-Birthday-Slash', - source: path.join( + source: path.posix.join( '@site', pluginDir, '2018-12-14-Happy-First-Birthday-Slash.md', diff --git a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts index e9486fe65d..6e30e84e96 100644 --- a/packages/docusaurus-plugin-content-blog/src/blogUtils.ts +++ b/packages/docusaurus-plugin-content-blog/src/blogUtils.ts @@ -9,6 +9,7 @@ import fs from 'fs-extra'; import globby from 'globby'; import chalk from 'chalk'; import path from 'path'; +import {resolve} from 'url'; import readingTime from 'reading-time'; import {Feed} from 'feed'; import { @@ -240,13 +241,18 @@ export function linkify({ while (mdMatch !== null) { const mdLink = mdMatch[1]; - const aliasedPostSource = `@site/${path.relative( - siteDir, - path.resolve(folderPath, mdLink), - )}`; + + const aliasedSource = (source: string) => + aliasedSitePath(source, siteDir); const blogPost: BlogPost | undefined = - blogPostsBySource[aliasedPostSource]; + blogPostsBySource[aliasedSource(resolve(filePath, mdLink))] || + blogPostsBySource[ + aliasedSource(`${contentPaths.contentPathLocalized}/${mdLink}`) + ] || + blogPostsBySource[ + aliasedSource(`${contentPaths.contentPath}/${mdLink}`) + ]; if (blogPost) { modifiedLine = modifiedLine.replace( diff --git a/packages/docusaurus-plugin-content-blog/src/index.ts b/packages/docusaurus-plugin-content-blog/src/index.ts index 022765d9f1..6229e14e87 100644 --- a/packages/docusaurus-plugin-content-blog/src/index.ts +++ b/packages/docusaurus-plugin-content-blog/src/index.ts @@ -14,6 +14,7 @@ import { aliasedSitePath, getPluginI18nPath, reportMessage, + posixPath, } from '@docusaurus/utils'; import { STATIC_DIR_NAME, @@ -84,7 +85,7 @@ export default function pluginContentBlog( ); const dataDir = path.join(pluginDataDirRoot, pluginId); const aliasedSource = (source: string) => - `~blog/${path.relative(pluginDataDirRoot, source)}`; + `~blog/${posixPath(path.relative(pluginDataDirRoot, source))}`; let blogPosts: BlogPost[] = []; diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts index 5c54583186..5872e12826 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/docs.test.ts @@ -20,6 +20,7 @@ import {LoadContext} from '@docusaurus/types'; import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants'; import {DEFAULT_OPTIONS} from '../options'; import {Optional} from 'utility-types'; +import {posixPath} from '@docusaurus/utils'; const fixtureDir = path.join(__dirname, '__fixtures__'); @@ -89,10 +90,10 @@ function createTestUtils({ lastUpdatedAt: undefined, sidebar_label: undefined, editUrl: undefined, - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, versionMetadata.docsDirPath), - docFileSource, + posixPath(path.relative(siteDir, versionMetadata.docsDirPath)), + posixPath(docFileSource), ), ...expectedMetadata, }); diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts index baf1a971e0..753b977c7d 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/index.test.ts @@ -140,11 +140,15 @@ describe('empty/no docs website', () => { pluginContentDocs( context, normalizePluginOptions(OptionsSchema, { - path: '/path/does/not/exist/', + path: `path/doesnt/exist`, }), ), - ).toThrowErrorMatchingInlineSnapshot( - `"The docs folder does not exist for version [current]. A docs folder is expected to be found at /path/does/not/exist"`, + ).toThrowError( + `The docs folder does not exist for version [current]. A docs folder is expected to be found at ${ + process.platform === 'win32' + ? 'path\\doesnt\\exist' + : 'path/doesnt/exist' + }`, ); }); }); @@ -248,9 +252,9 @@ describe('simple website', () => { permalink: '/docs/foo/bazSlug.html', }, sidebar: 'docs', - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, currentVersion.docsDirPath), + posixPath(path.relative(siteDir, currentVersion.docsDirPath)), 'hello.md', ), title: 'Hello, World !', @@ -270,9 +274,9 @@ describe('simple website', () => { permalink: '/docs/foo/bar', slug: '/foo/bar', sidebar: 'docs', - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, currentVersion.docsDirPath), + posixPath(path.relative(siteDir, currentVersion.docsDirPath)), 'foo', 'bar.md', ), @@ -418,9 +422,9 @@ describe('versioned website', () => { isDocsHomePage: false, permalink: '/docs/next/foo/barSlug', slug: '/foo/barSlug', - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, currentVersion.docsDirPath), + posixPath(path.relative(siteDir, currentVersion.docsDirPath)), 'foo', 'bar.md', ), @@ -440,9 +444,9 @@ describe('versioned website', () => { isDocsHomePage: true, permalink: '/docs/next/', slug: '/', - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, currentVersion.docsDirPath), + posixPath(path.relative(siteDir, currentVersion.docsDirPath)), 'hello.md', ), title: 'hello', @@ -461,9 +465,9 @@ describe('versioned website', () => { isDocsHomePage: true, permalink: '/docs/', slug: '/', - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, version101.docsDirPath), + posixPath(path.relative(siteDir, version101.docsDirPath)), 'hello.md', ), title: 'hello', @@ -482,9 +486,9 @@ describe('versioned website', () => { isDocsHomePage: false, permalink: '/docs/1.0.0/foo/baz', slug: '/foo/baz', - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, version100.docsDirPath), + posixPath(path.relative(siteDir, version100.docsDirPath)), 'foo', 'baz.md', ), @@ -629,13 +633,6 @@ describe('versioned website (community)', () => { isDocsHomePage: false, permalink: '/community/next/team', slug: '/team', - /* - source: path.join( - '@site', - path.relative(siteDir, currentVersion.docsDirPath), - 'team.md', - ), - */ source: '@site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md', title: 'Team title translated', @@ -650,9 +647,9 @@ describe('versioned website (community)', () => { isDocsHomePage: false, permalink: '/community/team', slug: '/team', - source: path.join( + source: path.posix.join( '@site', - path.relative(siteDir, version100.docsDirPath), + posixPath(path.relative(siteDir, version100.docsDirPath)), 'team.md', ), title: 'team', diff --git a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts index 188c0875dd..c5108e5fbd 100644 --- a/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts +++ b/packages/docusaurus-plugin-content-docs/src/__tests__/versions.test.ts @@ -24,30 +24,30 @@ const DefaultI18N: I18n = { }; describe('version paths', () => { - test('getVersionedDocsDirPath', () => { + test('getVersionsFilePath', () => { expect(getVersionsFilePath('someSiteDir', DEFAULT_PLUGIN_ID)).toBe( - 'someSiteDir/versions.json', + `someSiteDir${path.sep}versions.json`, ); expect(getVersionsFilePath('otherSite/dir', 'pluginId')).toBe( - 'otherSite/dir/pluginId_versions.json', + `otherSite${path.sep}dir${path.sep}pluginId_versions.json`, ); }); test('getVersionedDocsDirPath', () => { expect(getVersionedDocsDirPath('someSiteDir', DEFAULT_PLUGIN_ID)).toBe( - 'someSiteDir/versioned_docs', + `someSiteDir${path.sep}versioned_docs`, ); expect(getVersionedDocsDirPath('otherSite/dir', 'pluginId')).toBe( - 'otherSite/dir/pluginId_versioned_docs', + `otherSite${path.sep}dir${path.sep}pluginId_versioned_docs`, ); }); test('getVersionedSidebarsDirPath', () => { expect(getVersionedSidebarsDirPath('someSiteDir', DEFAULT_PLUGIN_ID)).toBe( - 'someSiteDir/versioned_sidebars', + `someSiteDir${path.sep}versioned_sidebars`, ); expect(getVersionedSidebarsDirPath('otherSite/dir', 'pluginId')).toBe( - 'otherSite/dir/pluginId_versioned_sidebars', + `otherSite${path.sep}dir${path.sep}pluginId_versioned_sidebars`, ); }); }); diff --git a/packages/docusaurus-plugin-content-docs/src/index.ts b/packages/docusaurus-plugin-content-docs/src/index.ts index b84f59b832..e7588ae877 100644 --- a/packages/docusaurus-plugin-content-docs/src/index.ts +++ b/packages/docusaurus-plugin-content-docs/src/index.ts @@ -16,6 +16,7 @@ import { docuHash, aliasedSitePath, reportMessage, + posixPath, } from '@docusaurus/utils'; import {LoadContext, Plugin, RouteConfig} from '@docusaurus/types'; @@ -66,7 +67,7 @@ export default function pluginContentDocs( ); const dataDir = path.join(pluginDataDirRoot, pluginId); const aliasedSource = (source: string) => - `~docs/${path.relative(pluginDataDirRoot, source)}`; + `~docs/${posixPath(path.relative(pluginDataDirRoot, source))}`; return { name: 'docusaurus-plugin-content-docs', diff --git a/packages/docusaurus-plugin-content-docs/src/markdown/linkify.ts b/packages/docusaurus-plugin-content-docs/src/markdown/linkify.ts index 87a81ab705..2697be19f9 100644 --- a/packages/docusaurus-plugin-content-docs/src/markdown/linkify.ts +++ b/packages/docusaurus-plugin-content-docs/src/markdown/linkify.ts @@ -5,7 +5,6 @@ * LICENSE file in the root directory of this source tree. */ -import path from 'path'; import {resolve} from 'url'; import { DocsMarkdownOption, @@ -13,6 +12,7 @@ import { BrokenMarkdownLink, } from '../types'; import {getDocsDirPaths} from '../versions'; +import {aliasedSitePath} from '@docusaurus/utils'; function getVersion(filePath: string, options: DocsMarkdownOption) { const versionFound = options.versionsMetadata.find((version) => @@ -58,7 +58,7 @@ function replaceMarkdownLinks( const mdLink = mdMatch[1]; const aliasedSource = (source: string) => - `@site/${path.relative(siteDir, source)}`; + aliasedSitePath(source, siteDir); const permalink = sourceToPermalink[aliasedSource(resolve(filePath, mdLink))] || diff --git a/packages/docusaurus-plugin-content-docs/src/versions.ts b/packages/docusaurus-plugin-content-docs/src/versions.ts index c47fa56638..34ffd1409e 100644 --- a/packages/docusaurus-plugin-content-docs/src/versions.ts +++ b/packages/docusaurus-plugin-content-docs/src/versions.ts @@ -316,13 +316,21 @@ function createVersionMetadata({ } function checkVersionMetadataPaths({ - versionName, - docsDirPath, - sidebarFilePath, -}: VersionMetadata) { + versionMetadata, + context, +}: { + versionMetadata: VersionMetadata; + context: Pick; +}) { + const {versionName, docsDirPath, sidebarFilePath} = versionMetadata; + const {siteDir} = context; + if (!fs.existsSync(docsDirPath)) { throw new Error( - `The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${docsDirPath}`, + `The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${path.relative( + siteDir, + docsDirPath, + )}`, ); } @@ -457,7 +465,9 @@ export function readVersionsMetadata({ options, }), ); - versionsMetadata.forEach(checkVersionMetadataPaths); + versionsMetadata.forEach((versionMetadata) => + checkVersionMetadataPaths({versionMetadata, context}), + ); return versionsMetadata; } diff --git a/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts b/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts index daddf4062b..cedd171041 100644 --- a/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-pages/src/__tests__/index.test.ts @@ -28,37 +28,47 @@ describe('docusaurus-plugin-content-pages', () => { { type: 'jsx', permalink: '/', - source: path.join('@site', pluginPath, 'index.js'), + source: path.posix.join('@site', pluginPath, 'index.js'), }, { type: 'jsx', permalink: '/typescript', - source: path.join('@site', pluginPath, 'typescript.tsx'), + source: path.posix.join('@site', pluginPath, 'typescript.tsx'), }, { type: 'mdx', permalink: '/hello/', - source: path.join('@site', pluginPath, 'hello', 'index.md'), + source: path.posix.join('@site', pluginPath, 'hello', 'index.md'), }, { type: 'mdx', permalink: '/hello/mdxPage', - source: path.join('@site', pluginPath, 'hello', 'mdxPage.mdx'), + source: path.posix.join('@site', pluginPath, 'hello', 'mdxPage.mdx'), }, { type: 'jsx', permalink: '/hello/translatedJs', - source: path.join('@site', pluginPath, 'hello', 'translatedJs.js'), + source: path.posix.join( + '@site', + pluginPath, + 'hello', + 'translatedJs.js', + ), }, { type: 'mdx', permalink: '/hello/translatedMd', - source: path.join('@site', pluginPath, 'hello', 'translatedMd.md'), + source: path.posix.join( + '@site', + pluginPath, + 'hello', + 'translatedMd.md', + ), }, { type: 'jsx', permalink: '/hello/world', - source: path.join('@site', pluginPath, 'hello', 'world.js'), + source: path.posix.join('@site', pluginPath, 'hello', 'world.js'), }, ]); }); @@ -81,7 +91,7 @@ describe('docusaurus-plugin-content-pages', () => { ); const pagesMetadatas = (await plugin.loadContent?.())!; - const frTranslationsPath = path.join( + const frTranslationsPath = path.posix.join( '@site', 'i18n', 'fr', @@ -92,37 +102,37 @@ describe('docusaurus-plugin-content-pages', () => { { type: 'jsx', permalink: '/', - source: path.join('@site', pluginPath, 'index.js'), + source: path.posix.join('@site', pluginPath, 'index.js'), }, { type: 'jsx', permalink: '/typescript', - source: path.join('@site', pluginPath, 'typescript.tsx'), + source: path.posix.join('@site', pluginPath, 'typescript.tsx'), }, { type: 'mdx', permalink: '/hello/', - source: path.join('@site', pluginPath, 'hello', 'index.md'), + source: path.posix.join('@site', pluginPath, 'hello', 'index.md'), }, { type: 'mdx', permalink: '/hello/mdxPage', - source: path.join('@site', pluginPath, 'hello', 'mdxPage.mdx'), + source: path.posix.join('@site', pluginPath, 'hello', 'mdxPage.mdx'), }, { type: 'jsx', permalink: '/hello/translatedJs', - source: path.join(frTranslationsPath, 'hello', 'translatedJs.js'), + source: path.posix.join(frTranslationsPath, 'hello', 'translatedJs.js'), }, { type: 'mdx', permalink: '/hello/translatedMd', - source: path.join(frTranslationsPath, 'hello', 'translatedMd.md'), + source: path.posix.join(frTranslationsPath, 'hello', 'translatedMd.md'), }, { type: 'jsx', permalink: '/hello/world', - source: path.join('@site', pluginPath, 'hello', 'world.js'), + source: path.posix.join('@site', pluginPath, 'hello', 'world.js'), }, ]); }); diff --git a/packages/docusaurus-plugin-debug/src/index.ts b/packages/docusaurus-plugin-debug/src/index.ts index 8123868796..bbb09c09e9 100644 --- a/packages/docusaurus-plugin-debug/src/index.ts +++ b/packages/docusaurus-plugin-debug/src/index.ts @@ -6,7 +6,7 @@ */ import {LoadContext, Plugin} from '@docusaurus/types'; -import {docuHash, normalizeUrl} from '@docusaurus/utils'; +import {docuHash, normalizeUrl, posixPath} from '@docusaurus/utils'; import path from 'path'; export default function pluginDebug({ @@ -18,7 +18,7 @@ export default function pluginDebug({ 'docusaurus-plugin-debug', ); const aliasedSource = (source: string) => - `~debug/${path.relative(pluginDataDirRoot, source)}`; + `~debug/${posixPath(path.relative(pluginDataDirRoot, source))}`; return { name: 'docusaurus-plugin-debug', diff --git a/packages/docusaurus-remark-plugin-npm2yarn/README.md b/packages/docusaurus-remark-plugin-npm2yarn/README.md index e6dda3a3b4..0bc2794296 100644 --- a/packages/docusaurus-remark-plugin-npm2yarn/README.md +++ b/packages/docusaurus-remark-plugin-npm2yarn/README.md @@ -34,15 +34,21 @@ module.exports = { { docs: { // ... - remarkPlugins: [[require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}]], + remarkPlugins: [ + [require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}], + ], }, blog: { // ... - remarkPlugins: [[require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}]], + remarkPlugins: [ + [require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}], + ], }, pages: { // ... - remarkPlugins: [[require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}]], + remarkPlugins: [ + [require('@docusaurus/remark-plugin-npm2yarn'), {sync: true}], + ], }, // ... }, @@ -54,6 +60,6 @@ module.exports = { ## Options -| Property | Type | Default | Description | -|----------|-----------|---------|---------------------------------------------------------------------------------------------------------------------------| -| `sync` | `boolean` | `false` | Syncing tab choices (yarn and npm). See https://v2.docusaurus.io/docs/markdown-features/#syncing-tab-choices for details. | +| Property | Type | Default | Description | +| --- | --- | --- | --- | +| `sync` | `boolean` | `false` | Syncing tab choices (yarn and npm). See https://v2.docusaurus.io/docs/markdown-features/#syncing-tab-choices for details. | diff --git a/packages/docusaurus-utils/src/__tests__/index.test.ts b/packages/docusaurus-utils/src/__tests__/index.test.ts index 18ac523724..7ad612a0c3 100644 --- a/packages/docusaurus-utils/src/__tests__/index.test.ts +++ b/packages/docusaurus-utils/src/__tests__/index.test.ts @@ -45,7 +45,9 @@ describe('load utils', () => { 'user/docs/test.md': '@site/../docs/test.md', }; Object.keys(asserts).forEach((file) => { - expect(aliasedSitePath(file, 'user/website')).toBe(asserts[file]); + expect(posixPath(aliasedSitePath(file, 'user/website'))).toBe( + asserts[file], + ); }); }); @@ -521,15 +523,15 @@ describe('removePrefix', () => { describe('getFilePathForRoutePath', () => { test('works for /', () => { - expect(getFilePathForRoutePath('/')).toEqual('/index.html'); + expect(posixPath(getFilePathForRoutePath('/'))).toEqual('/index.html'); }); test('works for /somePath', () => { - expect(getFilePathForRoutePath('/somePath')).toEqual( + expect(posixPath(getFilePathForRoutePath('/somePath'))).toEqual( '/somePath/index.html', ); }); test('works for /somePath/', () => { - expect(getFilePathForRoutePath('/somePath/')).toEqual( + expect(posixPath(getFilePathForRoutePath('/somePath/'))).toEqual( '/somePath/index.html', ); }); diff --git a/packages/docusaurus-utils/src/index.ts b/packages/docusaurus-utils/src/index.ts index 2727976a9d..a8a96696cc 100644 --- a/packages/docusaurus-utils/src/index.ts +++ b/packages/docusaurus-utils/src/index.ts @@ -140,6 +140,17 @@ export function posixPath(str: string): string { return str.replace(/\\/g, '/'); } +// When you want to display a path in a message/warning/error, +// it's more convenient to: +// - make it relative to cwd() +// - convert to posix (ie not using windows \ path separator) +// This way, Jest tests can run more reliably on any computer/CI +// on both Unix/Windows +// For Windows users this is not perfect (as they see / instead of \) but it's probably good enough +export function toMessageRelativeFilePath(filePath: string) { + return posixPath(path.relative(process.cwd(), filePath)); +} + const chunkNameCache = new Map(); /** * Generate unique chunk name given a module path. @@ -365,7 +376,7 @@ export function normalizeUrl(rawUrls: string[]): string { * Example: some/path/to/website/docs/foo.md -> @site/docs/foo.md */ export function aliasedSitePath(filePath: string, siteDir: string): string { - const relativePath = path.relative(siteDir, filePath); + const relativePath = posixPath(path.relative(siteDir, filePath)); // Cannot use path.join() as it resolves '../' and removes // the '@site'. Let webpack loader resolve it. return `@site/${relativePath}`; diff --git a/packages/docusaurus/src/server/__tests__/i18n.test.ts b/packages/docusaurus/src/server/__tests__/i18n.test.ts index 7014ac8601..de094634ec 100644 --- a/packages/docusaurus/src/server/__tests__/i18n.test.ts +++ b/packages/docusaurus/src/server/__tests__/i18n.test.ts @@ -147,7 +147,7 @@ describe('localizePath', () => { }, options: {localizePath: true}, }), - ).toEqual(`/baseFsPath${path.sep}fr${path.sep}`); + ).toEqual(`${path.sep}baseFsPath${path.sep}fr${path.sep}`); }); test('should localize path for default locale, if requested', () => { diff --git a/packages/docusaurus/src/server/config.ts b/packages/docusaurus/src/server/config.ts index ffecdcd1b7..78ee8ebf30 100644 --- a/packages/docusaurus/src/server/config.ts +++ b/packages/docusaurus/src/server/config.ts @@ -11,6 +11,7 @@ import path from 'path'; import {DocusaurusConfig} from '@docusaurus/types'; import {CONFIG_FILE_NAME} from '../constants'; import {validateConfig} from './configValidation'; +import {toMessageRelativeFilePath} from '@docusaurus/utils'; export default function loadConfig(siteDir: string): DocusaurusConfig { // TODO temporary undocumented env variable: we should be able to use a cli option instead! @@ -21,8 +22,7 @@ export default function loadConfig(siteDir: string): DocusaurusConfig { if (!fs.existsSync(configPath)) { throw new Error( - `${CONFIG_FILE_NAME} not found at ${path.relative( - process.cwd(), + `${CONFIG_FILE_NAME} not found at ${toMessageRelativeFilePath( configPath, )}`, ); diff --git a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts index 319187aa8b..529a913e9c 100644 --- a/packages/docusaurus/src/server/translations/__tests__/translations.test.ts +++ b/packages/docusaurus/src/server/translations/__tests__/translations.test.ts @@ -28,21 +28,19 @@ async function createTmpSiteDir() { async function createTmpTranslationFile( content: TranslationFileContent | null, ) { - const file = await tmp.file({ + const filePath = await tmp.tmpName({ prefix: 'jest-createTmpTranslationFile', postfix: '.json', }); - // null means we don't want a file, but tmp.file() creates an empty file :( - if (content === null) { - await fs.unlink(file.path); - } else { - await fs.writeFile(file.path, JSON.stringify(content, null, 2)); + // null means we don't want a file, just a filename + if (content !== null) { + await fs.writeFile(filePath, JSON.stringify(content, null, 2)); } return { - filePath: file.path, - readFile: async () => JSON.parse(await fs.readFile(file.path, 'utf8')), + filePath, + readFile: async () => JSON.parse(await fs.readFile(filePath, 'utf8')), }; } diff --git a/packages/docusaurus/src/server/translations/translations.ts b/packages/docusaurus/src/server/translations/translations.ts index 9ff63f9537..dde540bb7d 100644 --- a/packages/docusaurus/src/server/translations/translations.ts +++ b/packages/docusaurus/src/server/translations/translations.ts @@ -9,7 +9,7 @@ import fs from 'fs-extra'; import {InitPlugin} from '../plugins/init'; import {mapValues, difference} from 'lodash'; import {TranslationFileContent, TranslationFile} from '@docusaurus/types'; -import {getPluginI18nPath} from '@docusaurus/utils'; +import {getPluginI18nPath, toMessageRelativeFilePath} from '@docusaurus/utils'; import * as Joi from 'joi'; import chalk from 'chalk'; @@ -128,8 +128,10 @@ Maybe you should remove them? console.log( `${Object.keys(mergedContent) .length.toString() - .padStart(3, ' ')} translations written at ${path.relative( - process.cwd(), + .padStart( + 3, + ' ', + )} translations will be written at ${toMessageRelativeFilePath( filePath, )}`, ); diff --git a/packages/docusaurus/src/server/translations/translationsExtractor.ts b/packages/docusaurus/src/server/translations/translationsExtractor.ts index f48db7fc9e..e4a581f017 100644 --- a/packages/docusaurus/src/server/translations/translationsExtractor.ts +++ b/packages/docusaurus/src/server/translations/translationsExtractor.ts @@ -14,6 +14,7 @@ import {TranslationFileContent, TranslationMessage} from '@docusaurus/types'; import globby from 'globby'; import nodePath from 'path'; import {InitPlugin} from '../plugins/init'; +import {posixPath} from '@docusaurus/utils'; // We only support extracting source code translations from these kind of files const TranslatableSourceCodeExtension = new Set([ @@ -40,7 +41,13 @@ async function getSourceCodeFilePaths( plugins.map((plugin) => plugin.getPathsToWatch?.() ?? []), ); - const filePaths = await globby(allPathsToWatch); + // Required for Windows support, as paths using \ should not be used by globby + // (also using the windows hard drive prefix like c: is not a good idea) + const allRelativePosixPathsToWatch = allPathsToWatch.map((path) => + posixPath(nodePath.relative(process.cwd(), path)), + ); + + const filePaths = await globby(allRelativePosixPathsToWatch); return filePaths.filter(isTranslatableSourceCodePath); } diff --git a/packages/docusaurus/src/webpack/__tests__/base.test.ts b/packages/docusaurus/src/webpack/__tests__/base.test.ts index db6acff6dc..c12c188b5c 100644 --- a/packages/docusaurus/src/webpack/__tests__/base.test.ts +++ b/packages/docusaurus/src/webpack/__tests__/base.test.ts @@ -15,6 +15,7 @@ import { } from '../base'; import * as utils from '../utils'; import {mapValues} from 'lodash'; +import {posixPath} from '@docusaurus/utils'; describe('babel transpilation exclude logic', () => { test('always transpile client dir files', () => { @@ -70,7 +71,7 @@ describe('getDocusaurusAliases()', () => { // using relative paths makes tests work everywhere const relativeDocusaurusAliases = mapValues( getDocusaurusAliases(), - (aliasValue) => path.relative(__dirname, aliasValue), + (aliasValue) => posixPath(path.relative(__dirname, aliasValue)), ); expect(relativeDocusaurusAliases).toMatchSnapshot(); }); diff --git a/packages/docusaurus/src/webpack/__tests__/utils.test.ts b/packages/docusaurus/src/webpack/__tests__/utils.test.ts index 5785bb7d89..f4922e6ada 100644 --- a/packages/docusaurus/src/webpack/__tests__/utils.test.ts +++ b/packages/docusaurus/src/webpack/__tests__/utils.test.ts @@ -135,7 +135,7 @@ describe('extending generated webpack config', () => { describe('getFileLoaderUtils()', () => { test('plugin svgo/removeViewBox should be disabled', () => { - const use = getFileLoaderUtils().rules.svg().use; + const {use} = getFileLoaderUtils().rules.svg(); expect(use).toContainEqual( expect.objectContaining({ loader: '@svgr/webpack', diff --git a/packages/stylelint-copyright/__tests__/index.js b/packages/stylelint-copyright/__tests__/index.js index 1da3eedc36..7dbd9cb09a 100644 --- a/packages/stylelint-copyright/__tests__/index.js +++ b/packages/stylelint-copyright/__tests__/index.js @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. */ +const path = require('path'); const rule = require('..'); const {ruleName, messages} = rule; @@ -12,7 +13,7 @@ const {ruleName, messages} = rule; testStylelintRule( { // Relative to repo root. - plugins: ['./packages/stylelint-copyright'], + plugins: [path.join(process.cwd(), 'packages', 'stylelint-copyright')], rules: { [ruleName]: true, }, diff --git a/website/docs/deployment.mdx b/website/docs/deployment.mdx index c4d78f5aaf..09c97c0a54 100644 --- a/website/docs/deployment.mdx +++ b/website/docs/deployment.mdx @@ -51,9 +51,11 @@ First, modify your `docusaurus.config.js` and add the required params: | `baseUrl` | Base URL for your project. For projects hosted on GitHub pages, it follows the format "/_projectName_/". For https://github.com/facebook/docusaurus, `baseUrl` is `/docusaurus/`. | :::info + In case you want to use your custom domain for GitHub Pages, create a `CNAME` file in the `static` directory. Anything within the `static` directory will be copied to the root of the `build` directory for deployment. You may refer to GitHub Pages' documentation [User, Organization, and Project Pages](https://help.github.com/en/articles/user-organization-and-project-pages) for more details. + ::: Example: @@ -94,20 +96,20 @@ Optional parameters, also set as environment variables: GitHub enterprise installations should work in the same manner as github.com; you only need to set the organization's GitHub Enterprise host as an environment veriable: -| Name | Description | -| --- | --- | +| Name | Description | +| ------------- | ----------------------------------------------- | | `GITHUB_HOST` | The domain name of your GitHub enterprise site. | ### Deploy Finally, to deploy your site to GitHub Pages, run: - diff --git a/website/docs/sidebar.md b/website/docs/sidebar.md index 54bb125665..87f8157926 100644 --- a/website/docs/sidebar.md +++ b/website/docs/sidebar.md @@ -78,7 +78,9 @@ module.exports = { ``` :::note + Shorthand notation relies on the iteration order of JavaScript object keys for the category name. When using this notation, keep in mind that EcmaScript does not guarantee `Object.keys({a,b}) === ['a','b']`, yet this is generally true. + ::: ## Using multiple sidebars