From f80ee1c22eda7486b3470191de1ac093eb448a26 Mon Sep 17 00:00:00 2001 From: Jeff Date: Fri, 29 Nov 2019 19:26:47 -0800 Subject: [PATCH] test(slots): add test coverage for slots, getOptionLabel https://github.com/vuejs/vue/pull/10229 --- src/components/Select.vue | 4 ++-- tests/unit/Labels.spec.js | 37 ++++++++++++++++++++++++++++++++++++ tests/unit/Selecting.spec.js | 15 +++++++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/components/Select.vue b/src/components/Select.vue index e0dfc65de..1adba4ecd 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -386,7 +386,7 @@ * @return {Boolean} */ filter: { - "type": Function, + type: Function, default(options, search) { return options.filter((option) => { let label = this.getOptionLabel(option) @@ -1077,7 +1077,7 @@ */ showClearButton() { return !this.multiple && this.clearable && !this.open && !this.isValueEmpty - } + }, }, } diff --git a/tests/unit/Labels.spec.js b/tests/unit/Labels.spec.js index ae7c4cf2d..513ca5cff 100755 --- a/tests/unit/Labels.spec.js +++ b/tests/unit/Labels.spec.js @@ -39,4 +39,41 @@ describe("Labels", () => { Select.vm.$data._value = "one"; expect(Select.vm.searchPlaceholder).not.toBeDefined(); }); + + describe('getOptionLabel', () => { + it('will return undefined if the option lacks the label key', () => { + const getOptionLabel = VueSelect.props.getOptionLabel.default.bind({ label: 'label' }); + expect(getOptionLabel({name: 'vue'})).toEqual(undefined); + }); + + it('will return a string value for a valid key', () => { + const getOptionLabel = VueSelect.props.getOptionLabel.default.bind({ label: 'label' }); + expect(getOptionLabel({label: 'vue'})).toEqual('vue'); + }); + + /** + * this test fails because of a bug where Vue executes the default contents + * of a slot, even if it is implemented by the consumer. + * @see https://github.com/vuejs/vue/issues/10224 + * @see https://github.com/vuejs/vue/pull/10229 + */ + xit('will not call getOptionLabel if both scoped option slots are used and a filter is provided', () => { + const spy = spyOn(VueSelect.props.getOptionLabel, 'default'); + const Select = shallowMount(VueSelect, { + propsData: { + options: [{name: 'one'}], + filter: () => {}, + }, + scopedSlots: { + 'option': '{{ props.name }}', + 'selected-option': '{{ props.name }}', + }, + }); + + Select.vm.select({name: 'one'}); + + expect(spy).toHaveBeenCalledTimes(0); + expect(Select.find('.selected').exists()).toBeTruthy(); + }); + }); }); diff --git a/tests/unit/Selecting.spec.js b/tests/unit/Selecting.spec.js index d4d1489bf..b7a729084 100755 --- a/tests/unit/Selecting.spec.js +++ b/tests/unit/Selecting.spec.js @@ -1,5 +1,6 @@ import { mount, shallowMount } from "@vue/test-utils"; import VueSelect from "../../src/components/Select.vue"; +import { mountDefault } from '../helpers'; describe("VS - Selecting Values", () => { let defaultProps; @@ -192,10 +193,20 @@ describe("VS - Selecting Values", () => { value: [{ label: "foo", value: "bar" }] } }); - expect(Select.vm.isOptionSelected("foo")).toEqual(true); + expect(Select.vm.isOptionSelected({ label: "foo", value: "bar" })).toEqual(true); }); - describe("change Event", () => { + it('can select two options with the same label', () => { + const options = [{label: 'one', id: 1}, {label: 'one', id: 2}]; + const Select = mountDefault({options, multiple: true}); + + Select.vm.select({label: 'one', id: 1}); + Select.vm.select({label: 'one', id: 2}); + + expect(Select.vm.selectedValue).toEqual(options); + }); + + describe("input Event", () => { it("will trigger the input event when the selection changes", () => { const Select = shallowMount(VueSelect); Select.vm.select("bar");