mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
test: rework tests using @nuxt/test-utils
(#3308)
This commit is contained in:
parent
87eb7d0d39
commit
12a95ad86c
53
.github/workflows/ci.yml
vendored
53
.github/workflows/ci.yml
vendored
@ -33,7 +33,7 @@ jobs:
|
||||
- name: Lint (docs)
|
||||
run: yarn lint:docs
|
||||
|
||||
test:
|
||||
test-fixtures:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
@ -51,19 +51,16 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
|
||||
- name: Build
|
||||
run: yarn build
|
||||
- name: Stub
|
||||
run: yarn stub
|
||||
|
||||
- name: Test (unit)
|
||||
run: yarn test:unit
|
||||
|
||||
- name: Test (presets)
|
||||
run: yarn test:presets
|
||||
- name: Test (fixtures)
|
||||
run: yarn test:fixtures
|
||||
|
||||
- name: Test (types)
|
||||
run: yarn test:types
|
||||
|
||||
test-bridge:
|
||||
test-fixtures-webpack:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
@ -77,8 +74,30 @@ jobs:
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: |
|
||||
yarn.lock
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
|
||||
- name: Stub
|
||||
run: yarn stub
|
||||
|
||||
- name: Test (fixtures)
|
||||
run: yarn test:fixtures:webpack
|
||||
|
||||
test-types:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node: [14]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: ${{ matrix.node }}
|
||||
cache: 'yarn'
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn --immutable
|
||||
@ -86,17 +105,15 @@ jobs:
|
||||
- name: Build
|
||||
run: yarn build
|
||||
|
||||
- name: Test with webpack
|
||||
run: yarn test:bridge:webpack
|
||||
|
||||
- name: Test with vite
|
||||
run: yarn test:bridge:vite
|
||||
- name: Test (types)
|
||||
run: yarn test:types
|
||||
|
||||
build-release:
|
||||
needs:
|
||||
- test
|
||||
- test-bridge
|
||||
- lint
|
||||
- test-fixtures
|
||||
- test-fixtures-webpack
|
||||
- test-types
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
|
@ -14,7 +14,7 @@
|
||||
"@docus/theme": "1.2.2",
|
||||
"@nuxt/typescript-build": "^2.1.0",
|
||||
"fs-extra": "^10.0.0",
|
||||
"jiti": "^1.12.15",
|
||||
"jiti": "^1.13.0",
|
||||
"pathe": "^0.2.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"scule": "^0.2.1",
|
||||
|
33
package.json
33
package.json
@ -10,30 +10,27 @@
|
||||
],
|
||||
"scripts": {
|
||||
"build": "FORCE_COLOR=1 lerna run prepack --stream --no-prefix",
|
||||
"stub": "lerna run prepack -- --stub",
|
||||
"release": "yarn && yarn lint && FORCE_COLOR=1 lerna publish -m \"chore: release\" && yarn stub",
|
||||
"nuxi": "./node_modules/.bin/nuxi",
|
||||
"nuxt": "./node_modules/.bin/nuxi",
|
||||
"play": "yarn run nuxi dev playground",
|
||||
"example": "yarn workspace example-$0 dev",
|
||||
"example:build": "yarn workspace example-$0 build",
|
||||
"lint": "eslint --ext .vue,.ts,.js,.mjs .",
|
||||
"lint:docs": "./node_modules/.bin/markdownlint ./",
|
||||
"test": "yarn lint && yarn test:presets",
|
||||
"test:presets": "vitest test/presets",
|
||||
"test:bridge:webpack": "TEST_BRIDGE=1 yarn test:presets",
|
||||
"test:bridge:vite": "TEST_BRIDGE_VITE=1 TEST_BRIDGE=1 yarn test:presets",
|
||||
"nuxi": "./node_modules/.bin/nuxi",
|
||||
"nuxt": "./node_modules/.bin/nuxi",
|
||||
"play": "yarn run nuxi dev playground",
|
||||
"release": "yarn && yarn lint && FORCE_COLOR=1 lerna publish -m \"chore: release\" && yarn stub",
|
||||
"stub": "lerna run prepack -- --stub",
|
||||
"test:fixtures": "JITI_ESM_RESOLVE=1 vitest test",
|
||||
"test:fixtures:webpack": "TEST_WITH_WEBPACK=1 yarn test:fixtures",
|
||||
"test:types": "yarn run nuxi prepare test/fixtures/basic && cd test/fixtures/basic && npx vue-tsc --noEmit",
|
||||
"test:unit": "vitest packages",
|
||||
"test:utils": "vitest run test/examples",
|
||||
"test:unit": "JITI_ESM_RESOLVE=1 yarn vitest packages",
|
||||
"version": "yarn && git add yarn.lock"
|
||||
},
|
||||
"resolutions": {
|
||||
"nuxt3": "workspace:./packages/nuxt3",
|
||||
"@nuxt/ui": "npm:@nuxt/ui-edge@latest",
|
||||
"unbuild": "^0.6.9",
|
||||
"jiti": "^1.13.0",
|
||||
"nitropack-dev": "link:../nitropack",
|
||||
"jiti": "^1.12.15"
|
||||
"nuxt3": "workspace:./packages/nuxt3",
|
||||
"unbuild": "^0.6.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify-json/carbon": "^1.1.1",
|
||||
@ -50,7 +47,7 @@
|
||||
"execa": "^6.1.0",
|
||||
"expect-type": "^0.13.0",
|
||||
"globby": "^13.1.1",
|
||||
"jiti": "^1.12.15",
|
||||
"jiti": "^1.13.0",
|
||||
"lerna": "^4.0.0",
|
||||
"markdownlint-cli": "^0.31.1",
|
||||
"miniflare": "^1.4.1",
|
||||
@ -58,12 +55,12 @@
|
||||
"pathe": "^0.2.0",
|
||||
"typescript": "^4.5.5",
|
||||
"unbuild": "^0.6.9",
|
||||
"vitest": "^0.3.6",
|
||||
"vitest": "^0.4.1",
|
||||
"vue-router": "next",
|
||||
"vue-tsc": "^0.31.4"
|
||||
},
|
||||
"packageManager": "yarn@3.1.1",
|
||||
"engines": {
|
||||
"node": "^14.16.0 || ^16.11.0 || ^17.0.0"
|
||||
}
|
||||
},
|
||||
"packageManager": "yarn@3.1.1"
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
"defu": "^5.0.1",
|
||||
"globby": "^13.1.1",
|
||||
"hash-sum": "^2.0.0",
|
||||
"jiti": "^1.12.15",
|
||||
"jiti": "^1.13.0",
|
||||
"knitwork": "^0.1.0",
|
||||
"lodash.template": "^4.5.0",
|
||||
"mlly": "^0.4.3",
|
||||
|
@ -3,7 +3,7 @@ import { fileURLToPath } from 'url'
|
||||
import { basename, dirname, resolve, join, normalize, isAbsolute } from 'pathe'
|
||||
import { globby } from 'globby'
|
||||
import { useNuxt } from './context'
|
||||
import { tryResolveModule } from '.'
|
||||
import { tryResolveModule } from './internal/cjs'
|
||||
|
||||
export interface ResolvePathOptions {
|
||||
/** Base for resolving paths from. Default is Nuxt rootDir. */
|
||||
|
@ -47,7 +47,7 @@
|
||||
"hookable": "^5.1.1",
|
||||
"http-proxy": "^1.18.1",
|
||||
"is-primitive": "^3.0.1",
|
||||
"jiti": "^1.12.15",
|
||||
"jiti": "^1.13.0",
|
||||
"knitwork": "^0.1.0",
|
||||
"listhen": "^0.2.6",
|
||||
"mime": "^3.0.0",
|
||||
|
@ -33,7 +33,7 @@
|
||||
"destr": "^1.1.0",
|
||||
"execa": "^6.1.0",
|
||||
"flat": "^5.0.2",
|
||||
"jiti": "^1.12.15",
|
||||
"jiti": "^1.13.0",
|
||||
"listhen": "^0.2.6",
|
||||
"mlly": "^0.4.3",
|
||||
"mri": "^1.2.0",
|
||||
|
@ -22,7 +22,7 @@
|
||||
"c12": "^0.1.3",
|
||||
"create-require": "^1.1.1",
|
||||
"defu": "^5.0.1",
|
||||
"jiti": "^1.12.15",
|
||||
"jiti": "^1.13.0",
|
||||
"pathe": "^0.2.0",
|
||||
"scule": "^0.2.1",
|
||||
"std-env": "^3.0.1",
|
||||
|
@ -18,13 +18,13 @@
|
||||
"defu": "^5.0.1",
|
||||
"execa": "^6.1.0",
|
||||
"get-port-please": "^2.3.0",
|
||||
"jiti": "^1.12.15",
|
||||
"jiti": "^1.13.0",
|
||||
"ohmyfetch": "^0.4.15"
|
||||
},
|
||||
"devDependencies": {
|
||||
"playwright": "^1.19.1",
|
||||
"unbuild": "latest",
|
||||
"vitest": "^0.3.6"
|
||||
"vitest": "^0.4.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "3.2.31"
|
||||
|
@ -21,7 +21,7 @@ function checkPort (port: number, host: string): Promise<number|false> {
|
||||
export async function listen () {
|
||||
const ctx = useTestContext()
|
||||
const host = process.env.HOST || '0.0.0.0'
|
||||
const port = await getPort({ host })
|
||||
const port = await getPort({ host, random: true })
|
||||
|
||||
ctx.url = 'http://localhost:' + port
|
||||
execa('node', [
|
||||
|
13
test/basic.test.ts
Normal file
13
test/basic.test.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { fileURLToPath } from 'url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { setup, $fetch } from '@nuxt/test-utils'
|
||||
|
||||
describe('fixtures:basic', async () => {
|
||||
await setup({
|
||||
rootDir: fileURLToPath(new URL('./fixtures/basic', import.meta.url)),
|
||||
server: true
|
||||
})
|
||||
it('Render hello world', async () => {
|
||||
expect(await $fetch('/')).to.contain('Hello Nuxt 3!')
|
||||
})
|
||||
})
|
14
test/bridge.test.ts
Normal file
14
test/bridge.test.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { fileURLToPath } from 'url'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { setup, $fetch } from '@nuxt/test-utils'
|
||||
|
||||
describe('fixtures:bridge', async () => {
|
||||
await setup({
|
||||
rootDir: fileURLToPath(new URL('./fixtures/bridge', import.meta.url)),
|
||||
server: true
|
||||
})
|
||||
|
||||
it('Render hello world', async () => {
|
||||
expect(await $fetch('/')).to.contain('Hello Vue 2!')
|
||||
})
|
||||
})
|
@ -1,17 +0,0 @@
|
||||
import { fileURLToPath } from 'url'
|
||||
import { resolve } from 'path'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { setup, $fetch } from '@nuxt/test-utils'
|
||||
|
||||
const examplesDir = fileURLToPath(new URL('../../examples', import.meta.url))
|
||||
|
||||
await setup({
|
||||
rootDir: resolve(examplesDir, 'hello-world'),
|
||||
server: true
|
||||
})
|
||||
|
||||
describe('examples:hello-world', () => {
|
||||
it('Render hello world test', async () => {
|
||||
expect(await $fetch('/')).to.contain('Hello Nuxt 3!')
|
||||
})
|
||||
})
|
1
test/fixtures/basic/nuxt.config.ts
vendored
1
test/fixtures/basic/nuxt.config.ts
vendored
@ -3,6 +3,7 @@ import { addComponent } from '@nuxt/kit'
|
||||
|
||||
export default defineNuxtConfig({
|
||||
buildDir: process.env.NITRO_BUILD_DIR,
|
||||
vite: !process.env.TEST_WITH_WEBPACK,
|
||||
nitro: {
|
||||
output: { dir: process.env.NITRO_OUTPUT_DIR }
|
||||
},
|
||||
|
2
test/fixtures/basic/pages/index.vue
vendored
2
test/fixtures/basic/pages/index.vue
vendored
@ -3,7 +3,7 @@
|
||||
<Head>
|
||||
<Title>Basic fixture</Title>
|
||||
</Head>
|
||||
<h1>Hello Vue 3</h1>
|
||||
<h1>Hello Nuxt 3!</h1>
|
||||
<div>Config: {{ $config.testConfig }}</div>
|
||||
<CustomComponent />
|
||||
</div>
|
||||
|
2
test/fixtures/bridge/nuxt.config.ts
vendored
2
test/fixtures/bridge/nuxt.config.ts
vendored
@ -20,6 +20,6 @@ export default defineNuxtConfig({
|
||||
},
|
||||
bridge: {
|
||||
meta: true,
|
||||
vite: !!process.env.TEST_BRIDGE_VITE
|
||||
vite: !process.env.TEST_WITH_WEBPACK
|
||||
}
|
||||
})
|
||||
|
@ -1,83 +0,0 @@
|
||||
import { pathToFileURL } from 'url'
|
||||
import { resolve } from 'pathe'
|
||||
import destr from 'destr'
|
||||
import { listen, Listener } from 'listhen'
|
||||
import { $fetch } from 'ohmyfetch'
|
||||
import { execa } from 'execa'
|
||||
import { expect, it, beforeAll, afterAll } from 'vitest'
|
||||
import { fixtureDir, resolveWorkspace } from '../utils'
|
||||
|
||||
const isBridge = Boolean(process.env.TEST_BRIDGE)
|
||||
|
||||
interface Context {
|
||||
rootDir: string
|
||||
outDir: string
|
||||
fetch: (url:string) => Promise<any>
|
||||
server?: Listener
|
||||
}
|
||||
|
||||
export function importModule (path) {
|
||||
return import(pathToFileURL(path).href)
|
||||
}
|
||||
|
||||
export function setupTest (preset) {
|
||||
const fixture = isBridge ? 'bridge' : 'basic'
|
||||
const rootDir = fixtureDir(fixture)
|
||||
const buildDir = resolve(rootDir, '.nuxt-' + preset)
|
||||
|
||||
const ctx: Context = {
|
||||
rootDir,
|
||||
outDir: resolve(buildDir, 'output'),
|
||||
fetch: url => $fetch(url, { baseURL: ctx.server!.url })
|
||||
}
|
||||
|
||||
beforeAll(async () => {
|
||||
const nuxtCLI = isBridge
|
||||
? resolve(ctx.rootDir, 'node_modules/nuxt-edge/bin/nuxt.js')
|
||||
: resolveWorkspace('packages/nuxi/bin/nuxi.mjs')
|
||||
|
||||
await execa('node', [nuxtCLI, 'build', ctx.rootDir], {
|
||||
env: {
|
||||
NITRO_PRESET: preset,
|
||||
NITRO_BUILD_DIR: buildDir,
|
||||
NITRO_OUTPUT_DIR: ctx.outDir,
|
||||
NODE_ENV: 'production'
|
||||
}
|
||||
})
|
||||
}, (isBridge ? 120 : 60) * 1000)
|
||||
|
||||
afterAll(async () => {
|
||||
if (ctx.server) {
|
||||
await ctx.server.close()
|
||||
}
|
||||
})
|
||||
|
||||
return ctx
|
||||
}
|
||||
|
||||
export async function startServer (ctx, handle) {
|
||||
ctx.server = await listen(handle)
|
||||
}
|
||||
|
||||
export function testNitroBehavior (_ctx, getHandler) {
|
||||
let handler
|
||||
|
||||
it('setup handler', async () => {
|
||||
handler = await getHandler()
|
||||
})
|
||||
|
||||
it('SSR Works', async () => {
|
||||
const { data } = await handler({ url: '/' })
|
||||
expect(data).to.have.string('Hello Vue')
|
||||
})
|
||||
|
||||
it('API Works', async () => {
|
||||
const { data: helloData } = await handler({ url: '/api/hello' })
|
||||
const { data: heyData } = await handler({ url: '/api/hey' })
|
||||
expect(destr(helloData)).to.have.string('Hello API')
|
||||
expect(destr(heyData)).to.deep.equal({
|
||||
foo: 'bar',
|
||||
baz: 'qux'
|
||||
})
|
||||
})
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
import { promises as fsp } from 'fs'
|
||||
import { resolve } from 'pathe'
|
||||
import { Miniflare } from 'miniflare'
|
||||
import { describe } from 'vitest'
|
||||
|
||||
import { setupTest, testNitroBehavior } from './_tests'
|
||||
|
||||
// TODO: fix SyntaxError: Unexpected end of input on script executation
|
||||
describe('nitro:preset:cloudflare', () => {
|
||||
const ctx = setupTest('cloudflare')
|
||||
testNitroBehavior(ctx, async () => {
|
||||
const script = await fsp.readFile(resolve(ctx.outDir, 'server/index.mjs'), 'utf-8')
|
||||
const mf = new Miniflare({ script })
|
||||
|
||||
return async ({ url, headers, method, body }) => {
|
||||
const data = await mf.dispatchFetch('http://localhost' + url, {
|
||||
headers: headers || {},
|
||||
method: method || 'GET',
|
||||
redirect: null,
|
||||
body: body || null
|
||||
}).then(r => r.text())
|
||||
|
||||
return { data }
|
||||
}
|
||||
})
|
||||
})
|
@ -1,57 +0,0 @@
|
||||
import { resolve } from 'pathe'
|
||||
import { describe } from 'vitest'
|
||||
import type { APIGatewayProxyEvent, APIGatewayProxyEventV2 } from 'aws-lambda'
|
||||
import { setupTest, testNitroBehavior, importModule } from './_tests'
|
||||
|
||||
describe('nitro:preset:lambda', () => {
|
||||
const ctx = setupTest('lambda')
|
||||
// Lambda v1 paylod
|
||||
testNitroBehavior(ctx, async () => {
|
||||
const { handler } = await importModule(resolve(ctx.outDir, 'server/index.mjs'))
|
||||
return async ({ url: rawRelativeUrl, headers, method, body }) => {
|
||||
// creating new URL object to parse query easier
|
||||
const url = new URL(`https://example.com${rawRelativeUrl}`)
|
||||
const queryStringParameters = Object.fromEntries(url.searchParams.entries())
|
||||
const event: Partial<APIGatewayProxyEvent> = {
|
||||
resource: '/my/path',
|
||||
path: url.pathname,
|
||||
headers: headers || {},
|
||||
httpMethod: method || 'GET',
|
||||
queryStringParameters,
|
||||
body: body || ''
|
||||
}
|
||||
const res = await handler(event)
|
||||
return {
|
||||
data: res.body
|
||||
}
|
||||
}
|
||||
})
|
||||
// Lambda v2 paylod
|
||||
testNitroBehavior(ctx, async () => {
|
||||
const { handler } = await importModule(resolve(ctx.outDir, 'server/index.mjs'))
|
||||
return async ({ url: rawRelativeUrl, headers, method, body }) => {
|
||||
// creating new URL object to parse query easier
|
||||
const url = new URL(`https://example.com${rawRelativeUrl}`)
|
||||
const queryStringParameters = Object.fromEntries(url.searchParams.entries())
|
||||
const event: Partial<APIGatewayProxyEventV2> = {
|
||||
rawPath: url.pathname,
|
||||
headers: headers || {},
|
||||
requestContext: {
|
||||
...Object.fromEntries([['accountId'], ['apiId'], ['domainName'], ['domainPrefix']]),
|
||||
http: {
|
||||
path: url.pathname,
|
||||
protocol: 'http',
|
||||
...Object.fromEntries([['userAgent'], ['sourceIp']]),
|
||||
method: method || 'GET'
|
||||
}
|
||||
},
|
||||
queryStringParameters,
|
||||
body: body || ''
|
||||
}
|
||||
const res = await handler(event)
|
||||
return {
|
||||
data: res.body
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
@ -1,17 +0,0 @@
|
||||
import { resolve } from 'pathe'
|
||||
import { describe } from 'vitest'
|
||||
import { startServer, setupTest, testNitroBehavior, importModule } from './_tests.js'
|
||||
|
||||
describe('nitro:preset:node', () => {
|
||||
const ctx = setupTest('node')
|
||||
testNitroBehavior(ctx, async () => {
|
||||
const { handle } = await importModule(resolve(ctx.outDir, 'server/index.mjs'))
|
||||
await startServer(ctx, handle)
|
||||
return async ({ url }) => {
|
||||
const data = await ctx.fetch(url)
|
||||
return {
|
||||
data
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
@ -1,18 +0,0 @@
|
||||
import { resolve } from 'pathe'
|
||||
import { describe } from 'vitest'
|
||||
import { setupTest, startServer, testNitroBehavior, importModule } from './_tests'
|
||||
|
||||
describe('nitro:preset:vercel', () => {
|
||||
const ctx = setupTest('vercel')
|
||||
testNitroBehavior(ctx, async () => {
|
||||
const handle = await importModule(resolve(ctx.outDir, 'functions/node/server/index.mjs'))
|
||||
.then(r => r.default || r)
|
||||
await startServer(ctx, handle)
|
||||
return async ({ url }) => {
|
||||
const data = await ctx.fetch(url)
|
||||
return {
|
||||
data
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
@ -3,7 +3,7 @@ import { describe, it } from 'vitest'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
import { useRouter as vueUseRouter } from 'vue-router'
|
||||
import { defineNuxtConfig } from '~~/../../../packages/nuxt3/src'
|
||||
import { defineNuxtConfig } from '~~/../../packages/nuxt3/src'
|
||||
import { useRouter } from '#imports'
|
||||
import { isVue3 } from '#app'
|
||||
|
@ -1,92 +0,0 @@
|
||||
import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync } from 'fs'
|
||||
import { execSync } from 'child_process'
|
||||
import { resolve, dirname } from 'pathe'
|
||||
import defu from 'defu'
|
||||
import hash from 'object-hash'
|
||||
import { execa, Options as ExecaOptions } from 'execa'
|
||||
import { createCommonJS } from 'mlly'
|
||||
|
||||
const cjs = createCommonJS(import.meta.url)
|
||||
|
||||
export function resolveWorkspace (name: string) {
|
||||
return resolve(cjs.__dirname, '../', name)
|
||||
}
|
||||
|
||||
export function fixtureDir (name: string) {
|
||||
return resolve(cjs.__dirname, 'fixtures', name)
|
||||
}
|
||||
|
||||
export async function execNuxtCLI (args: string[], opts: ExecaOptions) {
|
||||
const nuxtCLI = resolveWorkspace('packages/nuxi/bin/nuxi.mjs')
|
||||
await execa('node', [nuxtCLI, ...args], opts)
|
||||
}
|
||||
|
||||
export async function loadFixture (opts: any, unhashedConfig?: any) {
|
||||
const buildId = hash(opts)
|
||||
const buildDir = resolve(opts.rootDir, '.nuxt', buildId)
|
||||
const { loadNuxt } = await import('@nuxt/kit')
|
||||
const nuxt = await loadNuxt(defu(opts, { config: { buildDir, ...unhashedConfig } }))
|
||||
return nuxt
|
||||
}
|
||||
|
||||
export async function buildFixture (opts) {
|
||||
const buildId = hash(opts)
|
||||
const buildDir = resolve(opts.rootDir, '.nuxt', buildId)
|
||||
|
||||
const lockFile = resolve(opts.rootDir, `.build-${buildId}.lock`)
|
||||
mkdirpSync(dirname(lockFile))
|
||||
await waitWhile(() => isAlive(readSync(lockFile)))
|
||||
writeFileSync(lockFile, process.pid + '', 'utf8')
|
||||
|
||||
try {
|
||||
const integrity = gitHead() // TODO: Calculate hash from project source
|
||||
const integrityFile = resolve(buildDir, '.integrity')
|
||||
const lastBuildIntegrity = readSync(integrityFile)
|
||||
if (integrity !== lastBuildIntegrity) {
|
||||
const nuxt = await loadFixture(opts)
|
||||
const { buildNuxt } = await import('@nuxt/kit')
|
||||
await buildNuxt(nuxt)
|
||||
await nuxt.close()
|
||||
await writeFileSync(integrityFile, integrity)
|
||||
}
|
||||
} finally {
|
||||
existsSync(lockFile) && rmSync(lockFile)
|
||||
}
|
||||
}
|
||||
|
||||
function mkdirpSync (dir: string) {
|
||||
if (!existsSync(dir)) {
|
||||
mkdirpSync(dirname(dir))
|
||||
mkdirSync(dir)
|
||||
}
|
||||
}
|
||||
|
||||
function readSync (file) {
|
||||
return existsSync(file) ? readFileSync(file, 'utf8') : null
|
||||
}
|
||||
|
||||
function isAlive (pid) {
|
||||
try {
|
||||
process.kill(pid, 0)
|
||||
return true
|
||||
} catch (e) {
|
||||
return e.code === 'EPERM'
|
||||
}
|
||||
}
|
||||
|
||||
function waitWhile (check, interval = 100, timeout = 30000) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const t = setTimeout(() => reject(new Error('Timeout')), timeout)
|
||||
const i = setInterval(() => {
|
||||
if (!check()) {
|
||||
clearTimeout(t)
|
||||
clearInterval(i)
|
||||
resolve(true)
|
||||
}
|
||||
}, interval)
|
||||
})
|
||||
}
|
||||
|
||||
function gitHead () {
|
||||
return execSync('git rev-parse HEAD').toString('utf8').trim()
|
||||
}
|
42
yarn.lock
42
yarn.lock
@ -2997,7 +2997,7 @@ __metadata:
|
||||
defu: ^5.0.1
|
||||
globby: ^13.1.1
|
||||
hash-sum: ^2.0.0
|
||||
jiti: ^1.12.15
|
||||
jiti: ^1.13.0
|
||||
knitwork: ^0.1.0
|
||||
lodash.template: ^4.5.0
|
||||
mlly: ^0.4.3
|
||||
@ -3094,7 +3094,7 @@ __metadata:
|
||||
hookable: ^5.1.1
|
||||
http-proxy: ^1.18.1
|
||||
is-primitive: ^3.0.1
|
||||
jiti: ^1.12.15
|
||||
jiti: ^1.13.0
|
||||
knitwork: ^0.1.0
|
||||
listhen: ^0.2.6
|
||||
mime: ^3.0.0
|
||||
@ -3161,7 +3161,7 @@ __metadata:
|
||||
c12: ^0.1.3
|
||||
create-require: ^1.1.1
|
||||
defu: ^5.0.1
|
||||
jiti: ^1.12.15
|
||||
jiti: ^1.13.0
|
||||
pathe: ^0.2.0
|
||||
scule: ^0.2.1
|
||||
std-env: ^3.0.1
|
||||
@ -3273,11 +3273,11 @@ __metadata:
|
||||
defu: ^5.0.1
|
||||
execa: ^6.1.0
|
||||
get-port-please: ^2.3.0
|
||||
jiti: ^1.12.15
|
||||
jiti: ^1.13.0
|
||||
ohmyfetch: ^0.4.15
|
||||
playwright: ^1.19.1
|
||||
unbuild: latest
|
||||
vitest: ^0.3.6
|
||||
vitest: ^0.4.1
|
||||
peerDependencies:
|
||||
vue: 3.2.31
|
||||
languageName: unknown
|
||||
@ -13245,12 +13245,12 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"jiti@npm:^1.12.15":
|
||||
version: 1.12.15
|
||||
resolution: "jiti@npm:1.12.15"
|
||||
"jiti@npm:^1.13.0":
|
||||
version: 1.13.0
|
||||
resolution: "jiti@npm:1.13.0"
|
||||
bin:
|
||||
jiti: bin/jiti.js
|
||||
checksum: 8e53259f427eb7a7c0cd834c284e18cd05760cb7f0f15b4971ab11874e8b0e7b15fc1f13000eb3a8c7f804ff15637a283d6595858811d61effe8c5aeaacb02ac
|
||||
checksum: 1e74d99b9a551df952057b8bce56f744caccca0044aa05021643e6ce0837ed47bc2d5b290fecb462e32988c6bf318afe77e341310c5ecf6bb63c19c80c929cb6
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -15513,7 +15513,7 @@ __metadata:
|
||||
execa: ^6.1.0
|
||||
flat: ^5.0.2
|
||||
fsevents: ~2.3.2
|
||||
jiti: ^1.12.15
|
||||
jiti: ^1.13.0
|
||||
listhen: ^0.2.6
|
||||
mlly: ^0.4.3
|
||||
mri: ^1.2.0
|
||||
@ -15577,7 +15577,7 @@ __metadata:
|
||||
execa: ^6.1.0
|
||||
expect-type: ^0.13.0
|
||||
globby: ^13.1.1
|
||||
jiti: ^1.12.15
|
||||
jiti: ^1.13.0
|
||||
lerna: ^4.0.0
|
||||
markdownlint-cli: ^0.31.1
|
||||
miniflare: ^1.4.1
|
||||
@ -15585,7 +15585,7 @@ __metadata:
|
||||
pathe: ^0.2.0
|
||||
typescript: ^4.5.5
|
||||
unbuild: ^0.6.9
|
||||
vitest: ^0.3.6
|
||||
vitest: ^0.4.1
|
||||
vue-router: next
|
||||
vue-tsc: ^0.31.4
|
||||
languageName: unknown
|
||||
@ -20774,10 +20774,10 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinyspy@npm:^0.2.10":
|
||||
version: 0.2.10
|
||||
resolution: "tinyspy@npm:0.2.10"
|
||||
checksum: 7c4d89f603f5e12b335f5a97811b11712a6cc44565c2d1c1d76ccf6a0cb9c2b0ca8b7eb84f6cdabd0a49149fb9dababaefadab43bec6d8252dfc797a205f48bd
|
||||
"tinyspy@npm:^0.3.0":
|
||||
version: 0.3.0
|
||||
resolution: "tinyspy@npm:0.3.0"
|
||||
checksum: 8776bc6b29d190195c12a0769f8e9f0ae7756ff4a8de070b181a5962fc17fdffb1b95043501f7970cea007d4ddf41559c5b376576c8d244ccf35d04a49e664fb
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
@ -21756,16 +21756,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"vitest@npm:^0.3.6":
|
||||
version: 0.3.6
|
||||
resolution: "vitest@npm:0.3.6"
|
||||
"vitest@npm:^0.4.1":
|
||||
version: 0.4.1
|
||||
resolution: "vitest@npm:0.4.1"
|
||||
dependencies:
|
||||
"@types/chai": ^4.3.0
|
||||
"@types/chai-subset": ^1.3.3
|
||||
chai: ^4.3.6
|
||||
local-pkg: ^0.4.1
|
||||
tinypool: ^0.1.2
|
||||
tinyspy: ^0.2.10
|
||||
tinyspy: ^0.3.0
|
||||
vite: ^2.8.2
|
||||
peerDependencies:
|
||||
"@vitest/ui": "*"
|
||||
@ -21783,7 +21783,7 @@ __metadata:
|
||||
optional: true
|
||||
bin:
|
||||
vitest: vitest.mjs
|
||||
checksum: 3079f19837384b96c74825fbd4e7dc48b018f48d9317665aad193c7339a438d7e5c47e4f7f1b121de162a9dbbb80a40df5ec3fc9f17321560de1c667b056e74e
|
||||
checksum: f350464cd674612151ea6e63fd37401156ff9d3fafd3f663595beb1dbe19658fb1f7f345253250f3a9c5dff7febf8fc3284f94d46ed167f37141bd609d424e05
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user