feat: `@nuxt/test-utils` (#2952)

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
This commit is contained in:
pooya parsa 2022-02-11 14:22:58 +01:00 committed by GitHub
parent 61188e15cf
commit c53c7360b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 627 additions and 4 deletions

View File

@ -24,6 +24,7 @@
"test:bridge:webpack": "TEST_BRIDGE=1 yarn test:presets", "test:bridge:webpack": "TEST_BRIDGE=1 yarn test:presets",
"test:bridge:vite": "TEST_BRIDGE_VITE=1 TEST_BRIDGE=1 yarn test:presets", "test:bridge:vite": "TEST_BRIDGE_VITE=1 TEST_BRIDGE=1 yarn test:presets",
"test:unit": "vitest packages", "test:unit": "vitest packages",
"test:utils": "vitest run test/examples",
"version": "yarn && git add yarn.lock" "version": "yarn && git add yarn.lock"
}, },
"resolutions": { "resolutions": {

View File

@ -0,0 +1,3 @@
# Nuxt Test Utils
Test utilities for Nuxt.

View File

@ -0,0 +1,15 @@
import { defineBuildConfig } from 'unbuild'
export default defineBuildConfig({
declaration: true,
entries: [
'src/index'
],
dependencies: [
],
externals: [
'vitest',
'playwright',
'playwright-core'
]
})

View File

@ -0,0 +1,35 @@
{
"name": "@nuxt/test-utils",
"version": "3.0.0",
"repository": "nuxt/framework",
"license": "MIT",
"type": "module",
"exports": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": {
"prepack": "unbuild"
},
"dependencies": {
"@nuxt/kit": "3.0.0",
"@nuxt/schema": "3.0.0",
"defu": "^5.0.1",
"execa": "^6.0.0",
"get-port-please": "^2.2.0",
"jiti": "^1.12.15",
"ohmyfetch": "^0.4.15"
},
"devDependencies": {
"playwright": "^1.18.0",
"unbuild": "latest",
"vitest": "^0.3.2"
},
"peerDependencies": {
"vue": "3.2.29"
},
"engines": {
"node": "^14.16.0 || ^16.11.0 || ^17.0.0"
}
}

View File

@ -0,0 +1,44 @@
import type { Browser, BrowserContextOptions } from 'playwright'
import { useTestContext } from './context'
import { url } from './server'
export async function createBrowser () {
const ctx = useTestContext()
let playwright: typeof import('playwright')
try {
playwright = await import('playwright')
} catch {
/* istanbul ignore next */
throw new Error(`
The dependency 'playwright' not found.
Please run 'yarn add --dev playwright' or 'npm install --save-dev playwright'
`)
}
const { type, launch } = ctx.options.browserOptions
if (!playwright[type]) {
throw new Error(`Invalid browser '${type}'`)
}
ctx.browser = await playwright[type].launch(launch)
}
export async function getBrowser (): Promise<Browser> {
const ctx = useTestContext()
if (!ctx.browser) {
await createBrowser()
}
return ctx.browser
}
export async function createPage (path?: string, options?: BrowserContextOptions) {
const browser = await getBrowser()
const page = await browser.newPage(options)
if (path) {
await page.goto(url(path))
}
return page
}

View File

@ -0,0 +1,36 @@
import { resolve } from 'path'
import defu from 'defu'
import type { TestContext, TestOptions, TestRunner } from './types'
let currentContext: TestContext
export function createTestContext (options: Partial<TestOptions>): TestContext {
const _options: Partial<TestOptions> = defu(options, {
testDir: resolve(process.cwd(), 'test'),
fixture: 'fixture',
configFile: 'nuxt.config',
setupTimeout: 60000,
server: options.browser,
build: options.browser || options.server,
nuxtConfig: {},
// TODO: auto detect based on process.env
runner: <TestRunner>'vitest',
browserOptions: {
type: 'chromium'
}
})
return setTestContext({ options: _options as TestOptions })
}
export function useTestContext (): TestContext {
if (!currentContext) {
throw new Error('No context is available. (Forgot calling setup or createContext?)')
}
return currentContext
}
export function setTestContext (context: TestContext): TestContext {
currentContext = context
return currentContext
}

View File

@ -0,0 +1,5 @@
export * from './browser'
export * from './context'
export * from './nuxt'
export * from './server'
export * from './setup'

View File

@ -0,0 +1,63 @@
import { existsSync, promises as fsp } from 'fs'
import { resolve } from 'path'
import * as _kit from '@nuxt/kit'
import { useTestContext } from './context'
// @ts-ignore type cast
const kit: typeof _kit = _kit.default || _kit
const isNuxtApp = (dir: string) => {
return existsSync(dir) && (
existsSync(resolve(dir, 'pages')) ||
existsSync(resolve(dir, 'nuxt.config.js')) ||
existsSync(resolve(dir, 'nuxt.config.ts'))
)
}
const resolveRootDir = () => {
const { options } = useTestContext()
const dirs = [
options.rootDir,
resolve(options.testDir, options.fixture),
process.cwd()
]
for (const dir of dirs) {
if (dir && isNuxtApp(dir)) {
return dir
}
}
throw new Error('Invalid nuxt app. (Please explicitly set `options.rootDir` pointing to a valid nuxt app)')
}
export async function loadFixture () {
const ctx = useTestContext()
ctx.options.rootDir = resolveRootDir()
const randomId = Math.random().toString(36).substr(2, 8)
const buildDir = resolve(ctx.options.rootDir, '.nuxt', randomId)
Object.assign(ctx.options.nuxtConfig, {
buildDir,
nitro: {
output: {
dir: resolve(buildDir, 'output')
}
}
})
ctx.nuxt = await kit.loadNuxt({
rootDir: ctx.options.rootDir,
config: ctx.options.nuxtConfig,
configFile: ctx.options.configFile
})
await fsp.mkdir(ctx.nuxt.options.buildDir, { recursive: true })
}
export async function buildFixture () {
const ctx = useTestContext()
await kit.buildNuxt(ctx.nuxt)
}

View File

@ -0,0 +1,63 @@
import { resolve } from 'path'
import { createServer, AddressInfo } from 'net'
import { execa } from 'execa'
import { getPort } from 'get-port-please'
import { fetch as _fetch, $fetch as _$fetch, FetchOptions } from 'ohmyfetch'
import { useTestContext } from './context'
// TODO: use the export from `get-port-please`
function checkPort (port: number, host: string): Promise<number|false> {
return new Promise((resolve) => {
const server = createServer()
server.unref()
server.on('error', () => { resolve(false) })
server.listen(port, host, () => {
const { port } = server.address() as AddressInfo
server.close(() => { resolve(port) })
})
})
}
export async function listen () {
const ctx = useTestContext()
const host = process.env.HOST || '0.0.0.0'
const port = await getPort({ host })
ctx.url = 'http://localhost:' + port
execa('node', [
// @ts-ignore
resolve(ctx.nuxt.options.nitro.output.dir, 'server/index.mjs')
], {
env: {
PORT: String(port),
NODE_ENV: 'test'
}
})
const TRIES = 50
const DELAY = 100
for (let i = TRIES; i; i--) {
await new Promise(resolve => setTimeout(resolve, DELAY))
// wait until port is in used
if (await checkPort(port, host) === false) {
return
}
}
}
export function fetch (path: string, options?: any) {
return _fetch(url(path), options)
}
export function $fetch (path: string, options?: FetchOptions) {
return _$fetch(url(path), options)
}
export function url (path: string) {
const ctx = useTestContext()
if (!ctx.url) {
throw new Error('url is not availabe (is server option enabled?)')
}
return ctx.url + path
}

View File

@ -0,0 +1,71 @@
import { createTestContext, setTestContext } from '../context'
import { loadFixture, buildFixture } from '../nuxt'
import { listen } from '../server'
import { createBrowser } from '../browser'
import type { TestHooks, TestOptions } from '../types'
import setupJest from './jest'
import setupVitest from './vitest'
export const setupMaps = {
jest: setupJest,
vitest: setupVitest
}
export function createTest (options: Partial<TestOptions>): TestHooks {
const ctx = createTestContext(options)
const beforeEach = () => {
setTestContext(ctx)
}
const afterEach = () => {
setTestContext(undefined)
}
const afterAll = async () => {
if (ctx.nuxt && ctx.nuxt.options.dev) {
await ctx.nuxt.close()
}
if (ctx.browser) {
await ctx.browser.close()
}
}
const setup = async () => {
if (ctx.options.fixture) {
await loadFixture()
}
if (ctx.options.build) {
await buildFixture()
}
if (ctx.options.server) {
await listen()
}
if (ctx.options.waitFor) {
await (new Promise(resolve => setTimeout(resolve, ctx.options.waitFor)))
}
if (ctx.options.browser) {
await createBrowser()
}
}
return {
beforeEach,
afterEach,
afterAll,
setup,
ctx
}
}
export async function setup (options: Partial<TestOptions>) {
const hooks = createTest(options)
const setupFn = setupMaps[hooks.ctx.options.runner]
await setupFn(hooks)
}

View File

@ -0,0 +1,13 @@
import type { TestHooks } from '../types'
export default function setupJest (hooks: TestHooks) {
// TODO: add globals existing check to provide better error message
// @ts-expect-error jest types
test('setup', hooks.setup, 60000)
// @ts-expect-error jest types
beforeEach(hooks.beforeEach)
// @ts-expect-error jest types
afterEach(hooks.afterEach)
// @ts-expect-error jest types
afterAll(hooks.afterAll)
}

View File

@ -0,0 +1,9 @@
import type { TestHooks } from '../types'
export default async function setupVitest (hooks: TestHooks) {
const vitest = await import('vitest')
vitest.test('setup nuxt', hooks.setup, 60000)
vitest.beforeEach(hooks.beforeEach)
vitest.afterEach(hooks.afterEach)
vitest.afterAll(hooks.afterAll)
}

View File

@ -0,0 +1,38 @@
import type { Nuxt, NuxtConfig } from '@nuxt/schema'
import type { Browser, LaunchOptions } from 'playwright'
export type TestRunner = 'vitest' | 'jest'
export interface TestOptions {
testDir: string
fixture: string
configFile: string
rootDir: string
buildDir: string
nuxtConfig: NuxtConfig
build: boolean
setupTimeout: number
waitFor: number
browser: boolean
runner: TestRunner
browserOptions: {
type: 'chromium' | 'firefox' | 'webkit'
launch?: LaunchOptions
}
server: boolean
}
export interface TestContext {
options: TestOptions
nuxt?: Nuxt
browser?: Browser
url?: string
}
export interface TestHooks {
beforeEach: () => void
afterEach: () => void
afterAll: () => void
setup: () => void
ctx: TestContext
}

View File

@ -0,0 +1,19 @@
import { fileURLToPath } from 'url'
import { resolve } from 'path'
import { describe, expect, it } from 'vitest'
// TODO: Should import from @nuxt/test-utils
import { setup, $fetch } from '../../packages/test-utils/src'
const examplesDir = fileURLToPath(new URL('../../examples', import.meta.url))
await setup({
rootDir: resolve(examplesDir, 'hello-world'),
runner: 'vitest',
server: true
})
describe('examples:hello-world', () => {
it('Render hello world test', async () => {
expect(await $fetch('/')).to.contain('Hello Nuxt 3!')
})
})

216
yarn.lock
View File

@ -3168,6 +3168,25 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@nuxt/test-utils@workspace:packages/test-utils":
version: 0.0.0-use.local
resolution: "@nuxt/test-utils@workspace:packages/test-utils"
dependencies:
"@nuxt/kit": 3.0.0
"@nuxt/schema": 3.0.0
defu: ^5.0.1
execa: ^6.0.0
get-port-please: ^2.2.0
jiti: ^1.12.15
ohmyfetch: ^0.4.15
playwright: ^1.18.0
unbuild: latest
vitest: ^0.3.2
peerDependencies:
vue: 3.2.29
languageName: unknown
linkType: soft
"@nuxt/types@npm:^2.15.8": "@nuxt/types@npm:^2.15.8":
version: 2.15.8 version: 2.15.8
resolution: "@nuxt/types@npm:2.15.8" resolution: "@nuxt/types@npm:2.15.8"
@ -4612,6 +4631,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/yauzl@npm:^2.9.1":
version: 2.9.2
resolution: "@types/yauzl@npm:2.9.2"
dependencies:
"@types/node": "*"
checksum: dfb49abe82605615712fc694eaa4f7068fe30aa03f38c085e2c2e74408beaad30471d36da9654a811482ece2ea4405575fd99b19c0aa327ed2a9736b554bbf43
languageName: node
linkType: hard
"@typescript-eslint/eslint-plugin@npm:^5.1.0": "@typescript-eslint/eslint-plugin@npm:^5.1.0":
version: 5.11.0 version: 5.11.0
resolution: "@typescript-eslint/eslint-plugin@npm:5.11.0" resolution: "@typescript-eslint/eslint-plugin@npm:5.11.0"
@ -6685,7 +6713,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"buffer-crc32@npm:^0.2.1, buffer-crc32@npm:^0.2.13": "buffer-crc32@npm:^0.2.1, buffer-crc32@npm:^0.2.13, buffer-crc32@npm:~0.2.3":
version: 0.2.13 version: 0.2.13
resolution: "buffer-crc32@npm:0.2.13" resolution: "buffer-crc32@npm:0.2.13"
checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c checksum: 06252347ae6daca3453b94e4b2f1d3754a3b146a111d81c68924c22d91889a40623264e95e67955b1cb4a68cbedf317abeabb5140a9766ed248973096db5ce1c
@ -7525,6 +7553,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"commander@npm:^8.2.0":
version: 8.3.0
resolution: "commander@npm:8.3.0"
checksum: 0f82321821fc27b83bd409510bb9deeebcfa799ff0bf5d102128b500b7af22872c0c92cb6a0ebc5a4cf19c6b550fba9cedfa7329d18c6442a625f851377bacf0
languageName: node
linkType: hard
"commander@npm:~9.0.0": "commander@npm:~9.0.0":
version: 9.0.0 version: 9.0.0
resolution: "commander@npm:9.0.0" resolution: "commander@npm:9.0.0"
@ -9872,6 +9907,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"escape-string-regexp@npm:^2.0.0":
version: 2.0.0
resolution: "escape-string-regexp@npm:2.0.0"
checksum: 9f8a2d5743677c16e85c810e3024d54f0c8dea6424fad3c79ef6666e81dd0846f7437f5e729dfcdac8981bc9e5294c39b4580814d114076b8d36318f46ae4395
languageName: node
linkType: hard
"escape-string-regexp@npm:^4.0.0": "escape-string-regexp@npm:^4.0.0":
version: 4.0.0 version: 4.0.0
resolution: "escape-string-regexp@npm:4.0.0" resolution: "escape-string-regexp@npm:4.0.0"
@ -10638,6 +10680,23 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"extract-zip@npm:^2.0.1":
version: 2.0.1
resolution: "extract-zip@npm:2.0.1"
dependencies:
"@types/yauzl": ^2.9.1
debug: ^4.1.1
get-stream: ^5.1.0
yauzl: ^2.10.0
dependenciesMeta:
"@types/yauzl":
optional: true
bin:
extract-zip: cli.js
checksum: 8cbda9debdd6d6980819cc69734d874ddd71051c9fe5bde1ef307ebcedfe949ba57b004894b585f758b7c9eeeea0e3d87f2dda89b7d25320459c2c9643ebb635
languageName: node
linkType: hard
"extsprintf@npm:1.3.0": "extsprintf@npm:1.3.0":
version: 1.3.0 version: 1.3.0
resolution: "extsprintf@npm:1.3.0" resolution: "extsprintf@npm:1.3.0"
@ -10695,6 +10754,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"fd-slicer@npm:~1.1.0":
version: 1.1.0
resolution: "fd-slicer@npm:1.1.0"
dependencies:
pend: ~1.2.0
checksum: c8585fd5713f4476eb8261150900d2cb7f6ff2d87f8feb306ccc8a1122efd152f1783bdb2b8dc891395744583436bfd8081d8e63ece0ec8687eeefea394d4ff2
languageName: node
linkType: hard
"fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4": "fetch-blob@npm:^3.1.2, fetch-blob@npm:^3.1.4":
version: 3.1.4 version: 3.1.4
resolution: "fetch-blob@npm:3.1.4" resolution: "fetch-blob@npm:3.1.4"
@ -11294,6 +11362,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"get-stream@npm:^5.1.0":
version: 5.2.0
resolution: "get-stream@npm:5.2.0"
dependencies:
pump: ^3.0.0
checksum: 8bc1a23174a06b2b4ce600df38d6c98d2ef6d84e020c1ddad632ad75bac4e092eeb40e4c09e0761c35fc2dbc5e7fff5dab5e763a383582c4a167dd69a905bd12
languageName: node
linkType: hard
"get-stream@npm:^6.0.0, get-stream@npm:^6.0.1": "get-stream@npm:^6.0.0, get-stream@npm:^6.0.1":
version: 6.0.1 version: 6.0.1
resolution: "get-stream@npm:6.0.1" resolution: "get-stream@npm:6.0.1"
@ -12912,6 +12989,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"jpeg-js@npm:^0.4.2":
version: 0.4.3
resolution: "jpeg-js@npm:0.4.3"
checksum: 9e5bacc9135efa7da340b62e81fa56fab0c8516ef617228758132af5b7d31b516cc6e1500cdffb82d3161629be341be980099f2b37eb76b81e26db6e3e848c77
languageName: node
linkType: hard
"js-tokens@npm:^4.0.0": "js-tokens@npm:^4.0.0":
version: 4.0.0 version: 4.0.0
resolution: "js-tokens@npm:4.0.0" resolution: "js-tokens@npm:4.0.0"
@ -15972,6 +16056,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pend@npm:~1.2.0":
version: 1.2.0
resolution: "pend@npm:1.2.0"
checksum: 6c72f5243303d9c60bd98e6446ba7d30ae29e3d56fdb6fae8767e8ba6386f33ee284c97efe3230a0d0217e2b1723b8ab490b1bbf34fcbb2180dbc8a9de47850d
languageName: node
linkType: hard
"performance-now@npm:^2.1.0": "performance-now@npm:^2.1.0":
version: 2.1.0 version: 2.1.0
resolution: "performance-now@npm:2.1.0" resolution: "performance-now@npm:2.1.0"
@ -16057,6 +16148,43 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"playwright-core@npm:=1.18.1":
version: 1.18.1
resolution: "playwright-core@npm:1.18.1"
dependencies:
commander: ^8.2.0
debug: ^4.1.1
extract-zip: ^2.0.1
https-proxy-agent: ^5.0.0
jpeg-js: ^0.4.2
mime: ^2.4.6
pngjs: ^5.0.0
progress: ^2.0.3
proper-lockfile: ^4.1.1
proxy-from-env: ^1.1.0
rimraf: ^3.0.2
socks-proxy-agent: ^6.1.0
stack-utils: ^2.0.3
ws: ^7.4.6
yauzl: ^2.10.0
yazl: ^2.5.1
bin:
playwright: cli.js
checksum: 7b3d5a228bb0559eece28c82f6aa963a9f3cb68f56e470feb968fe414e4f0074edb9a2d9b27266f4927be31d57203cdfb739e57d5b30744d5f30800a8025b3b8
languageName: node
linkType: hard
"playwright@npm:^1.18.0":
version: 1.18.1
resolution: "playwright@npm:1.18.1"
dependencies:
playwright-core: =1.18.1
bin:
playwright: cli.js
checksum: a50c4c3b04c0f4c2698898003b5cba8d24af0de01e13e9af754d34af4d928d5397704ab7e84a593fb614d538fe72e307f69f01971219857118cd619ee3f91c88
languageName: node
linkType: hard
"pluralize@npm:^8.0.0": "pluralize@npm:^8.0.0":
version: 8.0.0 version: 8.0.0
resolution: "pluralize@npm:8.0.0" resolution: "pluralize@npm:8.0.0"
@ -16064,6 +16192,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pngjs@npm:^5.0.0":
version: 5.0.0
resolution: "pngjs@npm:5.0.0"
checksum: 04e912cc45fb9601564e2284efaf0c5d20d131d9b596244f8a6789fc6cdb6b18d2975a6bbf7a001858d7e159d5c5c5dd7b11592e97629b7137f7f5cef05904c8
languageName: node
linkType: hard
"pnp-webpack-plugin@npm:^1.6.4, pnp-webpack-plugin@npm:^1.7.0": "pnp-webpack-plugin@npm:^1.6.4, pnp-webpack-plugin@npm:^1.7.0":
version: 1.7.0 version: 1.7.0
resolution: "pnp-webpack-plugin@npm:1.7.0" resolution: "pnp-webpack-plugin@npm:1.7.0"
@ -17703,6 +17838,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"progress@npm:^2.0.3":
version: 2.0.3
resolution: "progress@npm:2.0.3"
checksum: f67403fe7b34912148d9252cb7481266a354bd99ce82c835f79070643bb3c6583d10dbcfda4d41e04bbc1d8437e9af0fb1e1f2135727878f5308682a579429b7
languageName: node
linkType: hard
"promise-inflight@npm:^1.0.1": "promise-inflight@npm:^1.0.1":
version: 1.0.1 version: 1.0.1
resolution: "promise-inflight@npm:1.0.1" resolution: "promise-inflight@npm:1.0.1"
@ -17729,7 +17871,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"proper-lockfile@npm:^4.1.2": "proper-lockfile@npm:^4.1.1, proper-lockfile@npm:^4.1.2":
version: 4.1.2 version: 4.1.2
resolution: "proper-lockfile@npm:4.1.2" resolution: "proper-lockfile@npm:4.1.2"
dependencies: dependencies:
@ -17754,6 +17896,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"proxy-from-env@npm:^1.1.0":
version: 1.1.0
resolution: "proxy-from-env@npm:1.1.0"
checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4
languageName: node
linkType: hard
"prr@npm:~1.0.1": "prr@npm:~1.0.1":
version: 1.0.1 version: 1.0.1
resolution: "prr@npm:1.0.1" resolution: "prr@npm:1.0.1"
@ -19208,7 +19357,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"socks-proxy-agent@npm:^6.0.0": "socks-proxy-agent@npm:^6.0.0, socks-proxy-agent@npm:^6.1.0":
version: 6.1.1 version: 6.1.1
resolution: "socks-proxy-agent@npm:6.1.1" resolution: "socks-proxy-agent@npm:6.1.1"
dependencies: dependencies:
@ -19463,6 +19612,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"stack-utils@npm:^2.0.3":
version: 2.0.5
resolution: "stack-utils@npm:2.0.5"
dependencies:
escape-string-regexp: ^2.0.0
checksum: 76b69da0f5b48a34a0f93c98ee2a96544d2c4ca2557f7eef5ddb961d3bdc33870b46f498a84a7c4f4ffb781df639840e7ebf6639164ed4da5e1aeb659615b9c7
languageName: node
linkType: hard
"stackframe@npm:^1.1.1": "stackframe@npm:^1.1.1":
version: 1.2.0 version: 1.2.0
resolution: "stackframe@npm:1.2.0" resolution: "stackframe@npm:1.2.0"
@ -21216,6 +21374,37 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vitest@npm:^0.3.2":
version: 0.3.2
resolution: "vitest@npm:0.3.2"
dependencies:
"@types/chai": ^4.3.0
"@types/chai-subset": ^1.3.3
chai: ^4.3.6
local-pkg: ^0.4.1
tinypool: ^0.1.1
tinyspy: ^0.2.10
vite: ">=2.7.13"
peerDependencies:
"@vitest/ui": "*"
c8: "*"
happy-dom: "*"
jsdom: "*"
peerDependenciesMeta:
"@vitest/ui":
optional: true
c8:
optional: true
happy-dom:
optional: true
jsdom:
optional: true
bin:
vitest: vitest.mjs
checksum: 858dd3d16f7583b77bca0ab7810d4b1efdba92392cd6a2d97a62cf26ef1c041bda08e15e1694f69d1654bb7aaaab65d52c3684e03a8c364e5edab261f992e218
languageName: node
linkType: hard
"vm-browserify@npm:^1.0.1": "vm-browserify@npm:^1.0.1":
version: 1.1.2 version: 1.1.2
resolution: "vm-browserify@npm:1.1.2" resolution: "vm-browserify@npm:1.1.2"
@ -21934,7 +22123,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ws@npm:^7.3.1, ws@npm:^7.5.0": "ws@npm:^7.3.1, ws@npm:^7.4.6, ws@npm:^7.5.0":
version: 7.5.7 version: 7.5.7
resolution: "ws@npm:7.5.7" resolution: "ws@npm:7.5.7"
peerDependencies: peerDependencies:
@ -22073,6 +22262,25 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"yauzl@npm:^2.10.0":
version: 2.10.0
resolution: "yauzl@npm:2.10.0"
dependencies:
buffer-crc32: ~0.2.3
fd-slicer: ~1.1.0
checksum: 7f21fe0bbad6e2cb130044a5d1d0d5a0e5bf3d8d4f8c4e6ee12163ce798fee3de7388d22a7a0907f563ac5f9d40f8699a223d3d5c1718da90b0156da6904022b
languageName: node
linkType: hard
"yazl@npm:^2.5.1":
version: 2.5.1
resolution: "yazl@npm:2.5.1"
dependencies:
buffer-crc32: ~0.2.3
checksum: daec5154b5485d8621bfea359e905ddca0b2f068430a4aa0a802bf5d67391157a383e0c2767acccbf5964264851da643bc740155a9458e2d8dce55b94c1cc2ed
languageName: node
linkType: hard
"yocto-queue@npm:^0.1.0": "yocto-queue@npm:^0.1.0":
version: 0.1.0 version: 0.1.0
resolution: "yocto-queue@npm:0.1.0" resolution: "yocto-queue@npm:0.1.0"