Skip to content

Commit

Permalink
test: switch to vitest (element-plus#5991)
Browse files Browse the repository at this point in the history
* test: use vitest

* test: add script and ci

* chore: improve tsconfig

* refactor: use-form-item

* fix: remove unused

* chore: improve scripts

* test: improve mock

* refactor: change coverage
  • Loading branch information
sxzz authored Feb 21, 2022
1 parent 0b4acfb commit aaf90d9
Show file tree
Hide file tree
Showing 30 changed files with 507 additions and 348 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Lint
run: pnpm lint
- name: Test
run: pnpm test -- --coverage
run: pnpm test:coverage
- name: Upload to codecov.io
uses: codecov/codecov-action@v2
with:
Expand Down
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ pnpm install
Then you can following command to verify your installation.

```shell
pnpm test
pnpm run format
pnpm t
pnpm format
```

## Getting Started developing
Expand Down
5 changes: 5 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
*/
module.exports = {
setupFiles: ['./jest.setup.js'],
testMatch: [
'**/__tests__/**/*.[jt]s?(x)',
'**/?(*.)+(spec|test).[jt]s?(x)',
'!**/**vitest**',
],
testPathIgnorePatterns: ['/node_modules/', 'dist'],
modulePathIgnorePatterns: ['/node_modules/', 'dist', 'cypress'],
testEnvironment: 'jsdom',
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
},
"scripts": {
"cz": "git-cz",
"test": "jest",
"test": "pnpm test:jest && pnpm test:vitest",
"test:jest": "jest",
"test:vitest": "vitest",
"test:coverage": "vitest --coverage",
"prepare:e2e": "if [ ! -d \"docs/.vitepress/dist\" ]; then pnpm run docs:build; fi;",
"e2e": "cypress open",
"e2e:ci": "cypress run",
Expand Down Expand Up @@ -96,10 +99,12 @@
"@typescript-eslint/parser": "5.12.0",
"@vitejs/plugin-vue": "2.2.2",
"@vitejs/plugin-vue-jsx": "1.3.7",
"@vitest/ui": "^0.3.2",
"@vue/babel-plugin-jsx": "1.1.1",
"@vue/test-utils": "2.0.0-rc.16",
"@vue/tsconfig": "0.1.3",
"babel-jest": "26.6.3",
"c8": "^7.11.0",
"chalk": "4.1.2",
"components-helper": "2.0.0",
"csstype": "2.6.19",
Expand Down Expand Up @@ -134,6 +139,7 @@
"type-fest": "2.12.0",
"typescript": "4.5.5",
"unplugin-vue-define-options": "0.3.1",
"vitest": "^0.3.2",
"vue": "3.2.30",
"vue-jest": "5.0.0-alpha.10",
"vue-router": "4.0.12",
Expand Down
3 changes: 2 additions & 1 deletion packages/constants/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
{
"name": "@element-plus/constants",
"private": true,
"license": "MIT"
"license": "MIT",
"main": "index.ts"
}
Original file line number Diff line number Diff line change
@@ -1,60 +1,58 @@
import { defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, it, expect, fn, afterEach, vi } from 'vitest'
import { useAttrs } from '../use-attrs'
import type { ComponentOptions } from 'vue'

const CLASS = 'a'
const WIDTH = '50px'
const TEST_KEY = 'test'
const TEST_VALUE = 'fake'
const ANOTHER_TEST_VALUE = 'fake1'

const handleClick = jest.fn()
const handleClick = fn()

const genComp = (
inheritAttrs = true,
excludeListeners = false,
excludeKeys: string[] = []
) => {
return {
template: `
<div>
<span v-bind="attrs"></span>
</div>
`,
return defineComponent({
inheritAttrs,
props: {},
setup() {
const attrs = useAttrs({ excludeListeners, excludeKeys })

return {
attrs,
}
return () => (
<div>
<span {...attrs.value} />
</div>
)
},
}
})
}

const _mount = (Comp: ComponentOptions) => {
const _mount = (Comp: ReturnType<typeof genComp>) => {
return mount({
components: { Comp },
template: `
<comp
class="${CLASS}"
style="width: ${WIDTH}"
${TEST_KEY}="${TEST_VALUE}"
@click="handleClick"
/>`,
methods: {
handleClick,
setup() {
return () => (
<Comp
class={CLASS}
style={{ width: WIDTH }}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
onClick={handleClick}
{...{ [TEST_KEY]: TEST_VALUE }}
/>
)
},
})
}

afterEach(() => {
handleClick.mockClear()
})

describe('useAttrs', () => {
test('class and style should not bind to child node', async () => {
afterEach(() => {
vi.restoreAllMocks()
})

it('class and style should not bind to child node', async () => {
const wrapper = _mount(genComp())
const container = wrapper.element as HTMLDivElement
const span = wrapper.find('span')
Expand All @@ -70,15 +68,15 @@ describe('useAttrs', () => {
expect(handleClick).toBeCalledTimes(2)
})

test("child node's attributes should update when prop change", async () => {
it("child node's attributes should update when prop change", async () => {
const wrapper = _mount(genComp())
const span = wrapper.find('span')

await wrapper.setProps({ [TEST_KEY]: ANOTHER_TEST_VALUE })
expect(span.attributes(TEST_KEY)).toBe(ANOTHER_TEST_VALUE)
})

test('excluded listeners should not bind to child node', async () => {
it('excluded listeners should not bind to child node', async () => {
const wrapper = _mount(genComp(true, true))
const span = wrapper.find('span')

Expand All @@ -87,7 +85,7 @@ describe('useAttrs', () => {
expect(handleClick).toBeCalledTimes(1)
})

test('excluded attributes should not bind to child node', async () => {
it('excluded attributes should not bind to child node', async () => {
const wrapper = _mount(genComp(true, false, [TEST_KEY]))
const span = wrapper.find('span')

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
import { computed, defineComponent, nextTick } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, it, fn, vi, expect, afterEach } from 'vitest'
import { debugWarn } from '@element-plus/utils'
import { useDeprecated } from '../use-deprecated'

jest.mock('@element-plus/utils/error', () => {
const AXIOM = 'Rem is the best girl'

vi.mock('@element-plus/utils/error', async () => {
return {
debugWarn: jest.fn(),
...(await vi.importActual<any>('@element-plus/utils/error')),
debugWarn: fn(),
}
})

Expand All @@ -24,14 +28,15 @@ const DummyComponent = defineComponent({
},
computed(() => props.shouldWarn)
)
return () => AXIOM
},
template: `<div>Rem is the best girl</div>`,
})

describe('useDeprecated', () => {
beforeEach(() => {
;(debugWarn as jest.Mock).mockClear()
afterEach(() => {
vi.restoreAllMocks()
})

it('should warn when condition is true', async () => {
mount(DummyComponent, {
props: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ref } from 'vue'
import { describe, it, expect } from 'vitest'
import { useFocus } from '../use-focus'

describe('useFocus', () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { h, provide } from 'vue'
import { defineComponent, provide } from 'vue'
import { NOOP } from '@vue/shared'
import { mount } from '@vue/test-utils'
import { describe, it, expect } from 'vitest'
import { ElButton } from '@element-plus/components'
import {
elFormKey,
Expand All @@ -16,23 +17,16 @@ import type {

const AXIOM = 'Rem is the best girl'

const Component = {
render() {
return h(ElButton, this.$attrs, {
default: () => [AXIOM],
})
},
}

const mountComponent = (setup = NOOP, options = {}) => {
return mount(
{
...Component,
const mountComponent = (setup = NOOP, options = {}) =>
mount(
defineComponent({
setup,
},
render() {
return <ElButton {...this.$attrs}>{AXIOM}</ElButton>
},
}),
options
)
}

describe('use-form-item', () => {
it('should return local value', () => {
Expand All @@ -44,14 +38,10 @@ describe('use-form-item', () => {
const propSize = 'small'
const wrapper = mountComponent(
() => {
provide(elFormItemKey, {
size: 'large',
} as ElFormItemContext)
provide(elFormItemKey, { size: 'large' } as ElFormItemContext)
},
{
props: {
size: propSize,
},
props: { size: propSize },
}
)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,43 @@
import { h, nextTick, computed } from 'vue'
import { nextTick, computed, defineComponent } from 'vue'
import { mount } from '@vue/test-utils'
import { describe, it, expect, beforeEach, afterEach } from 'vitest'
import Chinese from '@element-plus/locale/lang/zh-cn'
import English from '@element-plus/locale/lang/en'
import { useLocale, buildTranslator } from '../use-locale'
import { provideGlobalConfig } from '..'
import type { Language } from '@element-plus/locale'
import type { PropType, ComponentPublicInstance } from 'vue'
import type { VueWrapper } from '@vue/test-utils'

const TestComp = {
const TestComp = defineComponent({
setup() {
const { t } = useLocale()
return () => {
return h(
'div',
{ class: 'locale-manifest' },
t('el.popconfirm.confirmButtonText')
)
}
return () => (
<div class="locale-manifest">{t('el.popconfirm.confirmButtonText')}</div>
)
},
}
})

describe('use-locale', () => {
let wrapper
let wrapper: VueWrapper<ComponentPublicInstance>

beforeEach(() => {
wrapper = mount(
{
props: {
locale: Object,
locale: Object as PropType<Language>,
},
components: {
'el-test': TestComp,
},
setup(props, { slots }) {
provideGlobalConfig(computed(() => ({ locale: props.locale })))
return () => slots.default()
return () => slots.default?.()
},
},
{
props: {
locale: Chinese,
},
slots: {
default: () => h(TestComp),
},
props: { locale: Chinese },
slots: { default: () => <TestComp /> },
}
)
})
Expand Down Expand Up @@ -70,7 +67,7 @@ describe('use-locale', () => {
)
})

test('return key name if not defined', () => {
it('return key name if not defined', () => {
const t = buildTranslator(English)
expect(t('el.popconfirm.someThing')).toBe('el.popconfirm.someThing')
})
Expand Down
Loading

0 comments on commit aaf90d9

Please sign in to comment.