Use vitest instead of jest (#50150)
This commit is contained in:
2
.github/workflows/headless-tests.yml
vendored
2
.github/workflows/headless-tests.yml
vendored
@@ -2,7 +2,7 @@ name: Headless Tests
|
||||
|
||||
# **What it does**: This runs our browser tests to test things that depend
|
||||
# on client-side JavaScript.
|
||||
# **Why we have it**: Because most automated jest tests only test static
|
||||
# **Why we have it**: Because most automated vitest tests only test static
|
||||
# input and outputs.
|
||||
# **Who does it impact**: Docs engineering, open-source engineering contributors.
|
||||
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -19,7 +19,7 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# Setting this will activate the jest tests that depend on actually
|
||||
# Setting this will activate the vitest tests that depend on actually
|
||||
# sending real search queries to Elasticsearch
|
||||
ELASTICSEARCH_URL: http://localhost:9200/
|
||||
|
||||
|
||||
1330
package-lock.json
generated
1330
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
49
package.json
49
package.json
@@ -35,7 +35,7 @@
|
||||
"index-test-fixtures": "npm run index-elasticsearch -- -l en -l ja -V ghec -V dotcom --index-prefix tests -- src/search/tests/fixtures/search-indexes",
|
||||
"lint": "eslint '**/*.{js,mjs,ts,tsx}'",
|
||||
"lint-content": "node src/content-linter/scripts/lint-content.js",
|
||||
"lint-translation": "cross-env NODE_OPTIONS=--experimental-vm-modules jest src/content-linter/tests/lint-files.js",
|
||||
"lint-translation": "cross-env NODE_OPTIONS=--experimental-vm-modules vitest src/content-linter/tests/lint-files.js",
|
||||
"generate-code-scanning-query-list": "tsx src/code-scanning/scripts/generate-code-scanning-query-list.ts",
|
||||
"generate-content-linter-docs": "tsx src/content-linter/scripts/generate-docs.ts",
|
||||
"move-content": "node src/content-render/scripts/move-content.js",
|
||||
@@ -63,10 +63,9 @@
|
||||
"sync-search-indices": "node src/search/scripts/sync-search-indices.js",
|
||||
"sync-search-server": "cross-env NODE_ENV=production PORT=4002 MINIMAL_RENDER=true CHANGELOG_DISABLED=true tsx src/frame/server.ts",
|
||||
"sync-webhooks": "src/rest/scripts/update-files.js -o webhooks",
|
||||
"test": "cross-env NODE_OPTIONS='--max_old_space_size=4096 --experimental-vm-modules' jest --logHeapUsage",
|
||||
"test": "cross-env NODE_OPTIONS='--max_old_space_size=4096 --experimental-vm-modules' vitest",
|
||||
"test-local-dev": "node src/workflows/test-local-dev.js",
|
||||
"test-moved-content": "tsx src/content-render/scripts/test-moved-content.ts",
|
||||
"test-watch": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --watch --notify --notifyMode=change --coverage",
|
||||
"tsc": "tsc --noEmit",
|
||||
"unallowed-contributions": "node src/workflows/unallowed-contributions.js",
|
||||
"update-data-and-image-paths": "node src/early-access/scripts/update-data-and-image-paths.js",
|
||||
@@ -153,14 +152,6 @@
|
||||
]
|
||||
},
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"**/tests/**/*.js"
|
||||
],
|
||||
"env": {
|
||||
"jest": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"**/*.tsx",
|
||||
@@ -197,41 +188,6 @@
|
||||
"src/code-scanning/scripts/generate-code-scanning-query-list.ts"
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"testTimeout": 30000,
|
||||
"coverageThreshold": {
|
||||
"global": {
|
||||
"branches": 95,
|
||||
"functions": 95,
|
||||
"lines": 95,
|
||||
"statements": -5
|
||||
}
|
||||
},
|
||||
"globalSetup": "./src/tests/scripts/start-server-for-jest.js",
|
||||
"globalTeardown": "./src/tests/scripts/kill-server-for-jest.js",
|
||||
"moduleNameMapper": {
|
||||
"@primer/behaviors": "<rootDir>/node_modules/@primer/behaviors/dist/cjs/index.js"
|
||||
},
|
||||
"preset": "ts-jest",
|
||||
"reporters": [
|
||||
"default",
|
||||
"github-actions"
|
||||
],
|
||||
"setupFilesAfterEnv": [
|
||||
"./src/tests/jest.setup.js",
|
||||
"jest-expect-message"
|
||||
],
|
||||
"testEnvironment": "node",
|
||||
"testMatch": [
|
||||
"**/tests/**/*.js"
|
||||
],
|
||||
"testPathIgnorePatterns": [
|
||||
"node_modules/",
|
||||
"vendor/",
|
||||
"src/fixtures/fixtures/",
|
||||
"src/tests/helpers/"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@elastic/elasticsearch": "8.11.0",
|
||||
"@github/failbot": "0.8.3",
|
||||
@@ -383,6 +339,7 @@
|
||||
"typescript": "^5.4.4",
|
||||
"unist-util-remove": "^4.0.0",
|
||||
"unist-util-visit-parents": "6.0.1",
|
||||
"vitest": "1.5.0",
|
||||
"website-scraper": "^5.3.1"
|
||||
},
|
||||
"overrides": {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { describe, jest, test } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
|
||||
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.js'
|
||||
|
||||
describe('enterprise deprecation', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test('redirects language-prefixed requests for deprecated enterprise content', async () => {
|
||||
const res = await get('/en/enterprise/2.12')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { jest } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import sharp from 'sharp'
|
||||
import { fileTypeFromBuffer } from 'file-type'
|
||||
|
||||
@@ -6,7 +7,7 @@ import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.
|
||||
import { get, head } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('dynamic assets', () => {
|
||||
jest.setTimeout(3 * 60 * 1000)
|
||||
vi.setConfig({ testTimeout: 3 * 60 * 1000 })
|
||||
|
||||
test('GET PNG as a WebP', async () => {
|
||||
const res = await get('/assets/images/_fixtures/screenshot.webp', {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest'
|
||||
import nock from 'nock'
|
||||
import { expect, jest } from '@jest/globals'
|
||||
|
||||
import { checkCachingHeaders } from '#src/tests/helpers/caching-headers.js'
|
||||
import { setDefaultFastlySurrogateKey } from '#src/frame/middleware/set-fastly-surrogate-key.js'
|
||||
@@ -57,7 +57,7 @@ describe('archived enterprise static assets', () => {
|
||||
// Sometimes static assets are proxied. The URL for the static asset
|
||||
// might not indicate it's based on archived enterprise version.
|
||||
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
beforeAll(async () => {
|
||||
// The first page load takes a long time so let's get it out of the way in
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { jest, expect } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { get } from '#src/tests/helpers/e2etest.js'
|
||||
import { checkCachingHeaders } from '#src/tests/helpers/caching-headers.js'
|
||||
@@ -14,7 +14,7 @@ function getNextStaticAsset(directory) {
|
||||
}
|
||||
|
||||
describe('static assets', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test('should serve /assets/cb-* with optimal headers', async () => {
|
||||
const res = await get('/assets/cb-1234/images/site/logo.png')
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
import { allVersions } from '#src/versions/lib/all-versions.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import {
|
||||
filterByAllowlistValues,
|
||||
filterAndUpdateGhesDataByAllowlistValues,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe, expect } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { supported } from '#src/versions/lib/enterprise-server-releases.js'
|
||||
import { allVersionKeys, allVersions } from '#src/versions/lib/all-versions.js'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { readFileSync } from 'fs'
|
||||
|
||||
import cheerio from 'cheerio'
|
||||
import { jest, test } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { loadPages } from '#src/frame/lib/page-data.js'
|
||||
import { get } from '#src/tests/helpers/e2etest.js'
|
||||
@@ -10,7 +10,7 @@ import { get } from '#src/tests/helpers/e2etest.js'
|
||||
const pageList = await loadPages(undefined, ['en'])
|
||||
|
||||
describe('autogenerated docs render', () => {
|
||||
jest.setTimeout(3 * 60 * 1000)
|
||||
vi.setConfig({ testTimeout: 3 * 60 * 1000 })
|
||||
|
||||
const autogeneratedPages = pageList.filter((page) => page.autogenerated)
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { tmpdir } from 'os'
|
||||
import { mkdirp } from 'mkdirp'
|
||||
import { cp, rm, readFile } from 'fs/promises'
|
||||
import { existsSync } from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
import { mkdirp } from 'mkdirp'
|
||||
import matter from 'gray-matter'
|
||||
|
||||
import { updateContentDirectory } from '../lib/update-markdown.js'
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
import nock from 'nock'
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import { getChangelogItems } from '#src/changelogs/lib/changelog.js'
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, expect, test } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import {
|
||||
getComponentTheme,
|
||||
getCssTheme,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
|
||||
import walk from 'walk-sync'
|
||||
import { zip, difference } from 'lodash-es'
|
||||
import GithubSlugger from 'github-slugger'
|
||||
import { decode } from 'html-entities'
|
||||
import { beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import matter from '#src/frame/lib/read-frontmatter.js'
|
||||
import { renderContent } from '#src/content-render/index.js'
|
||||
@@ -33,10 +35,13 @@ describe('category pages', () => {
|
||||
const productIndices = walk(contentDir, walkOptions)
|
||||
const productNames = productIndices.map((index) => path.basename(path.dirname(index)))
|
||||
|
||||
// Combine those to fit Jest's `.each` usage
|
||||
// Combine those to fit vitest's `.each` usage
|
||||
const productTuples = zip(productNames, productIndices)
|
||||
|
||||
describe.each(productTuples)('product "%s"', (productName, productIndex) => {
|
||||
// Use a regular forEach loop to generate the `describe(...)` blocks
|
||||
// otherwise, if one of them has no categories, the tests will fail.
|
||||
productTuples.forEach((tuple) => {
|
||||
const [, productIndex] = tuple
|
||||
// Get links included in product index page.
|
||||
// Each link corresponds to a product subdirectory (category).
|
||||
// Example: "getting-started-with-github"
|
||||
@@ -48,7 +53,7 @@ describe('category pages', () => {
|
||||
const categoryLinks = data.children
|
||||
// Only include category directories, not standalone category files like content/actions/quickstart.md
|
||||
.filter((link) => fs.existsSync(getPath(productDir, link, 'index')))
|
||||
// TODO this should move to async, but you can't asynchronously define tests with Jest...
|
||||
// TODO this should move to async, but you can't asynchronously define tests with vitest...
|
||||
|
||||
// Map those to the Markdown file paths that represent that category page index
|
||||
const categoryPaths = categoryLinks.map((link) => getPath(productDir, link, 'index'))
|
||||
@@ -56,11 +61,9 @@ describe('category pages', () => {
|
||||
// Make them relative for nicer display in test names
|
||||
const categoryRelativePaths = categoryPaths.map((p) => path.relative(contentDir, p))
|
||||
|
||||
// Combine those to fit Jest's `.each` usage
|
||||
// Combine those to fit vitests's `.each` usage
|
||||
const categoryTuples = zip(categoryRelativePaths, categoryPaths, categoryLinks)
|
||||
|
||||
if (!categoryTuples.length) return
|
||||
|
||||
describe.each(categoryTuples)(
|
||||
'category index "%s"',
|
||||
(indexRelPath, indexAbsPath, indexLink) => {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import yaml from 'js-yaml'
|
||||
import { readFile } from 'fs/promises'
|
||||
|
||||
import walk from 'walk-sync'
|
||||
import { beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import { liquid } from '#src/content-render/index.js'
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { fileURLToPath } from 'url'
|
||||
import path from 'path'
|
||||
import yaml from 'js-yaml'
|
||||
import fs from 'fs/promises'
|
||||
|
||||
import slash from 'slash'
|
||||
import walk from 'walk-sync'
|
||||
import { zip } from 'lodash-es'
|
||||
import yaml from 'js-yaml'
|
||||
import fs from 'fs/promises'
|
||||
import { beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import languages from '#src/languages/lib/languages.js'
|
||||
import { getDiffFiles } from '../lib/diff-files.js'
|
||||
@@ -235,198 +237,198 @@ if (ymlToLint.length === 0) {
|
||||
describe('deliberately do nothing', () => {
|
||||
test('void', () => {})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
describe('lint yaml content', () => {
|
||||
if (ymlToLint.length < 1) return
|
||||
describe.each(ymlToLint)('%s', (yamlRelPath, yamlAbsPath) => {
|
||||
let dictionary, isEarlyAccess, fileContents
|
||||
// This variable is used to determine if the file was parsed successfully.
|
||||
// When `yaml.load()` fails to parse the file, it is overwritten with the error message.
|
||||
// `false` is intentionally chosen since `null` and `undefined` are valid return values.
|
||||
let dictionaryError = false
|
||||
|
||||
describe('lint yaml content', () => {
|
||||
if (ymlToLint.length < 1) return
|
||||
describe.each(ymlToLint)('%s', (yamlRelPath, yamlAbsPath) => {
|
||||
let dictionary, isEarlyAccess, fileContents
|
||||
// This variable is used to determine if the file was parsed successfully.
|
||||
// When `yaml.load()` fails to parse the file, it is overwritten with the error message.
|
||||
// `false` is intentionally chosen since `null` and `undefined` are valid return values.
|
||||
let dictionaryError = false
|
||||
beforeAll(async () => {
|
||||
fileContents = await fs.readFile(yamlAbsPath, 'utf8')
|
||||
try {
|
||||
dictionary = yaml.load(fileContents, { filename: yamlRelPath })
|
||||
} catch (error) {
|
||||
dictionaryError = error
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
fileContents = await fs.readFile(yamlAbsPath, 'utf8')
|
||||
try {
|
||||
dictionary = yaml.load(fileContents, { filename: yamlRelPath })
|
||||
} catch (error) {
|
||||
dictionaryError = error
|
||||
}
|
||||
isEarlyAccess = yamlRelPath.split('/').includes('early-access')
|
||||
})
|
||||
|
||||
isEarlyAccess = yamlRelPath.split('/').includes('early-access')
|
||||
})
|
||||
test('it can be parsed as a single yaml document', () => {
|
||||
expect(dictionaryError).toBe(false)
|
||||
})
|
||||
|
||||
test('it can be parsed as a single yaml document', () => {
|
||||
expect(dictionaryError).toBe(false)
|
||||
})
|
||||
|
||||
test('placeholder string is not present in any yaml files', () => {
|
||||
const matches = fileContents.match(placeholderRegex) || []
|
||||
const errorMessage = `
|
||||
test('placeholder string is not present in any yaml files', () => {
|
||||
const matches = fileContents.match(placeholderRegex) || []
|
||||
const errorMessage = `
|
||||
Found ${matches.length} placeholder string '${placeholder}'! Please update all placeholders.
|
||||
`
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
||||
test('relative URLs must start with "/"', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(relativeArticleLinkRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(relativeArticleLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
||||
test('must not leak Early Access doc URLs', async () => {
|
||||
// Only execute for docs that are NOT Early Access
|
||||
if (!isEarlyAccess) {
|
||||
test('relative URLs must start with "/"', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(earlyAccessLinkRegex) || []
|
||||
const valMatches = contentStr.match(relativeArticleLinkRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(earlyAccessLinkErrorText, matches)
|
||||
const errorMessage = formatLinkError(relativeArticleLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('must not leak Early Access image URLs', async () => {
|
||||
// Only execute for docs that are NOT Early Access
|
||||
if (!isEarlyAccess) {
|
||||
test('must not leak Early Access doc URLs', async () => {
|
||||
// Only execute for docs that are NOT Early Access
|
||||
if (!isEarlyAccess) {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(earlyAccessLinkRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(earlyAccessLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
}
|
||||
})
|
||||
|
||||
test('must not leak Early Access image URLs', async () => {
|
||||
// Only execute for docs that are NOT Early Access
|
||||
if (!isEarlyAccess) {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(earlyAccessImageRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(earlyAccessImageErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
}
|
||||
})
|
||||
|
||||
test('must have correctly formatted Early Access image URLs', async () => {
|
||||
// Execute for ALL docs (not just Early Access) to ensure non-EA docs
|
||||
// are not leaking incorrectly formatted EA image URLs
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(earlyAccessImageRegex) || []
|
||||
const valMatches = contentStr.match(badEarlyAccessImageRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(earlyAccessImageErrorText, matches)
|
||||
const errorMessage = formatLinkError(badEarlyAccessImageErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
test('must have correctly formatted Early Access image URLs', async () => {
|
||||
// Execute for ALL docs (not just Early Access) to ensure non-EA docs
|
||||
// are not leaking incorrectly formatted EA image URLs
|
||||
const matches = []
|
||||
test('URLs must not contain a hard-coded language code', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(badEarlyAccessImageRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(languageLinkRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(badEarlyAccessImageErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
const errorMessage = formatLinkError(languageLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
||||
test('URLs must not contain a hard-coded language code', async () => {
|
||||
const matches = []
|
||||
test('URLs must not contain a hard-coded version number', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(languageLinkRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(versionLinkRegEx) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(languageLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
const errorMessage = formatLinkError(versionLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
||||
test('URLs must not contain a hard-coded version number', async () => {
|
||||
const matches = []
|
||||
test('URLs must not contain a hard-coded domain name', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(versionLinkRegEx) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(domainLinkRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(versionLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
const errorMessage = formatLinkError(domainLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
||||
test('URLs must not contain a hard-coded domain name', async () => {
|
||||
const matches = []
|
||||
test('does not use old site.data variable syntax', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(domainLinkRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(oldVariableRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(
|
||||
...valMatches.map((match) => {
|
||||
const example = match.replace(
|
||||
/{{\s*?site\.data\.([a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]+)+)\s*?}}/g,
|
||||
'{% data $1 %}',
|
||||
)
|
||||
return `Key "${key}": ${match} => ${example}`
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(domainLinkErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
const errorMessage = formatLinkError(oldVariableErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
||||
test('does not use old site.data variable syntax', async () => {
|
||||
const matches = []
|
||||
test('does not use old octicon variable syntax', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(oldVariableRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(
|
||||
...valMatches.map((match) => {
|
||||
const example = match.replace(
|
||||
/{{\s*?site\.data\.([a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]+)+)\s*?}}/g,
|
||||
'{% data $1 %}',
|
||||
)
|
||||
return `Key "${key}": ${match} => ${example}`
|
||||
}),
|
||||
)
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(oldOcticonRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(oldVariableErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
|
||||
test('does not use old octicon variable syntax', async () => {
|
||||
const matches = []
|
||||
|
||||
for (const [key, content] of Object.entries(dictionary)) {
|
||||
const contentStr = getContent(content)
|
||||
if (!contentStr) continue
|
||||
const valMatches = contentStr.match(oldOcticonRegex) || []
|
||||
if (valMatches.length > 0) {
|
||||
matches.push(...valMatches.map((match) => `Key "${key}": ${match}`))
|
||||
}
|
||||
}
|
||||
|
||||
const errorMessage = formatLinkError(oldOcticonErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
const errorMessage = formatLinkError(oldOcticonErrorText, matches)
|
||||
expect(matches.length, errorMessage).toBe(0)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { loadPages, loadPageMap } from '#src/frame/lib/page-data.js'
|
||||
import loadRedirects from '#src/redirects/lib/precompile.js'
|
||||
import { checkURL } from '#src/tests/helpers/check-url.js'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import path from 'path'
|
||||
import { isEqual, uniqWith } from 'lodash-es'
|
||||
import { jest } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import patterns from '#src/frame/lib/patterns.js'
|
||||
import { getDataByLanguage, getDeepDataByLanguage } from '#src/data-directory/lib/get-data.js'
|
||||
@@ -30,7 +30,7 @@ const getDataReferences = (content) => {
|
||||
}
|
||||
|
||||
describe('data references', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test('every data reference found in English variable files is defined and has a value', async () => {
|
||||
let errors = []
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { codeAnnotations } from '../../lib/linting-rules/code-annotations.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { codeFenceLineLength } from '../../lib/linting-rules/code-fence-line-length.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import {
|
||||
earlyAccessReferences,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import {
|
||||
expiredContent,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { frontmatterHiddenDocs } from '../../lib/linting-rules/frontmatter-hidden-docs.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { frontmatterSchema } from '../../lib/linting-rules/frontmatter-schema.js'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { frontmatterVideoTranscripts } from '../../lib/linting-rules/frontmatter-video-transcripts.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { githubOwnedActionReferences } from '../../lib/linting-rules/github-owned-action-references.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { hardcodedDataVariable } from '../../lib/linting-rules/hardcoded-data-variable.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { imageAltTextEndPunctuation } from '../../lib/linting-rules/image-alt-text-end-punctuation.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { imageAltTextExcludeStartWords } from '../../lib/linting-rules/image-alt-text-exclude-start-words.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { incorrectAltTextLength } from '../../lib/linting-rules/image-alt-text-length.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { imageFileKebabCase } from '../../lib/linting-rules/image-file-kebab-case.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { imageNoGif } from '../../lib/linting-rules/image-no-gif.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { internalLinksNoLang } from '../../lib/linting-rules/internal-links-no-lang.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { internalLinksOldVersion } from '../../lib/linting-rules/internal-links-old-version.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { internalLinksSlash } from '../../lib/linting-rules/internal-links-slash.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { linkPunctuation } from '../../lib/linting-rules/link-punctuation.js'
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import path from 'path'
|
||||
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import {
|
||||
liquidDataReferencesDefined,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import {
|
||||
liquidIfVersionVersions,
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { liquidQuotedConditionalArg } from '../../lib/linting-rules/liquid-quoted-conditional-arg.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { frontmatterLiquidSyntax, liquidSyntax } from '../../lib/linting-rules/liquid-syntax.js'
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import path from 'path'
|
||||
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { liquidIfTags, liquidIfVersionTags } from '../../lib/linting-rules/liquid-versioning.js'
|
||||
import { nextNext } from '#src/versions/lib/enterprise-server-releases.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { listFirstWordCapitalization } from '../../lib/linting-rules/list-first-word-capitalization.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { raiReusableUsage } from '../../lib/linting-rules/rai-reusable-usage.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import searchReplace from 'markdownlint-rule-search-replace'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { runRule } from '../../lib/init-test.js'
|
||||
import { yamlScheduledJobs } from '../../lib/linting-rules/yaml-scheduled-jobs.js'
|
||||
|
||||
|
||||
@@ -1,4 +1,27 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
||||
|
||||
exports[`annotate > renders annotations 1`] = `
|
||||
"<div class="annotate beside"><div class="annotate-header"><header class="d-flex flex-items-center flex-justify-between p-2 text-small rounded-top-1 border-top border-left border-right"><span class="flex-1">YAML</span><div class="BtnGroup"><button name="annotate-display" value="beside" type="button" class="BtnGroup-item btn btn-sm">Beside</button><button name="annotate-display" value="inline" type="button" class="BtnGroup-item btn btn-sm">Inline</button></div><button class="js-btn-copy btn btn-sm tooltipped tooltipped-nw" aria-label="Copy YAML code to clipboard" data-clipboard="1746955726" aria-live="polite" aria-atomic="true"><svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-copy" aria-hidden="true"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><pre hidden data-clipboard="1746955726"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.
|
||||
name: Post welcome comment
|
||||
|
||||
# Add the \`pull_request\` event, so that the workflow runs automatically
|
||||
# every time a pull request is created.
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened]
|
||||
</pre></header></div><div class="annotate-beside"><div class="annotate-row"><div class="annotate-code"><pre><code class="hljs language-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Post</span> <span class="hljs-string">welcome</span> <span class="hljs-string">comment</span></code></pre></div><div class="annotate-note"><p>The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.</p></div></div><div class="annotate-row"><div class="annotate-code"><pre><code class="hljs language-yaml"><span class="hljs-attr">on:</span>
|
||||
<span class="hljs-attr">pull_request:</span>
|
||||
<span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>]</code></pre></div><div class="annotate-note"><p>Add the <code>pull_request</code> event, so that the workflow runs automatically
|
||||
every time a pull request is created.</p></div></div></div><div class="annotate-inline"><pre><code class="hljs language-yaml"><span class="hljs-comment"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.</span>
|
||||
<span class="hljs-attr">name:</span> <span class="hljs-string">Post</span> <span class="hljs-string">welcome</span> <span class="hljs-string">comment</span>
|
||||
|
||||
<span class="hljs-comment"># Add the \`pull_request\` event, so that the workflow runs automatically</span>
|
||||
<span class="hljs-comment"># every time a pull request is created.</span>
|
||||
<span class="hljs-attr">on:</span>
|
||||
<span class="hljs-attr">pull_request:</span>
|
||||
<span class="hljs-attr">types:</span> [<span class="hljs-string">opened</span>]
|
||||
</code></pre></div></div>"
|
||||
`;
|
||||
|
||||
exports[`annotate renders annotations 1`] = `
|
||||
"<div class="annotate beside"><div class="annotate-header"><header class="d-flex flex-items-center flex-justify-between p-2 text-small rounded-top-1 border-top border-left border-right"><span class="flex-1">YAML</span><div class="BtnGroup"><button name="annotate-display" value="beside" type="button" class="BtnGroup-item btn btn-sm">Beside</button><button name="annotate-display" value="inline" type="button" class="BtnGroup-item btn btn-sm">Inline</button></div><button class="js-btn-copy btn btn-sm tooltipped tooltipped-nw" aria-label="Copy YAML code to clipboard" data-clipboard="1746955726" aria-live="polite" aria-atomic="true"><svg version="1.1" width="16" height="16" viewBox="0 0 16 16" class="octicon octicon-copy" aria-hidden="true"><path d="M0 6.75C0 5.784.784 5 1.75 5h1.5a.75.75 0 0 1 0 1.5h-1.5a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-1.5a.75.75 0 0 1 1.5 0v1.5A1.75 1.75 0 0 1 9.25 16h-7.5A1.75 1.75 0 0 1 0 14.25Z"></path><path d="M5 1.75C5 .784 5.784 0 6.75 0h7.5C15.216 0 16 .784 16 1.75v7.5A1.75 1.75 0 0 1 14.25 11h-7.5A1.75 1.75 0 0 1 5 9.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h7.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"></path></svg></button><pre hidden data-clipboard="1746955726"># The name of the workflow as it will appear in the "Actions" tab of the GitHub repository.
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import cheerio from 'cheerio'
|
||||
|
||||
import { renderContent } from '#src/content-render/index.js'
|
||||
|
||||
const example = `
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { afterAll, beforeAll, expect, describe } from '@jest/globals'
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import Page from '#src/frame/lib/page.js'
|
||||
import languages from '#src/languages/lib/languages.js'
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { afterAll, jest, beforeAll, expect } from '@jest/globals'
|
||||
import { afterAll, beforeAll, describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { liquid } from '#src/content-render/index.js'
|
||||
import languages from '#src/languages/lib/languages.js'
|
||||
import { DataDirectory } from '#src/tests/helpers/data-directory.js'
|
||||
|
||||
describe('liquid helper tags', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
const context = {}
|
||||
let dd
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { jest } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { liquid } from '#src/content-render/index.js'
|
||||
import shortVersionsMiddleware from '#src/versions/middleware/short-versions.js'
|
||||
@@ -43,7 +43,7 @@ const contextualize = (req) => {
|
||||
}
|
||||
|
||||
describe('liquid template parser', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
describe('short versions', () => {
|
||||
// Create a fake req so we can test the shortVersions middleware
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { renderContent } from '#src/content-render/index.js'
|
||||
|
||||
describe('octicon tag', () => {
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
import path from 'path'
|
||||
|
||||
import { jest } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { head, get } from '#src/tests/helpers/e2etest.js'
|
||||
import { loadPages } from '#src/frame/lib/page-data.js'
|
||||
@@ -62,7 +62,7 @@ function getContentFiles(spaceSeparatedList) {
|
||||
// It can also happen if some of the pages involves are infamously slow.
|
||||
// For example guide pages because they involved a lot of processing
|
||||
// to gather and preview linked data.
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
describe('changed-content', () => {
|
||||
const changedContentFiles = getChangedContentFiles()
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import cheerio from 'cheerio'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { renderContent } from '#src/content-render/index.js'
|
||||
import { EOL } from 'os'
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { beforeAll } from '@jest/globals'
|
||||
import yaml from 'js-yaml'
|
||||
import { readFileSync } from 'fs'
|
||||
import walk from 'walk-sync'
|
||||
import { extname, basename } from 'path'
|
||||
|
||||
import walk from 'walk-sync'
|
||||
import { beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import { getJsonValidator, validateJson } from '#src/tests/lib/validate-json-schema.js'
|
||||
import { formatAjvErrors } from '#src/tests/helpers/schemas.js'
|
||||
import dataSchemas from '#src/data-directory/lib/data-schemas/index.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import filenameToKey from '#src/data-directory/lib/filename-to-key.js'
|
||||
|
||||
describe('filename-to-key', () => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
|
||||
import { expect, test, describe, beforeAll, afterAll } from '@jest/globals'
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'vitest'
|
||||
|
||||
import languages from '#src/languages/lib/languages.js'
|
||||
import {
|
||||
@@ -14,7 +14,7 @@ import { DataDirectory } from '#src/tests/helpers/data-directory.js'
|
||||
describe('get-data', () => {
|
||||
let dd
|
||||
const enDirBefore = languages.en.dir
|
||||
// Only `en` is available in jest tests, so pretend we also have Japanese
|
||||
// Only `en` is available in tests, so pretend we also have Japanese
|
||||
languages.ja = Object.assign({}, languages.en, {})
|
||||
|
||||
beforeAll(() => {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import { fileURLToPath } from 'url'
|
||||
import path from 'path'
|
||||
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import dataDirectory from '#src/data-directory/lib/data-directory.js'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const fixturesDir = path.join(__dirname, 'fixtures')
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { stat } from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
import { expect } from '@jest/globals'
|
||||
import { describe, expect } from 'vitest'
|
||||
|
||||
import { testViaActionsOnly } from '#src/tests/helpers/conditional-runs.js'
|
||||
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect, jest, test } from '@jest/globals'
|
||||
import { expect, test, vi } from 'vitest'
|
||||
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
import { describeIfDocsEarlyAccess } from '#src/tests/helpers/conditional-runs.js'
|
||||
@@ -7,7 +7,7 @@ import languages from '#src/languages/lib/languages.js'
|
||||
const VALID_EARLY_ACCESS_URI = '/early-access/github/save-time-with-slash-commands'
|
||||
|
||||
describeIfDocsEarlyAccess('early access rendering', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test('viewing landing page', async () => {
|
||||
const res = await get('/en/early-access')
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { afterEach } from '@jest/globals'
|
||||
import { afterEach, describe, expect, test } from 'vitest'
|
||||
|
||||
import nock from 'nock'
|
||||
import { publish } from '../lib/hydro.js'
|
||||
|
||||
|
||||
@@ -1,19 +1,20 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { validateJson } from '#src/tests/lib/validate-json-schema.js'
|
||||
import { formatErrors } from '../lib/middleware-errors.js'
|
||||
import { schemas } from '../lib/schema.js'
|
||||
|
||||
expect.extend({
|
||||
toMatchSchema(data, schema) {
|
||||
const { isValid, errors } = validateJson(schema, data)
|
||||
return {
|
||||
pass: isValid,
|
||||
message: () => (isValid ? '' : errors.message),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
describe('formatErrors', () => {
|
||||
test('should produce objects that match the validation spec', () => {
|
||||
expect.extend({
|
||||
toMatchSchema(data, schema) {
|
||||
const { isValid, errors } = validateJson(schema, data)
|
||||
return {
|
||||
pass: isValid,
|
||||
message: () => (isValid ? '' : errors.message),
|
||||
}
|
||||
},
|
||||
})
|
||||
// Produce an error
|
||||
const { errors } = validateJson({ type: 'string' }, 0)
|
||||
const formattedErrors = formatErrors(errors, '')
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { expect, jest } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { post } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('POST /events', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
async function checkEvent(data) {
|
||||
const body = JSON.stringify(data)
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { parseUserAgent } from '../components/user-agent.ts'
|
||||
|
||||
describe('parseUserAgent', () => {
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
There are currently 3 general automated tests:
|
||||
|
||||
1. `jest` tests against real English content (and some code)
|
||||
1. `jest` tests against fixture content
|
||||
1. `vitest` tests against real English content (and some code)
|
||||
1. `vitest` tests against fixture content
|
||||
1. `playwright` tests against fixture content (What this document is about!)
|
||||
|
||||
## Quickstart
|
||||
|
||||
Just like with regular `jest` tests, if you haven't already done so...
|
||||
Just like with regular `vitest` tests, if you haven't already done so...
|
||||
|
||||
```shell
|
||||
npm run build
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('annotations', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { head } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('bad URLs', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('breadcrumbs', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM, head } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('map topics', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
import nonEnterpriseDefaultVersion from '#src/versions/lib/non-enterprise-default-version.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('glossary', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { get, getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('guides', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('<head>', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import sharp from 'sharp'
|
||||
|
||||
import { get, head, getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { get, getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
|
||||
import { allVersions } from '#src/versions/lib/all-versions.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('product landing page', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDataByLanguage } from '#src/data-directory/lib/get-data.js'
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
import { supported } from '#src/versions/lib/enterprise-server-releases.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('markdown rendering', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('permission statements', () => {
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOMCached as getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('sidebar', () => {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { TRANSLATIONS_FIXTURE_ROOT } from '#src/frame/lib/constants.js'
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM, head } from '#src/tests/helpers/e2etest.js'
|
||||
import { supported } from '#src/versions/lib/enterprise-server-releases.js'
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { describe } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { getDOM } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { expect, jest, test } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { get } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('general /api pages', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test("any /api URL that isn't found should JSON", async () => {
|
||||
const res = await get('/api')
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import { blockIndex } from '#src/frame/middleware/block-robots.js'
|
||||
import { productMap } from '#src/products/lib/all-products.js'
|
||||
import enterpriseServerReleases from '#src/versions/lib/enterprise-server-releases.js'
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import path from 'path'
|
||||
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import walk from 'walk-sync'
|
||||
|
||||
import createTree from '#src/frame/lib/create-tree.js'
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { expect, jest } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.js'
|
||||
import { get } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('favicon assets', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test('should serve a valid and aggressively caching /favicon.ico', async () => {
|
||||
const res = await get('/favicon.ico')
|
||||
|
||||
@@ -2,7 +2,7 @@ import { fileURLToPath } from 'url'
|
||||
import path from 'path'
|
||||
import http from 'http'
|
||||
|
||||
import { expect, describe, test } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import Page from '#src/frame/lib/page.js'
|
||||
import findPage from '#src/frame/middleware/find-page.js'
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { jest } from '@jest/globals'
|
||||
import { fileURLToPath } from 'url'
|
||||
import path from 'path'
|
||||
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import Page from '#src/frame/lib/page.js'
|
||||
import findPage from '#src/frame/lib/find-page.js'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
describe('find page', () => {
|
||||
jest.setTimeout(1000 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test('follows redirects', async () => {
|
||||
const page = await Page.init({
|
||||
|
||||
@@ -3,8 +3,9 @@ import path from 'path'
|
||||
import os from 'os'
|
||||
|
||||
import { rimraf } from 'rimraf'
|
||||
import { expect, test, describe, beforeAll, afterAll } from '@jest/globals'
|
||||
import { afterAll, afterEach, beforeAll, describe, expect, test } from 'vitest'
|
||||
import nock from 'nock'
|
||||
|
||||
import getRemoteJSON, { cache } from '#src/frame/lib/get-remote-json.js'
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import fs from 'fs/promises'
|
||||
import path from 'path'
|
||||
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
const gitignorePath = path.join(process.cwd(), '.gitignore')
|
||||
const gitignore = await fs.readFile(gitignorePath, 'utf8')
|
||||
const entries = gitignore.split(/\r?\n/)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import sharp from 'sharp'
|
||||
|
||||
import { SURROGATE_ENUMS } from '#src/frame/middleware/set-fastly-surrogate-key.js'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { expect } from '@jest/globals'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
|
||||
import getMiniTocItems from '#src/frame/lib/get-mini-toc-items'
|
||||
|
||||
function generateHeading(h) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, expect, jest, test } from '@jest/globals'
|
||||
import { describe, expect, test, vi } from 'vitest'
|
||||
|
||||
import { get } from '#src/tests/helpers/e2etest.js'
|
||||
|
||||
describe('bad requests', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
test('any _next/image request should 404', async () => {
|
||||
const res = await get('/_next/image?what=ever')
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { fileURLToPath } from 'url'
|
||||
import path from 'path'
|
||||
|
||||
import cheerio from 'cheerio'
|
||||
import { describe, expect } from '@jest/globals'
|
||||
import { beforeAll, beforeEach, describe, expect, test } from 'vitest'
|
||||
|
||||
import Page, { FrontmatterErrorsError } from '#src/frame/lib/page.js'
|
||||
import { allVersions } from '#src/versions/lib/all-versions.js'
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
import { jest } from '@jest/globals'
|
||||
import path from 'path'
|
||||
|
||||
import { beforeAll, describe, expect, test, vi } from 'vitest'
|
||||
import GithubSlugger from 'github-slugger'
|
||||
import { decode } from 'html-entities'
|
||||
import { chain, pick } from 'lodash-es'
|
||||
|
||||
import { loadPages } from '#src/frame/lib/page-data.js'
|
||||
import libLanguages from '#src/languages/lib/languages.js'
|
||||
import { liquid } from '#src/content-render/index.js'
|
||||
import patterns from '#src/frame/lib/patterns.js'
|
||||
import GithubSlugger from 'github-slugger'
|
||||
import { decode } from 'html-entities'
|
||||
import { chain, pick } from 'lodash-es'
|
||||
import removeFPTFromPath from '#src/versions/lib/remove-fpt-from-path.js'
|
||||
|
||||
const languageCodes = Object.keys(libLanguages)
|
||||
const slugger = new GithubSlugger()
|
||||
|
||||
describe('pages module', () => {
|
||||
jest.setTimeout(60 * 1000)
|
||||
vi.setConfig({ testTimeout: 60 * 1000 })
|
||||
|
||||
let pages
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user