Commit 5da043ee8d44c536e102a4655bfaea893a39665c

Authored by Aresn
Committed by GitHub
2 parents 66728eda 3b9de249

Merge pull request #1696 from SergioCrisostomo/add-select-specs

Add simple unit tests for Select component
Showing 2 changed files with 206 additions and 0 deletions   Show diff stats
test/unit/specs/select.spec.js 0 → 100644
  1 +import {createVue, destroyVM, waitForIt} from '../util';
  2 +
  3 +describe('Select.vue', () => {
  4 + let vm;
  5 + afterEach(() => {
  6 + destroyVM(vm);
  7 + });
  8 +
  9 + describe('Props tests', () => {
  10 + it('should create a Select component with passed placeholder', done => {
  11 + const placeholder = 'Hi! Select something!';
  12 + vm = createVue({
  13 + template: `
  14 + <Select placeholder="${placeholder}">
  15 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  16 + </Select>
  17 + `,
  18 + data() {
  19 + return {
  20 + value: '',
  21 + options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]
  22 + };
  23 + }
  24 + });
  25 + vm.$nextTick(() => {
  26 + const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
  27 + expect(placeholderSpan.textContent).to.equal(placeholder);
  28 + expect(placeholderSpan.style.display).to.not.equal('none');
  29 +
  30 + expect(vm.$children[0].showPlaceholder).to.equal(true);
  31 + done();
  32 + });
  33 + });
  34 +
  35 + it('should create a Select component and take a pre-selected value', done => {
  36 + vm = createVue({
  37 + template: `
  38 + <Select :value="2">
  39 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  40 + </Select>
  41 + `,
  42 + data() {
  43 + return {
  44 + value: '',
  45 + options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]
  46 + };
  47 + }
  48 + });
  49 + vm.$nextTick(() => {
  50 + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
  51 + expect(selectedValueSpan.textContent).to.equal('Bar');
  52 + expect(selectedValueSpan.style.display).to.not.equal('none');
  53 + expect(vm.$children[0].selectedSingle).to.equal('Bar');
  54 + expect(vm.$children[0].model).to.equal(2);
  55 + done();
  56 + });
  57 + });
  58 +
  59 + xit('should accept normal characters', done => {
  60 + vm = createVue({
  61 + template: `
  62 + <Select :value="2">
  63 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  64 + </Select>
  65 + `,
  66 + data() {
  67 + return {
  68 + value: '',
  69 + options: [{value: 1, label: '> 100$'}, {value: 2, label: '< 100$'}]
  70 + };
  71 + }
  72 + });
  73 + vm.$nextTick(() => {
  74 + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
  75 + expect(selectedValueSpan.textContent).to.equal('< 100$');
  76 + done();
  77 + });
  78 + });
  79 +
  80 + it('should use the value\'s label instead of placeholder when both are set', done => {
  81 + vm = createVue({
  82 + template: `
  83 + <Select placeholder="Choose anything!" :value="2">
  84 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  85 + </Select>
  86 + `,
  87 + data() {
  88 + return {
  89 + value: '',
  90 + options: [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}]
  91 + };
  92 + }
  93 + });
  94 + vm.$nextTick(() => {
  95 + const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
  96 + const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
  97 + expect(placeholderSpan.style.display).to.equal('none');
  98 + expect(selectedValueSpan.style.display).to.not.equal('none');
  99 + done();
  100 + });
  101 + });
  102 +
  103 + it('should set different classes for different sizes', done => {
  104 + vm = createVue(`
  105 + <div>
  106 + <Select placeholder="Choose anything!"><Option v-for="item in []" :value="item" :key="item">{{item}}</Option></Select>
  107 + <Select placeholder="Choose anything!" size="large"><Option v-for="item in []" :value="item" :key="item">{{item}}</Option></Select>
  108 + <Select placeholder="Choose anything!" size="small"><Option v-for="item in []" :value="item" :key="item">{{item}}</Option></Select>
  109 + </div>
  110 + `);
  111 + vm.$nextTick(() => {
  112 + const [defaultSelect, largeSelect, smallSelect] = [...vm.$el.querySelectorAll('.ivu-select')];
  113 + expect(defaultSelect.className).to.equal('ivu-select ivu-select-single');
  114 + expect(largeSelect.classList.contains('ivu-select-large')).to.equal(true);
  115 + expect(smallSelect.classList.contains('ivu-select-small')).to.equal(true);
  116 + done();
  117 + });
  118 + });
  119 +
  120 + it('should set new options', done => {
  121 + const laterOptions = [{value: 1, label: 'Foo'}, {value: 2, label: 'Bar'}];
  122 +
  123 + vm = createVue({
  124 + template: `
  125 + <Select>
  126 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  127 + </Select>
  128 + `,
  129 + data() {
  130 + return {
  131 + value: '',
  132 + options: []
  133 + };
  134 + },
  135 + mounted() {
  136 + this.$nextTick(() => (this.options = laterOptions));
  137 + }
  138 + });
  139 + const condition = function() {
  140 + return vm.$children[0].options.length > 0;
  141 + };
  142 + const callback = function() {
  143 + if (vm.$children[0].options == 0) return setTimeout(waitForIt.bind(null, done), 50);
  144 + expect(JSON.stringify(vm.$children[0].options)).to.equal(JSON.stringify(laterOptions));
  145 +
  146 + const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li');
  147 + expect(renderedOptions.length).to.equal(laterOptions.length);
  148 +
  149 + const labels = [...renderedOptions].map(el => el.textContent).join('<>');
  150 + const expected = laterOptions.map(o => o.label).join('<>');
  151 + expect(labels).to.equal(expected);
  152 + done();
  153 + };
  154 + waitForIt(condition, callback);
  155 + });
  156 + });
  157 +
  158 + describe('Performance tests', () => {
  159 + xit('should handle big numbers of options', done => {
  160 + const manyLaterOptions = Array.apply(null, Array(200)).map((_, i) => {
  161 + return {
  162 + value: i + 1,
  163 + label: Math.random().toString(36).slice(2).toUpperCase()
  164 + };
  165 + });
  166 + const start = +new Date();
  167 + vm = createVue({
  168 + template: `
  169 + <Select>
  170 + <Option v-for="item in options" :value="item.value" :key="item.value">{{ item.label }}</Option>
  171 + </Select>
  172 + `,
  173 + data() {
  174 + return {
  175 + value: '',
  176 + options: []
  177 + };
  178 + },
  179 + mounted() {
  180 + this.$nextTick(() => (this.options = manyLaterOptions));
  181 + }
  182 + });
  183 + const condition = function() {
  184 + return vm.$children[0].options.length == manyLaterOptions.length;
  185 + };
  186 + const callback = function() {
  187 + const end = +new Date();
  188 + const renderedOptions = vm.$el.querySelectorAll('.ivu-select-dropdown-list li');
  189 + expect(renderedOptions.length).to.equal(manyLaterOptions.length);
  190 + expect(end - start).to.be.not.above(1000);
  191 + done();
  192 + };
  193 + waitForIt(condition, callback);
  194 + });
  195 + });
  196 +});
... ...
test/unit/util.js
... ... @@ -83,3 +83,13 @@ exports.triggerEvent = function(elm, name, ...opts) {
83 83  
84 84 return elm;
85 85 };
  86 +
  87 +/**
  88 +* Wait for components inner async process, when this.$nextTick is not enough
  89 +* @param {Function} the condition to verify before calling the callback
  90 +* @param {Function} the callback to call when condition is true
  91 +*/
  92 +exports.waitForIt = function waitForIt(condition, callback) {
  93 + if (condition()) callback();
  94 + else setTimeout(() => waitForIt(condition, callback), 50);
  95 +};
... ...