Back to Repositories

Testing ESLint Configuration Management in vue-cli

This test suite validates the ESLint configuration functionality in Vue CLI’s ESLint plugin. It covers configuration name resolution, default value handling, and ESLint prompt generation for Vue.js projects.

Test Coverage Overview

The test suite provides comprehensive coverage of ESLint configuration handling:
  • Configuration name resolution for both string and array-based extends
  • Default value determination based on rule categories
  • ESLint prompt generation with rule organization
  • Edge cases for various ESLint configuration scenarios

Implementation Analysis

The testing approach uses Jest’s describe/it pattern for organized test grouping. It implements thorough validation of the configDescriptor module functionality with detailed test cases for different configuration scenarios and rule categories.

The tests utilize Jest’s expect assertions and mock data structures to validate ESLint configuration behavior.

Technical Details

  • Testing Framework: Jest
  • Test Focus: Unit tests
  • Key Functions Tested: getEslintConfigName, getDefaultValue, getEslintPrompts
  • Mock Data: ESLint configuration objects and rule definitions

Best Practices Demonstrated

The test suite exemplifies several testing best practices:
  • Hierarchical test organization using nested describe blocks
  • Comprehensive edge case coverage
  • Clear test case descriptions
  • Consistent test data structure
  • Modular test organization by functionality

vuejs/vue-cli

packages/@vue/cli-plugin-eslint/__tests__/ui.spec.js

            
const configDescriptor = require('../ui/configDescriptor')
const { getEslintConfigName, getDefaultValue, getEslintPrompts } = configDescriptor

describe('getEslintConfigName', () => {
  describe('for "extend" of string type', () => {
    it('returns null if it doesn\'t extend vue plugin config', () => {
      expect(getEslintConfigName({
        extends: 'eslint:recommended'
      })).toBe(null)
    })

    it('returns vue config used', () => {
      expect(getEslintConfigName({
        extends: 'plugin:vue/recommended'
      })).toBe('plugin:vue/recommended')
    })
  })

  describe('for "extend" of array type', () => {
    it('returns null if it doesn\'t extend vue plugin config', () => {
      expect(getEslintConfigName({
        extends: ['eslint:recommended', 'standard']
      })).toBe(null)
    })

    it('returns vue config used', () => {
      expect(getEslintConfigName({
        extends: ['eslint:recommended', 'plugin:vue/recommended']
      })).toBe('plugin:vue/recommended')
    })
  })
})

describe('getDefaultValue', () => {
  const getResult = (config, ruleCategory) => {
    const rule = {
      meta: {
        docs: {
          category: ruleCategory
        }
      }
    }

    const data = {
      eslint: {
        extends: config
      }
    }

    return getDefaultValue(rule, data)
  }

  it('returns "ERROR" value if the rule belongs to the selected configuration', () => {
    expect(getResult('plugin:vue/base', 'base')).toBe('error')
    expect(getResult('plugin:vue/essential', 'base')).toBe('error')
    expect(getResult('plugin:vue/essential', 'essential')).toBe('error')
    expect(getResult('plugin:vue/strongly-recommended', 'base')).toBe('error')
    expect(getResult('plugin:vue/strongly-recommended', 'essential')).toBe('error')
    expect(getResult('plugin:vue/strongly-recommended', 'strongly-recommended')).toBe('error')
    expect(getResult('plugin:vue/recommended', 'base')).toBe('error')
    expect(getResult('plugin:vue/recommended', 'essential')).toBe('error')
    expect(getResult('plugin:vue/recommended', 'strongly-recommended')).toBe('error')
    expect(getResult('plugin:vue/recommended', 'recommended')).toBe('error')
  })

  it('returns "OFF" value if the rule doesn\'t belong to the selected configuration', () => {
    expect(getResult('plugin:vue/base', 'essential')).toBe('off')
    expect(getResult('plugin:vue/base', 'strongly-recommended')).toBe('off')
    expect(getResult('plugin:vue/base', 'recommended')).toBe('off')
    expect(getResult('plugin:vue/essential', 'strongly-recommended')).toBe('off')
    expect(getResult('plugin:vue/essential', 'recommended')).toBe('off')
    expect(getResult('plugin:vue/strongly-recommended', 'recommended')).toBe('off')
    expect(getResult('plugin:vue/base', undefined)).toBe('off')
    expect(getResult('plugin:vue/essential', undefined)).toBe('off')
    expect(getResult('plugin:vue/strongly-recommended', undefined)).toBe('off')
    expect(getResult('plugin:vue/recommended', undefined)).toBe('off')
  })
})

describe('getEslintPrompts', () => {
  // project configuration
  const data = {
    eslint: {
      extends: 'plugin:vue/recommended',
      rules: {
        'vue/lorem': ['error', ['asd']], // custom setting
        'vue/ipsum': 'warn'
      }
    }
  }

  // all rules
  const rules = {
    'lorem': {
      meta: {
        docs: {
          category: undefined,
          description: 'Lorem description',
          url: 'http://test.com/lorem'
        }
      }
    },
    'ipsum': {
      meta: {
        docs: {
          category: 'recommended',
          description: 'Ipsum description',
          url: 'http://test.com/ipsum'
        }
      }
    },
    'dolor': {
      meta: {
        docs: {
          category: 'strongly-recommended',
          description: 'Dolor description',
          url: 'http://test.com/dolor'
        }
      }
    },
    'sit': {
      meta: {
        docs: {
          category: 'base',
          description: 'Sit description',
          url: 'http://test.com/sit'
        }
      }
    }
  }

  const prompts = getEslintPrompts(data, rules)

  it('creates an array with 3 settings, leaving out category "base"', () => {
    expect(prompts).toHaveLength(3)
  })

  it('creates an array which order matches eslint categories', () => {
    expect(prompts[0].name).toBe('vue/dolor')
    expect(prompts[1].name).toBe('vue/ipsum')
    expect(prompts[2].name).toBe('vue/lorem')
  })

  it('doesn\'t set value on prompt item, if the rule wasn\'t set in project\'s eslint config', () => {
    expect(prompts[0].value).toBe(undefined)
  })

  it('sets value on prompt item, if the rule was set in project\'s eslint config', () => {
    expect(prompts[1].value).toBe('"warn"')
    expect(prompts[2].value).toBe('["error",["asd"]]')
  })

  it('generates an extra choice for rules that have a custom setting', () => {
    expect(prompts[0].choices).toHaveLength(3)
    expect(prompts[1].choices).toHaveLength(3)
    expect(prompts[2].choices).toHaveLength(4)
  })

  it('sets a default value to "ERROR" for rule that belong to the chosen config', () => {
    expect(prompts[0].default).toBe('"error"')
    expect(prompts[1].default).toBe('"error"')
    expect(prompts[2].default).toBe('"off"')
  })
})