Skip to content

Commit

Permalink
test: introducing 100% coverage tests
Browse files Browse the repository at this point in the history
fix(slide): fix some bugs find in test for slide animation
  • Loading branch information
xsjcTony committed Nov 30, 2023
1 parent adf6e31 commit 6e34314
Show file tree
Hide file tree
Showing 15 changed files with 1,789 additions and 35 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"typecheck": "tsc --noEmit",
"lint": "eslint .",
"test": "vitest",
"test:update": "vitest -u",
"test:update": "vitest run -u",
"test:ci": "pnpm typecheck && pnpm build && pnpm lint && pnpm test",
"docs:dev": "vitepress dev docs",
"docs:build": "vitepress build docs",
Expand Down
6 changes: 3 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { definePreset } from '@unocss/core'
import { rules } from './rules'
import { shortcuts } from './shortcuts'
import { theme } from './theme'
import { rules } from '@/rules'
import { shortcuts } from '@/shortcuts'
import { theme } from '@/theme'


// This is for fixing the `rollup-plugin-dts` generating wrong import issue.
Expand Down
34 changes: 7 additions & 27 deletions src/rules.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { h } from '@unocss/preset-mini/utils'
import { CSS_VARIABLE_PREFIX } from './constants'
import { normalizeDirection } from './utils'
import { CSS_VARIABLE_PREFIX } from '@/constants'
import { handleSlide } from '@/utils'
import type { Theme } from '@unocss/preset-mini'
import type { Rule } from 'unocss'


const DEFAULT_FADE_OPACITY = '0'
const DEFAULT_ZOOM_SCALE = '0'
const DEFAULT_SPIN_DEGREE = '30deg'
const DEFAULT_SLIDE_TRANSLATE = '100%'
export const DEFAULT_SLIDE_TRANSLATE = '100%'


const DIRECTIONS_AUTOCOMPLETE = '(t|b|l|r|top|bottom|left|right)'
Expand Down Expand Up @@ -64,40 +64,20 @@ const spinRules: Rule<Theme>[] = [
]


const _handleSlideValue = (val: string | undefined, dir: string | undefined): string | undefined => {
let value = h.cssvar.fraction.rem(val || DEFAULT_SLIDE_TRANSLATE)

if (!value)
return

dir = normalizeDirection(dir)

if (!value.startsWith('var(--') && ['top', 'left'].includes(dir ?? '')) {
if (value.startsWith('-'))
value = value.slice(1)
else
value = `-${value}`
}

return value
}

const slideRules: Rule<Theme>[] = [
[
/^slide-in(?:-from)?-(t|b|l|r|top|bottom|left|right)(?:-(.+))?$/,
([, dir, val]) => {
const value = _handleSlideValue(val, dir)
const [value, direction] = handleSlide(val, dir)

if (!value)
return

switch (dir) {
switch (direction) {
case 'top':
return { [`${CSS_VARIABLE_PREFIX}-enter-translate-y`]: `-${value}` }
case 'bottom':
return { [`${CSS_VARIABLE_PREFIX}-enter-translate-y`]: value }
case 'left':
return { [`${CSS_VARIABLE_PREFIX}-enter-translate-x`]: `-${value}` }
case 'right':
return { [`${CSS_VARIABLE_PREFIX}-enter-translate-x`]: value }
default:
Expand All @@ -117,12 +97,12 @@ const slideRules: Rule<Theme>[] = [
[
/^slide-out(?:-to)?-(t|b|l|r|top|bottom|left|right)(?:-(.+))?$/,
([, dir, val]) => {
const value = _handleSlideValue(val, dir)
const [value, direction] = handleSlide(val, dir)

if (!value)
return

switch (dir) {
switch (direction) {
case 'top':
case 'bottom':
return { [`${CSS_VARIABLE_PREFIX}-exit-translate-y`]: value }
Expand Down
2 changes: 1 addition & 1 deletion src/shortcuts.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CSS_VARIABLE_PREFIX, ENTER_ANIMATION_NAME, EXIT_ANIMATION_NAME } from './constants'
import { CSS_VARIABLE_PREFIX, ENTER_ANIMATION_NAME, EXIT_ANIMATION_NAME } from '@/constants'
import type { Theme } from '@unocss/preset-mini'
import type { UserShortcuts } from 'unocss'

Expand Down
2 changes: 1 addition & 1 deletion src/theme.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CSS_VARIABLE_PREFIX, ENTER_ANIMATION_NAME, EXIT_ANIMATION_NAME } from './constants'
import { CSS_VARIABLE_PREFIX, ENTER_ANIMATION_NAME, EXIT_ANIMATION_NAME } from '@/constants'
import type { Theme } from '@unocss/preset-mini'


Expand Down
28 changes: 27 additions & 1 deletion src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export const normalizeDirection = (dir: string | undefined): string | undefined => {
import { h } from '@unocss/preset-mini/utils'
import { DEFAULT_SLIDE_TRANSLATE } from '@/rules'


const normalizeDirection = (dir: string | undefined): string | undefined => {
const dirMap: Record<string, string> = {
t: 'top',
b: 'bottom',
Expand All @@ -8,3 +12,25 @@ export const normalizeDirection = (dir: string | undefined): string | undefined

return dirMap[dir ?? ''] ?? dir
}


export const handleSlide = (
val: string | undefined,
dir: string | undefined
): [value?: string | undefined, direction?: string | undefined] => {
let value = h.cssvar.fraction.rem(val || DEFAULT_SLIDE_TRANSLATE)

if (!value)
return []

dir = normalizeDirection(dir)

if (!value.startsWith('var(--') && ['top', 'left'].includes(dir ?? '')) {
if (value.startsWith('-'))
value = value.slice(1)
else
value = `-${value}`
}

return [value, dir]
}
36 changes: 36 additions & 0 deletions test/base.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { describe, it, expect } from 'vitest'
import { generator, uno } from '~/utils'


describe('base classname', () => {
it('"animate-in" should generate enter keyframe and css variables', async () => {
const { css } = await uno.generate('animate-in')

expect(css).toMatchInlineSnapshot(`
"/* layer: default */
@keyframes una-in{from{opacity:var(--una-enter-opacity,1);transform:translate3d(var(--una-enter-translate-x,0),var(--una-enter-translate-y,0),0) scale3d(var(--una-enter-scale,1),var(--una-enter-scale,1),var(--una-enter-scale,1)) rotate(var(--una-enter-rotate,0))}}
.animate-in{animation:una-in;animation-name:una-in;animation-duration:150ms;--una-enter-opacity:initial;--una-enter-scale:initial;--una-enter-rotate:initial;--una-enter-translate-x:initial;--una-enter-translate-y:initial;}"
`)
})


it('"animate-out" should generate exit keyframe and css variables', async () => {
const { css } = await uno.generate('animate-out')

expect(css).toMatchInlineSnapshot(`
"/* layer: default */
@keyframes una-out{to{opacity:var(--una-exit-opacity,1);transform:translate3d(var(--una-exit-translate-x,0),var(--una-exit-translate-y,0),0) scale3d(var(--una-exit-scale,1),var(--una-exit-scale,1),var(--una-exit-scale,1)) rotate(var(--una-exit-rotate,0))}}
.animate-out{animation:una-out;animation-name:una-out;animation-duration:150ms;--una-exit-opacity:initial;--una-exit-scale:initial;--una-exit-rotate:initial;--una-exit-translate-x:initial;--una-exit-translate-y:initial;}"
`)
})


it('"animation-duration" should be default to "theme.duration"', async () => {
const DURATION = '500ms'

const uno = generator({ duration: { DEFAULT: DURATION } })
const { css } = await uno.generate('animate-in')

expect(css).toContain(`animation-duration:${DURATION};`)
})
})
9 changes: 9 additions & 0 deletions test/data/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const INTEGERS_0_TO_100 = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]
export const INTEGERS = [-200, -190, -180, -170, -160, -150, -140, -130, -120, -110, -100, -90, -80, -70, -60, -50, -40, -30, -20, -10, ...INTEGERS_0_TO_100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200]

export const DECIMALS_0_TO_100 = [0.1, 10.1, 52.1, 66.66, 99.9]
export const DECIMALS = [-199.9, -180.37, -66.66, -52.1, -10.1, -0.1, ...DECIMALS_0_TO_100, 180.37, 199.9]

export const FRACTIONS = ['-1/6', '-5/6', '-1/4', '-3/4', '-1/3', '-2/3', '1/6', '5/6', '1/4', '3/4', '1/3', '2/3']

export const CSS_VARIABLES = ['$foo', '$foo-bar', '$fooBar']
142 changes: 142 additions & 0 deletions test/fade.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { describe, it, expect } from 'vitest'
import { CSS_VARIABLE_PREFIX } from '@/constants'
import { CSS_VARIABLES, DECIMALS_0_TO_100, INTEGERS_0_TO_100 } from '~/data'
import { uno } from '~/utils'


describe('fade animation', () => {
describe('fade-in', () => {
it(`should generate "${CSS_VARIABLE_PREFIX}-enter-opacity" css variable and default to "0"`, async () => {
const { css } = await uno.generate('fade-in')

expect(css).toContain(`.fade-in{${CSS_VARIABLE_PREFIX}-enter-opacity:0;}`)
})


describe('percentage', () => {
it(`should covert percentages from "0" to "100"`, async () => {
const classnames = INTEGERS_0_TO_100.map(i => `fade-in-${i}`)

const { matched, css } = await uno.generate(classnames.join(' '))

expect(matched).toStrictEqual(new Set(classnames))
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.fade-in-0{--una-enter-opacity:0;}
.fade-in-10{--una-enter-opacity:0.1;}
.fade-in-100{--una-enter-opacity:1;}
.fade-in-20{--una-enter-opacity:0.2;}
.fade-in-30{--una-enter-opacity:0.3;}
.fade-in-40{--una-enter-opacity:0.4;}
.fade-in-50{--una-enter-opacity:0.5;}
.fade-in-60{--una-enter-opacity:0.6;}
.fade-in-70{--una-enter-opacity:0.7;}
.fade-in-80{--una-enter-opacity:0.8;}
.fade-in-90{--una-enter-opacity:0.9;}"
`)
})


it(`should also convert decimals`, async () => {
const classnames = DECIMALS_0_TO_100.map(i => `fade-in-${i}`)

const { matched, css } = await uno.generate(classnames.join(' '))

expect(matched).toStrictEqual(new Set(classnames))
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.fade-in-0\\\\.1{--una-enter-opacity:0.001;}
.fade-in-10\\\\.1{--una-enter-opacity:0.101;}
.fade-in-52\\\\.1{--una-enter-opacity:0.521;}
.fade-in-66\\\\.66{--una-enter-opacity:0.6666;}
.fade-in-99\\\\.9{--una-enter-opacity:0.999;}"
`)
})
})


describe('css variable', () => {
it(`should handle css variables`, async () => {
const classnames = CSS_VARIABLES.map(i => `fade-in-${i}`)

const { matched, css } = await uno.generate(classnames.join(' '))

expect(matched).toStrictEqual(new Set(classnames))
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.fade-in-\\\\$foo{--una-enter-opacity:var(--foo);}
.fade-in-\\\\$foo-bar{--una-enter-opacity:var(--foo-bar);}
.fade-in-\\\\$fooBar{--una-enter-opacity:var(--fooBar);}"
`)
})
})
})


describe('fade-out', () => {
it(`should generate "${CSS_VARIABLE_PREFIX}-exit-opacity" css variable and default to "0"`, async () => {
const { css } = await uno.generate('fade-out')

expect(css).toContain(`.fade-out{${CSS_VARIABLE_PREFIX}-exit-opacity:0;}`)
})


describe('percentage', () => {
it(`should covert percentages from "0" to "100"`, async () => {
const classnames = INTEGERS_0_TO_100.map(i => `fade-out-${i}`)

const { matched, css } = await uno.generate(classnames.join(' '))

expect(matched).toStrictEqual(new Set(classnames))
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.fade-out-0{--una-exit-opacity:0;}
.fade-out-10{--una-exit-opacity:0.1;}
.fade-out-100{--una-exit-opacity:1;}
.fade-out-20{--una-exit-opacity:0.2;}
.fade-out-30{--una-exit-opacity:0.3;}
.fade-out-40{--una-exit-opacity:0.4;}
.fade-out-50{--una-exit-opacity:0.5;}
.fade-out-60{--una-exit-opacity:0.6;}
.fade-out-70{--una-exit-opacity:0.7;}
.fade-out-80{--una-exit-opacity:0.8;}
.fade-out-90{--una-exit-opacity:0.9;}"
`)
})


it(`should also convert decimals`, async () => {
const classnames = DECIMALS_0_TO_100.map(i => `fade-out-${i}`)

const { matched, css } = await uno.generate(classnames.join(' '))

expect(matched).toStrictEqual(new Set(classnames))
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.fade-out-0\\\\.1{--una-exit-opacity:0.001;}
.fade-out-10\\\\.1{--una-exit-opacity:0.101;}
.fade-out-52\\\\.1{--una-exit-opacity:0.521;}
.fade-out-66\\\\.66{--una-exit-opacity:0.6666;}
.fade-out-99\\\\.9{--una-exit-opacity:0.999;}"
`)
})
})


describe('css variable', () => {
it(`should handle css variables`, async () => {
const classnames = CSS_VARIABLES.map(i => `fade-out-${i}`)

const { matched, css } = await uno.generate(classnames.join(' '))

expect(matched).toStrictEqual(new Set(classnames))
expect(css).toMatchInlineSnapshot(`
"/* layer: default */
.fade-out-\\\\$foo{--una-exit-opacity:var(--foo);}
.fade-out-\\\\$foo-bar{--una-exit-opacity:var(--foo-bar);}
.fade-out-\\\\$fooBar{--una-exit-opacity:var(--fooBar);}"
`)
})
})
})
})
Loading

0 comments on commit 6e34314

Please sign in to comment.