Nuxt/packages/cli/test/unit/command.test.js

164 lines
5.0 KiB
JavaScript
Raw Normal View History

import Command from '../../src/command'
import { common, server } from '../../src/options'
import * as utils from '../../src/utils/'
import * as config from '../../src/utils/config'
import * as constants from '../../src/utils/constants'
import { consola } from '../utils'
jest.mock('@nuxt/core')
jest.mock('@nuxt/builder')
jest.mock('@nuxt/generator')
const allOptions = {
...common,
...server
}
describe('cli/command', () => {
beforeEach(() => jest.restoreAllMocks())
test('builds minimist options', () => {
const cmd = new Command({ options: allOptions })
const minimistOptions = cmd._getMinimistOptions()
feat: options.target and full-static export (#6159) * feat: add options.target * fix(lint): lint * fix(test): update snapshots * fix(builder): default value for target * fix(test): fix test * fix(test): test fixing * fix: use this.options.target * fix: final test * Update packages/vue-renderer/src/renderer.js Co-Authored-By: Alexander Lichter <manniL@gmx.net> * feat: Add target option and update banner * fix(lint): fix * feat: Add warning when using serverMiddleware in static target * chore(utils): add TARGETS and MODES as constants * hotfix: lint * chore(module): add filename as alias of fileName * feat: introducing nuxt export and router/routes.json * hotfix: Fix the linting lord * chore(core): add comment for filename vs fileName * fix: use targets constant * chore: remove warning * fix: unit testing * wip: refactor and use TARGETS * fix: lint * feat: add target as alias for first arg value * fix: generate only for SPA * chore: explain to use nuxt static X * fix: render SPA fallback on redirect for static target * fix: lint issue * fix: only target is useful for now * wip * wip: nuxt static export is looking good * Update packages/generator/src/generator.js Co-Authored-By: Devon Rueckner <indirectlylit@users.noreply.github.com> * Update packages/cli/src/options/common.js Co-Authored-By: Alexander Lichter <manniL@gmx.net> * feat: add options.target * fix(lint): lint * fix(test): update snapshots * fix(builder): default value for target * fix(test): fix test * fix(test): test fixing * fix: use this.options.target * fix: final test * Update packages/vue-renderer/src/renderer.js Co-Authored-By: Alexander Lichter <manniL@gmx.net> * feat: Add target option and update banner * fix(lint): fix * feat: Add warning when using serverMiddleware in static target * chore(utils): add TARGETS and MODES as constants * hotfix: lint * chore(module): add filename as alias of fileName * feat: introducing nuxt export and router/routes.json * hotfix: Fix the linting lord * chore(core): add comment for filename vs fileName * fix: use targets constant * chore: remove warning * fix: unit testing * wip: refactor and use TARGETS * fix: lint * feat: add target as alias for first arg value * chore: explain to use nuxt static X * fix: render SPA fallback on redirect for static target * fix: lint issue * fix: only target is useful for now * wip * wip: nuxt static export is looking good * Update packages/generator/src/generator.js Co-Authored-By: Devon Rueckner <indirectlylit@users.noreply.github.com> * Update packages/cli/src/options/common.js Co-Authored-By: Alexander Lichter <manniL@gmx.net> * fix: duplicate imports * chore: don't server render if an error happens on static target * test: update unit and add export * lint: fix * lint: fix * fix: e2e test * fix: fallback only for static target * fix: dev test * feat: add generate.crawler * fix: full static is when generate.static is given * chore: improvements * fix: Add isFullStatic in nuxt/config.json * feat: handle fetch for full static * feat: router.prefetchPayloads for full static * chore: use fetch in async-data example * fix: add target only if given * fix: use created to have access to props in fetchOnServer * chore: add console.error in dev for easy debugging * feat: payload smart pre-fetching * fix: remove alias for target * fix: increment payloadFetchIndex is static set to false * chore: lint * chore: add serve command * chore: rename universal to server-side * fix: handle payloadPath on SPA fallback * fix: lint * chore lint again * feat: handle spa fallback * feat: support string for exclude * fix: fallback only if no extension or html * chore: use JSON.stringify() for static target * chore: lint again, dammit * chore: fix tests and remove too early return * fix: early return only for server target * fix: update tests * fix: unit tests * chore: add ssr option * chore: add logic for ssr option * fix: #6682 * chore(dx): add next command to run * fix: lint * fix: tests * chore: keep old behaviour for nuxt build in spa * fix: test again, oh boy * fix: alright this is good now * chore: add comment for spa fallback * chore: move routes.json to dot nuxt dir * chore: simplify check for promise * chore: unique lock id * chore: refactor isFullStatic * fix: dont set default in build context * chore: add test for serve * chore: update tests * hotfix: lint tests * chore(dx): improve message for bundling * feat: js payload extraction with jsonp * fix: keep serialized session script for legacy generate * fix: call to setPagePayload from fetchPayload * use devalue for payload chunks * feat: add initial load state chunk * feat: preload payload and state scripts * fix(vue-app): don't re-render the app if trailing slash on SSG * hotfix: remove console.log * chore(dx): add deploy infos for nuxt export Co-authored-by: Pooya Parsa <pyapar@gmail.com> * chore: handle fetching payload.js for nuxt state * chore(dx): error when using nuxt generate and static * chore: remove static option for clarity * chore: remove serverless target * hotfix: lint * hotfix: unit tests * chore: update legacy js resource * chore: remove query params from url in static target * fix: use globalName and urlJoin * chore: typo * feat: previewMode 👀 * chore: rename to enablePreview * fix: wait next tick to avoid error on spa * chore: try 1 sec * hotfix: test only for linux, wtf azure * refactor: static assets - generalize logic for modules need emit export static assets - allow customization for version, dir and base - serialization logic is only in ssr now * feat: smart state chunk creates * fix(client): ignore payload load error * perf: avoide payload loading for spa initial * perf: avoid loading failed chunks again * chore(cli): add simple compression for nuxt serve * test: update snapshots * fix version snapshot * fix(generator): set staticAssetsBase on context only for full static * fix tests * fix: honor shouldHashCspScriptSrc * chore(dx): add log for client-side fallback creation Co-authored-by: Xin Du (Clark) <clark.duxin@gmail.com> Co-authored-by: Alexander Lichter <manniL@gmx.net> Co-authored-by: Pooya Parsa <pooya@pi0.ir> Co-authored-by: Devon Rueckner <indirectlylit@users.noreply.github.com> Co-authored-by: Pooya Parsa <pyapar@gmail.com>
2020-05-07 19:08:01 +00:00
expect(minimistOptions.string.length).toBe(6)
expect(minimistOptions.boolean.length).toBe(5)
expect(minimistOptions.alias.c).toBe('config-file')
expect(minimistOptions.default.c).toBe(common['config-file'].default)
})
test('parses args', () => {
const argv = ['-c', 'test-file', '-s', '-p', '3001']
const cmd = new Command({ options: { ...common, ...server } }, argv)
expect(cmd.argv['config-file']).toBe(argv[1])
expect(cmd.argv.spa).toBe(true)
expect(cmd.argv.universal).toBe(false)
expect(cmd.argv.port).toBe('3001')
const cmd2 = new Command({ options: { ...common, ...server } }, ['--no-build'])
expect(cmd2.argv.build).toBe(false)
})
test('prints version automatically', async () => {
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
const cmd = new Command({}, ['--version'])
cmd.showVersion = jest.fn()
await cmd.run()
expect(cmd.showVersion).toHaveBeenCalledTimes(1)
})
test('prints help automatically', async () => {
jest.spyOn(utils, 'forceExit').mockImplementation(() => {})
const cmd = new Command({ options: allOptions }, ['-h'])
cmd.showHelp = jest.fn()
await cmd.run()
expect(cmd.showHelp).toHaveBeenCalledTimes(1)
})
test('returns nuxt config', async () => {
const loadConfigSpy = jest.spyOn(config, 'loadNuxtConfig')
const cmd = new Command({ name: 'test', options: allOptions }, ['-c', 'test-file', '-a', '-p', '3001', '-q', '-H'])
const options = await cmd.getNuxtConfig({ testOption: true })
expect(options.testOption).toBe(true)
expect(options.server.port).toBe(3001)
expect(consola.fatal).toHaveBeenCalledWith('Provided hostname argument has no value') // hostname check
expect(loadConfigSpy).toHaveBeenCalledTimes(1)
expect(loadConfigSpy).toHaveBeenCalledWith(expect.any(Object), { command: 'test', dev: false })
loadConfigSpy.mockRestore()
})
test('returns Nuxt instance', async () => {
const cmd = new Command()
const nuxt = await cmd.getNuxt()
expect(nuxt.constructor.name).toBe('Nuxt')
expect(typeof nuxt.ready).toBe('function')
})
test('returns Builder instance', async () => {
const cmd = new Command()
const builder = await cmd.getBuilder()
expect(builder.constructor.name).toBe('Builder')
expect(typeof builder.build).toBe('function')
})
test('returns Generator instance', async () => {
const cmd = new Command()
const generator = await cmd.getGenerator()
expect(generator.constructor.name).toBe('Generator')
expect(typeof generator.generate).toBe('function')
})
test('builds help text', () => {
jest.spyOn(constants, 'maxCharsPerLine').mockReturnValue(40)
const cmd = new Command({
description: 'a very long description that should wrap to the next line because is not longer ' +
'than the terminal width',
usage: 'this is how you do it',
options: {
...allOptions,
foo: {
type: 'boolean',
description: 'very long option that is longer than the terminal width and ' +
'should wrap to the next line'
}
}
})
expect(cmd._getHelp()).toMatchSnapshot()
})
test('show version prints to stdout and exits', () => {
jest.spyOn(process.stdout, 'write').mockImplementation(() => {})
const cmd = new Command()
cmd.showVersion()
expect(process.stdout.write).toHaveBeenCalled()
process.stdout.write.mockRestore()
})
test('show help prints to stdout and exits', () => {
jest.spyOn(process.stdout, 'write').mockImplementation(() => {})
const cmd = new Command()
cmd.showHelp()
expect(process.stdout.write).toHaveBeenCalled()
process.stdout.write.mockRestore()
})
test('can set and release lock', () => {
const release = jest.fn(() => Promise.resolve())
const cmd = new Command()
cmd.setLock(release)
cmd.releaseLock()
expect(release).toHaveBeenCalledTimes(1)
})
test('logs warning when lock already exists and removes old lock', () => {
const release = jest.fn(() => Promise.resolve())
const cmd = new Command()
cmd.setLock(release)
cmd.setLock(release)
expect(consola.warn).toHaveBeenCalledTimes(1)
expect(consola.warn).toHaveBeenCalledWith(expect.stringMatching('A previous unreleased lock was found'))
expect(release).toHaveBeenCalledTimes(1)
cmd.releaseLock()
expect(release).toHaveBeenCalledTimes(2)
})
})