mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 23:22:02 +00:00
317 lines
7.6 KiB
TypeScript
317 lines
7.6 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest'
|
|
import { applyPlugins } from '#app/nuxt'
|
|
import { defineNuxtPlugin } from '#app'
|
|
|
|
vi.mock('#app', async (original) => {
|
|
return {
|
|
...(await original<typeof import('#app')>()),
|
|
applyPlugin: vi.fn(async (_nuxtApp, plugin) => {
|
|
await plugin()
|
|
}),
|
|
}
|
|
})
|
|
|
|
function pluginFactory (name: string, dependsOn: string[] | undefined, sequence: string[], parallel = true) {
|
|
return defineNuxtPlugin({
|
|
name,
|
|
// @ts-expect-error we have a strong type for plugin names
|
|
dependsOn,
|
|
async setup () {
|
|
sequence.push(`start ${name}`)
|
|
await new Promise(resolve => setTimeout(resolve, 10))
|
|
sequence.push(`end ${name}`)
|
|
},
|
|
parallel,
|
|
})
|
|
}
|
|
|
|
describe('plugin dependsOn', () => {
|
|
it('expect B to await A to finish before being run', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence),
|
|
pluginFactory('B', ['A'], sequence),
|
|
]
|
|
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'end A',
|
|
'start B',
|
|
'end B',
|
|
])
|
|
})
|
|
|
|
it('expect C to await A and B to finish before being run', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence),
|
|
pluginFactory('B', ['A'], sequence),
|
|
pluginFactory('C', ['A', 'B'], sequence),
|
|
]
|
|
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'end A',
|
|
'start B',
|
|
'end B',
|
|
'start C',
|
|
'end C',
|
|
])
|
|
})
|
|
|
|
it('expect C to not wait for A to finish before being run', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence),
|
|
pluginFactory('B', ['A'], sequence),
|
|
defineNuxtPlugin({
|
|
name: 'some plugin',
|
|
async setup () {
|
|
sequence.push('start C')
|
|
await new Promise(resolve => setTimeout(resolve, 5))
|
|
sequence.push('end C')
|
|
},
|
|
parallel: true,
|
|
}),
|
|
]
|
|
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'start C',
|
|
'end C',
|
|
'end A',
|
|
'start B',
|
|
'end B',
|
|
])
|
|
})
|
|
|
|
it('expect C to block the depends on of A-B since C is sequential', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence),
|
|
defineNuxtPlugin({
|
|
name: 'some plugin',
|
|
async setup () {
|
|
sequence.push('start C')
|
|
await new Promise(resolve => setTimeout(resolve, 50))
|
|
sequence.push('end C')
|
|
},
|
|
}),
|
|
pluginFactory('B', ['A'], sequence),
|
|
]
|
|
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'start C',
|
|
'end A',
|
|
'end C',
|
|
'start B',
|
|
'end B',
|
|
])
|
|
})
|
|
|
|
it('relying on plugin not registered yet', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('C', ['A'], sequence),
|
|
pluginFactory('A', undefined, sequence, true),
|
|
pluginFactory('E', ['B', 'C'], sequence, false),
|
|
pluginFactory('B', undefined, sequence),
|
|
pluginFactory('D', ['C'], sequence, false),
|
|
]
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'start B',
|
|
'end A',
|
|
'start C',
|
|
'end B',
|
|
'end C',
|
|
'start E',
|
|
'start D',
|
|
'end E',
|
|
'end D',
|
|
])
|
|
})
|
|
|
|
it('test depending on not yet registered plugin and already resolved plugin', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence),
|
|
pluginFactory('B', ['A', 'C'], sequence),
|
|
pluginFactory('C', undefined, sequence, false),
|
|
pluginFactory('D', undefined, sequence, false),
|
|
pluginFactory('E', ['C'], sequence, false),
|
|
]
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'start C',
|
|
'end A',
|
|
'end C',
|
|
'start B',
|
|
'start D',
|
|
'end B',
|
|
'end D',
|
|
'start E',
|
|
'end E',
|
|
])
|
|
})
|
|
|
|
it('multiple depth of plugin dependency', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence),
|
|
pluginFactory('C', ['B', 'A'], sequence),
|
|
pluginFactory('B', undefined, sequence, false),
|
|
pluginFactory('E', ['D'], sequence, false),
|
|
pluginFactory('D', ['C'], sequence, false),
|
|
]
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'start B',
|
|
'end A',
|
|
'end B',
|
|
'start C',
|
|
'end C',
|
|
'start D',
|
|
'end D',
|
|
'start E',
|
|
'end E',
|
|
])
|
|
})
|
|
|
|
it('does not throw when circular dependency is not a problem', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', ['B'], sequence),
|
|
pluginFactory('B', ['C'], sequence),
|
|
pluginFactory('C', ['D'], sequence),
|
|
pluginFactory('D', [], sequence),
|
|
]
|
|
|
|
await applyPlugins(nuxtApp, plugins)
|
|
expect(sequence).toMatchObject([
|
|
'start D',
|
|
'end D',
|
|
'start C',
|
|
'end C',
|
|
'start B',
|
|
'end B',
|
|
'start A',
|
|
'end A',
|
|
])
|
|
})
|
|
|
|
it('function plugin', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence),
|
|
defineNuxtPlugin(() => {
|
|
sequence.push('start C')
|
|
sequence.push('end C')
|
|
}),
|
|
pluginFactory('B', undefined, sequence, false),
|
|
]
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'start C',
|
|
'end C',
|
|
'start B',
|
|
'end A',
|
|
'end B',
|
|
])
|
|
})
|
|
|
|
it('expect B to execute after A, C when B depends on A and C', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('A', undefined, sequence, false),
|
|
pluginFactory('B', ['A', 'C'], sequence, false),
|
|
pluginFactory('C', undefined, sequence, false),
|
|
]
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'end A',
|
|
'start C',
|
|
'end C',
|
|
'start B',
|
|
'end B',
|
|
])
|
|
})
|
|
|
|
it('expect to execute plugins if a plugin depends on a plugin that does not exist', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
pluginFactory('B', undefined, sequence),
|
|
pluginFactory('C', ['A', 'B'], sequence),
|
|
]
|
|
await applyPlugins(nuxtApp, plugins)
|
|
|
|
expect(sequence).toMatchObject([
|
|
'start B',
|
|
'end B',
|
|
'start C',
|
|
'end C',
|
|
])
|
|
})
|
|
})
|
|
|
|
describe('plugin hooks', () => {
|
|
it('registers hooks before executing plugins', async () => {
|
|
const nuxtApp = useNuxtApp()
|
|
|
|
const sequence: string[] = []
|
|
const plugins = [
|
|
defineNuxtPlugin({
|
|
name: 'A',
|
|
setup (nuxt) {
|
|
sequence.push('start A')
|
|
nuxt.callHook('a:setup')
|
|
},
|
|
}),
|
|
defineNuxtPlugin({
|
|
name: 'B',
|
|
hooks: {
|
|
'a:setup': () => {
|
|
sequence.push('listen B')
|
|
},
|
|
},
|
|
}),
|
|
]
|
|
|
|
await applyPlugins(nuxtApp, plugins)
|
|
expect(sequence).toMatchObject([
|
|
'start A',
|
|
'listen B',
|
|
])
|
|
})
|
|
})
|