From e1d44f566ec4a06e03e7e272b5064f2e7f3aa9b9 Mon Sep 17 00:00:00 2001 From: Wang Yiwen Date: Fri, 29 Mar 2024 18:58:09 +0800 Subject: [PATCH 1/2] Rename core/test/unit/Site to Typescript --- packages/core/test/unit/{Site.test.js => Site.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename packages/core/test/unit/{Site.test.js => Site.test.ts} (100%) diff --git a/packages/core/test/unit/Site.test.js b/packages/core/test/unit/Site.test.ts similarity index 100% rename from packages/core/test/unit/Site.test.js rename to packages/core/test/unit/Site.test.ts From d86cc3f09ba9ff7ed7275f1ae43860ce0d583bd6 Mon Sep 17 00:00:00 2001 From: Wang Yiwen Date: Fri, 29 Mar 2024 20:20:06 +0800 Subject: [PATCH 2/2] Adapt core/test/unit/Site to Typescript --- .eslintignore | 1 - .gitignore | 1 - packages/core/test/unit/Site.test.ts | 181 ++++++++++++++------------- 3 files changed, 93 insertions(+), 90 deletions(-) diff --git a/.eslintignore b/.eslintignore index c09782a280..f5dda8b156 100644 --- a/.eslintignore +++ b/.eslintignore @@ -27,7 +27,6 @@ packages/core/test/unit/**/*.js # TODO: remove when migrated to TS !markdown-it-icons.test.js -!Site.test.js # Rules for pure JS files packages/core/src/lib/markdown-it/patches/* diff --git a/.gitignore b/.gitignore index fe84e40f0f..407c29d93c 100644 --- a/.gitignore +++ b/.gitignore @@ -92,6 +92,5 @@ packages/core/test/unit/**/*.js # TODO: remove when migrated to TS !markdown-it-icons.test.js -!Site.test.js # --- packages/core end --- diff --git a/packages/core/test/unit/Site.test.ts b/packages/core/test/unit/Site.test.ts index 8c0079dce9..7288ae698b 100644 --- a/packages/core/test/unit/Site.test.ts +++ b/packages/core/test/unit/Site.test.ts @@ -1,17 +1,19 @@ -const path = require('path'); -const fs = require('fs-extra'); -const ghpages = require('gh-pages'); -const { Site } = require('../../src/Site'); -const { Template } = require('../../src/Site/template'); - -const { - INDEX_MD_DEFAULT, - PAGE_NJK, - SITE_JSON_DEFAULT, - getDefaultTemplateFileFullPath, -} = require('./utils/data'); +import path from 'path'; +import fs from 'fs-extra'; +import ghpages from 'gh-pages'; +import { Site } from '../../src/Site'; +import { Template } from '../../src/Site/template'; + +import { + INDEX_MD_DEFAULT, PAGE_NJK, SITE_JSON_DEFAULT, getDefaultTemplateFileFullPath, +} from './utils/data'; +import { SiteConfig } from '../../src/Site/SiteConfig'; const DEFAULT_TEMPLATE = 'default'; +const mockFs = fs as any; +const mockGhPages = ghpages as any; +type SiteArguments = [string, string, string, undefined, undefined, any, boolean, () => void]; +const siteArguments: SiteArguments = ['./', '_site', '', undefined, undefined, undefined, false, () => {}]; jest.mock('fs'); jest.mock('walk-sync'); @@ -27,7 +29,7 @@ jest.mock('simple-git', () => () => ({ remote: jest.fn(() => 'https://github.com/mockName/mockRepo.git'), })); -afterEach(() => fs.vol.reset()); +afterEach(() => mockFs.vol.reset()); test('Site Init with invalid template fails', async () => { // Mock default template in MemFS without site config @@ -36,10 +38,10 @@ test('Site Init with invalid template fails', async () => { [getDefaultTemplateFileFullPath('index.md')]: INDEX_MD_DEFAULT, }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); const template = new Template('', DEFAULT_TEMPLATE); - await template.init('', DEFAULT_TEMPLATE) + await template.init() .catch((err) => { expect(err).toEqual( new Error('Template validation failed. Required files does not exist.')); @@ -57,7 +59,7 @@ test('Site Init does not overwrite existing files', async () => { [getDefaultTemplateFileFullPath('site.json')]: SITE_JSON_DEFAULT, }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); // index.md expect(fs.readFileSync(path.resolve('index.md'), 'utf8')).toEqual(EXISTING_INDEX_MD); @@ -71,13 +73,13 @@ test('Site baseurls are correct for sub nested subsites', async () => { 'sub/sub/site.json': SITE_JSON_DEFAULT, 'otherSub/sub/site.json': SITE_JSON_DEFAULT, }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); const baseUrlMapExpected = new Set(['', 'sub', 'sub/sub', 'otherSub/sub'].map(url => path.resolve(url))); - const site = new Site('./', '_site'); + const site = new Site(...siteArguments); await site.readSiteConfig(); - await site.collectBaseUrl(); + site.collectBaseUrl(); expect(site.baseUrlMap).toEqual(baseUrlMapExpected); }); @@ -88,9 +90,9 @@ test('Site removeAsync removes the correct asset', async () => { '_site/dontRemove.png': '', 'toRemove.html': '', }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + const site = new Site(...siteArguments); await site.removeAsset('toRemove.jpg'); expect(fs.existsSync(path.resolve('_site/toRemove.jpg'))).toEqual(false); expect(fs.existsSync(path.resolve('_site/dontRemove.png'))).toEqual(true); @@ -101,11 +103,11 @@ test('Site read site config for default', async () => { ...PAGE_NJK, 'site.json': SITE_JSON_DEFAULT, }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); const expectedSiteConfigDefaults = { enableSearch: true }; const expectedSiteConfig = { ...JSON.parse(SITE_JSON_DEFAULT), ...expectedSiteConfigDefaults }; - const site = new Site('./', '_site'); + const site = new Site(...siteArguments); const siteConfig = await site.readSiteConfig(); expect(siteConfig.baseUrl).toEqual(expectedSiteConfig.baseUrl); @@ -140,9 +142,9 @@ test('Site read site config for custom site config', async () => { ...PAGE_NJK, 'site.json': JSON.stringify(customSiteJson), }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + const site = new Site(...siteArguments); const siteConfig = await site.readSiteConfig(); expect(siteConfig.baseUrl).toEqual(customSiteJson.baseUrl); @@ -162,12 +164,12 @@ test('Site resolves variables referencing other variables', async () => { + 'Blue text' + '{{level3}}', }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + const site = new Site(...siteArguments); await site.readSiteConfig(); - await site.collectBaseUrl(); - await site.collectUserDefinedVariablesMap(); + site.collectBaseUrl(); + site.collectUserDefinedVariablesMap(); const root = site.variableProcessor.userDefinedVariablesMap[path.resolve('')]; @@ -193,12 +195,12 @@ test('Site read correct user defined variables', async () => { 'sub/sub/_markbind/variables.md': '9999', 'otherSub/sub/_markbind/variables.md': 'other_variable', }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + const site = new Site(...siteArguments); await site.readSiteConfig(); - await site.collectBaseUrl(); - await site.collectUserDefinedVariablesMap(); + site.collectBaseUrl(); + site.collectUserDefinedVariablesMap(); const root = site.variableProcessor.userDefinedVariablesMap[path.resolve('')]; const sub = site.variableProcessor.userDefinedVariablesMap[path.resolve('sub')]; @@ -227,11 +229,11 @@ test('Site deploys with default settings', async () => { 'site.json': SITE_JSON_DEFAULT, _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); - await site.deploy(); - expect(ghpages.dir).toEqual('_site'); - expect(ghpages.options) + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); + await site.deploy(false); + expect(mockGhPages.dir).toEqual('_site'); + expect(mockGhPages.options) .toEqual({ branch: 'gh-pages', message: 'Site Update. [skip ci]', @@ -252,11 +254,11 @@ test('Site deploys with custom settings', async () => { 'site.json': JSON.stringify(customConfig), _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); - await site.deploy(); - expect(ghpages.dir).toEqual('_site'); - expect(ghpages.options) + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); + await site.deploy(false); + expect(mockGhPages.dir).toEqual('_site'); + expect(mockGhPages.options) .toEqual({ branch: 'master', message: 'Custom Site Update. [skip ci]', @@ -270,9 +272,9 @@ test('Site should not deploy without a built site', async () => { ...PAGE_NJK, 'site.json': SITE_JSON_DEFAULT, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); - await expect(site.deploy()) + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); + await expect(site.deploy(false)) .rejects .toThrow( new Error('The site directory does not exist. ' @@ -311,14 +313,15 @@ describe('Site deploy with various CI environments', () => { ])('Site deploy -c/--ci deploys with default settings', /* eslint-enable max-len */ async (ciIdentifier, repoSlugIdentifier, deployBotUser) => { - process.env[ciIdentifier] = true; + process.env[ciIdentifier] = 'true'; process.env.GITHUB_TOKEN = 'githubToken'; const genericRepoSlug = 'GENERIC_USER/GENERIC_REPO'; - if (repoSlugIdentifier.reposlug) { - process.env[repoSlugIdentifier.reposlug] = genericRepoSlug; + if ((repoSlugIdentifier as { reposlug: string }).reposlug) { + process.env[(repoSlugIdentifier as { reposlug: string }).reposlug] = genericRepoSlug; } else { - process.env[repoSlugIdentifier.username] = 'GENERIC_USER'; - process.env[repoSlugIdentifier.reponame] = 'GENERIC_REPO'; + const repoSlugIdentifierCasted = repoSlugIdentifier as { username: string, reponame: string }; + process.env[repoSlugIdentifierCasted.username] = 'GENERIC_USER'; + process.env[repoSlugIdentifierCasted.reponame] = 'GENERIC_REPO'; } const json = { @@ -326,12 +329,12 @@ describe('Site deploy with various CI environments', () => { 'site.json': SITE_JSON_DEFAULT, _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); await site.deploy(true); - expect(ghpages.options.repo) + expect(mockGhPages.options.repo) .toEqual(`https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/${genericRepoSlug}.git`); - expect(ghpages.options.user).toEqual(deployBotUser); + expect(mockGhPages.options.user).toEqual(deployBotUser); }); test.each([ @@ -341,13 +344,14 @@ describe('Site deploy with various CI environments', () => { ['CIRCLECI', { username: 'CIRCLE_PROJECT_USERNAME', reponame: 'CIRCLE_PROJECT_REPONAME' }], ])('Site deploy -c/--ci deploys with custom GitHub repo', async (ciIdentifier, repoSlugIdentifier) => { - process.env[ciIdentifier] = true; + process.env[ciIdentifier] = 'true'; process.env.GITHUB_TOKEN = 'githubToken'; - if (repoSlugIdentifier.reposlug) { - process.env[repoSlugIdentifier.reposlug] = 'GENERIC_USER/GENERIC_REPO'; + if ((repoSlugIdentifier as { reposlug: string }).reposlug) { + process.env[(repoSlugIdentifier as { reposlug: string }).reposlug] = 'GENERIC_USER/GENERIC_REPO'; } else { - process.env[repoSlugIdentifier.username] = 'GENERIC_USER'; - process.env[repoSlugIdentifier.reponame] = 'GENERIC_REPO'; + const repoSlugIdentifierCasted = repoSlugIdentifier as { username: string, reponame: string }; + process.env[repoSlugIdentifierCasted.username] = 'GENERIC_USER'; + process.env[repoSlugIdentifierCasted.reponame] = 'GENERIC_REPO'; } const customRepoConfig = JSON.parse(SITE_JSON_DEFAULT); @@ -357,10 +361,10 @@ describe('Site deploy with various CI environments', () => { 'site.json': JSON.stringify(customRepoConfig), _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); await site.deploy(true); - expect(ghpages.options.repo) + expect(mockGhPages.options.repo) .toEqual(`https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/USER/REPO.git`); }); @@ -371,14 +375,15 @@ describe('Site deploy with various CI environments', () => { ['CIRCLECI', { username: 'CIRCLE_PROJECT_USERNAME', reponame: 'CIRCLE_PROJECT_REPONAME' }], ])('Site deploy -c/--ci deploys to correct repo when .git is in repo name', async (ciIdentifier, repoSlugIdentifier) => { - process.env[ciIdentifier] = true; + process.env[ciIdentifier] = 'true'; process.env.GITHUB_TOKEN = 'githubToken'; const genericRepoSlug = 'GENERIC_USER/GENERIC_REPO.github.io'; - if (repoSlugIdentifier.reposlug) { - process.env[repoSlugIdentifier.reposlug] = genericRepoSlug; + if ((repoSlugIdentifier as { reposlug: string }).reposlug) { + process.env[(repoSlugIdentifier as { reposlug: string }).reposlug] = genericRepoSlug; } else { - process.env[repoSlugIdentifier.username] = 'GENERIC_USER'; - process.env[repoSlugIdentifier.reponame] = 'GENERIC_REPO.github.io'; + const repoSlugIdentifierCasted = repoSlugIdentifier as { username: string, reponame: string }; + process.env[repoSlugIdentifierCasted.username] = 'GENERIC_USER'; + process.env[repoSlugIdentifierCasted.reponame] = 'GENERIC_REPO.github.io'; } const json = { @@ -386,10 +391,10 @@ describe('Site deploy with various CI environments', () => { 'site.json': SITE_JSON_DEFAULT, _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); await site.deploy(true); - expect(ghpages.options.repo) + expect(mockGhPages.options.repo) // eslint-disable-next-line max-len .toEqual(`https://x-access-token:${process.env.GITHUB_TOKEN}@github.com/${genericRepoSlug}.git`); }); @@ -402,8 +407,8 @@ describe('Site deploy with various CI environments', () => { 'site.json': SITE_JSON_DEFAULT, _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); await expect(site.deploy(true)) .rejects .toThrow(new Error('-c/--ci should only be run in CI environments.')); @@ -415,15 +420,15 @@ describe('Site deploy with various CI environments', () => { ['GITHUB_ACTIONS'], ['CIRCLECI'], ])('Site deploy -c/--ci should not deploy without authentication token', async (ciIdentifier) => { - process.env[ciIdentifier] = true; + process.env[ciIdentifier] = 'true'; const json = { ...PAGE_NJK, 'site.json': SITE_JSON_DEFAULT, _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); await expect(site.deploy(true)) .rejects .toThrow(new Error('The environment variable GITHUB_TOKEN does not exist.')); @@ -435,7 +440,7 @@ describe('Site deploy with various CI environments', () => { ['GITHUB_ACTIONS'], ['CIRCLECI'], ])('Site deploy -c/--ci should not deploy if custom repository is not on GitHub', async (ciIdentifier) => { - process.env[ciIdentifier] = true; + process.env[ciIdentifier] = 'true'; process.env.GITHUB_TOKEN = 'githubToken'; const invalidRepoConfig = JSON.parse(SITE_JSON_DEFAULT); @@ -445,8 +450,8 @@ describe('Site deploy with various CI environments', () => { 'site.json': JSON.stringify(invalidRepoConfig), _site: {}, }; - fs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); + mockFs.vol.fromJSON(json, ''); + const site = new Site(...siteArguments); await expect(site.deploy(true)) .rejects .toThrow(new Error('-c/--ci expects a GitHub repository.\n' @@ -563,10 +568,10 @@ siteJsonResolvePropertiesTestCases.forEach((testCase) => { ...PAGE_NJK, 'index.md': '', }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); - site.siteConfig = customSiteConfig; + const site = new Site(...siteArguments); + site.siteConfig = customSiteConfig as unknown as SiteConfig; site.collectAddressablePages(); expect(site.addressablePages) .toEqual(testCase.expected); @@ -599,10 +604,10 @@ test('Site config throws error on duplicate page src', async () => { ...PAGE_NJK, 'index.md': '', }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); - site.siteConfig = customSiteConfig; + const site = new Site(...siteArguments); + site.siteConfig = customSiteConfig as unknown as SiteConfig; expect(() => site.collectAddressablePages()) .toThrow(new Error('Duplicate page entries found in site config: index.md')); }); @@ -669,10 +674,10 @@ siteJsonPageExclusionTestCases.forEach((testCase) => { 'index.md': '', 'exclude.md': '', }; - fs.vol.fromJSON(json, ''); + mockFs.vol.fromJSON(json, ''); - const site = new Site('./', '_site'); - site.siteConfig = customSiteConfig; + const site = new Site(...siteArguments); + site.siteConfig = customSiteConfig as unknown as SiteConfig; site.collectAddressablePages(); expect(site.addressablePages) .toEqual(testCase.expected);