From 5692936722ba671920227767778d56e7186cdc09 Mon Sep 17 00:00:00 2001 From: cristijora Date: Mon, 27 Nov 2017 20:44:57 +0200 Subject: [PATCH] Add more tests for 80+% coverage --- package.json | 7 +- test/unit/index.js | 1 + test/unit/karma.conf.js | 5 +- test/unit/specs/FormWizard.spec.js | 299 +++++++++++++++++++++++------ yarn.lock | 12 ++ 5 files changed, 266 insertions(+), 58 deletions(-) diff --git a/package.json b/package.json index a6ab545..cf6750a 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,8 @@ "opn": "^5.1.0", "optimize-css-assets-webpack-plugin": "^3.2.0", "ora": "^1.1.0", + "phantomjs-polyfill": "^0.0.2", + "phantomjs-polyfill-find-index": "^1.0.1", "phantomjs-prebuilt": "^2.1.16", "rimraf": "^2.6.0", "sass-loader": "^6.0.3", @@ -112,5 +114,8 @@ "> 1%", "last 2 versions", "not ie <= 8" - ] + ], + "dependencies": { + "karma-polyfill": "^1.0.0" + } } diff --git a/test/unit/index.js b/test/unit/index.js index 8096273..424b295 100644 --- a/test/unit/index.js +++ b/test/unit/index.js @@ -1,4 +1,5 @@ import Vue from 'vue' +import 'phantomjs-polyfill' Vue.config.productionTip = false diff --git a/test/unit/karma.conf.js b/test/unit/karma.conf.js index 14c610e..c9af4a9 100644 --- a/test/unit/karma.conf.js +++ b/test/unit/karma.conf.js @@ -12,9 +12,10 @@ module.exports = function (config) { // http://karma-runner.github.io/0.13/config/browsers.html // 2. add it to the `browsers` array below. browsers: ['PhantomJS'], - frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim'], + frameworks: ['mocha', 'sinon-chai', 'phantomjs-shim', 'polyfill'], + polyfill: ['findIndex'], reporters: ['spec','progress', 'coverage'], - files: ['./index.js'], + files: ['./index.js', './../../node_modules/phantomjs-polyfill-find-index/findIndex-polyfill.js',], preprocessors: { './index.js': ['webpack', 'sourcemap'] }, diff --git a/test/unit/specs/FormWizard.spec.js b/test/unit/specs/FormWizard.spec.js index ff57d63..7307b23 100644 --- a/test/unit/specs/FormWizard.spec.js +++ b/test/unit/specs/FormWizard.spec.js @@ -6,7 +6,10 @@ import Vue from 'vue' const localVue = createLocalVue() localVue.use(VueFormWizard) const startIndex = 0 -const twoStepWizard = { +let validationMethod = sinon.stub() +validationMethod.returns(true) +let secondValidationMethod = sinon.stub() +let initialWizard = { template: ` @@ -16,17 +19,19 @@ const twoStepWizard = { icon="ti-settings"> My second tab content - My third tab content `, data () { return { - startIndex: startIndex + startIndex: startIndex, + showLastStep: true } } } +let threeStepWizard = initialWizard const divSlot = `
describe('FormWizard.vue', () => { it('contains wizard class', () => { - const wizard = mount(twoStepWizard, {localVue}) + const wizard = mount(threeStepWizard, {localVue}) wizard.hasClass('vue-form-wizard') }) - it('renders steps', (done) => { - const wizard = mount(twoStepWizard, {localVue}) - Vue.nextTick(() => { - const steps = wizard.findAll(WizardStep) - const firsStep = steps.at(0) - expect(steps.length).to.equal(3) - expect(firsStep.hasClass('active')) - const stepTitle = firsStep.find('.stepTitle') - expect(stepTitle.is('span')).to.equal(true) - const stepText = stepTitle.text().trim() - expect(stepText).to.equal('Personal details') - done() + describe('renders', () => { + it('steps', (done) => { + const wizard = mount(threeStepWizard, {localVue}) + Vue.nextTick(() => { + const steps = wizard.findAll(WizardStep) + const firsStep = steps.at(0) + expect(steps.length).to.equal(3) + expect(firsStep.hasClass('active')) + const stepTitle = firsStep.find('.stepTitle') + expect(stepTitle.is('span')).to.equal(true) + const stepText = stepTitle.text().trim() + expect(stepText).to.equal('Personal details') + done() + }) }) - }) - it('renders tabs', () => { - const wizard = mount(twoStepWizard, {localVue}) - const tabs = wizard.findAll(WizardTab) - expect(tabs.length).to.equal(3) - }) - it('displays only one tab', () => { - const wizard = mount(twoStepWizard, {localVue}) - const tabs = wizard.findAll(WizardTab).wrappers - const activeTabs = tabs.filter((tab) => tab.vm.active) - const inactiveTabs = tabs.filter((tab) => !tab.vm.active) - expect(activeTabs.length).to.equal(1) + it('tabs', () => { + const wizard = mount(threeStepWizard, {localVue}) + const tabs = wizard.findAll(WizardTab) + expect(tabs.length).to.equal(3) + }) + it('only one tab content', () => { + const wizard = mount(threeStepWizard, {localVue}) + const tabs = wizard.findAll(WizardTab).wrappers + const activeTabs = tabs.filter((tab) => tab.vm.active) + const inactiveTabs = tabs.filter((tab) => !tab.vm.active) + expect(activeTabs.length).to.equal(1) - inactiveTabs.forEach((tab) => { - expect(tab.hasStyle('display', 'none')).to.equal(true) + inactiveTabs.forEach((tab) => { + expect(tab.hasStyle('display', 'none')).to.equal(true) + }) + }) + it('slot wrapped in another tag', done => { + const wizard = mount(FormWizard, { + localVue, + slots: { + default: divSlot + } + }) + Vue.nextTick(() => { + const tabs = wizard.findAll(WizardTab) + expect(tabs.length).to.equal(3) + done() + }) + }) + it('less tabs when one tab is removed', (done) => { + const wizard = mount(threeStepWizard, {localVue}) + const tabs = wizard.findAll(WizardTab) + expect(tabs.length).to.equal(3) + wizard.setData({showLastStep: false}) + Vue.nextTick(() => { + const newTabs = wizard.findAll(WizardTab) + expect(newTabs.length).to.equal(2) + done() + }) }) }) - it('starts at a given index', () => { - const wizard = mount(twoStepWizard, {localVue}) - const tabs = wizard.findAll(WizardTab) - const activeTab = tabs.at(startIndex) - expect(activeTab.vm.active).to.equal(true) - const formWizard = wizard.find(FormWizard) - expect(formWizard.vm.activeTabIndex).to.equal(startIndex) + + it('warns when start index is incorrect', () => { + let originalConsole = window.console + window.console = {warn: sinon.stub()} + const wizard = mount(FormWizard, {localVue, slots: {default: divSlot}, propsData: {startIndex: 15}}) + expect(wizard.vm.activeTabIndex).to.not.equal(15) + expect(window.console.warn.called).to.equal(true) + window.console = originalConsole }) + it('resets wizard', () => { - const wizard = mount(twoStepWizard, {localVue}) + const wizard = mount(threeStepWizard, {localVue}) const wizardInstance = wizard.find(FormWizard) let tabs = wizard.findAll(WizardTab) expect(tabs.length).to.equal(3) @@ -104,27 +137,183 @@ describe('FormWizard.vue', () => { expect(wizardInstance.vm.activeTabIndex).to.equal(0) }) - it('next tab is called', () => { - const wizard = mount(twoStepWizard, {localVue}) - const nextButton = wizard.find('.wizard-footer-right span') - nextButton.trigger('click') - let tabs = wizard.findAll(WizardTab) - const secondTab = tabs.at(1) - expect(secondTab.vm.active).to.equal(true) - }) - - it('renders tab wrapped in another element', done => { - const wizard = mount(FormWizard, { - localVue, - slots: { - default: divSlot - } + describe('navigation', () => { + it('next tab is called', () => { + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + const nextButton = wizard.find('.wizard-footer-right span') + nextButton.trigger('click') + expect(wizardInstance.vm.activeTabIndex).to.equal(1) }) - Vue.nextTick(() => { + + it('prev tab is called', (done) => { + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + const nextButton = wizard.find('.wizard-footer-right span') + nextButton.trigger('click') + expect(wizardInstance.vm.activeTabIndex).to.equal(1) + Vue.nextTick(() => { + const backButton = wizardInstance.find('.wizard-footer-left span') + backButton.trigger('click') + expect(wizardInstance.vm.activeTabIndex).to.equal(0) + done() + }) + }) + it('is restricted to unvisted tabs by click', () => { + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + wizardInstance.vm.navigateToTab(1) + expect(wizardInstance.vm.activeTabIndex).to.equal(0) + }) + it('starts at a given index', () => { + const wizard = mount(threeStepWizard, {localVue}) + const tabs = wizard.findAll(WizardTab) + const activeTab = tabs.at(startIndex) + expect(activeTab.vm.active).to.equal(true) + const formWizard = wizard.find(FormWizard) + expect(formWizard.vm.activeTabIndex).to.equal(startIndex) + }) + + it('navigates to a visited tab', () => { + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + let tabs = wizard.findAll(WizardTab) + wizardInstance.vm.nextTab() + wizardInstance.vm.nextTab() + wizardInstance.vm.navigateToTab(0) + const firstTab = tabs.at(0) + expect(firstTab.vm.active).to.equal(true) + expect(wizardInstance.vm.activeTabIndex).to.equal(0) + expect(wizardInstance.vm.maxStep).to.equal(tabs.length - 1) + + wizardInstance.vm.navigateToTab(2) + expect(wizardInstance.vm.activeTabIndex).to.equal(2) + expect(wizardInstance.vm.maxStep).to.equal(tabs.length - 1) + }) + + it('active tab is prev when current active tab is removed', (done) => { + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + //navigate to last tab + wizardInstance.vm.nextTab() + wizardInstance.vm.nextTab() const tabs = wizard.findAll(WizardTab) expect(tabs.length).to.equal(3) - done() + wizard.setData({showLastStep: false}) + Vue.nextTick(() => { + const newTabs = wizard.findAll(WizardTab) + expect(newTabs.length).to.equal(2) + expect(wizardInstance.vm.activeTabIndex).to.equal(1) + done() + }) + }) + + it('with arrow keys on visited tabs', () => { + const wizard = mount(threeStepWizard, {localVue, attachToDocument: true}) + const wizardInstance = wizard.find(FormWizard) + wizardInstance.vm.nextTab() + wizardInstance.vm.nextTab() + wizard.trigger('tab') + wizard.trigger('keyup.right') + wizard.trigger('keyup.left') + expect(wizardInstance.vm.activeTabIndex).to.equal(2) + }) + + }) + describe('emits', () => { + it('on-complete upon last step', () => { + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + const nextButton = wizard.find('.wizard-footer-right span') + nextButton.trigger('click') + nextButton.trigger('click') + nextButton.trigger('click') + expect(wizardInstance.vm.activeTabIndex).to.equal(2) + expect(wizardInstance.emitted()['on-complete'].length).to.equal(1) }) }) + + describe('validation with', () => { + beforeEach(() => { + threeStepWizard = { + template: ` + + My first tab content + + + My second tab content + + + My third tab content + + `, + methods: { + validationMethod, + secondValidationMethod + } + } + }) + + it('simple method', () => { + threeStepWizard.methods.validationMethod = sinon.stub() + threeStepWizard.methods.validationMethod.returns(true) + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + wizardInstance.vm.nextTab() + expect(threeStepWizard.methods.validationMethod.called).to.equal(true) + expect(wizardInstance.vm.activeTabIndex).to.equal(1) + }) + it('simple method on back navigation', () => { + threeStepWizard.methods.secondValidationMethod = sinon.stub() + threeStepWizard.methods.secondValidationMethod.returns(true) + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + wizardInstance.vm.nextTab() + wizardInstance.vm.prevTab() + expect(threeStepWizard.methods.secondValidationMethod.called).to.equal(true) + }) + it('falsy method', () => { + threeStepWizard.methods.validationMethod = sinon.stub() + threeStepWizard.methods.validationMethod.returns(false) + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + wizardInstance.vm.nextTab() + expect(threeStepWizard.methods.validationMethod.called).to.equal(true) + expect(wizardInstance.vm.activeTabIndex).to.equal(0) + }) + it('promise', (done) => { + threeStepWizard.methods.validationMethod = sinon.stub() + threeStepWizard.methods.validationMethod.returns(Promise.resolve(true)) + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + wizardInstance.vm.nextTab() + expect(threeStepWizard.methods.validationMethod.called).to.equal(true) + Vue.nextTick(() => { + expect(wizardInstance.vm.activeTabIndex).to.equal(1) + done() + }) + }) + + it('failing promise', (done) => { + threeStepWizard.methods.validationMethod = sinon.stub() + threeStepWizard.methods.validationMethod.returns(Promise.reject(false)) + const wizard = mount(threeStepWizard, {localVue}) + const wizardInstance = wizard.find(FormWizard) + wizardInstance.vm.nextTab() + expect(threeStepWizard.methods.validationMethod.called).to.equal(true) + Vue.nextTick(() => { + expect(wizardInstance.vm.activeTabIndex).to.equal(0) + done() + }) + }) + }) + + }) diff --git a/yarn.lock b/yarn.lock index ef55156..2781d54 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3625,6 +3625,10 @@ karma-phantomjs-shim@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/karma-phantomjs-shim/-/karma-phantomjs-shim-1.5.0.tgz#e8db65883480f0dbd184cc961d39c64511742200" +karma-polyfill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/karma-polyfill/-/karma-polyfill-1.0.0.tgz#7f202d43e1a552ef650a7715a677b391572329f8" + karma-sinon-chai@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/karma-sinon-chai/-/karma-sinon-chai-1.3.3.tgz#a597e5b4a1369fe7b3d7d76c09ed2061a38e747f" @@ -4694,6 +4698,14 @@ performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" +phantomjs-polyfill-find-index@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/phantomjs-polyfill-find-index/-/phantomjs-polyfill-find-index-1.0.1.tgz#ffd8d636abc27e87fec57d47033b687967810c37" + +phantomjs-polyfill@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/phantomjs-polyfill/-/phantomjs-polyfill-0.0.2.tgz#8c6a7163e9bc8fd9ffdbe7d605cb5352f9fb891e" + phantomjs-prebuilt@^2.1.16: version "2.1.16" resolved "https://registry.yarnpkg.com/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.16.tgz#efd212a4a3966d3647684ea8ba788549be2aefef"