Skip to content

Commit

Permalink
[unit-test] Add tests for vue components and mixins
Browse files Browse the repository at this point in the history
  • Loading branch information
GianlucaGuarini committed Aug 17, 2018
1 parent eda8c79 commit 1e8131f
Show file tree
Hide file tree
Showing 12 changed files with 1,537 additions and 5,951 deletions.
7,200 changes: 1,284 additions & 5,916 deletions package-lock.json

Large diffs are not rendered by default.

37 changes: 19 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
"cov": "nyc report --reporter=text-lcov | coveralls",
"cov-html": "nyc report --reporter html --report-dir reports/coverage",
"build": "rollup -c",
"doc": "npm run doc-api",
"doc-config": "documentation readme src/presets.js --section='Plugin config'",
"doc-api": "documentation readme src/index.js --section=API",
"pretest": "npm run build",
"test": "npm run lint && nyc mocha -r reify -r test/runner src/**/*.spec.js"
},
"files": [
Expand All @@ -34,29 +32,32 @@
},
"homepage": "https://github.com/dreipol/vue-ui#readme",
"devDependencies": {
"@dreipol/eslint-config": "^3.0.0",
"babel-eslint": "^8.0.1",
"@dreipol/eslint-config": "^4.1.0",
"@vue/test-utils": "^1.0.0-beta.24",
"babel-eslint": "^8.2.3",
"chai": "^4.1.2",
"coveralls": "^3.0.2",
"documentation": "^5.3.3",
"eslint": "^4.4.0",
"jsdom": "9.5.0",
"jsdom-global": "2.1.0",
"mocha": "^4.0.1",
"eslint": "^4.19.1",
"jsdom": "11.11.0",
"jsdom-global": "3.0.2",
"mocha": "^5.2.0",
"nyc": "^12.0.2",
"postcss": "^7.0.2",
"reify": "^0.17.3",
"rollup": "^0.52.0",
"rollup-plugin-buble": "^0.18.0",
"rollup-plugin-commonjs": "^8.2.6",
"rollup-plugin-node-resolve": "^2.0.0",
"rollup": "^0.59.4",
"rollup-plugin-buble": "^0.19.2",
"rollup-plugin-commonjs": "^9.1.3",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-vue": "^4.3.2",
"sinon": "^5.0.10",
"sinon-chai": "^3.1.0",
"vue": "^2.5.9",
"vuex": "^3.0.0"
"vue": "^2.5.17",
"vue-template-compiler": "^2.5.17",
"vuex": "^3.0.1"
},
"dependencies": {
"lodash.clonedeep": "^4.0.0",
"lodash.clonedeep": "^4.5.0",
"lodash.isnil": "^4.0.0",
"lodash.omitby": "^4.0.0"
"lodash.omitby": "^4.6.0"
}
}
7 changes: 6 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import buble from 'rollup-plugin-buble';

import vue from 'rollup-plugin-vue';

export default {
input: 'src/index.js',
plugins: [
resolve({
jsnext: true,
}),
vue(),
buble({
objectAssign: 'Object.assign',
}),
Expand All @@ -19,5 +20,9 @@ export default {
file: 'dist/index.js',
format: 'cjs',
},
{
file: 'dist/index.esm.js',
format: 'esm',
},
],
};
64 changes: 62 additions & 2 deletions src/components/modal/modal.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,67 @@
/* eslint-disable no-unused-expressions, max-nested-callbacks */

import { createLocalVue, shallowMount } from '@vue/test-utils';
import { expect } from 'chai';
import { Modal } from '../../../';
import Vuex from 'vuex';
import cloneDeep from 'lodash.clonedeep';
import overalyModule from '../../modules/overlay';

const localVue = createLocalVue();

localVue.use(Vuex);

describe('Modal spec', () => {
it('The modal is a valid vue component', () => {
expect(true).to.be.equal(true);
function getDummyModalComponentOptions(customOptions = {}) {
const store = new Vuex.Store({
modules: {
overlay: cloneDeep(overalyModule),
},
});

return {
store,
localVue,
...customOptions,
};
}

it('The modal is an object', () => {
expect(Modal).to.be.an('object');
expect(Modal).to.be.not.empty;
});

it('It can be properly created without slots', () => {
const wrapper = shallowMount(Modal, getDummyModalComponentOptions());

expect(wrapper.find('.modal').exists()).to.be.ok;
});

it('Slots markup will not be rendered if not needed', () => {
const wrapper = shallowMount(Modal, getDummyModalComponentOptions());

expect(wrapper.find('.modal--header').exists()).to.be.not.ok;
expect(wrapper.find('.modal--body').exists()).to.be.not.ok;
expect(wrapper.find('.modal--footer').exists()).to.be.not.ok;
});

it('Slots markup rendered if needed', () => {
const wrapper = shallowMount(Modal, getDummyModalComponentOptions({
slots: {
default: '<div>Default</div>',
header: '<div>Header</div>',
footer: '<div>Footer</div>',
},
}));

expect(wrapper.find('.modal--header').exists()).to.be.ok;
expect(wrapper.find('.modal--body').exists()).to.be.ok;
expect(wrapper.find('.modal--footer').exists()).to.be.ok;
});

it('It has the close method', () => {
const { vm } = shallowMount(Modal, getDummyModalComponentOptions());
expect(vm.closeOverlay).to.be.a('function');
expect(vm.closeOverlay()).to.not.throw;
});
});
3 changes: 1 addition & 2 deletions src/components/modal/modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<div class="modal--close-wrap">
<div class="modal--close">
<button class="modal--close-button" @click.prevent="closeOverlay">
<base-icon symbol="close" size="large"></base-icon>
<!-- TODO: handle icons -->
</button>
</div>
</div>
Expand All @@ -24,7 +24,6 @@
import { mapActions } from 'vuex';
import bemMixin from '../../mixins/bem';
export default {
mixins: [
bemMixin('modal'),
Expand Down
50 changes: 50 additions & 0 deletions src/components/overlay/overlay.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* eslint-disable no-unused-expressions, max-nested-callbacks */

import { createLocalVue, shallowMount } from '@vue/test-utils';
import { expect } from 'chai';
import { Overlay } from '../../../';
import Vuex from 'vuex';
import cloneDeep from 'lodash.clonedeep';
import overalyModule from '../../modules/overlay';

const localVue = createLocalVue();

localVue.use(Vuex);


describe('Overlay spec', () => {
function getDummyOverlayComponentOptions(customOptions = {}) {
const store = new Vuex.Store({
modules: {
overlay: cloneDeep(overalyModule),
},
});

return {
store,
localVue,
propsData: {
id: 'foo',
},
...customOptions,
};
}

it('The overlay is an object', () => {
expect(Overlay).to.be.an('object');
expect(Overlay).to.be.not.empty;
});

it('It can be properly created without slots', () => {
const wrapper = shallowMount(Overlay, getDummyOverlayComponentOptions());

expect(wrapper.find('.overlay').exists()).to.be.ok;
});

it('It has the close method', () => {
const { vm } = shallowMount(Overlay, getDummyOverlayComponentOptions());

expect(vm.closeOverlay).to.be.a('function');
expect(vm.closeOverlay()).to.not.throw;
});
});
4 changes: 4 additions & 0 deletions src/components/overlay/overlay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import bemMixin from '../../mixins/bem';
import Modal from '../modal/modal.vue';
import scrollLockHelperMixin from '../../mixins/scroll-lock-helper';
Expand All @@ -38,6 +39,9 @@
bemMixin('overlay'),
scrollLockHelperMixin,
],
components: {
'cmp-modal': Modal,
},
props: {
id: {
type: String,
Expand Down
3 changes: 3 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ plugin.install = function(Vue, presets) {
console.log('hello world');
};

export { default as Modal } from './components/modal/modal.vue';
export { default as Overlay } from './components/overlay/overlay.vue';

export default plugin;
70 changes: 70 additions & 0 deletions src/mixins/bem/bem.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* eslint-disable max-nested-callbacks */

import { expect } from 'chai';
import { createLocalVue } from '@vue/test-utils';
import { DEFAULT_OPTIONS } from './helpers';
import bemMixin from './';

const ROOT_CLASS = 'root';
const localVue = createLocalVue();

describe('Bem Mixin', () => {
describe('Computed properties', () => {
it('It returns the bemRoot class properly', () => {
localVue.mixin(bemMixin(ROOT_CLASS));
const vm = new localVue();

expect(vm.bemRoot).to.be.equal(ROOT_CLASS);
});

it('It returns the bem facets properly', () => {
localVue.mixin(bemMixin(ROOT_CLASS));
const vm = new localVue();

expect(vm.bemFacets).to.be.an('array');
expect(vm.bemFacets).to.include(`${ ROOT_CLASS }${ DEFAULT_OPTIONS.bemModifierMarker }${ DEFAULT_OPTIONS.defaultFacet }`);
});

it('Custom bem mixin options have also an impact on the computed pros', () => {
const customOptions = {
bemModifierMarker: '$$',
defaultFacet: 'foo',
bemElementMarker: '??',
};
localVue.mixin(bemMixin(ROOT_CLASS, customOptions));
const vm = new localVue();

expect(vm.bemFacets).to.be.an('array');
expect(vm.bemFacets).to.include(`${ ROOT_CLASS }${ customOptions.bemModifierMarker }${ customOptions.defaultFacet }`);
});
});
describe('Methods', () => {
it('Simple custom facets can be easily added', () => {
localVue.mixin(bemMixin(ROOT_CLASS));
const vm = new localVue();
const customFacet = 'foo';

expect(vm.bemAdd(customFacet)).to.be.equal(`${ ROOT_CLASS }${ DEFAULT_OPTIONS.bemModifierMarker }${ customFacet }`);
});

it('Complex custom facets can be easily added', () => {
localVue.mixin(bemMixin(ROOT_CLASS));
const vm = new localVue();
const rootName = 'I';
const elementName = 'like';
const customFacet = 'pizzas';

expect(vm.bemAdd(customFacet, elementName, rootName)).to.be.equal(`${ rootName }${ DEFAULT_OPTIONS.bemElementMarker }${ elementName }${ DEFAULT_OPTIONS.bemModifierMarker }${ customFacet }`);
});

it('Bem classes can be properly switched conditionally', () => {
localVue.mixin(bemMixin(ROOT_CLASS));
const vm = new localVue();
const trueModifier = 'jep';
const falseModifier = 'nope';

expect(vm.bemIf(true, trueModifier, falseModifier)).to.be.equal(`${ ROOT_CLASS }${ DEFAULT_OPTIONS.bemModifierMarker }${ trueModifier }`);
expect(vm.bemIf(false, trueModifier, falseModifier)).to.be.equal(`${ ROOT_CLASS }${ DEFAULT_OPTIONS.bemModifierMarker }${ falseModifier }`);
});
});
});
2 changes: 1 addition & 1 deletion src/mixins/scroll-lock-helper/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mapGetters, mapState } from 'vuex';
import { isIos } from 'util/detect/ios-detect';
import { isIos } from '../../util/detect/ios-detect';

const SCROLL_LOCK_IOS_FIX_CLASS = 'u-scroll-lock-ios-fix';

Expand Down

0 comments on commit 1e8131f

Please sign in to comment.