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 87a6769ac2d5..94ce220ef79f 100644 --- a/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts +++ b/packages/docusaurus-plugin-content-blog/src/__tests__/index.test.ts @@ -541,14 +541,14 @@ describe('blog plugin', () => { }); it('excludes draft blog post from production build', async () => { - const originalEnv = process.env; vi.resetModules(); - process.env = {...originalEnv, NODE_ENV: 'production'}; + vi.stubEnv('NODE_ENV', 'production'); + const siteDir = path.join(__dirname, '__fixtures__', 'website'); const blogPosts = await getBlogPosts(siteDir); expect(blogPosts.find((v) => v.metadata.title === 'draft')).toBeUndefined(); - process.env = originalEnv; + vi.unstubAllEnvs(); }); it('creates blog post without date', async () => { diff --git a/packages/docusaurus/src/client/exports/__tests__/BrowserOnly.test.tsx b/packages/docusaurus/src/client/exports/__tests__/BrowserOnly.test.tsx index 23a8d3201f85..ea2d9a727a16 100644 --- a/packages/docusaurus/src/client/exports/__tests__/BrowserOnly.test.tsx +++ b/packages/docusaurus/src/client/exports/__tests__/BrowserOnly.test.tsx @@ -5,7 +5,8 @@ * LICENSE file in the root directory of this source tree. */ // @vitest-environment jsdom -import {afterAll, beforeEach, describe, expect, it, vi} from 'vitest'; + +import {afterAll, describe, expect, it, vi} from 'vitest'; import React from 'react'; import {render} from '@testing-library/react'; import '@testing-library/jest-dom/vitest'; @@ -13,24 +14,16 @@ import BrowserOnly from '../BrowserOnly'; import {Context} from '../../browserContext'; describe('', () => { - const originalEnv = process.env; - - beforeEach(() => { - vi.resetModules(); - process.env = {...originalEnv}; - }); - afterAll(() => { - process.env = originalEnv; + vi.unstubAllEnvs(); }); it('rejects react element children', () => { - process.env.NODE_ENV = 'development'; + vi.stubEnv('NODE_ENV', 'development'); expect(() => render( - {/* @ts-expect-error test */} {window.location.href} , @@ -42,11 +35,10 @@ describe('', () => { }); it('rejects string children', () => { - process.env.NODE_ENV = 'development'; + vi.stubEnv('NODE_ENV', 'development'); expect(() => { render( - {/* @ts-expect-error test */} , ); diff --git a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts index 5b2bd3a96656..c54bf533355e 100644 --- a/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts +++ b/packages/docusaurus/src/commands/swizzle/__tests__/index.test.ts @@ -5,15 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import { - afterEach, - beforeEach, - describe, - expect, - it, - vi, - type MockInstance, -} from 'vitest'; +import {describe, expect, it, vi} from 'vitest'; import path from 'path'; import fs from 'fs-extra'; import tree from 'tree-node-cli'; @@ -55,38 +47,19 @@ module.exports = { ); } -class MockExitError extends Error { - constructor(public code: number) { - super(`Exit with code ${code}`); - this.code = code; - } -} - -function createExitMock() { - let mock: MockInstance<(code?: number) => never>; - - /* eslint-disable-next-line vitest/require-top-level-describe */ - beforeEach(async () => { - mock = vi.spyOn(process, 'exit').mockImplementation((code) => { - throw new MockExitError(code as number); - }) as MockInstance<(code?: number) => never>; - }); - /* eslint-disable-next-line vitest/require-top-level-describe */ - afterEach(async () => { - mock.mockRestore(); - }); +function createExitMock(expectedExitCode: number = 0) { + const mock = vi + .spyOn(process, 'exit') + .mockImplementation((() => {}) as () => never); return { - expectExitCode: (code: number) => { - expect(mock).toHaveBeenCalledWith(code); + [Symbol.dispose]: () => { + expect(mock).toHaveBeenCalledExactlyOnceWith(expectedExitCode); + mock.mockRestore(); }, }; } -const swizzleWithExit: typeof swizzle = async (...args) => { - await expect(() => swizzle(...args)).rejects.toThrow(MockExitError); -}; - async function createTestSite() { const siteDir = await createTempSiteDir(); @@ -117,7 +90,7 @@ async function createTestSite() { component: string; typescript?: boolean; }) { - return swizzleWithExit(FixtureThemeName, component, siteDir, { + return swizzle(FixtureThemeName, component, siteDir, { wrap: true, danger: true, typescript, @@ -132,7 +105,7 @@ async function createTestSite() { component: string; typescript?: boolean; }) { - return swizzleWithExit(FixtureThemeName, component, siteDir, { + return swizzle(FixtureThemeName, component, siteDir, { eject: true, danger: true, typescript, @@ -150,18 +123,17 @@ async function createTestSite() { } describe('swizzle wrap', () => { - const exitMock = createExitMock(); - it(`${Components.FirstLevelComponent} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.FirstLevelComponent, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.FirstLevelComponent} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.FirstLevelComponent, @@ -171,76 +143,75 @@ describe('swizzle wrap', () => { }); it(`${Components.ComponentInFolder} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.ComponentInFolder, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.ComponentInFolder} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.ComponentInFolder, typescript: true, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.ComponentInSubFolder} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.ComponentInSubFolder, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.ComponentInSubFolder} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.ComponentInSubFolder, typescript: true, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.Sibling} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.Sibling, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.Sibling} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testWrap} = await createTestSite(); await testWrap({ component: Components.Sibling, typescript: true, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); }); describe('swizzle eject', () => { - const exitMock = createExitMock(); - it(`${Components.FirstLevelComponent} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.FirstLevelComponent, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.FirstLevelComponent} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.FirstLevelComponent, @@ -250,59 +221,59 @@ describe('swizzle eject', () => { }); it(`${Components.ComponentInFolder} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.ComponentInFolder, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.ComponentInFolder} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.ComponentInFolder, typescript: true, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.ComponentInSubFolder} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.ComponentInSubFolder, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.ComponentInSubFolder} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.ComponentInSubFolder, typescript: true, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.Sibling} JS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.Sibling, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); it(`${Components.Sibling} TS`, async () => { + using _exitMock = createExitMock(); const {snapshotThemeDir, testEject} = await createTestSite(); await testEject({ component: Components.Sibling, typescript: true, }); - exitMock.expectExitCode(0); await snapshotThemeDir(); }); }); diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap index e7e918141527..205c3da6e255 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap @@ -1844,7 +1844,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale es 1`] = "themes": [], "title": "Hello", "titleDelimiter": "|", - "url": "https://docusaurus.io", + "url": "https://es.docusaurus.io", }, "siteConfigPath": "/packages/docusaurus/src/server/__tests__/__fixtures__/loadSiteFixtures/simple-site-with-baseUrl-i18n/docusaurus.config.js", "siteDir": "/packages/docusaurus/src/server/__tests__/__fixtures__/loadSiteFixtures/simple-site-with-baseUrl-i18n", @@ -2312,7 +2312,7 @@ exports[`loadSite > simple-site-with-baseUrl-i18n > loads site - locale it 1`] = "themes": [], "title": "Hello", "titleDelimiter": "|", - "url": "https://docusaurus.io", + "url": "https://it.docusaurus.io", }, "siteConfigPath": "/packages/docusaurus/src/server/__tests__/__fixtures__/loadSiteFixtures/simple-site-with-baseUrl-i18n/docusaurus.config.js", "siteDir": "/packages/docusaurus/src/server/__tests__/__fixtures__/loadSiteFixtures/simple-site-with-baseUrl-i18n", diff --git a/packages/docusaurus/src/server/__tests__/site.test.ts b/packages/docusaurus/src/server/__tests__/site.test.ts index f4b8d6b657bb..ee4e8a7f9372 100644 --- a/packages/docusaurus/src/server/__tests__/site.test.ts +++ b/packages/docusaurus/src/server/__tests__/site.test.ts @@ -87,6 +87,13 @@ describe('loadSite', () => { expect(site.props).toMatchSnapshot(); }); + it('uses locale url in site config', async () => { + const site = await loadSiteFixture(siteFixture, { + locale: 'es', + }); + expect(site.props.siteConfig.url).toBe('https://es.docusaurus.io'); + }); + it('loads site - locale de', async () => { const site = await loadSiteFixture(siteFixture, { locale: 'de', diff --git a/packages/docusaurus/src/server/site.ts b/packages/docusaurus/src/server/site.ts index 8ab24425684e..46498747c0b9 100644 --- a/packages/docusaurus/src/server/site.ts +++ b/packages/docusaurus/src/server/site.ts @@ -149,6 +149,7 @@ export async function loadContext( const siteConfig: DocusaurusConfig = { ...initialSiteConfig, + url: localeConfig.url, baseUrl, }; diff --git a/packages/docusaurus/src/webpack/__tests__/base.test.ts b/packages/docusaurus/src/webpack/__tests__/base.test.ts index 910079654e10..91b1de0142c9 100644 --- a/packages/docusaurus/src/webpack/__tests__/base.test.ts +++ b/packages/docusaurus/src/webpack/__tests__/base.test.ts @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import {afterEach, describe, expect, it, vi} from 'vitest'; +import {describe, expect, it} from 'vitest'; import path from 'path'; import _ from 'lodash'; import webpack from 'webpack'; @@ -112,10 +112,6 @@ describe('base webpack config', () => { ], } as Props; - afterEach(() => { - vi.restoreAllMocks(); - }); - it('creates webpack aliases', async () => { const aliases = (( await createBaseConfig({ diff --git a/packages/docusaurus/src/webpack/utils/__tests__/getHttpsConfig.test.ts b/packages/docusaurus/src/webpack/utils/__tests__/getHttpsConfig.test.ts index f4b6db2e050d..8e7d4ab9eaff 100644 --- a/packages/docusaurus/src/webpack/utils/__tests__/getHttpsConfig.test.ts +++ b/packages/docusaurus/src/webpack/utils/__tests__/getHttpsConfig.test.ts @@ -5,24 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -import {afterAll, beforeEach, describe, expect, it, vi} from 'vitest'; +import {afterEach, describe, expect, it, vi} from 'vitest'; import path from 'path'; import getHttpsConfig from '../getHttpsConfig'; describe('getHttpsConfig', () => { - const originalEnv = process.env; - function getFixture(name: string) { return path.join(__dirname, '__fixtures__/getHttpsConfig', name); } - beforeEach(() => { - vi.resetModules(); - process.env = {...originalEnv}; - }); - - afterAll(() => { - process.env = originalEnv; + afterEach(() => { + vi.unstubAllEnvs(); }); it('returns true for HTTPS not env', async () => { @@ -30,14 +23,15 @@ describe('getHttpsConfig', () => { }); it('returns true for HTTPS in env', async () => { - process.env.HTTPS = 'true'; + vi.stubEnv('HTTPS', 'true'); await expect(getHttpsConfig()).resolves.toBe(true); }); it('returns custom certs if they are in env', async () => { - process.env.HTTPS = 'true'; - process.env.SSL_CRT_FILE = getFixture('host.crt'); - process.env.SSL_KEY_FILE = getFixture('host.key'); + vi.stubEnv('HTTPS', 'true'); + vi.stubEnv('SSL_CRT_FILE', getFixture('host.crt')); + vi.stubEnv('SSL_KEY_FILE', getFixture('host.key')); + await expect(getHttpsConfig()).resolves.toEqual({ key: expect.any(Buffer), cert: expect.any(Buffer), @@ -45,25 +39,25 @@ describe('getHttpsConfig', () => { }); it("throws if file doesn't exist", async () => { - process.env.HTTPS = 'true'; - process.env.SSL_CRT_FILE = getFixture('nonexistent.crt'); - process.env.SSL_KEY_FILE = getFixture('host.key'); + vi.stubEnv('HTTPS', 'true'); + vi.stubEnv('SSL_CRT_FILE', getFixture('nonexistent.crt')); + vi.stubEnv('SSL_KEY_FILE', getFixture('host.key')); await expect(getHttpsConfig()).rejects.toThrowErrorMatchingInlineSnapshot( `[Error: You specified SSL_CRT_FILE in your env, but the file "/packages/docusaurus/src/webpack/utils/__tests__/__fixtures__/getHttpsConfig/nonexistent.crt" can't be found.]`, ); }); it('throws for invalid key', async () => { - process.env.HTTPS = 'true'; - process.env.SSL_CRT_FILE = getFixture('host.crt'); - process.env.SSL_KEY_FILE = getFixture('invalid.key'); + vi.stubEnv('HTTPS', 'true'); + vi.stubEnv('SSL_CRT_FILE', getFixture('host.crt')); + vi.stubEnv('SSL_KEY_FILE', getFixture('invalid.key')); await expect(getHttpsConfig()).rejects.toThrow(); }); it('throws for invalid cert', async () => { - process.env.HTTPS = 'true'; - process.env.SSL_CRT_FILE = getFixture('invalid.crt'); - process.env.SSL_KEY_FILE = getFixture('host.key'); + vi.stubEnv('HTTPS', 'true'); + vi.stubEnv('SSL_CRT_FILE', getFixture('invalid.crt')); + vi.stubEnv('SSL_KEY_FILE', getFixture('host.key')); await expect(getHttpsConfig()).rejects.toThrow(); }); }); diff --git a/project-words.txt b/project-words.txt index 7b303b9f7d49..51627fb1725b 100644 --- a/project-words.txt +++ b/project-words.txt @@ -354,6 +354,7 @@ unlinkable Unlisteds unlisteds unlocalized +unstub unswizzle upvotes urlset diff --git a/test/snapshotPathNormalizer.ts b/test/snapshotPathNormalizer.ts index 55e550db03d3..c7bf6b8ba7dd 100644 --- a/test/snapshotPathNormalizer.ts +++ b/test/snapshotPathNormalizer.ts @@ -226,6 +226,8 @@ const snapshotSerializer: SnapshotSerializer = { }, test: (value: unknown): boolean => { + // TODO this is not ideal and not very performant + // see https://github.com/vitest-dev/vitest/issues/10349 return shouldNormalize(value); }, };