From d1cf803dfd0ea3bdfeb4fde69d88231214ff6df7 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Tue, 2 Jul 2019 18:08:59 +0800 Subject: [PATCH] test(select) --- .babelrc | 4 - babel.config.js | 2 + demo/demo.vue | 18 +- package.json | 4 +- test/unit/index.js | 5 +- .../packages/common/Select/index.spec.js | 457 ++++++++++++++++++ test/unit/specs/packages/utils.js | 6 +- 7 files changed, 480 insertions(+), 16 deletions(-) delete mode 100644 .babelrc create mode 100644 test/unit/specs/packages/common/Select/index.spec.js diff --git a/.babelrc b/.babelrc deleted file mode 100644 index 63ae86566..000000000 --- a/.babelrc +++ /dev/null @@ -1,4 +0,0 @@ -{ - "presets": ["@babel/preset-env"], - "plugins": ["transform-vue-jsx"] -} diff --git a/babel.config.js b/babel.config.js index 7c560c67a..7d6c66b63 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,4 +1,6 @@ module.exports = { + 'plugins': ['transform-vue-jsx'], + 'presets': ['@babel/preset-env'], env: { test: { plugins: ['istanbul'] diff --git a/demo/demo.vue b/demo/demo.vue index a594acb5e..af3d8f30f 100644 --- a/demo/demo.vue +++ b/demo/demo.vue @@ -2,7 +2,7 @@
@@ -46,6 +46,10 @@ export default { name: 'Common', path: '/', childItems: [ + { + name: 'Alert', + path: '/n-alert' + }, { name: 'Button', path: '/n-button' @@ -82,6 +86,10 @@ export default { name: 'Pagination', path: '/n-pagination' }, + { + name: 'Popup', + path: '/n-popup' + }, { name: 'Select', path: '/n-select' @@ -101,14 +109,6 @@ export default { { name: 'Tooltip', path: '/n-tooltip' - }, - { - name: 'Popup', - path: '/n-popup' - }, - { - name: 'Alert', - path: '/n-alert' } ] } diff --git a/package.json b/package.json index a279b995c..6c40fd865 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "naive-ui", - "version": "0.1.78", + "version": "0.1.79", "description": "", "main": "index.js", "scripts": { @@ -58,9 +58,11 @@ "karma-sourcemap-loader": "^0.3.7", "karma-spec-reporter": "0.0.32", "karma-webpack": "^3.0.5", + "lodash": "^4.17.11", "mocha": "^6.1.4", "prettier-eslint": "^9.0.0", "progress-bar-webpack-plugin": "^1.12.1", + "regenerator-runtime": "^0.13.2", "sinon": "^7.3.2", "style-loader": "^0.23.1", "stylelint": "^10.1.0", diff --git a/test/unit/index.js b/test/unit/index.js index 214cb66fd..033a8ef7b 100644 --- a/test/unit/index.js +++ b/test/unit/index.js @@ -1,7 +1,10 @@ +// import 'core-js/stable' +import 'regenerator-runtime/runtime' + // require all coverage files // const packagesContext = require.context('../../packages', true, /\.js$/) // packagesContext.keys().forEach(packagesContext) // require all test files (files that ends with .spec.js) -const testsContext = require.context('./specs', true, /\.spec.js$/) +const testsContext = require.context('./specs/packages/common/Select', true, /\.spec.js$/) testsContext.keys().forEach(testsContext) diff --git a/test/unit/specs/packages/common/Select/index.spec.js b/test/unit/specs/packages/common/Select/index.spec.js new file mode 100644 index 000000000..a2171e713 --- /dev/null +++ b/test/unit/specs/packages/common/Select/index.spec.js @@ -0,0 +1,457 @@ +import NSelect from 'packages/common/Select' +import { mount, createLocalVue } from '@vue/test-utils' +import { expect } from 'chai' +import { existsInClassList, sleep } from '../../utils' +import _ from 'lodash' + +describe('Select', function () { + const localVue = createLocalVue() + const items = [ + { + label: 'label1', + value: 'value1' + }, + { + label: 'label2', + value: 'value2' + }, + { + label: 'label3', + value: 'value3' + }, + { + label: 'label4', + value: 'value4' + } + ] + describe('props.items & menu', function () { + describe('single select', function () { + it('should not exist in dom tree when not clicked', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + const wrapper = mount(NSelectTestContext) + const html = wrapper.html() + items.forEach(item => expect(html).not.to.contain(item.label)) + }) + it('should be shown when select is clicked', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.trigger('click') + const html = wrapper.html() + items.forEach(item => expect(html).to.contain(item.label)) + }) + it('should be closed when outer dom is clicked', async function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.trigger('click') + await sleep() + document.body.click() + const html = wrapper.html() + items.forEach(item => expect(html).not.to.contain(item.label)) + }) + }) + describe('multiple select', function () { + it('should not exist in dom tree when not clicked', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + const html = wrapper.html() + items.forEach(item => expect(html).not.to.contain(item.label)) + }) + it('should be shown when select is clicked', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.trigger('click') + const html = wrapper.html() + items.forEach(item => expect(html).to.contain(item.label)) + }) + it('should be closed when outer dom is clicked', async function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.trigger('click') + await sleep() + document.body.click() + const html = wrapper.html() + items.forEach(item => expect(html).not.to.contain(item.label)) + }) + }) + }) + describe('props.multiple', function () { + it('should have multiple in class name when specified', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'mulitple', true)) + }) + it('should not have multiple in class name when not specified', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'mulitple', true)).to.equal(false) + }) + }) + describe('props.placeholder', function () { + describe('single select', function () { + it('should show when nothing is selected', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + const wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'placeholder', true)) + }) + it('should show `Please select` when not specified', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + const wrapper = mount(NSelectTestContext) + expect(wrapper.html().toLowerCase()).to.contain('please select') + }) + }) + describe('multiple select', function () { + it('should show when nothing is selected', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'placeholder', true)) + }) + it('should show `Please select` when not specified', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + expect(wrapper.html().toLowerCase()).to.contain('please select') + }) + }) + }) + + describe('props.size', function () { + describe('single select', function () { + it('should has effect in class name', function () { + it('should has effect in class name', function () { + let NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + let wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'small', true)) + NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'large', true)) + }) + }) + }) + describe('multiple select', function () { + it('should has effect in class name', function () { + let NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + let wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'small', true)) + NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'large', true)) + }) + }) + }) + describe('v-model', function () { + describe('single select', function () { + it('should sync view with value', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.vm.selectedValue = 'value1' + expect(wrapper.html()).to.contain('label1') + wrapper.vm.selectedValue = 'value2' + expect(wrapper.html()).to.contain('label2') + wrapper.vm.selectedValue = null + expect(wrapper.html().toLowerCase()).to.contain('please select') + }) + it('should sync value with view', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: null + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.trigger('click') + /** Todo using XPath */ + wrapper.find('.n-select-menu__item').trigger('click') + expect(wrapper.vm.selectedValue).to.equal('value1') + }) + it('should not be selected when v-model\'s value is not in items(show placeholder).', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedValue: 'not in anywhere' + } + } + } + const wrapper = mount(NSelectTestContext) + expect(existsInClassList(wrapper.element, 'placeholder', true)) + }) + }) + describe('multiple select', function () { + it('should sync view with value', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.vm.selectedArray.push('value1') + expect(wrapper.html()).to.contain('label1') + wrapper.vm.selectedArray.push('value2') + expect(wrapper.html()).to.contain('label1', 'label2') + wrapper.vm.selectedArray = [] + expect(wrapper.html().toLowerCase()).to.contain('please select') + }) + it('should sync value with view', function () { + const NSelectTestContext = { + localVue, + components: { + NSelect + }, + template: ``, + data () { + return { + items: _.cloneDeep(items), + selectedArray: [] + } + } + } + const wrapper = mount(NSelectTestContext) + wrapper.trigger('click') + /** Todo using XPath */ + wrapper.find('.n-select-menu__item').trigger('click') + expect(wrapper.vm.selectedArray).to.deep.equal(['value1']) + }) + }) + }) + describe('@change', function () { + describe('single select', function () { + it('should be called when change selected item', function () { + + }) + it('should return item object', function () { + + }) + }) + describe('multiple select', function () { + it('should be called when change selected item', function () { + + }) + it('should return item object', function () { + + }) + }) + }) +}) diff --git a/test/unit/specs/packages/utils.js b/test/unit/specs/packages/utils.js index 5a2557f0c..1f6c13d0d 100644 --- a/test/unit/specs/packages/utils.js +++ b/test/unit/specs/packages/utils.js @@ -14,4 +14,8 @@ function existsInClassList (el, searchPattern, alsoSearchDescendant = false) { return Array.from(el.classList).some(className => 1 + className.search(searchPattern)) } -export { existsInClassList } +async function sleep (ms = 0) { + return new Promise(resolve => setTimeout(() => resolve(), ms)) +} + +export { existsInClassList, sleep }