04bad16bf4
### What? see https://github.com/vercel/turbo/pull/6160 ### Turbopack Changes * https://github.com/vercel/turbo/pull/6116 * https://github.com/vercel/turbo/pull/6140 * https://github.com/vercel/turbo/pull/6118 * https://github.com/vercel/turbo/pull/6128 * https://github.com/vercel/turbo/pull/6129 * https://github.com/vercel/turbo/pull/6160 Closes WEB-1772 Co-authored-by: Justin Ridgewell <112982+jridgewell@users.noreply.github.com>
225 lines
8.4 KiB
JavaScript
225 lines
8.4 KiB
JavaScript
const fetch = require('node-fetch')
|
|
const fs = require('fs')
|
|
const prettier = require('prettier')
|
|
|
|
async function format(text) {
|
|
const options = await prettier.resolveConfig(__filename)
|
|
return prettier.format(text, { ...options, parser: 'json' })
|
|
}
|
|
|
|
const override = process.argv.includes('--override')
|
|
|
|
const RESULT_URL =
|
|
'https://raw.githubusercontent.com/vercel/turbo/nextjs-integration-test-data/test-results/main/nextjs-test-results.json'
|
|
const PASSING_JSON_PATH = `${__dirname}/turbopack-tests-manifest.json`
|
|
const WORKING_PATH = '/home/runner/work/turbo/turbo/'
|
|
|
|
const INITIALIZING_TEST_CASES = [
|
|
'compile successfully',
|
|
'should build successfully',
|
|
]
|
|
|
|
// please make sure this is sorted alphabetically when making changes.
|
|
const SKIPPED_TEST_SUITES = {
|
|
'test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts': [
|
|
'ReactRefreshLogBox app turbo Module not found missing global CSS',
|
|
],
|
|
'test/development/acceptance-app/ReactRefreshRegression.test.ts': [
|
|
'ReactRefreshRegression app can fast refresh a page with dynamic rendering',
|
|
'ReactRefreshRegression app can fast refresh a page with config',
|
|
],
|
|
'test/development/acceptance-app/ReactRefreshRequire.test.ts': [
|
|
'ReactRefreshRequire app re-runs accepted modules',
|
|
'ReactRefreshRequire app propagates a hot update to closest accepted module',
|
|
'ReactRefreshRequire app propagates hot update to all inverse dependencies',
|
|
],
|
|
'test/development/acceptance/ReactRefreshRequire.test.ts': [
|
|
'ReactRefreshRequire re-runs accepted modules',
|
|
'ReactRefreshRequire propagates a hot update to closest accepted module',
|
|
'ReactRefreshRequire propagates hot update to all inverse dependencies',
|
|
],
|
|
'test/development/jsconfig-path-reloading/index.test.ts': [
|
|
/should automatically fast refresh content when path is added without error/,
|
|
/should recover from module not found when paths is updated/,
|
|
],
|
|
'test/development/tsconfig-path-reloading/index.test.ts': [
|
|
/should automatically fast refresh content when path is added without error/,
|
|
],
|
|
'test/e2e/basepath.test.ts': [
|
|
'basePath should 404 when manually adding basePath with router.push',
|
|
'basePath should 404 when manually adding basePath with router.replace',
|
|
],
|
|
'test/e2e/middleware-rewrites/test/index.test.ts': [
|
|
'Middleware Rewrite should have props for afterFiles rewrite to SSG page',
|
|
],
|
|
'test/integration/absolute-assetprefix/test/index.test.js': [
|
|
'absolute assetPrefix with path prefix should work with getStaticPaths prerendered',
|
|
],
|
|
'test/integration/app-document-remove-hmr/test/index.test.js': [
|
|
'_app removal HMR should HMR when _document is removed',
|
|
],
|
|
'test/integration/create-next-app/package-manager.test.ts': [
|
|
'should use pnpm as the package manager on supplying --use-pnpm',
|
|
'should use pnpm as the package manager on supplying --use-pnpm with example',
|
|
'should infer pnpm as the package manager',
|
|
'should infer pnpm as the package manager with example',
|
|
],
|
|
'test/integration/css/test/css-modules.test.js': [
|
|
'CSS Modules Composes Ordering Development Mode should have correct color on index page (on nav from other)',
|
|
'CSS Modules Composes Ordering Development Mode should have correct color on index page (on nav from index)',
|
|
],
|
|
'test/integration/custom-error/test/index.test.js': [/Custom _error/],
|
|
'test/integration/dynamic-routing/test/index.test.js': [
|
|
'Dynamic Routing production mode should have correct cache entries on prefetch',
|
|
'Dynamic Routing production mode should render dynamic route with query',
|
|
],
|
|
'test/integration/dynamic-routing/test/middleware.test.js': [
|
|
'Dynamic Routing dev mode should resolve dynamic route href for page added later',
|
|
'Dynamic Routing production mode should output a routes-manifest correctly',
|
|
],
|
|
'test/integration/import-assertion/test/index.test.js': [
|
|
/should handle json assertions/,
|
|
],
|
|
'test/integration/trailing-slashes/test/index.test.js': [
|
|
'Trailing slashes dev mode, with basepath, trailingSlash: true /docs/linker?href=/ should navigate to /docs/',
|
|
'Trailing slashes dev mode, with basepath, trailingSlash: true /docs/linker?href=/ should push route to /docs/',
|
|
],
|
|
'test/integration/env-config/test/index.test.js': [
|
|
'Env Config dev mode with hot reload should provide env for SSG',
|
|
'Env Config dev mode with hot reload should provide env correctly for SSR',
|
|
'Env Config dev mode with hot reload should provide env correctly for API routes',
|
|
],
|
|
'test/integration/app-document/test/index.test.js': [
|
|
'Document and App Client side should detect the changes to pages/_document.js and display it',
|
|
],
|
|
'test/development/basic/hmr.test.ts': [
|
|
'basic HMR, basePath: "/docs" Error Recovery should show the error on all pages',
|
|
],
|
|
}
|
|
|
|
async function updatePassingTests() {
|
|
const passing = { __proto__: null }
|
|
const res = await fetch(RESULT_URL)
|
|
const results = await res.json()
|
|
|
|
for (const result of results.result) {
|
|
const runtimeError = result.data.numRuntimeErrorTestSuites > 0
|
|
for (const testResult of result.data.testResults) {
|
|
const filepath = stripWorkingPath(testResult.name)
|
|
|
|
const fileResults = (passing[filepath] ??= {
|
|
passed: [],
|
|
failed: [],
|
|
pending: [],
|
|
flakey: [],
|
|
runtimeError,
|
|
})
|
|
const skips = SKIPPED_TEST_SUITES[filepath] ?? []
|
|
|
|
let initializationFailed = false
|
|
for (const testCase of testResult.assertionResults) {
|
|
let { fullName, status } = testCase
|
|
|
|
if (
|
|
status === 'failed' &&
|
|
INITIALIZING_TEST_CASES.some((name) => fullName.includes(name))
|
|
) {
|
|
initializationFailed = true
|
|
} else if (initializationFailed) {
|
|
status = 'failed'
|
|
}
|
|
if (shouldSkip(fullName, skips)) {
|
|
status = 'flakey'
|
|
}
|
|
|
|
const statusArray = fileResults[status]
|
|
if (!statusArray) {
|
|
throw new Error(`unexpected status "${status}"`)
|
|
}
|
|
statusArray.push(fullName)
|
|
}
|
|
}
|
|
}
|
|
|
|
for (const info of Object.values(passing)) {
|
|
info.failed = [...new Set(info.failed)].sort()
|
|
info.pending = [...new Set(info.pending)].sort()
|
|
info.flakey = [...new Set(info.flakey)].sort()
|
|
info.passed = [
|
|
...new Set(info.passed.filter((name) => !info.failed.includes(name))),
|
|
].sort()
|
|
}
|
|
|
|
if (!override) {
|
|
const oldPassingData = JSON.parse(
|
|
fs.readFileSync(PASSING_JSON_PATH, 'utf8')
|
|
)
|
|
|
|
for (const file of Object.keys(oldPassingData)) {
|
|
const newData = passing[file]
|
|
const oldData = oldPassingData[file]
|
|
if (!newData) continue
|
|
|
|
// We want to find old passing tests that are now failing, and report them.
|
|
// Tests are allowed transition to skipped or flakey.
|
|
const shouldPass = new Set(
|
|
oldData.passed.filter((name) => newData.failed.includes(name))
|
|
)
|
|
if (shouldPass.size > 0) {
|
|
const list = JSON.stringify([...shouldPass], 0, 2)
|
|
console.log(
|
|
`${file} has ${shouldPass.size} test(s) that should pass but failed: ${list}`
|
|
)
|
|
}
|
|
// Merge the old passing tests with the new ones
|
|
newData.passed = [...new Set([...shouldPass, ...newData.passed])].sort()
|
|
// but remove them also from the failed list
|
|
newData.failed = newData.failed
|
|
.filter((name) => !shouldPass.has(name))
|
|
.sort()
|
|
|
|
if (!oldData.runtimeError && newData.runtimeError) {
|
|
console.log(`${file} has a runtime error that is shouldn't have`)
|
|
newData.runtimeError = false
|
|
}
|
|
}
|
|
}
|
|
|
|
// JS keys are ordered, this ensures the tests are written in a consistent order
|
|
// https://stackoverflow.com/questions/5467129/sort-javascript-object-by-key
|
|
const ordered = Object.keys(passing)
|
|
.sort()
|
|
.reduce((obj, key) => {
|
|
obj[key] = passing[key]
|
|
return obj
|
|
}, {})
|
|
|
|
fs.writeFileSync(
|
|
PASSING_JSON_PATH,
|
|
await format(JSON.stringify(ordered, null, 2))
|
|
)
|
|
}
|
|
|
|
function shouldSkip(name, skips) {
|
|
for (const skip of skips) {
|
|
if (typeof skip === 'string') {
|
|
// exact match
|
|
if (name === skip) return true
|
|
} else {
|
|
// regex
|
|
if (skip.test(name)) return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
function stripWorkingPath(path) {
|
|
if (!path.startsWith(WORKING_PATH)) {
|
|
throw new Error(
|
|
`found unexpected working path in "${path}", expected it to begin with ${WORKING_PATH}`
|
|
)
|
|
}
|
|
return path.slice(WORKING_PATH.length)
|
|
}
|
|
|
|
updatePassingTests()
|