diff --git a/.eslintrc.js b/.eslintrc.js index 69d2fd097..df3ff9fb5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -13,5 +13,16 @@ module.exports = { rules: { 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off' - } + }, + "overrides": [ + { + "files": [ + "**/__tests__/*.{j,t}s?(x)", + "**/tests/unit/**/*.spec.{j,t}s?(x)" + ], + "env": { + "jest": true + } + } + ] } \ No newline at end of file diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000..c8c81bf69 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,30 @@ +module.exports = { + "preset": "@vue/cli-plugin-unit-jest", + "transform": { + "^.+\\.vue$": "vue-jest" + }, + "moduleNameMapper": { + "^primevue/ripple(.*)$": "/src/components/ripple/Ripple.js", + "^primevue/tooltip(.*)$": "/src/components/tooltip/Tooltip.js", + "^primevue/useconfirm(.*)$": "/src/components/useconfirm/UseConfirm.js", + "^primevue/usetoast(.*)$": "/src/components/usetoast/UseToast.js", + "^primevue/utils(.*)$": "/src/components/utils/Utils.js", + "^primevue/api(.*)$": "/src/components/api/Api.js", + "^primevue/button(.*)$": "/src/components/button/Button.vue", + "^primevue/inputtext(.*)$": "/src/components/inputtext/InputText.vue", + "^primevue/dialog(.*)$": "/src/components/dialog/Dialog.vue", + "^primevue/menu(.*)$": "/src/components/menu/Menu.vue", + "^primevue/tieredmenu(.*)$": "/src/components/tieredmenu/TieredMenu.vue", + "^primevue/dropdown(.*)$": "/src/components/dropdown/Dropdown.vue", + "^primevue/inputnumber(.*)$": "/src/components/inputnumber/InputNumber.vue", + "^primevue/paginator(.*)$": "/src/components/paginator/Paginator.vue", + "^primevue/progressbar(.*)$": "/src/components/progressbar/ProgressBar.vue", + "^primevue/message(.*)$": "/src/components/message/Message.vue", + "^primevue/tree(.*)$": "/src/components/tree/Tree.vue", + "^primevue/confirmationeventbus(.*)$": "/src/components/confirmationeventbus/ConfirmationEventBus.js", + "^primevue/toasteventbus(.*)$": "/src/components/toasteventbus/ToastEventBus.js", + "^primevue/overlayeventbus(.*)$": "/src/components/overlayeventbus/OverlayEventBus.js", + "^primevue/terminalservice(.*)$": "/src/components/terminalservice/TerminalService.js", + "^primevue/virtualscroller(.*)$": "/src/components/virtualscroller/VirtualScroller.vue" + } +} \ No newline at end of file diff --git a/package.json b/package.json index 9ff355414..73a9ecf60 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,8 @@ "@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-router": "~4.5.0", + "@vue/cli-plugin-unit-jest": "~4.5.0", + "@vue/test-utils": "^2.0.0-0", "@vue/cli-service": "~4.5.0", "@vue/compiler-sfc": "3.1.5", "@vuelidate/core": "^2.0.0-alpha.14", @@ -65,6 +67,7 @@ "sass-loader": "^8.0.2", "vue": "3.1.5", "vue-router": "^4.0.0-0", + "vue-jest": "^5.0.0-0", "webpack-cli": "^4.3.0" } } diff --git a/tests/unit/Button.spec.js b/tests/unit/Button.spec.js new file mode 100644 index 000000000..51f014191 --- /dev/null +++ b/tests/unit/Button.spec.js @@ -0,0 +1,85 @@ +import { h } from 'vue'; +import { mount } from '@vue/test-utils'; +import Button from '@/components/button/Button.vue'; + +describe('Button.vue', () => { + it('is Button element exist', () => { + const wrapper = mount(Button); + + expect(wrapper.find('.p-button.p-component').exists()).toBe(true); + expect(wrapper.find('.p-button-label').exists()).toBe(true); + }) +}); + +describe('Button.vue', () => { + it('is icon exist and right position', () => { + const icon = 'pi pi-discord'; + const iconPos = 'right'; + const label = 'Save'; + const props = { icon, iconPos }; + let wrapper; + + wrapper = mount(Button, { + props + }); + + expect(wrapper.find('.p-button-icon-only').exists()).toBe(true); + + wrapper = mount(Button, { + props: { ...props, label } + }); + + expect(wrapper.find('.p-button-icon.p-button-icon-' + iconPos).exists()).toBe(true); + }) +}); + +describe('Button.vue', () => { + it('is badge working', () => { + const badge = '5'; + const badgeClass= 'p-badge-danger'; + const wrapper = mount(Button, { + props: { badge, badgeClass } + }); + + + expect(wrapper.find('.p-badge').text()).toEqual(badge); + expect(wrapper.find('.' + badgeClass).exists()).toBe(true); + }) +}); + +describe('Button.vue', () => { + it('is loading working', async () => { + const loadingIcon = 'pi pi-discord'; + const wrapper = mount(Button, { + props: { + loading: false, + loadingIcon + } + }); + + expect(wrapper.find('.p-disabled').exists()).toBe(false); + + await wrapper.setProps({ loading: true }) + const array = loadingIcon.split(' '); + const lastIcon = '.' + array.join('.'); + + expect(wrapper.find('.p-button-loading').exists()).toBe(true); + expect(wrapper.find('.p-button-loading-icon' + lastIcon).exists()).toBe(true); + + await wrapper.setProps({ loading: false }); + + expect(wrapper.find('.p-button-loading').exists()).toBe(false); + }) +}); + +describe('Button.vue', () => { + it('should render default slot', () => { + const wrapper = mount(Button, { + slots: { + default: h('span', {class: 'ml-2 font-bold'}, 'Default PrimeVue Button') + } + }); + + expect(wrapper.html()).toBe(''); + }) +}); \ No newline at end of file diff --git a/tests/unit/Dialog.spec.js b/tests/unit/Dialog.spec.js new file mode 100644 index 000000000..86f7df3c9 --- /dev/null +++ b/tests/unit/Dialog.spec.js @@ -0,0 +1,10 @@ +import { mount } from '@vue/test-utils'; +import Dialog from '@/components/dialog/Dialog.vue'; + +describe('Dialog.vue', () => { + it('is Dialog element exist', () => { + const wrapper = mount(Dialog); + + expect(wrapper.find('.p-dialog.p-component').exists()).toBe(false); + }) +}); \ No newline at end of file diff --git a/tests/unit/Dropdown.spec.js b/tests/unit/Dropdown.spec.js new file mode 100644 index 000000000..38382d14b --- /dev/null +++ b/tests/unit/Dropdown.spec.js @@ -0,0 +1,33 @@ +import { mount } from '@vue/test-utils'; +import PrimeVue from '@/components/config/PrimeVue'; +import Dropdown from '@/components/dropdown/Dropdown.vue'; + +'use strict'; + +describe('Dropdown', () => { + let wrapper; + + beforeEach(() => { + jest.useFakeTimers(); + + wrapper = mount(Dropdown, { + global: { + plugins: [PrimeVue] + } + }); + }); + + it('should Dropdown exist', async () => { + expect(wrapper.find('.p-dropdown.p-component').exists()).toBe(true); + + await wrapper.trigger('click'); + // console.log('before', new Date()); + // Promise.resolve().then(() => jest.advanceTimersByTime(1000)); + jest.advanceTimersByTime(1000); + + // console.log('after', new Date()); + + // expect(wrapper.find('.p-dropdowwn-panel')).toBe(true); + // console.log(wrapper.html()); + }) +}); \ No newline at end of file diff --git a/tests/unit/InputText.spec.js b/tests/unit/InputText.spec.js new file mode 100644 index 000000000..5466ccc16 --- /dev/null +++ b/tests/unit/InputText.spec.js @@ -0,0 +1,30 @@ +import { mount } from '@vue/test-utils'; +import InputText from '@/components/inputText/InputText.vue'; + +describe('InputText.vue', () => { + it('is InputText component exists', async () => { + const wrapper = mount(InputText); + + expect(wrapper.find('.p-inputtext.p-component').exists()).toBe(true); + + await wrapper.setProps({ modelValue: 'PrimeVue' }); + + expect(wrapper.find('.p-filled').exists()).toBe(true); + + const input = wrapper.find('input'); + expect(input.element.value).toEqual('PrimeVue'); + }) +}); + +describe('InputText.vue', () => { + it('input event', async () => { + const wrapper = mount(InputText); + const input = wrapper.find('input'); + + // await input.trigger('input', { keyCode: 65 }); + input.element.value = 'a'; + input.trigger('input'); + + expect(input.element.value).toEqual('a'); + }) +}); \ No newline at end of file diff --git a/tests/unit/Tag.spec.js b/tests/unit/Tag.spec.js new file mode 100644 index 000000000..595e656b8 --- /dev/null +++ b/tests/unit/Tag.spec.js @@ -0,0 +1,69 @@ +import { h } from 'vue'; +import { mount } from '@vue/test-utils'; +import Tag from '@/components/tag/Tag.vue'; + +describe('Tag.vue', () => { + it('is Tag element exist', () => { + const wrapper = mount(Tag); + + expect(wrapper.find('.p-tag.p-component').exists()).toBe(true); + }) +}); + +describe('Tag.vue', () => { + it('renders props severity when passed', () => { + const severity = 'info'; + const wrapper = mount(Tag, { + props: { severity } + }); + + expect(wrapper.find('.p-tag-' + severity).exists()).toBe(true); + }) +}); + +describe('Tag.vue', () => { + it('renders props value when passed', () => { + const value = 'submit'; + const wrapper = mount(Tag, { + props: { value } + }); + + expect(wrapper.find('span').text()).toBe(value); + }) +}); + +describe('Tag.vue', () => { + it('renders props icon when passed', () => { + const icon = 'pi pi-discord'; + const wrapper = mount(Tag, { + props: { icon } + }); + const array = icon.split(' '); + const lastIcon = '.' + array.join('.'); + + expect(wrapper.find('.p-tag-icon').isVisible()).toBe(true); + expect(wrapper.find('.p-tag-icon' + lastIcon).exists()).toBe(true); + }) +}); + +describe('Tag.vue', () => { + it('should be rounded', () => { + const wrapper = mount(Tag, { + props: { rounded: true } + }); + + expect(wrapper.find('.p-tag-rounded').exists()).toBe(true); + }) +}); + +describe('Tag.vue', () => { + it('should render default slot', () => { + const wrapper = mount(Tag, { + slots: { + default: h('i', {class: 'pi pi-discord'}, '') + } + }); + + expect(wrapper.html()).toBe(''); + }) +}); \ No newline at end of file diff --git a/tests/unit/example.spec.js b/tests/unit/example.spec.js deleted file mode 100644 index f84fb39dc..000000000 --- a/tests/unit/example.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import { shallowMount } from '@vue/test-utils' -import HelloWorld from '@/components/HelloWorld.vue' - -describe('HelloWorld.vue', () => { - it('renders props.msg when passed', () => { - const msg = 'new message' - const wrapper = shallowMount(HelloWorld, { - propsData: { msg } - }) - expect(wrapper.text()).toMatch(msg) - }) -})