Nuxt/packages/generator/test/generator.init.test.js

243 lines
8.1 KiB
JavaScript

import consola from 'consola'
import fsExtra from 'fs-extra'
import { flatRoutes, isString, isUrl, promisifyRoute } from '@nuxt/utils'
import Generator from '../src/generator'
import { createNuxt, hookCalls } from './__utils__'
jest.mock('fs-extra')
jest.mock('@nuxt/utils')
describe('generator: initialize', () => {
beforeAll(() => {
isString.mockImplementation(str => typeof str === 'string')
})
beforeEach(() => {
jest.clearAllMocks()
})
test('should construct Generator', () => {
isUrl.mockReturnValueOnce(true)
const nuxt = createNuxt()
nuxt.options = {
...nuxt.options,
build: { publicPath: 'http://localhost:3000' }
}
const builder = jest.fn()
const generator = new Generator(nuxt, builder)
expect(generator.nuxt).toBe(nuxt)
expect(generator.options).toBe(nuxt.options)
expect(generator.builder).toBe(builder)
expect(generator.staticRoutes).toBePath(
'/var/nuxt/static',
'C:\\nuxt\\static'
)
expect(generator.srcBuiltPath).toBePath(
'/var/nuxt/build/dist/client',
'C:\\nuxt\\build\\dist\\client'
)
expect(generator.distPath).toBePath(
'/var/nuxt/generate',
'C:\\nuxt\\generate'
)
expect(generator.distNuxtPath).toBePath(
'/var/nuxt/generate',
'C:\\nuxt\\generate'
)
})
test('should append publicPath to distPath if publicPath is not url', () => {
isUrl.mockReturnValueOnce(false)
const nuxt = createNuxt()
nuxt.options = {
...nuxt.options,
build: { publicPath: '__public' }
}
const builder = jest.fn()
const generator = new Generator(nuxt, builder)
expect(generator.distNuxtPath).toBePath(
'/var/nuxt/generate/__public',
'C:\\nuxt\\generate\\__public'
)
})
test('should initiate with build and init by default', async () => {
const nuxt = createNuxt()
const builder = { forGenerate: jest.fn(), build: jest.fn() }
const generator = new Generator(nuxt, builder)
generator.initDist = jest.fn()
await generator.initiate()
expect(nuxt.ready).toBeCalledTimes(1)
expect(hookCalls(nuxt, 'generate:before')[0]).toMatchObject([generator, { dir: generator.distPath }])
expect(builder.forGenerate).toBeCalledTimes(1)
expect(builder.build).toBeCalledTimes(1)
expect(generator.initDist).toBeCalledTimes(1)
})
test('should initiate without build and init if disabled', async () => {
const nuxt = createNuxt()
const builder = { forGenerate: jest.fn(), build: jest.fn() }
const generator = new Generator(nuxt, builder)
generator.initDist = jest.fn()
fsExtra.exists.mockReturnValueOnce(true)
generator.getBuildConfig = jest.fn(() => ({ ssr: true, target: 'static' }))
await generator.initiate({ build: false, init: false })
expect(nuxt.ready).toBeCalledTimes(1)
expect(hookCalls(nuxt, 'generate:before')[0]).toMatchObject([generator, { dir: generator.distPath }])
expect(builder.forGenerate).not.toBeCalled()
expect(builder.build).not.toBeCalled()
expect(generator.initDist).not.toBeCalled()
})
test('should throw error when build is not disabled, but Builder instance is omitted', async () => {
const nuxt = createNuxt()
const generator = new Generator(nuxt)
await expect(generator.initiate()).rejects.toThrow('Could not generate')
})
test('should init routes with generate.routes and routes.json', async () => {
const nuxt = createNuxt()
nuxt.options = {
...nuxt.options,
generate: {
...nuxt.options.generate,
exclude: [/test/],
routes: ['/foo', '/foo/bar']
},
router: {
mode: 'history'
}
}
const generator = new Generator(nuxt)
flatRoutes.mockImplementationOnce(routes => routes)
promisifyRoute.mockImplementationOnce(routes => routes)
generator.getAppRoutes = jest.fn(() => ['/index', '/about', '/test'])
generator.decorateWithPayloads = jest.fn(() => 'decoratedRoutes')
const routes = await generator.initRoutes()
expect(promisifyRoute).toBeCalledTimes(1)
expect(promisifyRoute).toBeCalledWith(['/foo', '/foo/bar'])
expect(flatRoutes).toBeCalledTimes(1)
expect(flatRoutes).toBeCalledWith(['/index', '/about', '/test'])
expect(generator.decorateWithPayloads).toBeCalledTimes(1)
expect(generator.decorateWithPayloads).toBeCalledWith(['/index', '/about'], ['/foo', '/foo/bar'])
expect(hookCalls(nuxt, 'generate:extendRoutes')[0][0]).toBe('decoratedRoutes')
expect(routes).toEqual('decoratedRoutes')
})
test('should init routes with hash mode', async () => {
const nuxt = createNuxt()
nuxt.options = {
...nuxt.options,
generate: {
...nuxt.options.generate,
exclude: [/test/],
routes: ['/foo', '/foo/bar']
},
router: {
mode: 'hash'
}
}
const generator = new Generator(nuxt)
flatRoutes.mockImplementationOnce(routes => routes)
promisifyRoute.mockImplementationOnce(routes => routes)
generator.decorateWithPayloads = jest.fn(() => 'decoratedRoutes')
const routes = await generator.initRoutes()
expect(promisifyRoute).not.toBeCalled()
expect(flatRoutes).not.toBeCalled()
expect(generator.decorateWithPayloads).toBeCalledTimes(1)
expect(generator.decorateWithPayloads).toBeCalledWith(['/'], [])
expect(hookCalls(nuxt, 'generate:extendRoutes')[0][0]).toBe('decoratedRoutes')
expect(routes).toEqual('decoratedRoutes')
promisifyRoute.mockReset()
flatRoutes.mockReset()
})
test('should throw error when route can not be resolved', async () => {
const nuxt = createNuxt()
nuxt.options.router = { mode: 'history' }
const generator = new Generator(nuxt)
promisifyRoute.mockImplementationOnce(() => {
throw new Error('promisifyRoute failed')
})
await expect(generator.initRoutes()).rejects.toThrow('promisifyRoute failed')
expect(promisifyRoute).toBeCalledTimes(1)
expect(promisifyRoute).toBeCalledWith([])
expect(consola.error).toBeCalledTimes(1)
expect(consola.error).toBeCalledWith('Could not resolve routes')
})
test('should initialize destination folder', async () => {
const nuxt = createNuxt()
nuxt.options.generate.fallback = 'fallback.html'
nuxt.options.generate.nojekyll = true
const generator = new Generator(nuxt)
fsExtra.exists.mockReturnValueOnce(false)
await generator.initDist()
expect(fsExtra.emptyDir).toBeCalledTimes(1)
expect(fsExtra.emptyDir).toBeCalledWith(generator.distPath)
expect(hookCalls(nuxt, 'generate:distRemoved')[0][0]).toMatchObject(generator)
expect(fsExtra.exists).toBeCalledTimes(1)
expect(fsExtra.exists).toBeCalledWith(generator.staticRoutes)
expect(fsExtra.copy).toBeCalledTimes(1)
expect(fsExtra.copy).toBeCalledWith(generator.srcBuiltPath, generator.distNuxtPath)
expect(fsExtra.writeFile).toBeCalledTimes(1)
expect(fsExtra.writeFile.mock.calls[0][0]).toBePath(
'/var/nuxt/generate/.nojekyll',
'C:\\nuxt\\generate\\.nojekyll'
)
expect(hookCalls(nuxt, 'generate:distCopied')[0][0]).toMatchObject(generator)
})
test('should copy static routes if path exists', async () => {
const nuxt = createNuxt()
nuxt.options.generate.fallback = 'fallback.html'
const generator = new Generator(nuxt)
fsExtra.exists.mockReturnValueOnce(true)
await generator.initDist()
expect(fsExtra.copy).toBeCalledTimes(2)
expect(fsExtra.copy).nthCalledWith(1, generator.staticRoutes, generator.distPath)
expect(fsExtra.copy).nthCalledWith(2, generator.srcBuiltPath, generator.distNuxtPath)
})
test('should decorate routes with payloads', () => {
const nuxt = createNuxt()
const generator = new Generator(nuxt)
const routes = ['/index', '/about', '/test']
const generateRoutes = ['/foo', { route: '/foo/bar', payload: { param: 'foo bar' } }]
const routeMap = generator.decorateWithPayloads(routes, generateRoutes)
expect(routeMap).toEqual([
{ payload: null, route: '/index' },
{ payload: null, route: '/about' },
{ payload: null, route: '/test' },
{ payload: null, route: '/foo' },
{ payload: { param: 'foo bar' }, route: '/foo/bar' }
])
})
})