2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-05-17 02:29:37 +03:00

V3 - Remove mutable class properties plus other misc changes (#781)

* Remove the mutableValue prop in the Select component.

* Add back mutable value when Vue Select has to manage its own value.

* Remove mutableOptions, valueAsAarray. Update webpack minifer to use Terser.

* Fix tabbing

* Fix bug with showClearButton

* Fix tests.

* Call clearSelection when possible

* Update dev sandbox to have all three options for setting value.

* Update dev sandbox to display current value

* Remove unused karma test setup.

* Revert onInput name change.

* Use coveralls

* Change this.internalValue to this.$data._value.

* Remove onInput prop and replace with internal method, updateValue.

* Update tests.

* Rename optionObjectComparator to optionComparator.
This commit is contained in:
Owen Conti
2019-03-23 12:25:31 -06:00
committed by Jeff Sagal
parent f95b118edb
commit f9725919a4
16 changed files with 250 additions and 1950 deletions
+1 -2
View File
@@ -5,5 +5,4 @@ node_js:
- node
script:
- yarn test --coverage --coverageReporters=text-lcov
- codecov
- yarn test --coverage --coverageReporters=text-lcov | coveralls
+13
View File
@@ -1,3 +1,4 @@
const TerserPlugin = require('terser-webpack-plugin');
const merge = require('webpack-merge');
const baseWebpackConfig = require('./webpack.base.conf');
@@ -9,4 +10,16 @@ module.exports = merge(baseWebpackConfig, {
libraryTarget: 'umd',
globalObject: 'typeof self !== \'undefined\' ? self : this',
},
optimization: {
minimizer: [
new TerserPlugin({
sourceMap: true,
terserOptions: {
compress: {
drop_console: true,
},
},
}),
],
}
});
+43
View File
@@ -2,7 +2,18 @@
<div id="app">
<sandbox hide-help>
<template slot-scope="config">
<p>Value managed by `v-model`:</p>
<v-select v-model="vModelValue" v-bind="config" />
<pre><code>`v-model` value: {{ vModelValueStringified }}</code></pre>
<hr />
<p>Value managed by `:value` and `@input`:</p>
<v-select :value="valueProp" @input="changeValueProp" v-bind="config" />
<pre><code>value passed to `@input`: {{ valuePropStringified }}</code></pre>
<hr />
<p>Value managed by Vue Select internally:</p>
<v-select v-bind="config" />
</template>
@@ -18,6 +29,30 @@ import Sandbox from '../docs/.vuepress/components/Sandbox';
export default {
components: {Sandbox, vSelect},
data: () => ({
vModelValue: {
value: 'CA',
label: 'Canada'
},
valueProp: {
value: 'US',
label: 'United States'
}
}),
methods: {
changeValueProp(value) {
this.valueProp = value;
}
},
computed: {
vModelValueStringified() {
return JSON.stringify(this.vModelValue, null, 2);
},
valuePropStringified() {
return JSON.stringify(this.valueProp, null, 2);
}
}
};
</script>
@@ -32,4 +67,12 @@ export default {
#app {
height: 100%;
}
hr {
border: none;
border-bottom: 1px solid #cacaca;
margin-bottom: 1em;
padding-top: 1em;
width: 90%;
}
</style>
+1 -16
View File
@@ -189,21 +189,6 @@ getOptionLabel: {
},
```
## onChange
An optional callback function that is called each time the selected
value(s) change. When integrating with Vuex, use this callback to trigger
an action, rather than using `v-model` to retrieve the selected value.
```js
onChange: {
type: Function,
default: function(val) {
this.$emit("input", val);
}
},
```
## onTab
Select the current value if `selectOnTab` is enabled
@@ -311,7 +296,7 @@ User defined function for adding Options
createOption: {
type: Function,
default(newOption) {
if (typeof this.mutableOptions[0] === "object") {
if (typeof this.optionList[0] === "object") {
newOption = { [this.label]: newOption };
}
this.$emit("option:created", newOption);
+1
View File
@@ -51,6 +51,7 @@
"postcss-loader": "^3.0.0",
"postcss-scss": "^2.0.0",
"sass-loader": "^7.1.0",
"terser-webpack-plugin": "^1.2.3",
"url-loader": "^1.1.2",
"vue": "^2.6.4",
"vue-html-loader": "^1.2.4",
+96 -139
View File
@@ -7,7 +7,7 @@
<div ref="toggle" @mousedown.prevent="toggleDropdown" class="vs__dropdown-toggle">
<div class="vs__selected-options" ref="selectedOptions">
<slot v-for="option in valueAsArray"
<slot v-for="option in selectedValue"
name="selected-option-container"
:option="(typeof option === 'object')?option:{[label]: option}"
:deselect="deselect"
@@ -90,9 +90,7 @@
* using 'change' event using v-on
* @type {Object||String||null}
*/
value: {
default: null
},
value: {},
/**
* An array of strings or objects to be used as dropdown choices.
@@ -191,7 +189,6 @@
default: 'label'
},
/**
* Value of the 'autocomplete' field of the input
* element.
@@ -246,27 +243,6 @@
}
},
/**
* An optional callback function that is called each time the selected
* value(s) change. When integrating with Vuex, use this callback to trigger
* an action, rather than using :value.sync to retreive the selected value.
* @type {Function}
* @param {Object || String} val
*/
onChange: {
type: Function,
default: function (val) {
this.$emit('change', val);
}
},
onInput: {
type: Function,
default: function (val) {
this.$emit('input', val);
}
},
/**
* Select the current value if selectOnTab is enabled
*/
@@ -366,9 +342,10 @@
createOption: {
type: Function,
default(newOption) {
if (typeof this.mutableOptions[0] === 'object') {
if (typeof this.optionList[0] === 'object') {
newOption = {[this.label]: newOption}
}
this.$emit('option:created', newOption)
return newOption
}
@@ -440,65 +417,31 @@
return {
search: '',
open: false,
mutableValue: null,
mutableOptions: []
pushedTags: [],
_value: [] // Internal value managed by Vue Select if no `value` prop is passed
}
},
watch: {
/**
* When the value prop changes, update
* the internal mutableValue.
* @param {mixed} val
* @return {void}
*/
value(val) {
this.mutableValue = val
},
/**
* Maybe run the onChange callback.
* @param {string|object} val
* @param {string|object} old
* @return {void}
*/
mutableValue(val, old) {
if (this.multiple) {
this.onChange ? this.onChange(val) : null
} else {
this.onChange && val !== old ? this.onChange(val) : null
}
},
/**
* When options change, update
* the internal mutableOptions.
* @param {array} val
* @return {void}
*/
options(val) {
this.mutableOptions = val
},
/**
* Maybe reset the mutableValue
* when mutableOptions change.
* Maybe reset the value
* when options change.
* @return {[type]} [description]
*/
mutableOptions() {
options(val) {
if (!this.taggable && this.resetOnOptionsChange) {
this.mutableValue = this.multiple ? [] : null
this.clearSelection()
}
},
/**
* Always reset the mutableValue when
* Always reset the value when
* the multiple prop changes.
* @param {Boolean} val
* @param {Boolean} isMultiple
* @return {void}
*/
multiple(val) {
this.mutableValue = val ? [] : null
multiple() {
this.clearSelection()
},
},
@@ -507,8 +450,6 @@
* attach any event listeners.
*/
created() {
this.mutableValue = this.value
this.mutableOptions = this.options.slice(0)
this.mutableLoading = this.loading
this.$on('option:created', this.maybePushTag)
@@ -526,7 +467,8 @@
if (this.taggable && !this.optionExists(option)) {
option = this.createOption(option)
}
if(this.index) {
if (this.index) {
if (!option.hasOwnProperty(this.index)) {
return console.warn(
`[vue-select warn]: Index key "option.${this.index}" does not` +
@@ -535,14 +477,11 @@
}
option = option[this.index]
}
if (this.multiple && !this.mutableValue) {
this.mutableValue = [option]
} else if (this.multiple) {
this.mutableValue.push(option)
} else {
this.mutableValue = option
if (this.multiple) {
option = this.selectedValue.concat(option)
}
this.onInput(this.mutableValue);
this.updateValue(option);
}
this.onAfterSelect(option)
@@ -554,14 +493,14 @@
* @return {void}
*/
deselect(option) {
let value = null
if (this.multiple) {
this.mutableValue = this.mutableValue.filter(val => {
return ! (val === option || (this.index && val === option[this.index]) || (typeof val === 'object' && val[this.label] === option[this.label]));
value = this.selectedValue.filter(val => {
return ! this.optionComparator(val, option)
});
} else {
this.mutableValue = null
}
this.onInput(this.mutableValue);
this.updateValue(value);
},
/**
@@ -569,8 +508,7 @@
* @return {void}
*/
clearSelection() {
this.mutableValue = this.multiple ? [] : null
this.onInput(this.mutableValue)
this.updateValue(this.multiple ? [] : null)
},
/**
@@ -589,6 +527,14 @@
}
},
updateValue(value) {
if (typeof this.value === 'undefined') {
// Vue select has to manage value
this.$data._value = value;
}
this.$emit('input', value);
},
/**
* Toggle the visibility of the dropdown menu.
* @param {Event} e
@@ -614,11 +560,8 @@
* @return {Boolean} True when selected | False otherwise
*/
isOptionSelected(option) {
return this.valueAsArray.some(value => {
if (typeof value === 'object') {
return this.optionObjectComparator(value, option)
}
return value === option || value === option[this.index]
return this.selectedValue.some(value => {
return this.optionComparator(value, option)
})
},
@@ -629,14 +572,26 @@
* @param option {Object}
* @returns {boolean}
*/
optionObjectComparator(value, option) {
if (this.index && value === option[this.index]) {
return true
} else if ((value[this.label] === option[this.label]) || (value[this.label] === option)) {
return true
} else if (this.index && value[this.index] === option[this.index]) {
return true
optionComparator(value, option) {
// This method will need to be cleaned/replaced when the `reducer` API is added
if (typeof value !== 'object' && typeof option !== 'object') {
// Comparing primitives
if (value === option) {
return true
}
} else {
// Comparing objects
if (this.index && value === option[this.index]) {
return true
}
if ((value[this.label] === option[this.label]) || (value[this.label] === option)) {
return true
}
if (this.index && value[this.index] === option[this.index]) {
return true
}
}
return false;
},
@@ -686,7 +641,7 @@
return
}
// Fixed bug where no-options message could not be closed
if(this.search.length === 0 && this.options.length === 0){
if (this.search.length === 0 && this.options.length === 0){
this.closeSearchOptions()
return
}
@@ -718,42 +673,43 @@
* @return {this.value}
*/
maybeDeleteValue() {
if (!this.searchEl.value.length && this.mutableValue && this.clearable) {
return this.multiple ? this.mutableValue.pop() : this.mutableValue = null
if (!this.searchEl.value.length && this.selectedValue && this.clearable) {
let value = null;
if (this.multiple) {
value = [...this.selectedValue.slice(0, this.selectedValue.length - 1)]
}
this.updateValue(value)
}
},
/**
* Determine if an option exists
* within this.mutableOptions array.
* within this.optionList array.
*
* @param {Object || String} option
* @return {boolean}
*/
optionExists(option) {
let exists = false
this.mutableOptions.forEach(opt => {
return this.optionList.some(opt => {
if (typeof opt === 'object' && opt[this.label] === option) {
exists = true
return true
} else if (opt === option) {
exists = true
return true
}
return false
})
return exists
},
/**
* If push-tags is true, push the
* given option to mutableOptions.
* given option to `this.pushedTags`.
*
* @param {Object || String} option
* @return {void}
*/
maybePushTag(option) {
if (this.pushTags) {
this.mutableOptions.push(option)
this.pushedTags.push(option)
}
},
@@ -812,6 +768,25 @@
computed: {
selectedValue () {
let value = this.value;
if (typeof this.value === 'undefined') {
// Vue select has to manage value internally
value = this.$data._value;
}
if (value) {
return [].concat(value);
}
return [];
},
optionList () {
return this.options.concat(this.pushedTags);
},
/**
* Find the search input DOM element.
* @returns {HTMLInputElement}
@@ -848,7 +823,7 @@
'keyup': this.onSearchKeyUp,
'blur': this.onSearchBlur,
'focus': this.onSearchFocus,
'input': (e) => this.search = e.target.value,
'input': (e) => this.search = e.target.value
},
},
spinner: {
@@ -919,10 +894,13 @@
* @return {array}
*/
filteredOptions() {
const optionList = [].concat(this.optionList);
if (!this.filterable && !this.taggable) {
return this.mutableOptions.slice()
return optionList;
}
let options = this.search.length ? this.filter(this.mutableOptions, this.search, this) : this.mutableOptions;
let options = this.search.length ? this.filter(optionList, this.search, this) : optionList;
if (this.taggable && this.search.length && !this.optionExists(this.search)) {
options.unshift(this.search)
}
@@ -934,28 +912,7 @@
* @return {Boolean}
*/
isValueEmpty() {
if (this.mutableValue) {
if (typeof this.mutableValue === 'object') {
return ! Object.keys(this.mutableValue).length
}
return ! this.valueAsArray.length
}
return true;
},
/**
* Return the current value in array format.
* @return {Array}
*/
valueAsArray() {
if (this.multiple && this.mutableValue) {
return this.mutableValue
} else if (this.mutableValue) {
return [].concat(this.mutableValue)
}
return []
return this.selectedValue.length === 0;
},
/**
@@ -963,7 +920,7 @@
* @return {Boolean}
*/
showClearButton() {
return !this.multiple && this.clearable && !this.open && this.mutableValue != null
return !this.multiple && this.clearable && !this.open && !this.isValueEmpty
}
},
-42
View File
@@ -1,42 +0,0 @@
var merge = require('webpack-merge')
var baseWebpackConfig = require('../../build/webpack.base.conf')
module.exports = function(config) {
config.set({
browsers: ['PhantomJS'],
frameworks: ['jasmine'],
files: [
'../../node_modules/phantomjs-polyfill-object-assign/object-assign-polyfill.js',
'**/*.js'
],
reporters: ['spec', 'coverage'],
preprocessors: {
'**/*.js': ['webpack', 'sourcemap']
},
captureConsole: true,
browserConsoleLogOptions: {
terminal: true,
level: ""
},
webpack: merge(baseWebpackConfig, {
entry: './dev/dev.js'
}),
webpackMiddleware: {
noInfo: true
},
specReporter: {
suppressSkipped: true
},
coverageReporter: {
instrumenters: { isparta: require('isparta') },
instrumenter: {
'**/*.js': 'isparta'
}
}
})
}
File diff suppressed because it is too large Load Diff
+19 -11
View File
@@ -2,10 +2,12 @@ import { selectWithProps } from "../helpers";
describe("Removing values", () => {
it("can remove the given tag when its close icon is clicked", () => {
const Select = selectWithProps({ multiple: true, value: ["foo"] });
const Select = selectWithProps({ multiple: true });
Select.vm.$data._value = 'one';
Select.find(".vs__deselect").trigger("click");
expect(Select.vm.mutableValue).toEqual([]);
expect(Select.emitted().input).toEqual([[[]]]);
expect(Select.vm.selectedValue).toEqual([]);
});
it("should not remove tag when close icon is clicked and component is disabled", () => {
@@ -17,28 +19,32 @@ describe("Removing values", () => {
});
Select.find(".vs__deselect").trigger("click");
expect(Select.vm.mutableValue).toEqual(["one"]);
expect(Select.vm.selectedValue).toEqual(["one"]);
});
it("should remove the last item in the value array on delete keypress when multiple is true", () => {
const Select = selectWithProps({
multiple: true,
value: ["one", "two"],
options: ["one", "two", "three"]
});
Select.vm.maybeDeleteValue();
expect(Select.vm.mutableValue).toEqual(["one"]);
Select.vm.$data._value = ["one", "two"];
Select.find('.vs__search').trigger('keydown.backspace')
expect(Select.emitted().input).toEqual([[['one']]]);
expect(Select.vm.selectedValue).toEqual(["one"]);
});
it("should set value to null on delete keypress when multiple is false", () => {
const Select = selectWithProps({
value: "one",
options: ["one", "two", "three"]
});
Select.vm.$data._value = 'one';
Select.vm.maybeDeleteValue();
expect(Select.vm.mutableValue).toEqual(null);
expect(Select.vm.selectedValue).toEqual([]);
});
describe("Clear button", () => {
@@ -64,12 +70,14 @@ describe("Removing values", () => {
it("should remove selected value when clicked", () => {
const Select = selectWithProps({
options: ["foo", "bar"],
value: "foo"
});
Select.vm.$data._value = 'foo';
expect(Select.vm.mutableValue).toEqual("foo");
expect(Select.vm.selectedValue).toEqual(["foo"]);
Select.find("button.vs__clear").trigger("click");
expect(Select.vm.mutableValue).toEqual(null);
expect(Select.emitted().input).toEqual([[null]]);
expect(Select.vm.selectedValue).toEqual([]);
});
it("should be disabled when component is disabled", () => {
+1 -6
View File
@@ -59,11 +59,6 @@ describe("Toggling Dropdown", () => {
multiple: true,
closeOnSelect: false
});
// const vm = new Vue({
// template:
// '<div><v-select ref="select" :options="options" multiple :closeOnSelect="false" :value="value"></v-select></div>',
// components: { vSelect },
// }).$mount();
Select.vm.open = true;
Select.vm.select("one");
@@ -120,7 +115,7 @@ describe("Toggling Dropdown", () => {
});
Select.vm.search = "foo";
Select.vm.onEscape();
Select.find('.vs__search').trigger('keyup.esc')
expect(Select.vm.search).toEqual("");
});
+11
View File
@@ -2,6 +2,17 @@ import { shallowMount } from "@vue/test-utils";
import VueSelect from "../../src/components/Select";
describe("Filtering Options", () => {
it("should update the search value when the input element receives the 'input' event", () => {
const Select = shallowMount(VueSelect, {
propsData: { options: ["foo", "bar", "baz"] }
});
const input = Select.find('.vs__search');
input.element.value = 'a'
input.trigger('input')
expect(Select.vm.search).toEqual('a');
});
it("should filter an array of strings", () => {
const Select = shallowMount(VueSelect, {
propsData: { options: ["foo", "bar", "baz"] }
+1 -1
View File
@@ -36,7 +36,7 @@ describe("Labels", () => {
});
expect(Select.vm.searchPlaceholder).toEqual("foo");
Select.vm.mutableValue = "one";
Select.vm.$data._value = "one";
expect(Select.vm.searchPlaceholder).not.toBeDefined();
});
});
+7 -8
View File
@@ -10,7 +10,7 @@ describe("When index prop is defined", () => {
options: [{ label: "This is Foo", value: "foo" }]
}
});
expect(Select.vm.mutableValue).toEqual("foo");
expect(Select.vm.selectedValue).toEqual(["foo"]);
});
it("can determine if an object is pre-selected", () => {
@@ -66,7 +66,7 @@ describe("When index prop is defined", () => {
}
});
expect(Select.vm.mutableValue).toEqual(["foo", "bar"]);
expect(Select.vm.selectedValue).toEqual(["foo", "bar"]);
});
it("can deselect a pre-selected object", () => {
@@ -74,7 +74,6 @@ describe("When index prop is defined", () => {
propsData: {
multiple: true,
index: "value",
value: ["foo", "bar"],
options: [
{ label: "This is Foo", value: "foo" },
{ label: "This is Bar", value: "bar" }
@@ -82,16 +81,16 @@ describe("When index prop is defined", () => {
}
});
Select.vm.$data._value = ['foo', 'bar'];
Select.vm.deselect("foo");
expect(Select.vm.mutableValue.length).toEqual(1);
expect(Select.vm.mutableValue).toEqual(["bar"]);
expect(Select.vm.selectedValue).toEqual(["bar"]);
});
it("can deselect an option when multiple is false", () => {
const Select = shallowMount(VueSelect, {
propsData: {
index: "value",
value: "foo",
options: [
{ label: "This is Foo", value: "foo" },
{ label: "This is Bar", value: "bar" }
@@ -100,7 +99,7 @@ describe("When index prop is defined", () => {
});
Select.vm.deselect("foo");
expect(Select.vm.mutableValue).toEqual(null);
expect(Select.vm.selectedValue).toEqual([]);
});
it("can use v-model syntax for a two way binding to a parent component", () => {
@@ -120,7 +119,7 @@ describe("When index prop is defined", () => {
const Select = Parent.vm.$children[0];
expect(Select.value).toEqual("foo");
expect(Select.mutableValue).toEqual("foo");
expect(Select.selectedValue).toEqual(["foo"]);
Select.select({ label: "This is Bar", value: "bar" });
expect(Parent.vm.value).toEqual("bar");
+12 -6
View File
@@ -4,17 +4,23 @@ import VueSelect from "../../src/components/Select";
describe("Reset on options change", () => {
it("should not reset the selected value by default when the options property changes", () => {
const Select = shallowMount(VueSelect, {
propsData: { value: "one", options: ["one"] }
propsData: { options: ["one"] }
});
Select.vm.mutableOptions = ["four", "five", "six"];
expect(Select.vm.mutableValue).toEqual("one");
Select.vm.$data._value = 'one';
Select.setProps({options: ["four", "five", "six"]});
expect(Select.vm.selectedValue).toEqual(["one"]);
});
it("should reset the selected value when the options property changes", () => {
const Select = shallowMount(VueSelect, {
propsData: { resetOnOptionsChange: true, value: "one", options: ["one"] }
propsData: { resetOnOptionsChange: true, options: ["one"] }
});
Select.vm.mutableOptions = ["four", "five", "six"];
expect(Select.vm.mutableValue).toEqual(null);
Select.vm.$data._value = 'one';
Select.setProps({options: ["four", "five", "six"]});
expect(Select.vm.selectedValue).toEqual([]);
});
});
+22 -24
View File
@@ -15,7 +15,7 @@ describe("VS - Selecting Values", () => {
const Select = shallowMount(VueSelect, {
propsData: defaultProps
});
expect(Select.mutableValue).toEqual(Select.value);
expect(Select.selectedValue).toEqual(Select.value);
});
it("can accept an array of objects and pre-selected value (single)", () => {
@@ -28,7 +28,7 @@ describe("VS - Selecting Values", () => {
]
}
});
expect(Select.mutableValue).toEqual(Select.value);
expect(Select.selectedValue).toEqual(Select.value);
});
it("can accept an array of objects and pre-selected values (multiple)", () => {
@@ -46,7 +46,7 @@ describe("VS - Selecting Values", () => {
multiple: true
});
expect(Select.mutableValue).toEqual(Select.value);
expect(Select.selectedValue).toEqual(Select.value);
});
it("can select an option on tab", () => {
@@ -67,10 +67,6 @@ describe("VS - Selecting Values", () => {
const Select = shallowMount(VueSelect, {
propsData: {
multiple: true,
value: [
{ label: "This is Foo", value: "foo" },
{ label: "This is Bar", value: "bar" }
],
options: [
{ label: "This is Foo", value: "foo" },
{ label: "This is Bar", value: "bar" }
@@ -78,36 +74,41 @@ describe("VS - Selecting Values", () => {
}
});
Select.vm.$data._value = [
{ label: "This is Foo", value: "foo" },
{ label: "This is Bar", value: "bar" }
];
Select.vm.deselect({ label: "This is Foo", value: "foo" });
expect(Select.vm.mutableValue.length).toEqual(1);
expect(Select.vm.selectedValue).toEqual([{ label: "This is Bar", value: "bar" }]);
});
it("can deselect a pre-selected string", () => {
const Select = shallowMount(VueSelect, {
propsData: {
multiple: true,
value: ["foo", "bar"],
options: ["foo", "bar"]
}
});
Select.vm.$data._value = "foo";
Select.vm.deselect("foo");
expect(Select.vm.mutableValue.length).toEqual(1);
expect(Select.vm.selectedValue).toEqual([]);
});
it("can deselect an option when multiple is false", () => {
const Select = shallowMount(VueSelect, {
propsData: {
value: "foo"
}
});
const Select = shallowMount(VueSelect);
Select.vm.$data._value = "foo";
Select.vm.deselect("foo");
expect(Select.vm.mutableValue).toEqual(null);
expect(Select.vm.selectedValue).toEqual([]);
});
it("can determine if the value prop is empty", () => {
const Select = shallowMount(VueSelect, {
propsData: {
value: [],
options: ["one", "two", "three"]
}
});
@@ -134,19 +135,16 @@ describe("VS - Selecting Values", () => {
it("should reset the selected values when the multiple property changes", () => {
const Select = shallowMount(VueSelect, {
propsData: {
value: ["one"],
multiple: true,
options: ["one", "two", "three"]
}
});
expect(Select.vm.mutableValue).toEqual(["one"]);
Select.setProps({ multiple: false });
expect(Select.vm.mutableValue).toEqual(null);
expect(Select.vm.selectedValue).toEqual([]);
Select.setProps({ multiple: true });
expect(Select.vm.mutableValue).toEqual([]);
expect(Select.vm.selectedValue).toEqual([]);
});
it("can retain values present in a new array of options", () => {
@@ -158,7 +156,7 @@ describe("VS - Selecting Values", () => {
});
Select.setProps({ options: ["one", "five", "six"] });
expect(Select.vm.mutableValue).toEqual(["one"]);
expect(Select.vm.selectedValue).toEqual(["one"]);
});
it("can determine if an object is already selected", () => {
@@ -181,7 +179,7 @@ describe("VS - Selecting Values", () => {
const Select = Parent.vm.$children[0];
expect(Select.value).toEqual("foo");
expect(Select.mutableValue).toEqual("foo");
expect(Select.selectedValue).toEqual(["foo"]);
Select.select("bar");
expect(Parent.vm.value).toEqual("bar");
+22 -22
View File
@@ -44,25 +44,24 @@ describe("When Tagging Is Enabled", () => {
const Select = selectWithProps({
taggable: true,
multiple: true,
value: ["one"],
options: ["one", "two"]
});
searchSubmit(Select, "three");
expect(Select.vm.mutableValue).toEqual(["one", "three"]);
expect(Select.vm.selectedValue).toEqual(["three"]);
});
it("can select the current search text as an object", () => {
const Select = selectWithProps({
taggable: true,
multiple: true,
value: [{ label: "one" }],
options: [{ label: "one" }]
});
searchSubmit(Select, "two");
expect(Select.vm.mutableValue).toEqual([
{ label: "one" },
expect(Select.vm.selectedValue).toEqual([
{ label: "two" }
]);
});
@@ -77,7 +76,8 @@ describe("When Tagging Is Enabled", () => {
});
searchSubmit(Select, "three");
expect(Select.vm.mutableOptions).toEqual(["one", "two", "three"]);
expect(Select.vm.pushedTags).toEqual(["three"]);
expect(Select.vm.optionList).toEqual(["one", "two", "three"]);
});
it("should add a freshly created option/tag to the options list when pushTags is true and filterable is false", () => {
@@ -91,7 +91,8 @@ describe("When Tagging Is Enabled", () => {
});
searchSubmit(Select, "three");
expect(Select.vm.mutableOptions).toEqual(["one", "two", "three"]);
expect(Select.vm.pushedTags).toEqual(["three"]);
expect(Select.vm.optionList).toEqual(["one", "two", "three"]);
expect(Select.vm.filteredOptions).toEqual(["one", "two", "three"]);
});
@@ -105,7 +106,7 @@ describe("When Tagging Is Enabled", () => {
});
searchSubmit(Select, "three");
expect(Select.vm.mutableOptions).toEqual(["one", "two"]);
expect(Select.vm.optionList).toEqual(["one", "two"]);
});
it("wont add a freshly created option/tag to the options list when pushTags is false and filterable is false", () => {
@@ -119,16 +120,15 @@ describe("When Tagging Is Enabled", () => {
});
searchSubmit(Select, "three");
expect(Select.vm.mutableOptions).toEqual(["one", "two"]);
expect(Select.vm.optionList).toEqual(["one", "two"]);
expect(Select.vm.filteredOptions).toEqual(["one", "two"]);
});
it("should select an existing option if the search string matches a string from options", () => {
it("should select an existing option if the search string matches a string from options", async () => {
let two = "two";
const Select = selectWithProps({
taggable: true,
multiple: true,
value: null,
options: ["one", two]
});
@@ -136,7 +136,7 @@ describe("When Tagging Is Enabled", () => {
searchSubmit(Select);
expect(Select.vm.mutableValue[0]).toBe(two);
expect(Select.vm.selectedValue).toEqual([two]);
});
it("should select an existing option if the search string matches an objects label from options", () => {
@@ -149,7 +149,7 @@ describe("When Tagging Is Enabled", () => {
Select.vm.search = "two";
searchSubmit(Select);
expect(Select.vm.mutableValue.label).toBe(two.label);
expect(Select.vm.selectedValue).toEqual([two]);
});
it("should select an existing option if the search string matches an objects label from options when filter-options is false", () => {
@@ -163,7 +163,7 @@ describe("When Tagging Is Enabled", () => {
Select.vm.search = "two";
searchSubmit(Select);
expect(Select.vm.mutableValue.label).toBe(two.label);
expect(Select.vm.selectedValue).toEqual([two]);
});
it("should not reset the selected value when the options property changes", () => {
@@ -174,8 +174,8 @@ describe("When Tagging Is Enabled", () => {
options: [{ label: "one" }]
});
Select.vm.mutableOptions = [{ label: "two" }];
expect(Select.vm.mutableValue).toEqual([{ label: "one" }]);
Select.setProps({ options: [{ label: "two" }] });
expect(Select.vm.selectedValue).toEqual([{ label: "one" }]);
});
it("should not reset the selected value when the options property changes when filterable is false", () => {
@@ -187,8 +187,8 @@ describe("When Tagging Is Enabled", () => {
options: [{ label: "one" }]
});
Select.vm.mutableOptions = [{ label: "two" }];
expect(Select.vm.mutableValue).toEqual([{ label: "one" }]);
Select.setProps({ options: [{ label: "two" }] });
expect(Select.vm.selectedValue).toEqual([{ label: "one" }]);
});
it("should not allow duplicate tags when using string options", () => {
@@ -198,11 +198,11 @@ describe("When Tagging Is Enabled", () => {
});
searchSubmit(Select, "one");
expect(Select.vm.mutableValue).toEqual(["one"]);
expect(Select.vm.selectedValue).toEqual(["one"]);
expect(Select.vm.search).toEqual("");
searchSubmit(Select, "one");
expect(Select.vm.mutableValue).toEqual(["one"]);
expect(Select.vm.selectedValue).toEqual(["one"]);
expect(Select.vm.search).toEqual("");
});
@@ -214,11 +214,11 @@ describe("When Tagging Is Enabled", () => {
});
searchSubmit(Select, "one");
expect(Select.vm.mutableValue).toEqual([{ label: "one" }]);
expect(Select.vm.selectedValue).toEqual([{ label: "one" }]);
expect(Select.vm.search).toEqual("");
searchSubmit(Select, "one");
expect(Select.vm.mutableValue).toEqual([{ label: "one" }]);
expect(Select.vm.selectedValue).toEqual([{ label: "one" }]);
expect(Select.vm.search).toEqual("");
});
});