planFieldValidation.test.js 5.75 KB
/**
 * planFieldValidation 单元测试
 *
 * @description 测试字段验证系统
 * @module utils/__tests__/planFieldValidation.test
 */

import { describe, it, expect } from 'vitest'
import { validateField, validateForm, VALIDATION_RULES } from '../planFieldValidation'
import { isNotEmpty } from '../planFieldValidation'

describe('validateField', () => {
  it('should pass required validation for non-empty string', () => {
    const result = validateField('John', { required: true })
    expect(result.valid).toBe(true)
  })

  it('should fail required validation for empty string', () => {
    const result = validateField('', { required: true })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('该字段为必填')
  })

  it('should pass required validation for whitespace string', () => {
    const result = validateField('   ', { required: true })
    expect(result.valid).toBe(false)
  })

  it('should pass min validation', () => {
    const result = validateField('abc', { min: 3 })
    expect(result.valid).toBe(true)
  })

  it('should fail min validation', () => {
    const result = validateField('ab', { min: 3 })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('至少需要3个字符')
  })

  it('should pass max validation', () => {
    const result = validateField('abcde', { max: 5 })
    expect(result.valid).toBe(true)
  })

  it('should fail max validation', () => {
    const result = validateField('abcdef', { max: 5 })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('最多5个字符')
  })

  it('should pass range validation', () => {
    const result = validateField(18, { range: [18, 65] })
    expect(result.valid).toBe(true)
  })

  it('should fail range validation (too small)', () => {
    const result = validateField(17, { range: [18, 65] })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('18-65')
  })

  it('should fail range validation (too large)', () => {
    const result = validateField(66, { range: [18, 65] })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('18-65')
  })

  it('should pass pattern validation', () => {
    const result = validateField('13800138000', { pattern: '^1[3-9]\\d{9}$' })
    expect(result.valid).toBe(true)
  })

  it('should fail pattern validation', () => {
    const result = validateField('123456', { pattern: '^1[3-9]\\d{9}$' })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('格式不正确')
  })

  it('should pass custom validation', () => {
    const result = validateField(25, {
      custom: (value) => value >= 18
    })
    expect(result.valid).toBe(true)
  })

  it('should fail custom validation', () => {
    const result = validateField(15, {
      custom: (value) => value >= 18
    })
    expect(result.valid).toBe(false)
    expect(result.error).toBe('验证失败')
  })

  it('should handle null value', () => {
    const result = validateField(null, { required: true })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('该字段为必填')
  })

  it('should handle undefined value', () => {
    const result = validateField(undefined, { required: true })
    expect(result.valid).toBe(false)
    expect(result.error).toContain('该字段为必填')
  })
})

describe('validateForm', () => {
  it('should pass with valid data', () => {
    const formData = {
      customer_name: '张三',
      gender: 'male',
      age: 25
    }

    const fieldDefinitions = {
      customer_name: {
        validation: { required: (value) => value?.trim()?.length >= 2 }
      },
      age: {
        validation: { min: (value, ctx) => value >= ctx.age_range.min }
      }
    }

    const result = validateForm(formData, fieldDefinitions)
    expect(result.valid).toBe(true)
    expect(result.errors).toEqual({})
  })

  it('should fail with invalid data', () => {
    const formData = {
      customer_name: '张',
      age: 25
    }

    const fieldDefinitions = {
      customer_name: {
        validation: {
          required: (value) => value?.trim()?.length >= 2
        }
      },
      age: {
        validation: { min: (value) => value >= 18 }
      }
    }

    const result = validateForm(formData, fieldDefinitions, { age_range: { min: 18 } })
    expect(result.valid).toBe(false)
    expect(Object.keys(result.errors).length).toBeGreaterThan(0)
  })

  it('should skip validation for null/undefined values', () => {
    const formData = {
      customer_name: null,
      age: undefined
    }

    const fieldDefinitions = {
      customer_name: {
        validation: { required: (value) => value?.trim()?.length >= 2 }
      }
    }

    const result = validateForm(formData, fieldDefinitions)
    expect(result.valid).toBe(true)
  })

  it('should support context-dependent validation', () => {
    const formData = { age: 25 }

    const fieldDefinitions = {
      age: {
        validation: {
          min: (value, ctx) => value >= ctx.min_age,
          max: (value, ctx) => value <= ctx.max_age
        }
      }
    }

    const result = validateForm(formData, fieldDefinitions, {
      min_age: 18,
      max_age: 60
    })
    expect(result.valid).toBe(true)
    })
})

describe('isNotEmpty', () => {
  it('should return true for non-empty string', () => {
    expect(isNotEmpty('test')).toBe(true)
  })

  it('should return false for empty string', () => {
    expect(isNotEmpty('')).toBe(false)
  })

  it('should return false for null', () => {
    expect(isNotEmpty(null)).toBe(false)
  })

  it('should return false for undefined', () => {
    expect(isNotEmpty(undefined)).toBe(false)
  })

  it('should return false for whitespace string', () => {
    expect(isNotEmpty('   ')).toBe(false)
  })

  it('should return false for empty array', () => {
    expect(isNotEmpty([])).toBe(false)
  })
})