Back to Repositories

Testing Vue CLI Service Configuration Loading in vue-cli

This test suite validates the Vue CLI service configuration handling in ESM contexts, focusing on project options loading from various file formats and configurations. It ensures proper functionality of the Vue CLI service when working with ECMAScript modules.

Test Coverage Overview

The test suite provides comprehensive coverage of Vue CLI service configuration loading mechanisms.

Key areas tested include:
  • Package.json configuration loading
  • Vue config file loading from different formats (.js, .cjs, .mjs)
  • Function-based configuration support
  • ESM-specific configuration handling

Implementation Analysis

The testing approach utilizes Jest for unit testing Vue CLI service initialization and configuration loading. The implementation follows a modular pattern with isolated test cases for each configuration source, ensuring proper ESM compatibility and module loading behavior.

Key patterns include dependency injection through the Service constructor and file system manipulation for testing different config scenarios.

Technical Details

Testing tools and setup:
  • Jest as the testing framework
  • fs-extra for file system operations
  • Custom test utilities from @vue/cli-test-utils
  • Mock project creation for isolated testing
  • Dynamic configuration file generation

Best Practices Demonstrated

The test suite exemplifies several testing best practices including proper test isolation, cleanup, and comprehensive edge case coverage.

Notable practices:
  • Beforeall setup for test environment preparation
  • Isolated test cases for each configuration type
  • Proper cleanup of temporary files
  • Clear test case naming and organization

vuejs/vue-cli

packages/@vue/cli-service/__tests__/ServiceESM.spec.js

            
jest.setTimeout(200000)
const path = require('path')
const fs = require('fs-extra')

const { defaultPreset } = require('@vue/cli/lib/options')
const create = require('@vue/cli-test-utils/createTestProject')
const { loadModule } = require('@vue/cli-shared-utils')

let project
beforeAll(async () => {
  project = await create('service-esm-test', defaultPreset)
  const pkg = JSON.parse(await project.read('package.json'))
  pkg.type = 'module'
  pkg.vue = { lintOnSave: 'default' }
  await project.write('package.json', JSON.stringify(pkg, null, 2))
  fs.renameSync(path.resolve(project.dir, 'babel.config.js'), path.resolve(project.dir, 'babel.config.cjs'))
})

const createService = async () => {
  const Service = loadModule('@vue/cli-service/lib/Service', project.dir)
  const service = new Service(project.dir, {
    plugins: [],
    useBuiltIn: false
  })
  await service.init()
  return service
}

test('load project options from package.json', async () => {
  const service = await createService()
  expect(service.projectOptions.lintOnSave).toBe('default')
})

test('load project options from vue.config.cjs', async () => {
  const configPath = path.resolve(project.dir, './vue.config.cjs')
  fs.writeFileSync(configPath, 'module.exports = { lintOnSave: true }')
  const service = await createService()
  expect(service.projectOptions.lintOnSave).toBe(true)
  await fs.unlinkSync(configPath)
})

test('load project options from vue.config.cjs as a function', async () => {
  const configPath = path.resolve(project.dir, './vue.config.cjs')
  fs.writeFileSync(configPath, 'module.exports = function () { return { lintOnSave: true } }')
  const service = await createService()
  expect(service.projectOptions.lintOnSave).toBe(true)
  await fs.unlinkSync(configPath)
})

test('load project options from vue.config.js', async () => {
  const configPath = path.resolve(project.dir, './vue.config.js')
  fs.writeFileSync(configPath, 'export default { lintOnSave: true }')
  const service = await createService()
  expect(service.projectOptions.lintOnSave).toBe(true)
  await fs.unlinkSync(configPath)
})

test('load project options from vue.config.mjs', async () => {
  const configPath = path.resolve(project.dir, './vue.config.mjs')
  fs.writeFileSync(configPath, 'export default { lintOnSave: true }')
  const service = await createService()
  expect(service.projectOptions.lintOnSave).toBe(true)
  await fs.unlinkSync(configPath)
})