CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-vue--cli-plugin-unit-jest

A Vue CLI plugin that adds Jest unit testing capabilities to Vue.js projects, providing seamless integration with the Vue CLI service through the 'test:unit' command.

Pending
Overview
Eval results
Files

project-generation.mddocs/

Project Generation

The project generation capability provides generator functions that set up test configuration, dependencies, and example files when the plugin is added to a Vue CLI project.

Capabilities

Main Generator Function

The primary generator function that configures the project for Jest testing based on existing plugins and Vue version.

/**
 * Main generator function for project setup
 * @param api - Generator API for modifying project files
 * @param options - Plugin-specific options
 * @param rootOptions - Root project options (Vue version, etc.)
 * @param invoking - Whether this is the initial plugin invocation
 */
function generator(
  api: GeneratorAPI,
  options: any,
  rootOptions: any,
  invoking: boolean
): void;

Usage Example:

// generator/index.js
module.exports = (api, options, rootOptions, invoking) => {
  const isVue3 = rootOptions && rootOptions.vueVersion === '3'
  
  // Render template files
  api.render('./template', {
    isVue3,
    hasTS: api.hasPlugin('typescript'),
    hasRouter: api.hasPlugin('router')
  })
  
  // Configure package.json
  api.extendPackage({
    scripts: {
      'test:unit': 'vue-cli-service test:unit'
    },
    devDependencies: {
      '@vue/test-utils': isVue3 ? '^2.0.0-0' : '^1.0.3'
    }
  })
}

ESLint Integration

Configures ESLint settings for test files when ESLint plugin is present.

/**
 * Apply ESLint configuration for test files
 * @param api - Generator API for package modifications
 */
function applyESLint(api: GeneratorAPI): void;

Usage Example:

const applyESLint = api => {
  api.extendPackage({
    eslintConfig: {
      overrides: [
        {
          files: [
            '**/__tests__/*.{j,t}s?(x)',
            '**/tests/unit/**/*.spec.{j,t}s?(x)'
          ],
          env: {
            jest: true
          }
        }
      ]
    }
  })
}

TypeScript Integration

Configures TypeScript-specific Jest settings and type definitions.

/**
 * Apply TypeScript configuration for Jest
 * @param api - Generator API for package modifications
 * @param invoking - Whether this is initial plugin invocation
 */
function applyTS(api: GeneratorAPI, invoking: boolean): void;

Usage Example:

const applyTS = (api, invoking) => {
  api.extendPackage({
    jest: {
      preset: api.hasPlugin('babel')
        ? '@vue/cli-plugin-unit-jest/presets/typescript-and-babel'
        : '@vue/cli-plugin-unit-jest/presets/typescript'
    },
    devDependencies: {
      '@types/jest': '^24.0.19'
    }
  })
  
  // Inject Jest types into tsconfig.json if invoking
  if (invoking) {
    api.render(files => {
      const tsconfig = files['tsconfig.json']
      if (tsconfig) {
        const parsed = JSON.parse(tsconfig)
        if (!parsed.compilerOptions.types?.includes('jest')) {
          parsed.compilerOptions.types = parsed.compilerOptions.types || []
          parsed.compilerOptions.types.push('jest')
        }
        files['tsconfig.json'] = JSON.stringify(parsed, null, 2)
      }
    })
  }
}

Package Configuration

Script Addition

The generator automatically adds the test script to package.json:

const scriptConfig = {
  scripts: {
    'test:unit': 'vue-cli-service test:unit'
  }
};

Dependency Management

Dependencies are configured based on Vue version and existing plugins:

interface DependencyConfig {
  devDependencies: {
    /** Vue Test Utils version based on Vue version */
    '@vue/test-utils': string;
    /** Jest type definitions for TypeScript projects */
    '@types/jest'?: string;
    /** Vue Jest transformer for Vue 3 projects */
    'vue-jest'?: string;
    /** TypeScript requirement for Vue 3 with vue-jest */
    'typescript'?: string;
  };
}

Jest Configuration

The Jest configuration is set based on project plugins:

interface JestConfig {
  jest: {
    /** Preset selection based on Babel/TypeScript presence */
    preset: string;
    /** Vue 3 specific transform configuration */
    transform?: {
      '^.+\\.vue$': string;
    };
  };
}

Vue Version Handling

Vue 2 Configuration

const vue2Config = {
  devDependencies: {
    '@vue/test-utils': '^1.0.3'
  },
  jest: {
    preset: '@vue/cli-plugin-unit-jest' // Uses default preset
  }
};

Vue 3 Configuration

const vue3Config = {
  devDependencies: {
    '@vue/test-utils': '^2.0.0-0',
    'vue-jest': '^5.0.0-0',
    'typescript': '~3.9.3' // Required by vue-jest 5.0.0-alpha.1
  },
  jest: {
    transform: {
      '^.+\\.vue$': 'vue-jest'
    }
  }
};

Template Rendering

Template Data

The generator provides template data for conditional rendering:

interface TemplateData {
  /** Whether project uses Vue 3 */
  isVue3: boolean;
  /** Whether TypeScript plugin is present */
  hasTS: boolean;
  /** Whether Router plugin is present */
  hasRouter: boolean;
}

Example Test Templates

The generator creates example test files with conditional content based on project configuration:

JavaScript Template (example.spec.js):

// For regular Vue projects
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => {
  it('renders props.msg when passed', () => {
    const msg = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      // Vue 3 uses props, Vue 2 uses propsData
      props: { msg } // or propsData: { msg } for Vue 2
    })
    expect(wrapper.text()).toMatch(msg)
  })
})
// For bare projects without HelloWorld component
import { shallowMount } from '@vue/test-utils'
import App from '@/App.vue'

test('App should work', () => {
  const wrapper = shallowMount(App)
  expect(wrapper.text()).toMatch(`Welcome to Your Vue.js App`)
})
// For bare projects with router
import { mount, createLocalVue } from '@vue/test-utils'
import VueRouter from 'vue-router'
import App from '@/App.vue'
import router from '@/router'

const localVue = createLocalVue()
localVue.use(VueRouter)

test('App should render default route', () => {
  const wrapper = mount(App, {
    localVue,
    router
  })
  expect(wrapper.text()).toMatch(`Welcome to Your Vue.js App`)
})

TypeScript Template (example.spec.ts):

// Same as JavaScript but with TypeScript syntax and type checking
import { shallowMount } from '@vue/test-utils'
import HelloWorld from '@/components/HelloWorld.vue'

describe('HelloWorld.vue', () => {
  it('renders props.msg when passed', () => {
    const msg: string = 'new message'
    const wrapper = shallowMount(HelloWorld, {
      props: { msg } // Vue 3 syntax shown
    })
    expect(wrapper.text()).toMatch(msg)
  })
})

Plugin Detection

The generator uses plugin detection to configure Jest presets appropriately:

interface PluginDetection {
  /** Check if Babel plugin is present */
  hasPlugin(name: 'babel'): boolean;
  /** Check if TypeScript plugin is present */
  hasPlugin(name: 'typescript'): boolean;
  /** Check if ESLint plugin is present */
  hasPlugin(name: 'eslint'): boolean;
  /** Check if Router plugin is present */
  hasPlugin(name: 'router'): boolean;
}

Types

interface GeneratorAPI {
  /** Render template files with data */
  render(templatePath: string, templateData?: any): void;
  /** Render with file modification callback */
  render(callback: (files: Record<string, string>) => void): void;
  /** Extend package.json with additional configuration */
  extendPackage(packageAdditions: any): void;
  /** Check if a specific plugin is present in the project */
  hasPlugin(pluginName: string): boolean;
}

interface PackageExtension {
  /** NPM scripts to add */
  scripts?: Record<string, string>;
  /** Development dependencies to add */
  devDependencies?: Record<string, string>;
  /** Jest configuration */
  jest?: any;
  /** ESLint configuration */
  eslintConfig?: any;
}

Install with Tessl CLI

npx tessl i tessl/npm-vue--cli-plugin-unit-jest

docs

command-registration.md

index.md

jest-presets.md

project-generation.md

ui-integration.md

tile.json