mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-11 08:33:53 +00:00
feat(test): unit tests for @nuxt/builder (#4834)
This commit is contained in:
parent
422155ea14
commit
43491f6e53
@ -107,12 +107,10 @@ export default class Builder {
|
|||||||
|
|
||||||
async build() {
|
async build() {
|
||||||
// Avoid calling build() method multiple times when dev:true
|
// Avoid calling build() method multiple times when dev:true
|
||||||
/* istanbul ignore if */
|
|
||||||
if (this._buildStatus === STATUS.BUILD_DONE && this.options.dev) {
|
if (this._buildStatus === STATUS.BUILD_DONE && this.options.dev) {
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
// If building
|
// If building
|
||||||
/* istanbul ignore if */
|
|
||||||
if (this._buildStatus === STATUS.BUILDING) {
|
if (this._buildStatus === STATUS.BUILDING) {
|
||||||
await waitFor(1000)
|
await waitFor(1000)
|
||||||
return this.build()
|
return this.build()
|
||||||
@ -302,7 +300,7 @@ export default class Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async resolveLayouts({ templateVars, templateFiles }) {
|
async resolveLayouts({ templateVars, templateFiles }) {
|
||||||
if (fsExtra.existsSync(path.resolve(this.options.srcDir, this.options.dir.layouts))) {
|
if (await fsExtra.exists(path.resolve(this.options.srcDir, this.options.dir.layouts))) {
|
||||||
for (const file of await this.resolveFiles(this.options.dir.layouts)) {
|
for (const file of await this.resolveFiles(this.options.dir.layouts)) {
|
||||||
const name = file
|
const name = file
|
||||||
.replace(new RegExp(`^${this.options.dir.layouts}/`), '')
|
.replace(new RegExp(`^${this.options.dir.layouts}/`), '')
|
||||||
@ -467,7 +465,7 @@ export default class Builder {
|
|||||||
this.options.loadingIndicator.name
|
this.options.loadingIndicator.name
|
||||||
)
|
)
|
||||||
|
|
||||||
if (fsExtra.existsSync(indicatorPath)) {
|
if (await fsExtra.exists(indicatorPath)) {
|
||||||
customIndicator = true
|
customIndicator = true
|
||||||
} else {
|
} else {
|
||||||
indicatorPath = null
|
indicatorPath = null
|
||||||
@ -572,7 +570,7 @@ export default class Builder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Uncomment when generateConfig enabled again
|
// TODO: Uncomment when generateConfig enabled again
|
||||||
// async generateConfig() /* istanbul ignore next */ {
|
// async generateConfig() {
|
||||||
// const config = path.resolve(this.options.buildDir, 'build.config.js')
|
// const config = path.resolve(this.options.buildDir, 'build.config.js')
|
||||||
// const options = omit(this.options, Options.unsafeKeys)
|
// const options = omit(this.options, Options.unsafeKeys)
|
||||||
// await fsExtra.writeFile(
|
// await fsExtra.writeFile(
|
||||||
@ -603,7 +601,6 @@ export default class Builder {
|
|||||||
patterns = patterns.map(upath.normalizeSafe)
|
patterns = patterns.map(upath.normalizeSafe)
|
||||||
|
|
||||||
const options = this.options.watchers.chokidar
|
const options = this.options.watchers.chokidar
|
||||||
/* istanbul ignore next */
|
|
||||||
const refreshFiles = debounce(() => this.generateRoutesAndFiles(), 200)
|
const refreshFiles = debounce(() => this.generateRoutesAndFiles(), 200)
|
||||||
|
|
||||||
// Watch for src Files
|
// Watch for src Files
|
||||||
|
15
packages/builder/test/__utils__/index.js
Normal file
15
packages/builder/test/__utils__/index.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export const createNuxt = () => ({
|
||||||
|
options: {
|
||||||
|
globalName: 'global_name',
|
||||||
|
globals: [],
|
||||||
|
build: {},
|
||||||
|
router: {}
|
||||||
|
},
|
||||||
|
ready: jest.fn(),
|
||||||
|
hook: jest.fn(),
|
||||||
|
callHook: jest.fn(),
|
||||||
|
resolver: {
|
||||||
|
requireModule: jest.fn(() => ({ template: 'builder-template' })),
|
||||||
|
resolveAlias: jest.fn(src => `resolveAlias(${src})`)
|
||||||
|
}
|
||||||
|
})
|
287
packages/builder/test/builder.build.test.js
Normal file
287
packages/builder/test/builder.build.test.js
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import consola from 'consola'
|
||||||
|
import fsExtra from 'fs-extra'
|
||||||
|
import semver from 'semver'
|
||||||
|
import { r, waitFor } from '@nuxt/utils'
|
||||||
|
|
||||||
|
import Builder from '../src/builder'
|
||||||
|
import { createNuxt } from './__utils__'
|
||||||
|
|
||||||
|
jest.mock('fs-extra')
|
||||||
|
jest.mock('semver')
|
||||||
|
jest.mock('hash-sum', () => src => `hash(${src})`)
|
||||||
|
jest.mock('@nuxt/utils')
|
||||||
|
jest.mock('../src/ignore')
|
||||||
|
|
||||||
|
describe('builder: builder build', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.spyOn(path, 'join').mockImplementation((...args) => `join(${args.join(', ')})`)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
path.join.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should build all resources', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.buildDir = '/var/nuxt/build'
|
||||||
|
nuxt.options.dir = { pages: '/var/nuxt/src/pages' }
|
||||||
|
nuxt.options.build.createRoutes = jest.fn()
|
||||||
|
|
||||||
|
const bundleBuilder = { build: jest.fn() }
|
||||||
|
const builder = new Builder(nuxt, bundleBuilder)
|
||||||
|
builder.validatePages = jest.fn()
|
||||||
|
builder.validateTemplate = jest.fn()
|
||||||
|
builder.generateRoutesAndFiles = jest.fn()
|
||||||
|
builder.resolvePlugins = jest.fn()
|
||||||
|
|
||||||
|
r.mockImplementation((dir, src) => `r(${dir})`)
|
||||||
|
|
||||||
|
const buildReturn = await builder.build()
|
||||||
|
|
||||||
|
expect(consola.info).toBeCalledTimes(1)
|
||||||
|
expect(consola.info).toBeCalledWith('Production build')
|
||||||
|
expect(nuxt.ready).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.callHook).toBeCalledTimes(2)
|
||||||
|
expect(nuxt.callHook).nthCalledWith(1, 'build:before', builder, nuxt.options.build)
|
||||||
|
expect(builder.validatePages).toBeCalledTimes(1)
|
||||||
|
expect(builder.validateTemplate).toBeCalledTimes(1)
|
||||||
|
expect(consola.success).toBeCalledTimes(1)
|
||||||
|
expect(consola.success).toBeCalledWith('Builder initialized')
|
||||||
|
expect(consola.debug).toBeCalledTimes(1)
|
||||||
|
expect(consola.debug).toBeCalledWith('App root: /var/nuxt/src')
|
||||||
|
expect(fsExtra.remove).toBeCalledTimes(1)
|
||||||
|
expect(fsExtra.remove).toBeCalledWith('r(/var/nuxt/build)')
|
||||||
|
expect(fsExtra.mkdirp).toBeCalledTimes(3)
|
||||||
|
expect(fsExtra.mkdirp).nthCalledWith(1, 'r(/var/nuxt/build)')
|
||||||
|
expect(fsExtra.mkdirp).nthCalledWith(2, 'r(/var/nuxt/build)')
|
||||||
|
expect(fsExtra.mkdirp).nthCalledWith(3, 'r(/var/nuxt/build)')
|
||||||
|
expect(r).toBeCalledTimes(4)
|
||||||
|
expect(r).nthCalledWith(1, '/var/nuxt/build')
|
||||||
|
expect(r).nthCalledWith(2, '/var/nuxt/build', 'components')
|
||||||
|
expect(r).nthCalledWith(3, '/var/nuxt/build', 'dist', 'client')
|
||||||
|
expect(r).nthCalledWith(4, '/var/nuxt/build', 'dist', 'server')
|
||||||
|
expect(builder.generateRoutesAndFiles).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolvePlugins).toBeCalledTimes(1)
|
||||||
|
expect(bundleBuilder.build).toBeCalledTimes(1)
|
||||||
|
expect(builder._buildStatus).toEqual(2)
|
||||||
|
expect(nuxt.callHook).nthCalledWith(2, 'build:done', builder)
|
||||||
|
expect(buildReturn).toBe(builder)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should prevent duplicate build in dev mode', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.dev = true
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder._buildStatus = 3
|
||||||
|
|
||||||
|
waitFor.mockImplementationOnce(() => {
|
||||||
|
builder.build = jest.fn(() => 'calling build')
|
||||||
|
})
|
||||||
|
|
||||||
|
const buildReturn = await builder.build()
|
||||||
|
|
||||||
|
expect(nuxt.ready).not.toBeCalled()
|
||||||
|
expect(waitFor).toBeCalledTimes(1)
|
||||||
|
expect(waitFor).toBeCalledWith(1000)
|
||||||
|
expect(builder.build).toBeCalledTimes(1)
|
||||||
|
expect(buildReturn).toBe('calling build')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should wait 1000ms and retry if building is in progress', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.dev = true
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder._buildStatus = 2
|
||||||
|
|
||||||
|
const buildReturn = await builder.build()
|
||||||
|
|
||||||
|
expect(nuxt.ready).not.toBeCalled()
|
||||||
|
expect(buildReturn).toBe(builder)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should build in dev mode and print dev mode building messages', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.dev = true
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.buildDir = '/var/nuxt/build'
|
||||||
|
nuxt.options.dir = { pages: '/var/nuxt/src/pages' }
|
||||||
|
nuxt.options.build.createRoutes = jest.fn()
|
||||||
|
|
||||||
|
const bundleBuilder = { build: jest.fn() }
|
||||||
|
const builder = new Builder(nuxt, bundleBuilder)
|
||||||
|
builder.validatePages = jest.fn()
|
||||||
|
builder.validateTemplate = jest.fn()
|
||||||
|
builder.generateRoutesAndFiles = jest.fn()
|
||||||
|
builder.resolvePlugins = jest.fn()
|
||||||
|
|
||||||
|
await builder.build()
|
||||||
|
|
||||||
|
expect(consola.info).toBeCalledTimes(2)
|
||||||
|
expect(consola.info).nthCalledWith(1, 'Preparing project for development')
|
||||||
|
expect(consola.info).nthCalledWith(2, 'Initial build may take a while')
|
||||||
|
expect(fsExtra.mkdirp).toBeCalledTimes(1)
|
||||||
|
expect(fsExtra.mkdirp).toBeCalledWith('r(/var/nuxt/build)')
|
||||||
|
expect(r).toBeCalledTimes(2)
|
||||||
|
expect(r).nthCalledWith(1, '/var/nuxt/build')
|
||||||
|
expect(r).nthCalledWith(2, '/var/nuxt/build', 'components')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should throw error when validateTemplate failed', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.validatePages = jest.fn()
|
||||||
|
builder.validateTemplate = jest.fn(() => {
|
||||||
|
throw new Error('validate failed')
|
||||||
|
})
|
||||||
|
consola.success.mockImplementationOnce(() => {
|
||||||
|
throw new Error('exit')
|
||||||
|
})
|
||||||
|
|
||||||
|
await expect(builder.build()).rejects.toThrow('exit')
|
||||||
|
|
||||||
|
expect(builder._buildStatus).toEqual(3)
|
||||||
|
expect(consola.fatal).toBeCalledTimes(1)
|
||||||
|
expect(consola.fatal).toBeCalledWith(new Error('validate failed'))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should warn built-in page will be used if no pages dir found', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = { pages: '/var/nuxt/src/pages' }
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
fsExtra.exists.mockReturnValue(false)
|
||||||
|
|
||||||
|
await builder.validatePages()
|
||||||
|
|
||||||
|
expect(builder._nuxtPages).toEqual(true)
|
||||||
|
expect(path.join).toBeCalledTimes(2)
|
||||||
|
expect(path.join).nthCalledWith(1, '/var/nuxt/src', '/var/nuxt/src/pages')
|
||||||
|
expect(path.join).nthCalledWith(2, '/var/nuxt/src', '..', '/var/nuxt/src/pages')
|
||||||
|
expect(fsExtra.exists).toBeCalledTimes(2)
|
||||||
|
expect(fsExtra.exists).nthCalledWith(1, 'join(/var/nuxt/src, /var/nuxt/src/pages)')
|
||||||
|
expect(fsExtra.exists).nthCalledWith(2, 'join(/var/nuxt/src, .., /var/nuxt/src/pages)')
|
||||||
|
expect(builder._defaultPage).toEqual(true)
|
||||||
|
expect(consola.warn).toBeCalledTimes(1)
|
||||||
|
expect(consola.warn).toBeCalledWith('No `/var/nuxt/src/pages` directory found in /var/nuxt/src. Using the default built-in page.')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should throw error if pages is found in parent dir', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = { pages: '/var/nuxt/src/pages' }
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
fsExtra.exists
|
||||||
|
.mockReturnValueOnce(false)
|
||||||
|
.mockReturnValueOnce(true)
|
||||||
|
|
||||||
|
await expect(builder.validatePages()).rejects.toThrow(
|
||||||
|
'No `/var/nuxt/src/pages` directory found in /var/nuxt/src. Did you mean to run `nuxt` in the parent (`../`) directory?'
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(builder._nuxtPages).toEqual(true)
|
||||||
|
expect(path.join).toBeCalledTimes(2)
|
||||||
|
expect(path.join).nthCalledWith(1, '/var/nuxt/src', '/var/nuxt/src/pages')
|
||||||
|
expect(path.join).nthCalledWith(2, '/var/nuxt/src', '..', '/var/nuxt/src/pages')
|
||||||
|
expect(fsExtra.exists).toBeCalledTimes(2)
|
||||||
|
expect(fsExtra.exists).nthCalledWith(1, 'join(/var/nuxt/src, /var/nuxt/src/pages)')
|
||||||
|
expect(fsExtra.exists).nthCalledWith(2, 'join(/var/nuxt/src, .., /var/nuxt/src/pages)')
|
||||||
|
expect(builder._defaultPage).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should pass validation if createRoutes is function', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.build.createRoutes = jest.fn()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
await builder.validatePages()
|
||||||
|
|
||||||
|
expect(builder._nuxtPages).toEqual(false)
|
||||||
|
expect(fsExtra.exists).not.toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should pass validation if pages exists', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = { pages: '/var/nuxt/src/pages' }
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
fsExtra.exists.mockReturnValueOnce(true)
|
||||||
|
|
||||||
|
await builder.validatePages()
|
||||||
|
|
||||||
|
expect(builder._nuxtPages).toEqual(true)
|
||||||
|
expect(path.join).toBeCalledTimes(1)
|
||||||
|
expect(path.join).toBeCalledWith('/var/nuxt/src', '/var/nuxt/src/pages')
|
||||||
|
expect(fsExtra.exists).toBeCalledTimes(1)
|
||||||
|
expect(fsExtra.exists).toBeCalledWith('join(/var/nuxt/src, /var/nuxt/src/pages)')
|
||||||
|
expect(builder._defaultPage).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should validate dependencies in template', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.build.template = {
|
||||||
|
dependencies: {
|
||||||
|
vue: 'latest',
|
||||||
|
nuxt: 'edge'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
semver.satisfies
|
||||||
|
.mockReturnValueOnce(true)
|
||||||
|
.mockReturnValueOnce(true)
|
||||||
|
nuxt.resolver.requireModule
|
||||||
|
.mockReturnValueOnce({ version: 'alpha' })
|
||||||
|
.mockReturnValueOnce({ version: 'beta' })
|
||||||
|
|
||||||
|
builder.validateTemplate()
|
||||||
|
|
||||||
|
expect(nuxt.resolver.requireModule).toBeCalledTimes(2)
|
||||||
|
expect(nuxt.resolver.requireModule).nthCalledWith(1, 'join(vue, package.json)')
|
||||||
|
expect(nuxt.resolver.requireModule).nthCalledWith(2, 'join(nuxt, package.json)')
|
||||||
|
expect(semver.satisfies).toBeCalledTimes(2)
|
||||||
|
expect(semver.satisfies).nthCalledWith(1, 'alpha', 'latest')
|
||||||
|
expect(semver.satisfies).nthCalledWith(2, 'beta', 'edge')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should warn and throw error if dependencies is not installed', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.build.template = {
|
||||||
|
dependencies: {
|
||||||
|
vue: 'latest',
|
||||||
|
nuxt: 'edge'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
semver.satisfies
|
||||||
|
.mockReturnValueOnce(false)
|
||||||
|
nuxt.resolver.requireModule
|
||||||
|
.mockReturnValueOnce({ version: 'alpha' })
|
||||||
|
.mockReturnValueOnce(undefined)
|
||||||
|
|
||||||
|
expect(() => builder.validateTemplate()).toThrow('Missing Template Dependencies')
|
||||||
|
|
||||||
|
expect(nuxt.resolver.requireModule).toBeCalledTimes(2)
|
||||||
|
expect(nuxt.resolver.requireModule).nthCalledWith(1, 'join(vue, package.json)')
|
||||||
|
expect(nuxt.resolver.requireModule).nthCalledWith(2, 'join(nuxt, package.json)')
|
||||||
|
expect(consola.warn).toBeCalledTimes(2)
|
||||||
|
expect(consola.warn).nthCalledWith(1, 'vue@latest is required but vue@alpha is installed!')
|
||||||
|
expect(consola.warn).nthCalledWith(2, 'nuxt@edge is required but not installed!')
|
||||||
|
expect(consola.error).toBeCalledTimes(1)
|
||||||
|
expect(consola.error).toBeCalledWith(
|
||||||
|
'Please install missing dependencies:\n',
|
||||||
|
'\n',
|
||||||
|
'Using yarn:\n',
|
||||||
|
'yarn add vue@latest nuxt@edge\n',
|
||||||
|
'\n',
|
||||||
|
'Using npm:\n',
|
||||||
|
'npm i vue@latest nuxt@edge\n'
|
||||||
|
)
|
||||||
|
expect(semver.satisfies).toBeCalledTimes(1)
|
||||||
|
expect(semver.satisfies).nthCalledWith(1, 'alpha', 'latest')
|
||||||
|
})
|
||||||
|
})
|
59
packages/builder/test/builder.common.test.js
Normal file
59
packages/builder/test/builder.common.test.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
import { BundleBuilder } from '@nuxt/webpack'
|
||||||
|
|
||||||
|
import Builder from '../src/builder'
|
||||||
|
import BuildContext from '../src/context/build'
|
||||||
|
import { createNuxt } from './__utils__'
|
||||||
|
|
||||||
|
jest.mock('@nuxt/webpack', () => ({
|
||||||
|
BundleBuilder: jest.fn(function () {
|
||||||
|
this.name = 'webpack_builder'
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
jest.mock('../src/context/build', () => jest.fn(function () {
|
||||||
|
this.name = 'build_context'
|
||||||
|
}))
|
||||||
|
jest.mock('../src/ignore')
|
||||||
|
|
||||||
|
describe('builder: builder common', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should get webpack builder by default', () => {
|
||||||
|
const builder = new Builder(createNuxt(), {})
|
||||||
|
|
||||||
|
const bundleBuilder = builder.getBundleBuilder()
|
||||||
|
|
||||||
|
expect(BuildContext).toBeCalledTimes(1)
|
||||||
|
expect(BuildContext).toBeCalledWith(builder)
|
||||||
|
expect(BundleBuilder).toBeCalledTimes(1)
|
||||||
|
expect(BundleBuilder).toBeCalledWith({ name: 'build_context' })
|
||||||
|
expect(bundleBuilder).toEqual({ name: 'webpack_builder' })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should get custom builder from given constructor', () => {
|
||||||
|
const builder = new Builder(createNuxt(), {})
|
||||||
|
|
||||||
|
const CustomBundleBuilder = jest.fn(function () {
|
||||||
|
this.name = 'custom_builder'
|
||||||
|
})
|
||||||
|
const bundleBuilder = builder.getBundleBuilder(CustomBundleBuilder)
|
||||||
|
|
||||||
|
expect(BuildContext).toBeCalledTimes(1)
|
||||||
|
expect(BuildContext).toBeCalledWith(builder)
|
||||||
|
expect(CustomBundleBuilder).toBeCalledTimes(1)
|
||||||
|
expect(CustomBundleBuilder).toBeCalledWith({ name: 'build_context' })
|
||||||
|
expect(bundleBuilder).toEqual({ name: 'custom_builder' })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should call bundleBuilder forGenerate', () => {
|
||||||
|
const bundleBuilder = {
|
||||||
|
forGenerate: jest.fn()
|
||||||
|
}
|
||||||
|
const builder = new Builder(createNuxt(), bundleBuilder)
|
||||||
|
|
||||||
|
builder.forGenerate()
|
||||||
|
|
||||||
|
expect(bundleBuilder.forGenerate).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
|
})
|
117
packages/builder/test/builder.ctor.test.js
Normal file
117
packages/builder/test/builder.ctor.test.js
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
import consola from 'consola'
|
||||||
|
import { relativeTo, determineGlobals } from '@nuxt/utils'
|
||||||
|
|
||||||
|
import Builder from '../src/builder'
|
||||||
|
import { createNuxt } from './__utils__'
|
||||||
|
|
||||||
|
jest.mock('@nuxt/utils')
|
||||||
|
jest.mock('../src/ignore')
|
||||||
|
|
||||||
|
describe('builder: builder constructor', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should construct builder', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
|
||||||
|
const bundleBuilder = {}
|
||||||
|
determineGlobals.mockReturnValueOnce('__global')
|
||||||
|
|
||||||
|
const builder = new Builder(nuxt, bundleBuilder)
|
||||||
|
|
||||||
|
expect(builder.nuxt).toEqual(nuxt)
|
||||||
|
expect(builder.plugins).toEqual([])
|
||||||
|
expect(builder.options).toEqual(nuxt.options)
|
||||||
|
|
||||||
|
expect(determineGlobals).toBeCalledTimes(1)
|
||||||
|
expect(determineGlobals).toBeCalledWith(nuxt.options.globalName, nuxt.options.globals)
|
||||||
|
|
||||||
|
expect(builder.watchers).toEqual({
|
||||||
|
files: null,
|
||||||
|
custom: null,
|
||||||
|
restart: null
|
||||||
|
})
|
||||||
|
expect(builder.supportedExtensions).toEqual(['vue', 'js', 'ts', 'tsx'])
|
||||||
|
expect(builder.relativeToBuild).toBeInstanceOf(Function)
|
||||||
|
|
||||||
|
expect(builder._buildStatus).toEqual(1)
|
||||||
|
|
||||||
|
expect(nuxt.resolver.requireModule).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.resolver.requireModule).toBeCalledWith('@nuxt/vue-app')
|
||||||
|
expect(builder.template).toEqual('builder-template')
|
||||||
|
|
||||||
|
expect(builder.bundleBuilder).toBe(bundleBuilder)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should call relativeTo in relativeToBuild', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.buildDir = '/var/nuxt/build'
|
||||||
|
const bundleBuilder = {}
|
||||||
|
const builder = new Builder(nuxt, bundleBuilder)
|
||||||
|
|
||||||
|
const args = [{}, {}]
|
||||||
|
builder.relativeToBuild(...args)
|
||||||
|
|
||||||
|
expect(relativeTo).toBeCalledTimes(1)
|
||||||
|
expect(relativeTo).toBeCalledWith('/var/nuxt/build', ...args)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should add hooks in dev mode', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.dev = true
|
||||||
|
|
||||||
|
const bundleBuilder = {}
|
||||||
|
determineGlobals.mockReturnValueOnce('__global')
|
||||||
|
|
||||||
|
const builder = new Builder(nuxt, bundleBuilder)
|
||||||
|
|
||||||
|
expect(builder.options.dev).toEqual(true)
|
||||||
|
|
||||||
|
expect(nuxt.hook).toBeCalledTimes(2)
|
||||||
|
expect(nuxt.hook).toBeCalledWith('build:done', expect.any(Function))
|
||||||
|
expect(nuxt.hook).toBeCalledWith('close', expect.any(Function))
|
||||||
|
|
||||||
|
const doneHook = nuxt.hook.mock.calls[0][1]
|
||||||
|
builder.watchClient = jest.fn()
|
||||||
|
builder.watchRestart = jest.fn()
|
||||||
|
doneHook()
|
||||||
|
expect(consola.info).toBeCalledTimes(1)
|
||||||
|
expect(consola.info).toBeCalledWith('Waiting for file changes')
|
||||||
|
expect(builder.watchClient).toBeCalledTimes(1)
|
||||||
|
expect(builder.watchRestart).toBeCalledTimes(1)
|
||||||
|
|
||||||
|
const closeHook = nuxt.hook.mock.calls[1][1]
|
||||||
|
builder.close = jest.fn()
|
||||||
|
closeHook()
|
||||||
|
expect(builder.close).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should add hooks in analyze mode', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.build.analyze = true
|
||||||
|
|
||||||
|
const bundleBuilder = {}
|
||||||
|
const builder = new Builder(nuxt, bundleBuilder)
|
||||||
|
|
||||||
|
expect(builder.options.build.analyze).toEqual(true)
|
||||||
|
|
||||||
|
expect(nuxt.hook).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.hook).toBeCalledWith('build:done', expect.any(Function))
|
||||||
|
|
||||||
|
const doneHook = nuxt.hook.mock.calls[0][1]
|
||||||
|
doneHook()
|
||||||
|
expect(consola.warn).toBeCalledTimes(1)
|
||||||
|
expect(consola.warn).toBeCalledWith('Notice: Please do not deploy bundles built with analyze mode, it\'s only for analyzing purpose.')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should support function template', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.build.template = jest.fn()
|
||||||
|
const bundleBuilder = {}
|
||||||
|
const builder = new Builder(nuxt, bundleBuilder)
|
||||||
|
|
||||||
|
expect(builder.template).toBe(nuxt.options.build.template)
|
||||||
|
expect(nuxt.resolver.requireModule).not.toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
642
packages/builder/test/builder.generate.test.js
Normal file
642
packages/builder/test/builder.generate.test.js
Normal file
@ -0,0 +1,642 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import Glob from 'glob'
|
||||||
|
import fs from 'fs-extra'
|
||||||
|
import consola from 'consola'
|
||||||
|
import template from 'lodash/template'
|
||||||
|
import { r, createRoutes, stripWhitespace } from '@nuxt/utils'
|
||||||
|
import Builder from '../src/builder'
|
||||||
|
import TemplateContext from '../src/context/template'
|
||||||
|
import { createNuxt } from './__utils__'
|
||||||
|
|
||||||
|
jest.mock('glob')
|
||||||
|
jest.mock('pify', () => fn => fn)
|
||||||
|
jest.mock('fs-extra')
|
||||||
|
jest.mock('lodash/template')
|
||||||
|
jest.mock('@nuxt/utils')
|
||||||
|
jest.mock('../src/context/template', () => jest.fn())
|
||||||
|
jest.mock('../src/ignore', () => function () {
|
||||||
|
this.filter = jest.fn(files => files)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('builder: builder generate', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
r.mockImplementation((...args) => `r(${args.join(', ')})`)
|
||||||
|
fs.readFile.mockImplementation((...args) => `readFile(${args.join(', ')})`)
|
||||||
|
fs.outputFile.mockImplementation((...args) => `outputFile(${args.join(', ')})`)
|
||||||
|
jest.spyOn(path, 'join').mockImplementation((...args) => `join(${args.join(', ')})`)
|
||||||
|
jest.spyOn(path, 'resolve').mockImplementation((...args) => `resolve(${args.join(', ')})`)
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
path.join.mockRestore()
|
||||||
|
path.resolve.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should generate routes and files', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.build = {
|
||||||
|
template: {
|
||||||
|
dir: '/var/nuxt/src/template',
|
||||||
|
files: [ 'App.js', 'index.js' ]
|
||||||
|
},
|
||||||
|
watch: []
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.normalizePlugins = jest.fn(() => [{ name: 'test_plugin' }])
|
||||||
|
builder.resolveLayouts = jest.fn(() => 'resolveLayouts')
|
||||||
|
builder.resolveRoutes = jest.fn(() => 'resolveRoutes')
|
||||||
|
builder.resolveStore = jest.fn(() => 'resolveStore')
|
||||||
|
builder.resolveMiddleware = jest.fn(() => 'resolveMiddleware')
|
||||||
|
builder.resolveCustomTemplates = jest.fn()
|
||||||
|
builder.resolveLoadingIndicator = jest.fn()
|
||||||
|
builder.compileTemplates = jest.fn()
|
||||||
|
jest.spyOn(Promise, 'all').mockImplementation(() => {})
|
||||||
|
|
||||||
|
await builder.generateRoutesAndFiles()
|
||||||
|
|
||||||
|
expect(consola.debug).toBeCalledTimes(1)
|
||||||
|
expect(consola.debug).toBeCalledWith('Generating nuxt files')
|
||||||
|
expect(TemplateContext).toBeCalledTimes(1)
|
||||||
|
expect(TemplateContext).toBeCalledWith(builder, builder.options)
|
||||||
|
expect(builder.normalizePlugins).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveLayouts).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveRoutes).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveStore).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveMiddleware).toBeCalledTimes(1)
|
||||||
|
expect(Promise.all).toBeCalledTimes(1)
|
||||||
|
expect(Promise.all).toBeCalledWith([
|
||||||
|
'resolveLayouts',
|
||||||
|
'resolveRoutes',
|
||||||
|
'resolveStore',
|
||||||
|
'resolveMiddleware'
|
||||||
|
])
|
||||||
|
expect(builder.resolveCustomTemplates).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveLoadingIndicator).toBeCalledTimes(1)
|
||||||
|
expect(builder.options.build.watch).toEqual(['/var/nuxt/src/template'])
|
||||||
|
expect(builder.compileTemplates).toBeCalledTimes(1)
|
||||||
|
expect(consola.success).toBeCalledTimes(1)
|
||||||
|
expect(consola.success).toBeCalledWith('Nuxt files generated')
|
||||||
|
|
||||||
|
Promise.all.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve files', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.ignore = '/var/nuxt/ignore'
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
Glob.mockReturnValue('matched files')
|
||||||
|
|
||||||
|
const files = await builder.resolveFiles('/var/nuxt/dir')
|
||||||
|
|
||||||
|
expect(Glob).toBeCalledTimes(1)
|
||||||
|
expect(Glob).toBeCalledWith(
|
||||||
|
'/var/nuxt/dir/**/*.{vue,js,ts,tsx}',
|
||||||
|
{ cwd: '/var/nuxt/src', ignore: '/var/nuxt/ignore' }
|
||||||
|
)
|
||||||
|
expect(builder.ignore.filter).toBeCalledTimes(1)
|
||||||
|
expect(builder.ignore.filter).toBeCalledWith('matched files')
|
||||||
|
expect(files).toEqual('matched files')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve relative files', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.resolveFiles = jest.fn(dir => [ `${dir}/foo.vue`, `${dir}/bar.vue`, `${dir}/baz.vue` ])
|
||||||
|
|
||||||
|
const files = await builder.resolveRelative('/var/nuxt/dir')
|
||||||
|
|
||||||
|
expect(builder.resolveFiles).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveFiles).toBeCalledWith('/var/nuxt/dir')
|
||||||
|
expect(files).toEqual([
|
||||||
|
{ src: 'foo.vue' },
|
||||||
|
{ src: 'bar.vue' },
|
||||||
|
{ src: 'baz.vue' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve store modules', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.store = true
|
||||||
|
nuxt.options.dir = {
|
||||||
|
store: '/var/nuxt/src/store'
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.resolveRelative = jest.fn(dir => [
|
||||||
|
{ src: `${dir}/index.js` },
|
||||||
|
{ src: `${dir}/bar.js` },
|
||||||
|
{ src: `${dir}/baz.js` },
|
||||||
|
{ src: `${dir}/foo/bar.js` },
|
||||||
|
{ src: `${dir}/foo/baz.js` },
|
||||||
|
{ src: `${dir}/foo/index.js` }
|
||||||
|
])
|
||||||
|
|
||||||
|
const templateVars = {}
|
||||||
|
const templateFiles = []
|
||||||
|
await builder.resolveStore({ templateVars, templateFiles })
|
||||||
|
|
||||||
|
expect(templateVars.storeModules).toEqual([
|
||||||
|
{ 'src': '/var/nuxt/src/store/index.js' },
|
||||||
|
{ 'src': '/var/nuxt/src/store/bar.js' },
|
||||||
|
{ 'src': '/var/nuxt/src/store/baz.js' },
|
||||||
|
{ 'src': '/var/nuxt/src/store/foo/index.js' },
|
||||||
|
{ 'src': '/var/nuxt/src/store/foo/bar.js' },
|
||||||
|
{ 'src': '/var/nuxt/src/store/foo/baz.js' }]
|
||||||
|
)
|
||||||
|
expect(templateFiles).toEqual(['store.js'])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should disable store resolving', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.dir = {
|
||||||
|
store: '/var/nuxt/src/store'
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
const templateVars = {}
|
||||||
|
const templateFiles = []
|
||||||
|
await builder.resolveStore({ templateVars, templateFiles })
|
||||||
|
|
||||||
|
expect(templateVars.storeModules).toBeUndefined()
|
||||||
|
expect(templateFiles).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve middleware', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.store = false
|
||||||
|
nuxt.options.dir = {
|
||||||
|
middleware: '/var/nuxt/src/middleware'
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.resolveRelative = jest.fn(dir => [
|
||||||
|
{ src: `${dir}/midd.js` }
|
||||||
|
])
|
||||||
|
|
||||||
|
const templateVars = {}
|
||||||
|
await builder.resolveMiddleware({ templateVars })
|
||||||
|
|
||||||
|
expect(templateVars.middleware).toEqual([ { src: '/var/nuxt/src/middleware/midd.js' } ])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should custom templates', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.build = {
|
||||||
|
template: { dir: '/var/nuxt/templates' },
|
||||||
|
templates: [
|
||||||
|
'/var/nuxt/templates/foo.js',
|
||||||
|
{ src: '/var/nuxt/templates/bar.js' },
|
||||||
|
{ src: '/var/nuxt/templates/baz.js', dst: 'baz.js' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
fs.exists.mockReturnValueOnce(true)
|
||||||
|
|
||||||
|
const templateContext = {
|
||||||
|
templateFiles: [
|
||||||
|
'foo.js',
|
||||||
|
'bar.js',
|
||||||
|
'baz.js',
|
||||||
|
'router.js',
|
||||||
|
'store.js',
|
||||||
|
'middleware.js'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
await builder.resolveCustomTemplates(templateContext)
|
||||||
|
|
||||||
|
expect(templateContext.templateFiles).toEqual([
|
||||||
|
{ custom: true, dst: 'router.js', src: 'r(/var/nuxt/src, app, router.js)' },
|
||||||
|
{ custom: undefined, dst: 'store.js', src: 'r(/var/nuxt/templates, store.js)' },
|
||||||
|
{ custom: undefined, dst: 'middleware.js', src: 'r(/var/nuxt/templates, middleware.js)' },
|
||||||
|
{ custom: true, dst: 'foo.js', src: 'r(/var/nuxt/src, /var/nuxt/templates/foo.js)' },
|
||||||
|
{ custom: true, dst: 'bar.js', src: '/var/nuxt/templates/bar.js' },
|
||||||
|
{ custom: true, dst: 'baz.js', src: '/var/nuxt/templates/baz.js' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve loading indicator', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.loadingIndicator = {
|
||||||
|
name: 'test_loading_indicator'
|
||||||
|
}
|
||||||
|
nuxt.options.build = {
|
||||||
|
template: { dir: '/var/nuxt/templates' }
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
fs.exists.mockReturnValueOnce(true)
|
||||||
|
|
||||||
|
const templateFiles = []
|
||||||
|
await builder.resolveLoadingIndicator({ templateFiles })
|
||||||
|
|
||||||
|
expect(path.resolve).toBeCalledTimes(1)
|
||||||
|
expect(path.resolve).toBeCalledWith('/var/nuxt/templates', 'views/loading', 'test_loading_indicator.html')
|
||||||
|
expect(fs.exists).toBeCalledTimes(1)
|
||||||
|
expect(fs.exists).toBeCalledWith('resolve(/var/nuxt/templates, views/loading, test_loading_indicator.html)')
|
||||||
|
expect(templateFiles).toEqual([{
|
||||||
|
custom: false,
|
||||||
|
dst: 'loading.html',
|
||||||
|
options: { name: 'test_loading_indicator' },
|
||||||
|
src: 'resolve(/var/nuxt/templates, views/loading, test_loading_indicator.html)'
|
||||||
|
}])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve alias loading indicator', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.loadingIndicator = {
|
||||||
|
name: '@/app/template.vue'
|
||||||
|
}
|
||||||
|
nuxt.options.build = {
|
||||||
|
template: { dir: '/var/nuxt/templates' }
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
fs.exists
|
||||||
|
.mockReturnValueOnce(false)
|
||||||
|
.mockReturnValueOnce(true)
|
||||||
|
|
||||||
|
const templateFiles = []
|
||||||
|
await builder.resolveLoadingIndicator({ templateFiles })
|
||||||
|
|
||||||
|
expect(path.resolve).toBeCalledTimes(1)
|
||||||
|
expect(path.resolve).toBeCalledWith('/var/nuxt/templates', 'views/loading', '@/app/template.vue.html')
|
||||||
|
expect(fs.exists).toBeCalledTimes(2)
|
||||||
|
expect(fs.exists).nthCalledWith(1, 'resolve(/var/nuxt/templates, views/loading, @/app/template.vue.html)')
|
||||||
|
expect(fs.exists).nthCalledWith(2, 'resolveAlias(@/app/template.vue)')
|
||||||
|
expect(templateFiles).toEqual([{
|
||||||
|
custom: true,
|
||||||
|
dst: 'loading.html',
|
||||||
|
options: { name: '@/app/template.vue' },
|
||||||
|
src: 'resolveAlias(@/app/template.vue)'
|
||||||
|
}])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should display error if three is not loading indicator', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.loadingIndicator = {
|
||||||
|
name: '@/app/empty.vue'
|
||||||
|
}
|
||||||
|
nuxt.options.build = {
|
||||||
|
template: { dir: '/var/nuxt/templates' }
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
fs.exists
|
||||||
|
.mockReturnValueOnce(false)
|
||||||
|
.mockReturnValueOnce(false)
|
||||||
|
|
||||||
|
const templateFiles = []
|
||||||
|
await builder.resolveLoadingIndicator({ templateFiles })
|
||||||
|
|
||||||
|
expect(path.resolve).toBeCalledTimes(1)
|
||||||
|
expect(path.resolve).toBeCalledWith('/var/nuxt/templates', 'views/loading', '@/app/empty.vue.html')
|
||||||
|
expect(fs.exists).toBeCalledTimes(2)
|
||||||
|
expect(fs.exists).nthCalledWith(1, 'resolve(/var/nuxt/templates, views/loading, @/app/empty.vue.html)')
|
||||||
|
expect(fs.exists).nthCalledWith(2, 'resolveAlias(@/app/empty.vue)')
|
||||||
|
expect(consola.error).toBeCalledTimes(1)
|
||||||
|
expect(consola.error).toBeCalledWith('Could not fetch loading indicator: @/app/empty.vue')
|
||||||
|
expect(templateFiles).toEqual([])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should disable loading indicator', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.loadingIndicator = {
|
||||||
|
name: false
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
await builder.resolveLoadingIndicator({ templateFiles: [] })
|
||||||
|
|
||||||
|
expect(path.resolve).not.toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should compile templates', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.build.watch = []
|
||||||
|
nuxt.options.buildDir = '/var/nuxt/build'
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.relativeToBuild = jest.fn()
|
||||||
|
const templateFn = jest.fn(() => 'compiled content')
|
||||||
|
template.mockImplementation(() => templateFn)
|
||||||
|
stripWhitespace.mockImplementation(content => `trim(${content})`)
|
||||||
|
|
||||||
|
const templateContext = {
|
||||||
|
templateVars: { test: 'template_vars' },
|
||||||
|
templateFiles: [
|
||||||
|
{ src: '/var/nuxt/src/foo.js', dst: 'foo.js', options: { foo: true } },
|
||||||
|
{ src: '/var/nuxt/src/bar.js', dst: 'bar.js', options: { bar: true } },
|
||||||
|
{ src: '/var/nuxt/src/baz.js', dst: 'baz.js', custom: true }
|
||||||
|
],
|
||||||
|
templateOptions: {}
|
||||||
|
}
|
||||||
|
await builder.compileTemplates(templateContext)
|
||||||
|
|
||||||
|
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.callHook).toBeCalledWith('build:templates', {
|
||||||
|
templateVars: templateContext.templateVars,
|
||||||
|
templatesFiles: templateContext.templateFiles,
|
||||||
|
resolve: r
|
||||||
|
})
|
||||||
|
expect(templateContext.templateOptions.imports).toEqual({
|
||||||
|
resolvePath: nuxt.resolver.resolvePath,
|
||||||
|
resolveAlias: nuxt.resolver.resolveAlias,
|
||||||
|
relativeToBuild: builder.relativeToBuild
|
||||||
|
})
|
||||||
|
expect(nuxt.options.build.watch).toEqual([ '/var/nuxt/src/baz.js' ])
|
||||||
|
expect(fs.readFile).toBeCalledTimes(3)
|
||||||
|
expect(fs.readFile).nthCalledWith(1, '/var/nuxt/src/foo.js', 'utf8')
|
||||||
|
expect(fs.readFile).nthCalledWith(2, '/var/nuxt/src/bar.js', 'utf8')
|
||||||
|
expect(fs.readFile).nthCalledWith(3, '/var/nuxt/src/baz.js', 'utf8')
|
||||||
|
expect(template).toBeCalledTimes(3)
|
||||||
|
expect(template).nthCalledWith(1, 'readFile(/var/nuxt/src/foo.js, utf8)', templateContext.templateOptions)
|
||||||
|
expect(template).nthCalledWith(2, 'readFile(/var/nuxt/src/bar.js, utf8)', templateContext.templateOptions)
|
||||||
|
expect(template).nthCalledWith(3, 'readFile(/var/nuxt/src/baz.js, utf8)', templateContext.templateOptions)
|
||||||
|
expect(templateFn).toBeCalledTimes(3)
|
||||||
|
expect(templateFn).nthCalledWith(1, {
|
||||||
|
...templateContext.templateVars,
|
||||||
|
custom: undefined,
|
||||||
|
dst: 'foo.js',
|
||||||
|
src: '/var/nuxt/src/foo.js',
|
||||||
|
options: { foo: true }
|
||||||
|
})
|
||||||
|
expect(templateFn).nthCalledWith(2, {
|
||||||
|
...templateContext.templateVars,
|
||||||
|
custom: undefined,
|
||||||
|
dst: 'bar.js',
|
||||||
|
src: '/var/nuxt/src/bar.js',
|
||||||
|
options: { bar: true }
|
||||||
|
})
|
||||||
|
expect(templateFn).nthCalledWith(3, {
|
||||||
|
...templateContext.templateVars,
|
||||||
|
custom: true,
|
||||||
|
dst: 'baz.js',
|
||||||
|
src: '/var/nuxt/src/baz.js',
|
||||||
|
options: {}
|
||||||
|
})
|
||||||
|
expect(stripWhitespace).toBeCalledTimes(3)
|
||||||
|
expect(stripWhitespace).nthCalledWith(1, 'compiled content')
|
||||||
|
expect(stripWhitespace).nthCalledWith(2, 'compiled content')
|
||||||
|
expect(stripWhitespace).nthCalledWith(3, 'compiled content')
|
||||||
|
expect(fs.outputFile).toBeCalledTimes(3)
|
||||||
|
expect(fs.outputFile).nthCalledWith(1, 'r(/var/nuxt/build, foo.js)', 'trim(compiled content)', 'utf8')
|
||||||
|
expect(fs.outputFile).nthCalledWith(2, 'r(/var/nuxt/build, bar.js)', 'trim(compiled content)', 'utf8')
|
||||||
|
expect(fs.outputFile).nthCalledWith(3, 'r(/var/nuxt/build, baz.js)', 'trim(compiled content)', 'utf8')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should throw error if compile failed', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.relativeToBuild = jest.fn()
|
||||||
|
template.mockImplementation(() => {
|
||||||
|
throw new Error('compile failed')
|
||||||
|
})
|
||||||
|
|
||||||
|
const templateContext = {
|
||||||
|
templateVars: { test: 'template_vars' },
|
||||||
|
templateFiles: [ { src: '/var/nuxt/src/foo.js' } ],
|
||||||
|
templateOptions: {}
|
||||||
|
}
|
||||||
|
await expect(builder.compileTemplates(templateContext)).rejects.toThrow(
|
||||||
|
'Could not compile template /var/nuxt/src/foo.js: compile failed'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('builder: builder resolveLayouts', () => {
|
||||||
|
test('should resolve layouts', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.buildDir = '/var/nuxt/build'
|
||||||
|
nuxt.options.dir = {
|
||||||
|
layouts: '/var/nuxt/src/layouts'
|
||||||
|
}
|
||||||
|
nuxt.options.layouts = {
|
||||||
|
foo: '/var/nuxt/layouts/foo/index.vue'
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.resolveFiles = jest.fn(layouts => [
|
||||||
|
`${layouts}/foo.vue`,
|
||||||
|
`${layouts}/bar.js`,
|
||||||
|
`${layouts}/baz.vue`,
|
||||||
|
`${layouts}/error.vue`
|
||||||
|
])
|
||||||
|
builder.relativeToBuild = jest.fn((...args) => `relativeBuild(${args.join(', ')})`)
|
||||||
|
fs.exists.mockReturnValueOnce(true)
|
||||||
|
|
||||||
|
const templateVars = {
|
||||||
|
components: {},
|
||||||
|
layouts: {
|
||||||
|
bar: '/var/nuxt/layouts/bar/index.vue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const templateFiles = []
|
||||||
|
await builder.resolveLayouts({ templateVars, templateFiles })
|
||||||
|
|
||||||
|
expect(path.resolve).toBeCalledTimes(1)
|
||||||
|
expect(path.resolve).toBeCalledWith('/var/nuxt/src', '/var/nuxt/src/layouts')
|
||||||
|
expect(fs.exists).toBeCalledTimes(1)
|
||||||
|
expect(fs.exists).toBeCalledWith('resolve(/var/nuxt/src, /var/nuxt/src/layouts)')
|
||||||
|
expect(builder.resolveFiles).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveFiles).toBeCalledWith('/var/nuxt/src/layouts')
|
||||||
|
expect(builder.relativeToBuild).toBeCalledTimes(2)
|
||||||
|
expect(builder.relativeToBuild).nthCalledWith(1, '/var/nuxt/src', '/var/nuxt/src/layouts/baz.vue')
|
||||||
|
expect(builder.relativeToBuild).nthCalledWith(2, '/var/nuxt/src', '/var/nuxt/src/layouts/error.vue')
|
||||||
|
expect(templateVars.components.ErrorPage).toEqual('relativeBuild(/var/nuxt/src, /var/nuxt/src/layouts/error.vue)')
|
||||||
|
expect(consola.warn).toBeCalledTimes(1)
|
||||||
|
expect(consola.warn).toBeCalledWith('Duplicate layout registration, "foo" has been registered as "/var/nuxt/layouts/foo/index.vue"')
|
||||||
|
expect(templateVars.layouts).toEqual({
|
||||||
|
bar: '/var/nuxt/layouts/bar/index.vue',
|
||||||
|
baz: 'relativeBuild(/var/nuxt/src, /var/nuxt/src/layouts/baz.vue)',
|
||||||
|
default: './layouts/default.vue'
|
||||||
|
})
|
||||||
|
expect(fs.mkdirp).toBeCalledTimes(1)
|
||||||
|
expect(fs.mkdirp).toBeCalledWith('r(/var/nuxt/build, layouts)')
|
||||||
|
expect(templateFiles).toEqual(['layouts/default.vue'])
|
||||||
|
expect(templateVars.layouts.default).toEqual('./layouts/default.vue')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve error layouts', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = {
|
||||||
|
layouts: '/var/nuxt/src/layouts'
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.resolveFiles = jest.fn(layouts => [
|
||||||
|
`${layouts}/error.vue`
|
||||||
|
])
|
||||||
|
builder.relativeToBuild = jest.fn((...args) => `relativeBuild(${args.join(', ')})`)
|
||||||
|
fs.exists.mockReturnValueOnce(true)
|
||||||
|
|
||||||
|
const templateVars = {
|
||||||
|
components: {
|
||||||
|
ErrorPage: '/var/nuxt/components/error.vue'
|
||||||
|
},
|
||||||
|
layouts: {
|
||||||
|
default: '/var/nuxt/layouts/default.vue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await builder.resolveLayouts({ templateVars })
|
||||||
|
|
||||||
|
expect(builder.relativeToBuild).not.toBeCalled()
|
||||||
|
expect(templateVars.components.ErrorPage).toEqual('/var/nuxt/components/error.vue')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should not resolve layouts if layouts dir does not exist', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = {
|
||||||
|
layouts: '/var/nuxt/src/layouts'
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
const templateVars = {
|
||||||
|
layouts: {
|
||||||
|
default: '/var/nuxt/layouts/default.vue'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await builder.resolveLayouts({ templateVars })
|
||||||
|
builder.resolveFiles = jest.fn()
|
||||||
|
|
||||||
|
expect(path.resolve).toBeCalledTimes(1)
|
||||||
|
expect(path.resolve).toBeCalledWith('/var/nuxt/src', '/var/nuxt/src/layouts')
|
||||||
|
expect(fs.exists).toBeCalledTimes(1)
|
||||||
|
expect(fs.exists).toBeCalledWith('resolve(/var/nuxt/src, /var/nuxt/src/layouts)')
|
||||||
|
expect(builder.resolveFiles).not.toBeCalled()
|
||||||
|
expect(fs.mkdirp).not.toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('builder: builder resolveRoutes', () => {
|
||||||
|
test('should resolve routes via build.createRoutes', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.build.createRoutes = jest.fn(() => [ { name: 'default_route' } ])
|
||||||
|
nuxt.options.router.extendRoutes = jest.fn(routes => [ ...routes, { name: 'extend_route' } ])
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
const templateVars = {
|
||||||
|
router: {
|
||||||
|
routes: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await builder.resolveRoutes({ templateVars })
|
||||||
|
|
||||||
|
expect(consola.debug).toBeCalledTimes(1)
|
||||||
|
expect(consola.debug).toBeCalledWith('Generating routes...')
|
||||||
|
expect(nuxt.options.build.createRoutes).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.options.build.createRoutes).toBeCalledWith('/var/nuxt/src')
|
||||||
|
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.callHook).toBeCalledWith(
|
||||||
|
'build:extendRoutes',
|
||||||
|
[ { name: 'default_route' } ],
|
||||||
|
r
|
||||||
|
)
|
||||||
|
expect(nuxt.options.router.extendRoutes).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.options.router.extendRoutes).toBeCalledWith([ { name: 'default_route' } ], r)
|
||||||
|
expect(templateVars.router.routes).toEqual([
|
||||||
|
{ name: 'default_route' },
|
||||||
|
{ name: 'extend_route' }
|
||||||
|
])
|
||||||
|
expect(builder.routes).toEqual(templateVars.router.routes)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve routes from defualt pages dir', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.build = {
|
||||||
|
createRoutes: jest.fn(),
|
||||||
|
template: { dir: '/var/nuxt/templates' }
|
||||||
|
}
|
||||||
|
nuxt.options.router.routeNameSplitter = '[splitter]'
|
||||||
|
createRoutes.mockReturnValueOnce([ { name: 'default_route' } ])
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder._defaultPage = true
|
||||||
|
|
||||||
|
const templateVars = {
|
||||||
|
router: {
|
||||||
|
routes: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await builder.resolveRoutes({ templateVars })
|
||||||
|
|
||||||
|
expect(consola.debug).toBeCalledTimes(1)
|
||||||
|
expect(consola.debug).toBeCalledWith('Generating routes...')
|
||||||
|
expect(nuxt.options.build.createRoutes).not.toBeCalled()
|
||||||
|
expect(createRoutes).toBeCalledTimes(1)
|
||||||
|
expect(createRoutes).toBeCalledWith([ 'index.vue' ], '/var/nuxt/templates/pages', '', '[splitter]')
|
||||||
|
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.callHook).toBeCalledWith(
|
||||||
|
'build:extendRoutes',
|
||||||
|
[ { name: 'default_route' } ],
|
||||||
|
r
|
||||||
|
)
|
||||||
|
expect(templateVars.router.routes).toEqual([
|
||||||
|
{ name: 'default_route' }
|
||||||
|
])
|
||||||
|
expect(builder.routes).toEqual(templateVars.router.routes)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve routes from dir.pages', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = {
|
||||||
|
pages: '/var/nuxt/pages'
|
||||||
|
}
|
||||||
|
nuxt.options.build = {
|
||||||
|
createRoutes: jest.fn()
|
||||||
|
}
|
||||||
|
nuxt.options.router = {
|
||||||
|
routeNameSplitter: '[splitter]',
|
||||||
|
extendRoutes: jest.fn()
|
||||||
|
}
|
||||||
|
createRoutes.mockImplementationOnce(files => files.map(file => ({ path: file })))
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder._nuxtPages = true
|
||||||
|
builder.resolveFiles = jest.fn(dir => [
|
||||||
|
`${dir}/foo.js`,
|
||||||
|
`${dir}/bar.vue`,
|
||||||
|
`${dir}/baz.vue`,
|
||||||
|
`${dir}/foo.vue`,
|
||||||
|
`${dir}/bar.js`
|
||||||
|
])
|
||||||
|
|
||||||
|
const templateVars = {
|
||||||
|
router: {
|
||||||
|
routes: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await builder.resolveRoutes({ templateVars })
|
||||||
|
|
||||||
|
expect(consola.debug).toBeCalledTimes(1)
|
||||||
|
expect(consola.debug).toBeCalledWith('Generating routes...')
|
||||||
|
expect(nuxt.options.build.createRoutes).not.toBeCalled()
|
||||||
|
expect(builder.resolveFiles).toBeCalledTimes(1)
|
||||||
|
expect(builder.resolveFiles).toBeCalledWith('/var/nuxt/pages')
|
||||||
|
|
||||||
|
expect(createRoutes).toBeCalledTimes(1)
|
||||||
|
expect(createRoutes).toBeCalledWith(
|
||||||
|
[ '/var/nuxt/pages/foo.vue', '/var/nuxt/pages/bar.vue', '/var/nuxt/pages/baz.vue' ],
|
||||||
|
'/var/nuxt/src',
|
||||||
|
'/var/nuxt/pages',
|
||||||
|
'[splitter]'
|
||||||
|
)
|
||||||
|
expect(nuxt.callHook).toBeCalledTimes(1)
|
||||||
|
expect(nuxt.callHook).toBeCalledWith(
|
||||||
|
'build:extendRoutes',
|
||||||
|
[
|
||||||
|
{ path: '/var/nuxt/pages/foo.vue' },
|
||||||
|
{ path: '/var/nuxt/pages/bar.vue' },
|
||||||
|
{ path: '/var/nuxt/pages/baz.vue' }
|
||||||
|
],
|
||||||
|
r
|
||||||
|
)
|
||||||
|
expect(templateVars.router.routes).toEqual([
|
||||||
|
{ path: '/var/nuxt/pages/foo.vue' },
|
||||||
|
{ path: '/var/nuxt/pages/bar.vue' },
|
||||||
|
{ path: '/var/nuxt/pages/baz.vue' }
|
||||||
|
])
|
||||||
|
expect(builder.routes).toEqual(templateVars.router.routes)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
145
packages/builder/test/builder.plugin.test.js
Normal file
145
packages/builder/test/builder.plugin.test.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import Glob from 'glob'
|
||||||
|
import consola from 'consola'
|
||||||
|
import { isIndexFileAndFolder } from '@nuxt/utils'
|
||||||
|
|
||||||
|
import Builder from '../src/builder'
|
||||||
|
import { createNuxt } from './__utils__'
|
||||||
|
|
||||||
|
jest.mock('glob')
|
||||||
|
jest.mock('pify', () => fn => fn)
|
||||||
|
jest.mock('hash-sum', () => src => `hash(${src})`)
|
||||||
|
jest.mock('@nuxt/utils')
|
||||||
|
jest.mock('../src/ignore')
|
||||||
|
|
||||||
|
describe('builder: builder plugins', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should normalize plugins', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.plugins = [
|
||||||
|
'/var/nuxt/plugins/test.js',
|
||||||
|
{ src: '/var/nuxt/plugins/test.server', mode: 'server' },
|
||||||
|
{ src: '/var/nuxt/plugins/test.client', ssr: false }
|
||||||
|
]
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
const plugins = builder.normalizePlugins()
|
||||||
|
|
||||||
|
expect(plugins).toEqual([
|
||||||
|
{
|
||||||
|
mode: 'all',
|
||||||
|
name: 'nuxt_plugin_test_hash(/var/nuxt/plugins/test.js)',
|
||||||
|
src: 'resolveAlias(/var/nuxt/plugins/test.js)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mode: 'server',
|
||||||
|
name: 'nuxt_plugin_test_hash(/var/nuxt/plugins/test.server)',
|
||||||
|
src: 'resolveAlias(/var/nuxt/plugins/test.server)'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
mode: 'client',
|
||||||
|
name: 'nuxt_plugin_test_hash(/var/nuxt/plugins/test.client)',
|
||||||
|
src: 'resolveAlias(/var/nuxt/plugins/test.client)'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should warning and fallback invalid mode when normalize plugins', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.plugins = [
|
||||||
|
{ src: '/var/nuxt/plugins/test', mode: 'abc' }
|
||||||
|
]
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
const plugins = builder.normalizePlugins()
|
||||||
|
|
||||||
|
expect(plugins).toEqual([
|
||||||
|
{
|
||||||
|
mode: 'all',
|
||||||
|
name: 'nuxt_plugin_test_hash(/var/nuxt/plugins/test)',
|
||||||
|
src: 'resolveAlias(/var/nuxt/plugins/test)'
|
||||||
|
}
|
||||||
|
])
|
||||||
|
expect(consola.warn).toBeCalledTimes(1)
|
||||||
|
expect(consola.warn).toBeCalledWith("Invalid plugin mode (server/client/all): 'abc'. Falling back to 'all'")
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should resolve plugins', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.plugins = [
|
||||||
|
{ src: '/var/nuxt/plugins/test.js', mode: 'all' },
|
||||||
|
{ src: '/var/nuxt/plugins/test.client', mode: 'client' },
|
||||||
|
{ src: '/var/nuxt/plugins/test.server', mode: 'server' }
|
||||||
|
]
|
||||||
|
builder.relativeToBuild = jest.fn(src => `relative(${src})`)
|
||||||
|
for (let step = 0; step < builder.plugins.length; step++) {
|
||||||
|
Glob.mockImplementationOnce(src => [`${src.replace(/\{.*\}/, '')}.js`])
|
||||||
|
}
|
||||||
|
|
||||||
|
await builder.resolvePlugins()
|
||||||
|
|
||||||
|
expect(Glob).toBeCalledTimes(3)
|
||||||
|
expect(Glob).nthCalledWith(1, '/var/nuxt/plugins/test.js{?(.+([^.])),/index.+([^.])}')
|
||||||
|
expect(Glob).nthCalledWith(2, '/var/nuxt/plugins/test.client{?(.+([^.])),/index.+([^.])}')
|
||||||
|
expect(Glob).nthCalledWith(3, '/var/nuxt/plugins/test.server{?(.+([^.])),/index.+([^.])}')
|
||||||
|
expect(builder.plugins).toEqual([
|
||||||
|
{ mode: 'all', src: 'relative(/var/nuxt/plugins/test.js)' },
|
||||||
|
{ mode: 'client', src: 'relative(/var/nuxt/plugins/test.client)' },
|
||||||
|
{ mode: 'server', src: 'relative(/var/nuxt/plugins/test.server)' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should throw error if plugin no existed', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.plugins = [
|
||||||
|
{ src: '/var/nuxt/plugins/test.js', mode: 'all' }
|
||||||
|
]
|
||||||
|
Glob.mockImplementationOnce(() => [])
|
||||||
|
|
||||||
|
expect(builder.resolvePlugins()).rejects.toThrow('Plugin not found: /var/nuxt/plugins/test.js')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should warn if there are multiple files and not index', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.plugins = [
|
||||||
|
{ src: '/var/nuxt/plugins/test', mode: 'all' }
|
||||||
|
]
|
||||||
|
builder.relativeToBuild = jest.fn(src => `relative(${src})`)
|
||||||
|
|
||||||
|
Glob.mockImplementationOnce(src => [`${src}.js`, `${src}.ts`])
|
||||||
|
isIndexFileAndFolder.mockReturnValueOnce(false)
|
||||||
|
|
||||||
|
await builder.resolvePlugins()
|
||||||
|
|
||||||
|
expect(builder.plugins).toEqual([
|
||||||
|
{ mode: 'all', src: 'relative(/var/nuxt/plugins/test)' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should detect plugin mode for client/server plugins', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.plugins = [
|
||||||
|
{ src: '/var/nuxt/plugins/test.js', mode: 'all' },
|
||||||
|
{ src: '/var/nuxt/plugins/test.client', mode: 'all' },
|
||||||
|
{ src: '/var/nuxt/plugins/test.server', mode: 'all' }
|
||||||
|
]
|
||||||
|
builder.relativeToBuild = jest.fn(src => `relative(${src})`)
|
||||||
|
for (let step = 0; step < builder.plugins.length; step++) {
|
||||||
|
Glob.mockImplementationOnce(src => [`${src.replace(/\{.*\}/, '')}.js`])
|
||||||
|
}
|
||||||
|
|
||||||
|
await builder.resolvePlugins()
|
||||||
|
|
||||||
|
expect(builder.plugins).toEqual([
|
||||||
|
{ mode: 'all', src: 'relative(/var/nuxt/plugins/test.js)' },
|
||||||
|
{ mode: 'client', src: 'relative(/var/nuxt/plugins/test.client)' },
|
||||||
|
{ mode: 'server', src: 'relative(/var/nuxt/plugins/test.server)' }
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
330
packages/builder/test/builder.watch.test.js
Normal file
330
packages/builder/test/builder.watch.test.js
Normal file
@ -0,0 +1,330 @@
|
|||||||
|
import chokidar from 'chokidar'
|
||||||
|
import upath from 'upath'
|
||||||
|
import debounce from 'lodash/debounce'
|
||||||
|
import { r, isString } from '@nuxt/utils'
|
||||||
|
|
||||||
|
import Builder from '../src/builder'
|
||||||
|
import { createNuxt } from './__utils__'
|
||||||
|
|
||||||
|
jest.mock('chokidar', () => ({
|
||||||
|
watch: jest.fn().mockReturnThis(),
|
||||||
|
on: jest.fn().mockReturnThis(),
|
||||||
|
close: jest.fn().mockReturnThis()
|
||||||
|
}))
|
||||||
|
jest.mock('upath', () => ({ normalizeSafe: jest.fn(src => src) }))
|
||||||
|
jest.mock('lodash/debounce', () => jest.fn(fn => fn))
|
||||||
|
jest.mock('@nuxt/utils')
|
||||||
|
jest.mock('../src/ignore')
|
||||||
|
|
||||||
|
describe('builder: builder watch', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should watch client files', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = {
|
||||||
|
layouts: '/var/nuxt/src/layouts',
|
||||||
|
pages: '/var/nuxt/src/pages',
|
||||||
|
store: '/var/nuxt/src/store',
|
||||||
|
middleware: '/var/nuxt/src/middleware'
|
||||||
|
}
|
||||||
|
nuxt.options.build.watch = []
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
r.mockImplementation((dir, src) => src)
|
||||||
|
|
||||||
|
builder.watchClient()
|
||||||
|
|
||||||
|
const patterns = [
|
||||||
|
'/var/nuxt/src/layouts',
|
||||||
|
'/var/nuxt/src/store',
|
||||||
|
'/var/nuxt/src/middleware',
|
||||||
|
'/var/nuxt/src/layouts/*.{vue,js,ts,tsx}',
|
||||||
|
'/var/nuxt/src/layouts/**/*.{vue,js,ts,tsx}'
|
||||||
|
]
|
||||||
|
|
||||||
|
expect(r).toBeCalledTimes(5)
|
||||||
|
expect(r).nthCalledWith(1, '/var/nuxt/src', '/var/nuxt/src/layouts')
|
||||||
|
expect(r).nthCalledWith(2, '/var/nuxt/src', '/var/nuxt/src/store')
|
||||||
|
expect(r).nthCalledWith(3, '/var/nuxt/src', '/var/nuxt/src/middleware')
|
||||||
|
expect(r).nthCalledWith(4, '/var/nuxt/src', '/var/nuxt/src/layouts/*.{vue,js,ts,tsx}')
|
||||||
|
expect(r).nthCalledWith(5, '/var/nuxt/src', '/var/nuxt/src/layouts/**/*.{vue,js,ts,tsx}')
|
||||||
|
|
||||||
|
expect(upath.normalizeSafe).toBeCalledTimes(5)
|
||||||
|
expect(upath.normalizeSafe).nthCalledWith(1, '/var/nuxt/src/layouts', 0, patterns)
|
||||||
|
expect(upath.normalizeSafe).nthCalledWith(2, '/var/nuxt/src/store', 1, patterns)
|
||||||
|
expect(upath.normalizeSafe).nthCalledWith(3, '/var/nuxt/src/middleware', 2, patterns)
|
||||||
|
expect(upath.normalizeSafe).nthCalledWith(4, '/var/nuxt/src/layouts/*.{vue,js,ts,tsx}', 3, patterns)
|
||||||
|
expect(upath.normalizeSafe).nthCalledWith(5, '/var/nuxt/src/layouts/**/*.{vue,js,ts,tsx}', 4, patterns)
|
||||||
|
|
||||||
|
expect(chokidar.watch).toBeCalledTimes(1)
|
||||||
|
expect(chokidar.watch).toBeCalledWith(patterns, { test: true })
|
||||||
|
expect(chokidar.on).toBeCalledTimes(2)
|
||||||
|
expect(chokidar.on).nthCalledWith(1, 'add', expect.any(Function))
|
||||||
|
expect(chokidar.on).nthCalledWith(2, 'unlink', expect.any(Function))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should watch pages files', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = {
|
||||||
|
layouts: '/var/nuxt/src/layouts',
|
||||||
|
pages: '/var/nuxt/src/pages',
|
||||||
|
store: '/var/nuxt/src/store',
|
||||||
|
middleware: '/var/nuxt/src/middleware'
|
||||||
|
}
|
||||||
|
nuxt.options.build.watch = []
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder._nuxtPages = true
|
||||||
|
r.mockImplementation((dir, src) => src)
|
||||||
|
|
||||||
|
builder.watchClient()
|
||||||
|
|
||||||
|
expect(r).toBeCalledTimes(8)
|
||||||
|
expect(r).nthCalledWith(6, '/var/nuxt/src', '/var/nuxt/src/pages')
|
||||||
|
expect(r).nthCalledWith(7, '/var/nuxt/src', '/var/nuxt/src/pages/*.{vue,js,ts,tsx}')
|
||||||
|
expect(r).nthCalledWith(8, '/var/nuxt/src', '/var/nuxt/src/pages/**/*.{vue,js,ts,tsx}')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should watch custom in watchClient', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.srcDir = '/var/nuxt/src'
|
||||||
|
nuxt.options.dir = {
|
||||||
|
layouts: '/var/nuxt/src/layouts',
|
||||||
|
pages: '/var/nuxt/src/pages',
|
||||||
|
store: '/var/nuxt/src/store',
|
||||||
|
middleware: '/var/nuxt/src/middleware'
|
||||||
|
}
|
||||||
|
nuxt.options.build.watch = []
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.watchCustom = jest.fn()
|
||||||
|
r.mockImplementation((dir, src) => src)
|
||||||
|
|
||||||
|
builder.watchClient()
|
||||||
|
|
||||||
|
expect(debounce).toBeCalledTimes(1)
|
||||||
|
expect(debounce).toBeCalledWith(expect.any(Function), 200)
|
||||||
|
|
||||||
|
const refreshFiles = chokidar.on.mock.calls[0][1]
|
||||||
|
builder.generateRoutesAndFiles = jest.fn()
|
||||||
|
refreshFiles()
|
||||||
|
expect(builder.generateRoutesAndFiles).toBeCalled()
|
||||||
|
expect(builder.watchCustom).toBeCalledTimes(1)
|
||||||
|
expect(builder.watchCustom).toBeCalledWith(refreshFiles)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should watch custom patterns', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
nuxt.options.build.watch = [
|
||||||
|
'/var/nuxt/src/custom'
|
||||||
|
]
|
||||||
|
nuxt.options.build.styleResources = [
|
||||||
|
'/var/nuxt/src/style'
|
||||||
|
]
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
const refreshFiles = jest.fn()
|
||||||
|
|
||||||
|
builder.watchCustom(refreshFiles)
|
||||||
|
|
||||||
|
expect(chokidar.watch).toBeCalledTimes(1)
|
||||||
|
expect(chokidar.watch).toBeCalledWith(
|
||||||
|
['/var/nuxt/src/custom', '/var/nuxt/src/style'],
|
||||||
|
{ test: true }
|
||||||
|
)
|
||||||
|
expect(chokidar.on).toBeCalledTimes(1)
|
||||||
|
expect(chokidar.on).toBeCalledWith('change', refreshFiles)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should call refreshFiles before watching custom patterns', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
nuxt.options.build.watch = [
|
||||||
|
'/var/nuxt/src/custom'
|
||||||
|
]
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
const refreshFiles = jest.fn()
|
||||||
|
|
||||||
|
builder.watchCustom(refreshFiles, true)
|
||||||
|
|
||||||
|
expect(refreshFiles).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should rewatch custom patterns when event is included in rewatchOnRawEvents', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true },
|
||||||
|
rewatchOnRawEvents: ['rename']
|
||||||
|
}
|
||||||
|
nuxt.options.build.watch = [
|
||||||
|
'/var/nuxt/src/custom'
|
||||||
|
]
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
const refreshFiles = jest.fn()
|
||||||
|
|
||||||
|
builder.watchCustom(refreshFiles)
|
||||||
|
|
||||||
|
expect(chokidar.on).toBeCalledTimes(2)
|
||||||
|
expect(chokidar.on).nthCalledWith(2, 'raw', expect.any(Function))
|
||||||
|
|
||||||
|
const rewatchHandler = chokidar.on.mock.calls[1][1]
|
||||||
|
builder.watchCustom = jest.fn()
|
||||||
|
rewatchHandler('rename')
|
||||||
|
rewatchHandler('change')
|
||||||
|
|
||||||
|
expect(chokidar.close).toBeCalledTimes(1)
|
||||||
|
expect(builder.watchers.custom).toBeNull()
|
||||||
|
expect(builder.watchCustom).toBeCalledTimes(1)
|
||||||
|
expect(builder.watchCustom).toBeCalledWith(refreshFiles, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should watch files for restarting server', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
nuxt.options.watch = [
|
||||||
|
'/var/nuxt/src/watch/test'
|
||||||
|
]
|
||||||
|
nuxt.options.serverMiddleware = [
|
||||||
|
'/var/nuxt/src/middleware/test',
|
||||||
|
{ obj: 'test' }
|
||||||
|
]
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.ignore.ignoreFile = '/var/nuxt/src/.nuxtignore'
|
||||||
|
isString.mockImplementationOnce(src => typeof src === 'string')
|
||||||
|
|
||||||
|
builder.watchRestart()
|
||||||
|
|
||||||
|
expect(chokidar.watch).toBeCalledTimes(1)
|
||||||
|
expect(chokidar.watch).toBeCalledWith(
|
||||||
|
[
|
||||||
|
'resolveAlias(/var/nuxt/src/middleware/test)',
|
||||||
|
'resolveAlias(/var/nuxt/src/watch/test)',
|
||||||
|
'/var/nuxt/src/.nuxtignore'
|
||||||
|
],
|
||||||
|
{ test: true }
|
||||||
|
)
|
||||||
|
expect(chokidar.on).toBeCalledTimes(1)
|
||||||
|
expect(chokidar.on).toBeCalledWith('all', expect.any(Function))
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should trigger restarting when files changed', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
nuxt.options.watch = [
|
||||||
|
'/var/nuxt/src/watch/test'
|
||||||
|
]
|
||||||
|
nuxt.options.serverMiddleware = []
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
builder.watchRestart()
|
||||||
|
|
||||||
|
const restartHandler = chokidar.on.mock.calls[0][1]
|
||||||
|
const watchingFile = '/var/nuxt/src/watch/test/index.js'
|
||||||
|
restartHandler('add', watchingFile)
|
||||||
|
restartHandler('change', watchingFile)
|
||||||
|
restartHandler('unlink', watchingFile)
|
||||||
|
|
||||||
|
expect(nuxt.callHook).toBeCalledTimes(6)
|
||||||
|
expect(nuxt.callHook).nthCalledWith(1, 'watch:fileChanged', builder, watchingFile)
|
||||||
|
expect(nuxt.callHook).nthCalledWith(2, 'watch:restart', { event: 'add', path: watchingFile })
|
||||||
|
expect(nuxt.callHook).nthCalledWith(3, 'watch:fileChanged', builder, watchingFile)
|
||||||
|
expect(nuxt.callHook).nthCalledWith(4, 'watch:restart', { event: 'change', path: watchingFile })
|
||||||
|
expect(nuxt.callHook).nthCalledWith(5, 'watch:fileChanged', builder, watchingFile)
|
||||||
|
expect(nuxt.callHook).nthCalledWith(6, 'watch:restart', { event: 'unlink', path: watchingFile })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should ignore other events in watchRestart', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
nuxt.options.watchers = {
|
||||||
|
chokidar: { test: true }
|
||||||
|
}
|
||||||
|
nuxt.options.watch = [
|
||||||
|
'/var/nuxt/src/watch/test'
|
||||||
|
]
|
||||||
|
nuxt.options.serverMiddleware = []
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
|
||||||
|
builder.watchRestart()
|
||||||
|
|
||||||
|
const restartHandler = chokidar.on.mock.calls[0][1]
|
||||||
|
const watchingFile = '/var/nuxt/src/watch/test/index.js'
|
||||||
|
restartHandler('rename', watchingFile)
|
||||||
|
|
||||||
|
expect(nuxt.callHook).not.toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should unwatch every watcher', () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, {})
|
||||||
|
builder.watchers = {
|
||||||
|
files: { close: jest.fn() },
|
||||||
|
custom: { close: jest.fn() },
|
||||||
|
restart: { close: jest.fn() }
|
||||||
|
}
|
||||||
|
|
||||||
|
builder.unwatch()
|
||||||
|
|
||||||
|
expect(builder.watchers.files.close).toBeCalledTimes(1)
|
||||||
|
expect(builder.watchers.custom.close).toBeCalledTimes(1)
|
||||||
|
expect(builder.watchers.restart.close).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should close watch and bundle builder', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const bundleBuilderClose = jest.fn()
|
||||||
|
const builder = new Builder(nuxt, { close: bundleBuilderClose })
|
||||||
|
builder.unwatch = jest.fn()
|
||||||
|
|
||||||
|
expect(builder.__closed).toBeUndefined()
|
||||||
|
|
||||||
|
await builder.close()
|
||||||
|
|
||||||
|
expect(builder.__closed).toEqual(true)
|
||||||
|
expect(builder.unwatch).toBeCalledTimes(1)
|
||||||
|
expect(bundleBuilderClose).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should close bundleBuilder only if close api exists', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const builder = new Builder(nuxt, { })
|
||||||
|
builder.unwatch = jest.fn()
|
||||||
|
|
||||||
|
expect(builder.__closed).toBeUndefined()
|
||||||
|
|
||||||
|
await builder.close()
|
||||||
|
|
||||||
|
expect(builder.__closed).toEqual(true)
|
||||||
|
expect(builder.unwatch).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should prevent duplicate close', async () => {
|
||||||
|
const nuxt = createNuxt()
|
||||||
|
const bundleBuilderClose = jest.fn()
|
||||||
|
const builder = new Builder(nuxt, { close: bundleBuilderClose })
|
||||||
|
builder.unwatch = jest.fn()
|
||||||
|
builder.__closed = true
|
||||||
|
|
||||||
|
await builder.close()
|
||||||
|
|
||||||
|
expect(builder.unwatch).not.toBeCalled()
|
||||||
|
expect(bundleBuilderClose).not.toBeCalled()
|
||||||
|
})
|
||||||
|
})
|
@ -0,0 +1,105 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`builder: buildContext should construct context 1`] = `
|
||||||
|
TemplateContext {
|
||||||
|
"templateFiles": Array [
|
||||||
|
"template.js",
|
||||||
|
],
|
||||||
|
"templateVars": Object {
|
||||||
|
"appPath": "./App.js",
|
||||||
|
"components": Object {
|
||||||
|
"ErrorPage": "relativeBuild(test_error_page)",
|
||||||
|
},
|
||||||
|
"css": Array [
|
||||||
|
"test.css",
|
||||||
|
],
|
||||||
|
"debug": "test_debug",
|
||||||
|
"dir": Array [
|
||||||
|
"test_dir",
|
||||||
|
],
|
||||||
|
"env": "test_env",
|
||||||
|
"extensions": "test|ext",
|
||||||
|
"globalName": "test_global",
|
||||||
|
"globals": Array [
|
||||||
|
"globals",
|
||||||
|
],
|
||||||
|
"head": "test_head",
|
||||||
|
"isDev": "test_dev",
|
||||||
|
"isTest": "test_test",
|
||||||
|
"layoutTransition": Object {
|
||||||
|
"name": "test_layout_trans",
|
||||||
|
},
|
||||||
|
"layouts": Object {
|
||||||
|
"test-layout": "test.template",
|
||||||
|
},
|
||||||
|
"loading": "relativeBuild(test_src_dir, test-loading)",
|
||||||
|
"messages": Object {
|
||||||
|
"test": "test message",
|
||||||
|
},
|
||||||
|
"mode": "test mode",
|
||||||
|
"options": Object {
|
||||||
|
"ErrorPage": "test_error_page",
|
||||||
|
"build": Object {
|
||||||
|
"splitChunks": Object {
|
||||||
|
"testSC": true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"css": Array [
|
||||||
|
"test.css",
|
||||||
|
],
|
||||||
|
"debug": "test_debug",
|
||||||
|
"dev": "test_dev",
|
||||||
|
"dir": Array [
|
||||||
|
"test_dir",
|
||||||
|
],
|
||||||
|
"env": "test_env",
|
||||||
|
"extensions": Array [
|
||||||
|
"test",
|
||||||
|
"ext",
|
||||||
|
],
|
||||||
|
"globalName": "test_global",
|
||||||
|
"head": "test_head",
|
||||||
|
"layoutTransition": Object {
|
||||||
|
"name": "test_layout_trans",
|
||||||
|
},
|
||||||
|
"layouts": Object {
|
||||||
|
"test-layout": "test.template",
|
||||||
|
},
|
||||||
|
"loading": "test-loading",
|
||||||
|
"messages": Object {
|
||||||
|
"test": "test message",
|
||||||
|
},
|
||||||
|
"mode": "test mode",
|
||||||
|
"router": Object {
|
||||||
|
"route": "test",
|
||||||
|
},
|
||||||
|
"srcDir": "test_src_dir",
|
||||||
|
"store": "test_store",
|
||||||
|
"test": "test_test",
|
||||||
|
"transition": Object {
|
||||||
|
"name": "test_trans",
|
||||||
|
},
|
||||||
|
"vue": Object {
|
||||||
|
"config": "test_config",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"plugins": Array [
|
||||||
|
"plugins",
|
||||||
|
],
|
||||||
|
"router": Object {
|
||||||
|
"route": "test",
|
||||||
|
},
|
||||||
|
"splitChunks": Object {
|
||||||
|
"testSC": true,
|
||||||
|
},
|
||||||
|
"store": "test_store",
|
||||||
|
"transition": Object {
|
||||||
|
"name": "test_trans",
|
||||||
|
},
|
||||||
|
"uniqBy": [Function],
|
||||||
|
"vue": Object {
|
||||||
|
"config": "test_config",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
`;
|
23
packages/builder/test/context/build.test.js
Normal file
23
packages/builder/test/context/build.test.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import BuildContext from '../../src/context/build'
|
||||||
|
|
||||||
|
describe('builder: buildContext', () => {
|
||||||
|
test('should construct context', () => {
|
||||||
|
const builder = {
|
||||||
|
nuxt: { options: {} }
|
||||||
|
}
|
||||||
|
const context = new BuildContext(builder)
|
||||||
|
expect(context._builder).toEqual(builder)
|
||||||
|
expect(context.nuxt).toEqual(builder.nuxt)
|
||||||
|
expect(context.options).toEqual(builder.nuxt.options)
|
||||||
|
expect(context.isStatic).toEqual(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should return builder plugins context', () => {
|
||||||
|
const builder = {
|
||||||
|
plugins: [],
|
||||||
|
nuxt: { options: {} }
|
||||||
|
}
|
||||||
|
const context = new BuildContext(builder)
|
||||||
|
expect(context.plugins).toEqual(builder.plugins)
|
||||||
|
})
|
||||||
|
})
|
81
packages/builder/test/context/template.test.js
Normal file
81
packages/builder/test/context/template.test.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import hash from 'hash-sum'
|
||||||
|
import consola from 'consola'
|
||||||
|
import serialize from 'serialize-javascript'
|
||||||
|
|
||||||
|
import devalue from '@nuxt/devalue'
|
||||||
|
import { r, wp, wChunk, serializeFunction } from '@nuxt/utils'
|
||||||
|
import TemplateContext from '../../src/context/template'
|
||||||
|
|
||||||
|
jest.mock('lodash', () => ({ test: 'test lodash', warn: 'only once' }))
|
||||||
|
|
||||||
|
describe('builder: buildContext', () => {
|
||||||
|
const builder = {
|
||||||
|
template: { files: ['template.js'] },
|
||||||
|
globals: [ 'globals' ],
|
||||||
|
plugins: [ 'plugins' ],
|
||||||
|
relativeToBuild: jest.fn((...args) => `relativeBuild(${args.join(', ')})`)
|
||||||
|
}
|
||||||
|
const options = {
|
||||||
|
extensions: [ 'test', 'ext' ],
|
||||||
|
messages: { test: 'test message' },
|
||||||
|
build: {
|
||||||
|
splitChunks: { testSC: true }
|
||||||
|
},
|
||||||
|
dev: 'test_dev',
|
||||||
|
test: 'test_test',
|
||||||
|
debug: 'test_debug',
|
||||||
|
vue: { config: 'test_config' },
|
||||||
|
mode: 'test mode',
|
||||||
|
router: { route: 'test' },
|
||||||
|
env: 'test_env',
|
||||||
|
head: 'test_head',
|
||||||
|
store: 'test_store',
|
||||||
|
globalName: 'test_global',
|
||||||
|
css: [ 'test.css' ],
|
||||||
|
layouts: {
|
||||||
|
'test-layout': 'test.template'
|
||||||
|
},
|
||||||
|
srcDir: 'test_src_dir',
|
||||||
|
loading: 'test-loading',
|
||||||
|
transition: { name: 'test_trans' },
|
||||||
|
layoutTransition: { name: 'test_layout_trans' },
|
||||||
|
dir: ['test_dir'],
|
||||||
|
ErrorPage: 'test_error_page'
|
||||||
|
}
|
||||||
|
|
||||||
|
test('should construct context', () => {
|
||||||
|
const context = new TemplateContext(builder, options)
|
||||||
|
expect(context).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should return object loading template options', () => {
|
||||||
|
const context = new TemplateContext(builder, {
|
||||||
|
...options,
|
||||||
|
loading: { name: 'test_loading' }
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(context.templateVars.loading).toEqual({ name: 'test_loading' })
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should return object loading template options', () => {
|
||||||
|
const context = new TemplateContext(builder, options)
|
||||||
|
const templateOptions = context.templateOptions
|
||||||
|
expect(templateOptions).toEqual({
|
||||||
|
imports: {
|
||||||
|
serialize,
|
||||||
|
serializeFunction,
|
||||||
|
devalue,
|
||||||
|
hash,
|
||||||
|
r,
|
||||||
|
wp,
|
||||||
|
wChunk,
|
||||||
|
_: {}
|
||||||
|
},
|
||||||
|
interpolate: /<%=([\s\S]+?)%>/g
|
||||||
|
})
|
||||||
|
expect(templateOptions.imports._.test).toEqual('test lodash')
|
||||||
|
expect(templateOptions.imports._.warn).toEqual('only once')
|
||||||
|
expect(consola.warn).toBeCalledTimes(1)
|
||||||
|
expect(consola.warn).toBeCalledWith('Avoid using _ inside templates')
|
||||||
|
})
|
||||||
|
})
|
147
packages/builder/test/ignore.test.js
Normal file
147
packages/builder/test/ignore.test.js
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import path from 'path'
|
||||||
|
import fs from 'fs-extra'
|
||||||
|
|
||||||
|
import Ignore from '../src/ignore'
|
||||||
|
|
||||||
|
jest.mock('path')
|
||||||
|
jest.mock('fs-extra')
|
||||||
|
jest.mock('ignore', () => () => ({
|
||||||
|
add: jest.fn(),
|
||||||
|
filter: jest.fn(paths => paths)
|
||||||
|
}))
|
||||||
|
|
||||||
|
describe('builder: Ignore', () => {
|
||||||
|
beforeAll(() => {
|
||||||
|
path.resolve.mockImplementation((...args) => `resolve(${args.join(', ')})`)
|
||||||
|
})
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
jest.clearAllMocks()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should construct Ignore', () => {
|
||||||
|
jest.spyOn(Ignore.prototype, 'addIgnoresRules').mockImplementation(() => {})
|
||||||
|
|
||||||
|
const ignore = new Ignore({
|
||||||
|
rootDir: '/var/nuxt'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(Ignore.IGNORE_FILENAME).toEqual('.nuxtignore')
|
||||||
|
expect(ignore.rootDir).toEqual('/var/nuxt')
|
||||||
|
expect(ignore.addIgnoresRules).toBeCalledTimes(1)
|
||||||
|
|
||||||
|
Ignore.prototype.addIgnoresRules.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should add ignore file', () => {
|
||||||
|
jest.spyOn(Ignore.prototype, 'addIgnoresRules')
|
||||||
|
jest.spyOn(Ignore.prototype, 'readIgnoreFile').mockReturnValue('')
|
||||||
|
|
||||||
|
const ignore = new Ignore({
|
||||||
|
rootDir: '/var/nuxt'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(Ignore.IGNORE_FILENAME).toEqual('.nuxtignore')
|
||||||
|
expect(ignore.rootDir).toEqual('/var/nuxt')
|
||||||
|
expect(ignore.addIgnoresRules).toBeCalledTimes(1)
|
||||||
|
expect(ignore.readIgnoreFile).toBeCalledTimes(1)
|
||||||
|
|
||||||
|
Ignore.prototype.addIgnoresRules.mockRestore()
|
||||||
|
Ignore.prototype.readIgnoreFile.mockRestore()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should find ignore file', () => {
|
||||||
|
fs.existsSync.mockReturnValueOnce(true)
|
||||||
|
fs.statSync.mockReturnValueOnce({ isFile: () => true })
|
||||||
|
fs.readFileSync.mockReturnValueOnce('pages/ignore.vue')
|
||||||
|
|
||||||
|
const ignore = new Ignore({
|
||||||
|
rootDir: '/var/nuxt'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(path.resolve).toBeCalledTimes(1)
|
||||||
|
expect(path.resolve).toBeCalledWith('/var/nuxt', '.nuxtignore')
|
||||||
|
expect(fs.existsSync).toBeCalledTimes(1)
|
||||||
|
expect(fs.existsSync).toBeCalledWith('resolve(/var/nuxt, .nuxtignore)')
|
||||||
|
expect(fs.statSync).toBeCalledTimes(1)
|
||||||
|
expect(fs.statSync).toBeCalledWith('resolve(/var/nuxt, .nuxtignore)')
|
||||||
|
expect(ignore.ignoreFile).toEqual('resolve(/var/nuxt, .nuxtignore)')
|
||||||
|
expect(fs.readFileSync).toBeCalledTimes(1)
|
||||||
|
expect(fs.readFileSync).toBeCalledWith('resolve(/var/nuxt, .nuxtignore)', 'utf8')
|
||||||
|
expect(ignore.ignore.add).toBeCalledTimes(1)
|
||||||
|
expect(ignore.ignore.add).toBeCalledWith('pages/ignore.vue')
|
||||||
|
|
||||||
|
fs.existsSync.mockClear()
|
||||||
|
ignore.findIgnoreFile()
|
||||||
|
expect(fs.existsSync).not.toBeCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should only find existed ignore file', () => {
|
||||||
|
fs.existsSync.mockReturnValueOnce(false)
|
||||||
|
|
||||||
|
const ignore = new Ignore({
|
||||||
|
rootDir: '/var/nuxt'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(path.resolve).toBeCalledTimes(1)
|
||||||
|
expect(path.resolve).toBeCalledWith('/var/nuxt', '.nuxtignore')
|
||||||
|
expect(fs.existsSync).toBeCalledTimes(1)
|
||||||
|
expect(fs.existsSync).toBeCalledWith('resolve(/var/nuxt, .nuxtignore)')
|
||||||
|
expect(fs.statSync).not.toBeCalled()
|
||||||
|
expect(ignore.ignoreFile).toBeUndefined()
|
||||||
|
expect(ignore.ignore).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should filter ignore files', () => {
|
||||||
|
fs.existsSync.mockReturnValueOnce(true)
|
||||||
|
fs.statSync.mockReturnValueOnce({ isFile: () => true })
|
||||||
|
fs.readFileSync.mockReturnValueOnce('pages/ignore.vue')
|
||||||
|
|
||||||
|
const ignore = new Ignore({
|
||||||
|
rootDir: '/var/nuxt'
|
||||||
|
})
|
||||||
|
|
||||||
|
ignore.filter()
|
||||||
|
ignore.filter('pages/ignore.vue')
|
||||||
|
const paths = ignore.filter([ 'pages/ignore.vue', 'layouts/ignore.vue' ])
|
||||||
|
|
||||||
|
expect(ignore.ignore.filter).toBeCalledTimes(3)
|
||||||
|
expect(ignore.ignore.filter).nthCalledWith(1, [])
|
||||||
|
expect(ignore.ignore.filter).nthCalledWith(2, [ 'pages/ignore.vue' ])
|
||||||
|
expect(ignore.ignore.filter).nthCalledWith(3, [ 'pages/ignore.vue', 'layouts/ignore.vue' ])
|
||||||
|
expect(paths).toEqual([ 'pages/ignore.vue', 'layouts/ignore.vue' ])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should return origin paths if there is no ignorefile', () => {
|
||||||
|
fs.existsSync.mockReturnValueOnce(false)
|
||||||
|
|
||||||
|
const ignore = new Ignore({
|
||||||
|
rootDir: '/var/nuxt'
|
||||||
|
})
|
||||||
|
|
||||||
|
const paths = ignore.filter([ 'pages/ignore.vue', 'layouts/ignore.vue' ])
|
||||||
|
|
||||||
|
expect(paths).toEqual([ 'pages/ignore.vue', 'layouts/ignore.vue' ])
|
||||||
|
})
|
||||||
|
|
||||||
|
test('should reload ignore', () => {
|
||||||
|
fs.existsSync.mockReturnValueOnce(true)
|
||||||
|
fs.statSync.mockReturnValueOnce({ isFile: () => true })
|
||||||
|
fs.readFileSync.mockReturnValueOnce('pages/ignore.vue')
|
||||||
|
|
||||||
|
const ignore = new Ignore({
|
||||||
|
rootDir: '/var/nuxt'
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(ignore.ignore).toBeDefined()
|
||||||
|
expect(ignore.ignoreFile).toEqual('resolve(/var/nuxt, .nuxtignore)')
|
||||||
|
|
||||||
|
ignore.addIgnoresRules = jest.fn()
|
||||||
|
|
||||||
|
ignore.reload()
|
||||||
|
|
||||||
|
expect(ignore.ignore).toBeUndefined()
|
||||||
|
expect(ignore.ignoreFile).toBeUndefined()
|
||||||
|
expect(ignore.addIgnoresRules).toBeCalledTimes(1)
|
||||||
|
})
|
||||||
|
})
|
9
packages/builder/test/index.test.js
Normal file
9
packages/builder/test/index.test.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { Builder } from '../src'
|
||||||
|
|
||||||
|
jest.mock('../src/builder', () => jest.fn(() => 'nuxt builder'))
|
||||||
|
|
||||||
|
describe('builder: entry', () => {
|
||||||
|
test('should export Builder', () => {
|
||||||
|
expect(Builder()).toEqual('nuxt builder')
|
||||||
|
})
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user