slim-select 2.8.1 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +1 -0
- package/.prettierrc +4 -3
- package/README.md +2 -0
- package/dist/classes.d.ts +43 -0
- package/dist/helpers.d.ts +1 -1
- package/dist/index.d.ts +5 -2
- package/dist/render.d.ts +4 -44
- package/dist/select.d.ts +4 -2
- package/dist/settings.d.ts +2 -1
- package/dist/slimselect.cjs.js +248 -120
- package/dist/slimselect.css +1 -1
- package/dist/slimselect.css.map +1 -1
- package/dist/slimselect.es.js +248 -120
- package/dist/slimselect.global.js +248 -120
- package/dist/slimselect.js +248 -120
- package/dist/slimselect.min.js +1 -1
- package/dist/slimselect.umd.js +248 -120
- package/dist/slimselect.umd.min.js +1 -1
- package/dist/store.d.ts +4 -2
- package/index.html +1 -4
- package/jest.config.js +6 -0
- package/package.json +30 -41
- package/src/slim-select/classes.test.ts +72 -0
- package/src/slim-select/classes.ts +109 -0
- package/src/slim-select/helpers.test.ts +160 -0
- package/src/slim-select/helpers.ts +3 -12
- package/src/slim-select/index.test.ts +109 -16
- package/src/slim-select/index.ts +41 -12
- package/src/slim-select/render.test.ts +1169 -18
- package/src/slim-select/render.ts +75 -96
- package/src/slim-select/rollup.config.mjs +28 -28
- package/src/slim-select/select.test.ts +306 -156
- package/src/slim-select/select.ts +69 -20
- package/src/slim-select/settings.test.ts +257 -0
- package/src/slim-select/settings.ts +4 -0
- package/src/slim-select/slimselect.scss +7 -3
- package/src/slim-select/store.test.ts +986 -235
- package/src/slim-select/store.ts +70 -28
- package/src/{vue/slimselect.vue → slim-select/vue.vue} +19 -17
- package/tsconfig.json +2 -3
- package/src/react/.eslintignore +0 -2
- package/src/react/.eslintrc.cjs +0 -24
- package/src/react/index.html +0 -14
- package/src/react/jestconfig.json +0 -11
- package/src/react/package.json +0 -32
- package/src/react/src/frameworkpage.tsx +0 -133
- package/src/react/src/index.ts +0 -3
- package/src/react/src/slimselect.tsx +0 -148
- package/src/react/tests/slimselect.test.tsx +0 -52
- package/src/react/tsconfig.json +0 -37
- package/src/react/tsconfig.node.json +0 -10
- package/src/react/vite.config.ts +0 -55
- package/src/vue/README.md +0 -48
- package/src/vue/dist/slim-select/helpers.d.ts +0 -5
- package/src/vue/dist/slim-select/index.d.ts +0 -46
- package/src/vue/dist/slim-select/render.d.ts +0 -120
- package/src/vue/dist/slim-select/select.d.ts +0 -28
- package/src/vue/dist/slim-select/settings.d.ts +0 -34
- package/src/vue/dist/slim-select/store.d.ts +0 -80
- package/src/vue/dist/slimselectvue.es.js +0 -1978
- package/src/vue/dist/slimselectvue.global.js +0 -1981
- package/src/vue/dist/slimselectvue.ssr.js +0 -1980
- package/src/vue/dist/vue/hello.d.ts +0 -2
- package/src/vue/dist/vue/slimselect.vue.d.ts +0 -326
- package/src/vue/hello.ts +0 -5
- package/src/vue/package.json +0 -28
- package/src/vue/rollup.config.mjs +0 -44
- package/src/vue/tsconfig.json +0 -14
- /package/{vite.config.ts → vite.config.mts} +0 -0
|
@@ -1,242 +1,993 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
import { describe, expect, test } from '@jest/globals'
|
|
4
|
-
import Store, { Optgroup, Option } from './store'
|
|
4
|
+
import Store, { DataArray, DataObjectPartial, Optgroup, Option } from './store'
|
|
5
5
|
|
|
6
6
|
describe('store module', () => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
7
|
+
describe('constructor', () => {
|
|
8
|
+
test('constructor without data', () => {
|
|
9
|
+
let store = new Store('single', [])
|
|
10
|
+
expect(store).toBeInstanceOf(Store)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
test('constructor with single option', () => {
|
|
14
|
+
const store = new Store('single', [
|
|
15
|
+
{
|
|
16
|
+
text: 'test'
|
|
17
|
+
}
|
|
18
|
+
])
|
|
19
|
+
|
|
20
|
+
const data = store.getData()
|
|
21
|
+
|
|
22
|
+
// Make sure data has one item and that it has the correct text
|
|
23
|
+
expect(data).toHaveLength(1)
|
|
24
|
+
expect(data[0]).toBeInstanceOf(Option)
|
|
25
|
+
|
|
26
|
+
const option = data[0] as Option
|
|
27
|
+
|
|
28
|
+
expect(option.text).toBe('test')
|
|
29
|
+
expect(option.id).toBeDefined()
|
|
30
|
+
expect(option.value).toBeDefined()
|
|
31
|
+
expect(option.text).toBeDefined()
|
|
32
|
+
expect(option.html).toBeDefined()
|
|
33
|
+
expect(option.selected).toBeDefined()
|
|
34
|
+
expect(option.display).toBeDefined()
|
|
35
|
+
expect(option.disabled).toBeDefined()
|
|
36
|
+
expect(option.placeholder).toBeDefined()
|
|
37
|
+
expect(option.class).toBeDefined()
|
|
38
|
+
expect(option.style).toBeDefined()
|
|
39
|
+
expect(option.data).toBeDefined()
|
|
40
|
+
expect(option.mandatory).toBeDefined()
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('constructor with optgroup', () => {
|
|
44
|
+
const store = new Store('single', [
|
|
45
|
+
{
|
|
46
|
+
label: 'opt group',
|
|
47
|
+
options: [
|
|
48
|
+
{
|
|
49
|
+
text: 'test'
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
])
|
|
54
|
+
|
|
55
|
+
const data = store.getData()
|
|
56
|
+
|
|
57
|
+
expect(data).toHaveLength(1)
|
|
58
|
+
|
|
59
|
+
expect(data[0]).toBeInstanceOf(Optgroup)
|
|
60
|
+
const optGroup = data[0] as Optgroup
|
|
61
|
+
|
|
62
|
+
expect(optGroup.label).toBe('opt group')
|
|
63
|
+
expect(optGroup.options).toHaveLength(1)
|
|
64
|
+
expect(optGroup.options?.[0].text).toBe('test')
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
test('constructor with optgroup and option', () => {
|
|
68
|
+
const store = new Store('single', [
|
|
69
|
+
{
|
|
70
|
+
label: 'opt group',
|
|
71
|
+
options: [
|
|
72
|
+
{
|
|
73
|
+
text: 'opt group option'
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
text: 'option'
|
|
79
|
+
}
|
|
80
|
+
])
|
|
81
|
+
|
|
82
|
+
const data = store.getData()
|
|
83
|
+
|
|
84
|
+
expect(data).toHaveLength(2)
|
|
85
|
+
|
|
86
|
+
expect(data[0]).toBeInstanceOf(Optgroup)
|
|
87
|
+
const optGroup = data[0] as Optgroup
|
|
88
|
+
|
|
89
|
+
expect(optGroup.label).toBe('opt group')
|
|
90
|
+
expect(optGroup.options).toHaveLength(1)
|
|
91
|
+
expect(optGroup.options?.[0].text).toBe('opt group option')
|
|
92
|
+
|
|
93
|
+
expect(data[1]).toBeInstanceOf(Option)
|
|
94
|
+
expect((data[1] as Option).text).toBe('option')
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
test('constructor with multiple selected on single select only registers first selected', () => {
|
|
98
|
+
const store = new Store('single', [
|
|
99
|
+
{
|
|
100
|
+
text: 'test1'
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
text: 'test2',
|
|
104
|
+
value: 'test2',
|
|
105
|
+
selected: true
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
text: 'test3',
|
|
109
|
+
selected: true
|
|
110
|
+
}
|
|
111
|
+
])
|
|
112
|
+
|
|
113
|
+
// cast to an option array here, so we don't need casts in the comparisons
|
|
114
|
+
const data = store.getData() as Array<Option>
|
|
115
|
+
|
|
116
|
+
expect(data).toHaveLength(3)
|
|
117
|
+
expect(data[0].text).toBe('test1')
|
|
118
|
+
expect(data[0].selected).toBe(false)
|
|
119
|
+
expect(data[1].text).toBe('test2')
|
|
120
|
+
expect(data[1].selected).toBe(true)
|
|
121
|
+
expect(data[2].text).toBe('test3')
|
|
122
|
+
expect(data[2].selected).toBe(false)
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
test('constructor without a selected element on single select selects first option', () => {
|
|
126
|
+
const store = new Store('single', [
|
|
127
|
+
{
|
|
128
|
+
text: 'test1'
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
text: 'test2',
|
|
132
|
+
value: 'test2'
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
text: 'test3'
|
|
136
|
+
}
|
|
137
|
+
])
|
|
138
|
+
|
|
139
|
+
// cast to an option array here, so we don't need casts in the comparisons
|
|
140
|
+
const data = store.getData() as Array<Option>
|
|
141
|
+
|
|
142
|
+
expect(data).toHaveLength(3)
|
|
143
|
+
expect(data[0].text).toBe('test1')
|
|
144
|
+
expect(data[0].selected).toBe(true)
|
|
145
|
+
expect(data[1].text).toBe('test2')
|
|
146
|
+
expect(data[1].selected).toBe(false)
|
|
147
|
+
expect(data[2].text).toBe('test3')
|
|
148
|
+
expect(data[2].selected).toBe(false)
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
test('constructor with multiple selected on multiple select registers all selected', () => {
|
|
152
|
+
const store = new Store('multiple', [
|
|
153
|
+
{
|
|
154
|
+
text: 'test1'
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
text: 'test2',
|
|
158
|
+
value: 'test2',
|
|
159
|
+
selected: true
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
text: 'test3',
|
|
163
|
+
selected: true
|
|
164
|
+
}
|
|
165
|
+
])
|
|
166
|
+
|
|
167
|
+
// cast to an option array here, so we don't need casts in the comparisons
|
|
168
|
+
const data = store.getData() as Array<Option>
|
|
169
|
+
|
|
170
|
+
expect(data).toHaveLength(3)
|
|
171
|
+
expect(data[0].text).toBe('test1')
|
|
172
|
+
expect(data[0].selected).toBe(false)
|
|
173
|
+
expect(data[1].text).toBe('test2')
|
|
174
|
+
expect(data[1].selected).toBe(true)
|
|
175
|
+
expect(data[2].text).toBe('test3')
|
|
176
|
+
expect(data[2].selected).toBe(true)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('constructor without a selected element on multiple select does not select anything', () => {
|
|
180
|
+
const store = new Store('multiple', [
|
|
181
|
+
{
|
|
182
|
+
text: 'test1'
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
text: 'test2',
|
|
186
|
+
value: 'test2'
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
text: 'test3'
|
|
190
|
+
}
|
|
191
|
+
])
|
|
192
|
+
|
|
193
|
+
// cast to an option array here, so we don't need casts in the comparisons
|
|
194
|
+
const data = store.getData() as Array<Option>
|
|
195
|
+
|
|
196
|
+
expect(data).toHaveLength(3)
|
|
197
|
+
data.forEach((option) => {
|
|
198
|
+
expect(option.selected).toBe(false)
|
|
199
|
+
})
|
|
200
|
+
})
|
|
201
|
+
})
|
|
202
|
+
|
|
203
|
+
describe('validateDataArray', () => {
|
|
204
|
+
let store: Store
|
|
205
|
+
|
|
206
|
+
beforeAll(() => {
|
|
207
|
+
store = new Store('single', [])
|
|
208
|
+
})
|
|
209
|
+
|
|
210
|
+
test('invalid data returns error', () => {
|
|
211
|
+
const invalidData = { test: true }
|
|
212
|
+
|
|
213
|
+
const res = store.validateDataArray(invalidData as unknown as DataArray)
|
|
214
|
+
expect(res).toBeInstanceOf(Error)
|
|
215
|
+
expect(res?.message).toBe('Data must be an array')
|
|
216
|
+
})
|
|
217
|
+
|
|
218
|
+
test('single invalid data entry returns error', () => {
|
|
219
|
+
const invalidData = [{ name: 'this is invalid' }]
|
|
220
|
+
|
|
221
|
+
const res = store.validateDataArray(invalidData as unknown as DataArray)
|
|
222
|
+
expect(res).toBeInstanceOf(Error)
|
|
223
|
+
expect(res?.message).toBe('Data object must be a valid optgroup or option')
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
test('invalid data and valid option returns error', () => {
|
|
227
|
+
const invalidData = [
|
|
228
|
+
{
|
|
229
|
+
name: 'invalid data'
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
text: 'valid option'
|
|
233
|
+
}
|
|
234
|
+
]
|
|
235
|
+
|
|
236
|
+
const res = store.validateDataArray(invalidData as unknown as DataArray)
|
|
237
|
+
expect(res).toBeInstanceOf(Error)
|
|
238
|
+
expect(res?.message).toBe('Data object must be a valid optgroup or option')
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
test('valid option and invalid data returns error', () => {
|
|
242
|
+
const invalidData = [
|
|
243
|
+
{
|
|
244
|
+
text: 'valid'
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
name: 'this is invalid'
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
|
|
251
|
+
const res = store.validateDataArray(invalidData as unknown as DataArray)
|
|
252
|
+
expect(res).toBeInstanceOf(Error)
|
|
253
|
+
expect(res?.message).toBe('Data object must be a valid optgroup or option')
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
test('valid opt group with invalid data returns error', () => {
|
|
257
|
+
const invalidData = [
|
|
258
|
+
{
|
|
259
|
+
label: 'valid',
|
|
260
|
+
options: [
|
|
261
|
+
{
|
|
262
|
+
invalid: 'asdf'
|
|
263
|
+
}
|
|
264
|
+
]
|
|
265
|
+
}
|
|
266
|
+
]
|
|
267
|
+
|
|
268
|
+
const res = store.validateDataArray(invalidData as unknown as DataArray)
|
|
269
|
+
expect(res).toBeInstanceOf(Error)
|
|
270
|
+
expect(res?.message).toBe('Option must have a text')
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
test('single valid option validates', () => {
|
|
274
|
+
const validData = [
|
|
275
|
+
{
|
|
276
|
+
text: 'valid option'
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
|
|
280
|
+
const res = store.validateDataArray(validData)
|
|
281
|
+
expect(res).toBeNull()
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
test('multiple valid options validates', () => {
|
|
285
|
+
const validData = [
|
|
286
|
+
{
|
|
287
|
+
text: 'valid option 1'
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
text: 'valid option 2'
|
|
291
|
+
}
|
|
292
|
+
]
|
|
293
|
+
|
|
294
|
+
const res = store.validateDataArray(validData)
|
|
295
|
+
expect(res).toBeNull()
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
test('single valid opt group validates', () => {
|
|
299
|
+
const validData = [
|
|
300
|
+
{
|
|
301
|
+
label: 'valid opt group'
|
|
302
|
+
}
|
|
303
|
+
]
|
|
304
|
+
|
|
305
|
+
const res = store.validateDataArray(validData)
|
|
306
|
+
expect(res).toBeNull()
|
|
307
|
+
})
|
|
308
|
+
|
|
309
|
+
test('valid opt group with options validates', () => {
|
|
310
|
+
const validData = [
|
|
311
|
+
{
|
|
312
|
+
label: 'valid opt group',
|
|
313
|
+
options: [
|
|
314
|
+
{
|
|
315
|
+
text: 'option 1'
|
|
316
|
+
},
|
|
317
|
+
{
|
|
318
|
+
text: 'option 2'
|
|
319
|
+
}
|
|
320
|
+
]
|
|
321
|
+
}
|
|
322
|
+
]
|
|
323
|
+
|
|
324
|
+
const res = store.validateDataArray(validData)
|
|
325
|
+
expect(res).toBeNull()
|
|
326
|
+
})
|
|
327
|
+
test('valid opt group with options and separate options validates', () => {
|
|
328
|
+
const validData = [
|
|
329
|
+
{
|
|
330
|
+
label: 'valid opt group',
|
|
331
|
+
options: [
|
|
332
|
+
{
|
|
333
|
+
text: 'option 1'
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
text: 'option 2'
|
|
337
|
+
}
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
text: 'main option 1'
|
|
342
|
+
},
|
|
343
|
+
{
|
|
344
|
+
text: 'main option 2'
|
|
345
|
+
}
|
|
346
|
+
]
|
|
347
|
+
|
|
348
|
+
const res = store.validateDataArray(validData)
|
|
349
|
+
expect(res).toBeNull()
|
|
350
|
+
})
|
|
351
|
+
})
|
|
352
|
+
|
|
353
|
+
describe('validateOption', () => {
|
|
354
|
+
let store: Store
|
|
355
|
+
|
|
356
|
+
beforeAll(() => {
|
|
357
|
+
store = new Store('single', [])
|
|
358
|
+
})
|
|
359
|
+
|
|
360
|
+
test('empty option returns error', () => {
|
|
361
|
+
const res = store.validateOption({} as Option)
|
|
362
|
+
expect(res).toBeInstanceOf(Error)
|
|
363
|
+
expect(res?.message).toBe('Option must have a text')
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
test('invalid data returns error', () => {
|
|
367
|
+
const res = store.validateOption({ label: 'text' } as unknown as Option)
|
|
368
|
+
expect(res).toBeInstanceOf(Error)
|
|
369
|
+
expect(res?.message).toBe('Option must have a text')
|
|
370
|
+
})
|
|
371
|
+
|
|
372
|
+
test('valid data returns null', () => {
|
|
373
|
+
const res = store.validateOption({ text: 'text' })
|
|
374
|
+
expect(res).toBeNull()
|
|
375
|
+
})
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
describe('partialToFullData', () => {
|
|
379
|
+
let store: Store
|
|
380
|
+
|
|
381
|
+
beforeAll(() => {
|
|
382
|
+
store = new Store('single', [])
|
|
383
|
+
})
|
|
384
|
+
|
|
385
|
+
test('empty partial returns empty data array', () => {
|
|
386
|
+
const res = store.partialToFullData([])
|
|
387
|
+
expect(res).toBeInstanceOf(Array)
|
|
388
|
+
expect(res).toHaveLength(0)
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
test("invalid data get's ignored", () => {
|
|
392
|
+
const res = store.partialToFullData([
|
|
393
|
+
{ error: 'this is invalid' } as unknown as DataObjectPartial,
|
|
394
|
+
{ text: 'valid' }
|
|
395
|
+
])
|
|
396
|
+
expect(res).toBeInstanceOf(Array)
|
|
397
|
+
expect(res).toHaveLength(1)
|
|
398
|
+
|
|
399
|
+
expect(res[0]).toBeInstanceOf(Option)
|
|
400
|
+
|
|
401
|
+
const option = res[0] as Option
|
|
402
|
+
expect(option.text).toBe('valid')
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
test('valid data gets filled correctly', () => {
|
|
406
|
+
const res = store.partialToFullData([
|
|
407
|
+
{
|
|
408
|
+
label: 'opt group',
|
|
409
|
+
options: [{ text: 'opt 1' }, { text: 'opt 2' }]
|
|
410
|
+
},
|
|
411
|
+
{
|
|
412
|
+
text: 'opt 3'
|
|
413
|
+
}
|
|
414
|
+
])
|
|
415
|
+
|
|
416
|
+
expect(res).toHaveLength(2)
|
|
417
|
+
expect(res[0]).toBeInstanceOf(Optgroup)
|
|
418
|
+
|
|
419
|
+
const optGroup = res[0] as Optgroup
|
|
420
|
+
expect(optGroup.label).toBe('opt group')
|
|
421
|
+
expect(optGroup.options).toHaveLength(2)
|
|
422
|
+
expect(optGroup.options[0]).toBeInstanceOf(Option)
|
|
423
|
+
expect(optGroup.options[0].text).toBe('opt 1')
|
|
424
|
+
expect(optGroup.options[1]).toBeInstanceOf(Option)
|
|
425
|
+
expect(optGroup.options[1].text).toBe('opt 2')
|
|
426
|
+
})
|
|
427
|
+
})
|
|
428
|
+
|
|
429
|
+
describe('setData', () => {
|
|
430
|
+
let store: Store
|
|
431
|
+
|
|
432
|
+
beforeEach(() => {
|
|
433
|
+
store = new Store('single', [
|
|
434
|
+
{
|
|
435
|
+
text: 'initial option'
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
text: 'initial selected option',
|
|
439
|
+
selected: true
|
|
440
|
+
}
|
|
441
|
+
])
|
|
442
|
+
})
|
|
443
|
+
|
|
444
|
+
test('invalid data does override existing data', () => {
|
|
445
|
+
store.setData([{ invalid: true } as unknown as Option])
|
|
446
|
+
|
|
447
|
+
const data = store.getData()
|
|
448
|
+
expect(data).toHaveLength(0)
|
|
449
|
+
})
|
|
450
|
+
|
|
451
|
+
test('valid data overrides existing data', () => {
|
|
452
|
+
store.setData([
|
|
453
|
+
{
|
|
454
|
+
text: 'opt 1'
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
text: 'opt 2'
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
text: 'opt 3'
|
|
461
|
+
}
|
|
462
|
+
])
|
|
463
|
+
|
|
464
|
+
const data = store.getData() as Array<Option>
|
|
465
|
+
expect(data).toHaveLength(3)
|
|
466
|
+
expect(data[0].text).toBe('opt 1')
|
|
467
|
+
expect(data[1].text).toBe('opt 2')
|
|
468
|
+
expect(data[2].text).toBe('opt 3')
|
|
469
|
+
})
|
|
470
|
+
|
|
471
|
+
test('valid data on single select automatically selects first option', () => {
|
|
472
|
+
store.setData([
|
|
473
|
+
{
|
|
474
|
+
text: 'opt 1'
|
|
475
|
+
},
|
|
476
|
+
{
|
|
477
|
+
text: 'opt 2'
|
|
478
|
+
}
|
|
479
|
+
])
|
|
480
|
+
|
|
481
|
+
const data = store.getData() as Array<Option>
|
|
482
|
+
expect(data).toHaveLength(2)
|
|
483
|
+
expect(data[0].selected).toBe(true)
|
|
484
|
+
})
|
|
485
|
+
|
|
486
|
+
test('valid data on single select selects correct option', () => {
|
|
487
|
+
store.setData([
|
|
488
|
+
{
|
|
489
|
+
text: 'opt 1'
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
text: 'opt 2',
|
|
493
|
+
selected: true
|
|
494
|
+
}
|
|
495
|
+
])
|
|
496
|
+
|
|
497
|
+
const data = store.getData() as Array<Option>
|
|
498
|
+
expect(data).toHaveLength(2)
|
|
499
|
+
expect(data[1].text).toBe('opt 2')
|
|
500
|
+
expect(data[1].selected).toBe(true)
|
|
501
|
+
})
|
|
502
|
+
})
|
|
503
|
+
|
|
504
|
+
describe('getData', () => {
|
|
505
|
+
test('getData gets all options', () => {
|
|
506
|
+
const data = [
|
|
507
|
+
{
|
|
508
|
+
label: 'group test',
|
|
509
|
+
options: [
|
|
510
|
+
{
|
|
511
|
+
text: 'sub opt 1'
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
text: 'sub opt 2'
|
|
515
|
+
}
|
|
516
|
+
]
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
text: 'test1'
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
text: 'test2',
|
|
523
|
+
value: 'test2'
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
text: 'test3'
|
|
527
|
+
}
|
|
528
|
+
]
|
|
529
|
+
|
|
530
|
+
const flatData = [
|
|
531
|
+
{
|
|
532
|
+
text: 'sub opt 1'
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
text: 'sub opt 2'
|
|
536
|
+
},
|
|
537
|
+
{
|
|
538
|
+
text: 'test1'
|
|
539
|
+
},
|
|
540
|
+
{
|
|
541
|
+
text: 'test2',
|
|
542
|
+
value: 'test2'
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
text: 'test3'
|
|
546
|
+
}
|
|
547
|
+
]
|
|
548
|
+
|
|
549
|
+
const store = new Store('single', data)
|
|
550
|
+
|
|
551
|
+
const storedData = store.getData()
|
|
552
|
+
storedData.forEach((dataObject, index) => {
|
|
553
|
+
if ('label' in dataObject) {
|
|
554
|
+
expect(dataObject.label).toBe(data[index].label)
|
|
555
|
+
dataObject.options.forEach((subOpt, subIndex) => {
|
|
556
|
+
expect(subOpt.text).toBe(data[index].options![subIndex].text)
|
|
557
|
+
expect(subOpt.value).toBe(data[index].options![subIndex].text)
|
|
558
|
+
})
|
|
559
|
+
} else {
|
|
560
|
+
expect(dataObject.text).toBe(data[index].text)
|
|
561
|
+
expect(dataObject.value).toBe(data[index].text)
|
|
562
|
+
}
|
|
563
|
+
})
|
|
564
|
+
|
|
565
|
+
// test flat array directly
|
|
566
|
+
const storedDataOptions = store.getDataOptions()
|
|
567
|
+
storedDataOptions.forEach((option, index) => {
|
|
568
|
+
expect(option.text).toBe(flatData[index].text)
|
|
569
|
+
expect(option.value).toBe(flatData[index].text)
|
|
570
|
+
})
|
|
571
|
+
})
|
|
572
|
+
})
|
|
573
|
+
|
|
574
|
+
describe('getDataOptions', () => {
|
|
575
|
+
test('options only store returns same structure', () => {
|
|
576
|
+
const store = new Store('single', [
|
|
577
|
+
{
|
|
578
|
+
text: 'opt 0'
|
|
579
|
+
},
|
|
580
|
+
{
|
|
581
|
+
text: 'opt 1'
|
|
582
|
+
}
|
|
583
|
+
])
|
|
584
|
+
|
|
585
|
+
const data = store.getDataOptions()
|
|
586
|
+
expect(data).toHaveLength(2)
|
|
587
|
+
data.forEach((option, index) => {
|
|
588
|
+
expect(option).toBeInstanceOf(Option)
|
|
589
|
+
expect(option.text).toBe(`opt ${index}`)
|
|
590
|
+
})
|
|
591
|
+
})
|
|
592
|
+
|
|
593
|
+
test('option group gets flattened', () => {
|
|
594
|
+
const store = new Store('single', [
|
|
595
|
+
{
|
|
596
|
+
label: 'opt group',
|
|
597
|
+
options: [
|
|
598
|
+
{
|
|
599
|
+
text: 'opt 0'
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
text: 'opt 1'
|
|
603
|
+
}
|
|
604
|
+
]
|
|
605
|
+
},
|
|
606
|
+
{
|
|
607
|
+
text: 'opt 2'
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
text: 'opt 3'
|
|
611
|
+
}
|
|
612
|
+
])
|
|
613
|
+
|
|
614
|
+
const data = store.getDataOptions()
|
|
615
|
+
expect(data).toHaveLength(4)
|
|
616
|
+
data.forEach((option, index) => {
|
|
617
|
+
expect(option).toBeInstanceOf(Option)
|
|
618
|
+
expect(option.text).toBe(`opt ${index}`)
|
|
619
|
+
})
|
|
620
|
+
})
|
|
621
|
+
})
|
|
622
|
+
|
|
623
|
+
describe('addOption', () => {
|
|
624
|
+
test('append option', () => {
|
|
625
|
+
const store = new Store('single', [
|
|
626
|
+
{
|
|
627
|
+
text: 'test1'
|
|
628
|
+
}
|
|
629
|
+
])
|
|
630
|
+
|
|
631
|
+
store.addOption({ text: 'test2' })
|
|
632
|
+
|
|
633
|
+
const storeData = store.getDataOptions()
|
|
634
|
+
expect(storeData).toHaveLength(2)
|
|
635
|
+
expect(storeData[0].text).toBe('test1')
|
|
636
|
+
expect(storeData[1].text).toBe('test2')
|
|
637
|
+
})
|
|
638
|
+
})
|
|
639
|
+
|
|
640
|
+
describe('setSelectedBy', () => {
|
|
641
|
+
let store: Store
|
|
642
|
+
|
|
643
|
+
beforeEach(() => {
|
|
644
|
+
store = new Store('single', [
|
|
645
|
+
{
|
|
646
|
+
text: 'opt 1'
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
id: '12345678',
|
|
650
|
+
text: 'id opt'
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
text: 'opt 2'
|
|
654
|
+
},
|
|
655
|
+
{
|
|
656
|
+
text: 'opt 3'
|
|
657
|
+
}
|
|
658
|
+
])
|
|
659
|
+
})
|
|
660
|
+
|
|
661
|
+
test('set selected by ID', () => {
|
|
662
|
+
store.setSelectedBy('id', ['12345678'])
|
|
663
|
+
const data = store.getDataOptions()
|
|
664
|
+
|
|
665
|
+
expect(data[0].text).toBe('opt 1')
|
|
666
|
+
expect(data[0].selected).toBe(false)
|
|
667
|
+
|
|
668
|
+
expect(data[1].text).toBe('id opt')
|
|
669
|
+
expect(data[1].selected).toBe(true)
|
|
670
|
+
})
|
|
671
|
+
|
|
672
|
+
test('set selected by value', () => {
|
|
673
|
+
store.setSelectedBy('value', ['opt 3'])
|
|
674
|
+
|
|
675
|
+
const data = store.getDataOptions()
|
|
676
|
+
|
|
677
|
+
expect(data[0].text).toBe('opt 1')
|
|
678
|
+
expect(data[0].selected).toBe(false)
|
|
679
|
+
|
|
680
|
+
expect(data[3].text).toBe('opt 3')
|
|
681
|
+
expect(data[3].selected).toBe(true)
|
|
682
|
+
})
|
|
683
|
+
|
|
684
|
+
test('set selected to empty string selects first option', () => {
|
|
685
|
+
const store = new Store('single', [
|
|
686
|
+
{
|
|
687
|
+
text: 'all',
|
|
688
|
+
value: ''
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
text: 'Value 1',
|
|
692
|
+
value: '1',
|
|
693
|
+
selected: true
|
|
694
|
+
}
|
|
695
|
+
])
|
|
696
|
+
store.setSelectedBy('value', [''])
|
|
697
|
+
|
|
698
|
+
const data = store.getDataOptions()
|
|
699
|
+
|
|
700
|
+
expect(data[0].text).toBe('all')
|
|
701
|
+
expect(data[0].selected).toBe(true)
|
|
702
|
+
expect(data[1].selected).toBe(false)
|
|
703
|
+
})
|
|
704
|
+
|
|
705
|
+
test('set multiple selected by value on single select only selects the first element', () => {
|
|
706
|
+
store.setSelectedBy('value', ['opt 2', 'opt 3'])
|
|
707
|
+
|
|
708
|
+
const data = store.getDataOptions()
|
|
709
|
+
|
|
710
|
+
expect(data[2].selected).toBe(true)
|
|
711
|
+
expect(data[3].selected).toBe(false)
|
|
712
|
+
})
|
|
713
|
+
})
|
|
714
|
+
|
|
715
|
+
describe('getSelected', () => {
|
|
716
|
+
test('get correct value when one option is selected', () => {
|
|
717
|
+
const store = new Store('single', [
|
|
718
|
+
{
|
|
719
|
+
text: 'opt 0'
|
|
720
|
+
},
|
|
721
|
+
{
|
|
722
|
+
text: 'opt 1'
|
|
723
|
+
}
|
|
724
|
+
])
|
|
725
|
+
|
|
726
|
+
const selected = store.getSelectedValues()
|
|
727
|
+
expect(selected).toHaveLength(1)
|
|
728
|
+
expect(selected[0]).toBe('opt 0')
|
|
729
|
+
})
|
|
730
|
+
|
|
731
|
+
test('get correct value when two options is selected', () => {
|
|
732
|
+
const store = new Store('multiple', [
|
|
733
|
+
{
|
|
734
|
+
text: 'opt 0'
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
text: 'opt 1',
|
|
738
|
+
selected: true
|
|
739
|
+
},
|
|
740
|
+
{
|
|
741
|
+
text: 'opt 2',
|
|
742
|
+
selected: true
|
|
743
|
+
}
|
|
744
|
+
])
|
|
745
|
+
|
|
746
|
+
const selected = store.getSelectedValues()
|
|
747
|
+
expect(selected).toHaveLength(2)
|
|
748
|
+
|
|
749
|
+
expect(selected[0]).toBe('opt 1')
|
|
750
|
+
expect(selected[1]).toBe('opt 2')
|
|
751
|
+
})
|
|
752
|
+
|
|
753
|
+
test('get correct order when using reorder options', () => {
|
|
754
|
+
const store = new Store('multiple', [
|
|
755
|
+
{
|
|
756
|
+
text: 'opt 0'
|
|
757
|
+
},
|
|
758
|
+
{
|
|
759
|
+
text: 'opt 1'
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
text: 'opt 2'
|
|
763
|
+
}
|
|
764
|
+
])
|
|
765
|
+
|
|
766
|
+
store.setSelectedBy('value', ['opt 2', 'opt 0'])
|
|
767
|
+
|
|
768
|
+
let selected = store.getSelectedOptions()
|
|
769
|
+
selected = store.selectedOrderOptions(selected)
|
|
770
|
+
expect(selected.map((opt) => opt.text)).toEqual(['opt 2', 'opt 0'])
|
|
771
|
+
})
|
|
772
|
+
})
|
|
773
|
+
|
|
774
|
+
describe('getSelectedOptions', () => {
|
|
775
|
+
test('get correct value when one option is selected', () => {
|
|
776
|
+
const store = new Store('single', [
|
|
777
|
+
{
|
|
778
|
+
text: 'opt 0'
|
|
779
|
+
},
|
|
780
|
+
{
|
|
781
|
+
text: 'opt 1'
|
|
782
|
+
}
|
|
783
|
+
])
|
|
784
|
+
|
|
785
|
+
const selected = store.getSelectedOptions()
|
|
786
|
+
expect(selected).toHaveLength(1)
|
|
787
|
+
expect(selected[0].text).toBe('opt 0')
|
|
788
|
+
})
|
|
789
|
+
|
|
790
|
+
test('get correct value when two options is selected', () => {
|
|
791
|
+
const store = new Store('multiple', [
|
|
792
|
+
{
|
|
793
|
+
text: 'opt 0'
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
text: 'opt 1',
|
|
797
|
+
selected: true
|
|
798
|
+
},
|
|
799
|
+
{
|
|
800
|
+
text: 'opt 2',
|
|
801
|
+
selected: true
|
|
802
|
+
}
|
|
803
|
+
])
|
|
804
|
+
|
|
805
|
+
const selected = store.getSelectedOptions()
|
|
806
|
+
expect(selected).toHaveLength(2)
|
|
807
|
+
expect(selected[0].text).toBe('opt 1')
|
|
808
|
+
expect(selected[1].text).toBe('opt 2')
|
|
809
|
+
})
|
|
810
|
+
})
|
|
811
|
+
|
|
812
|
+
describe('getOptionByID', () => {
|
|
813
|
+
let store: Store
|
|
814
|
+
|
|
815
|
+
beforeAll(() => {
|
|
816
|
+
store = new Store('single', [
|
|
817
|
+
{
|
|
818
|
+
text: 'opt 1'
|
|
819
|
+
},
|
|
820
|
+
{
|
|
821
|
+
id: '12345678',
|
|
822
|
+
text: 'id opt'
|
|
823
|
+
},
|
|
824
|
+
{
|
|
825
|
+
text: 'opt 2'
|
|
826
|
+
},
|
|
827
|
+
{
|
|
828
|
+
text: 'opt 3'
|
|
829
|
+
}
|
|
830
|
+
])
|
|
831
|
+
})
|
|
832
|
+
|
|
833
|
+
test('invalid id gets null as result', () => {
|
|
834
|
+
const res = store.getOptionByID('0000')
|
|
835
|
+
expect(res).toBeNull()
|
|
836
|
+
})
|
|
837
|
+
|
|
838
|
+
test('valid id gets correct result', () => {
|
|
839
|
+
const res = store.getOptionByID('12345678')
|
|
840
|
+
expect(res).toBeInstanceOf(Option)
|
|
841
|
+
expect((res as Option).text).toBe('id opt')
|
|
842
|
+
})
|
|
843
|
+
})
|
|
844
|
+
|
|
845
|
+
describe('getSelectType', () => {
|
|
846
|
+
test('get correct type on single select', () => {
|
|
847
|
+
const store = new Store('single', [])
|
|
848
|
+
expect(store.getSelectType()).toBe('single')
|
|
849
|
+
})
|
|
850
|
+
|
|
851
|
+
test('get correct type on multiple select', () => {
|
|
852
|
+
const store = new Store('multiple', [])
|
|
853
|
+
expect(store.getSelectType()).toBe('multiple')
|
|
854
|
+
})
|
|
855
|
+
})
|
|
856
|
+
|
|
857
|
+
describe('getFirstOption', () => {
|
|
858
|
+
test('getFirstOption returns first option', () => {
|
|
859
|
+
const flatStore = new Store('single', [
|
|
860
|
+
{
|
|
861
|
+
text: 'test0'
|
|
862
|
+
},
|
|
863
|
+
{
|
|
864
|
+
text: 'test1'
|
|
865
|
+
}
|
|
866
|
+
])
|
|
867
|
+
|
|
868
|
+
expect(flatStore.getFirstOption()?.text).toBe('test0')
|
|
869
|
+
|
|
870
|
+
const store = new Store('single', [
|
|
871
|
+
{
|
|
872
|
+
label: 'group0',
|
|
873
|
+
options: [
|
|
874
|
+
{
|
|
875
|
+
text: 'test0'
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
text: 'test1'
|
|
879
|
+
}
|
|
880
|
+
]
|
|
881
|
+
},
|
|
882
|
+
{
|
|
883
|
+
text: 'test2'
|
|
884
|
+
}
|
|
885
|
+
])
|
|
886
|
+
|
|
887
|
+
expect(store.getFirstOption()?.text).toBe('test0')
|
|
888
|
+
})
|
|
889
|
+
})
|
|
890
|
+
|
|
891
|
+
describe('search', () => {
|
|
892
|
+
test('search with term returns correct option', () => {
|
|
893
|
+
const store = new Store('single', [
|
|
894
|
+
{
|
|
895
|
+
text: 'test1'
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
text: 'test2',
|
|
899
|
+
value: 'test2'
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
text: 'test3'
|
|
903
|
+
}
|
|
904
|
+
])
|
|
905
|
+
|
|
906
|
+
const searchFilter = (opt: Option, search: string): boolean => {
|
|
907
|
+
return opt.text.toLowerCase().indexOf(search.toLowerCase()) !== -1
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
// With searchFilter search against current store data set
|
|
911
|
+
const searchResults = store.search('test2', searchFilter)
|
|
912
|
+
expect(searchResults).toHaveLength(1)
|
|
913
|
+
expect((searchResults[0] as Option).value).toBe('test2')
|
|
914
|
+
})
|
|
915
|
+
|
|
916
|
+
test('empty search term returns all options', () => {
|
|
917
|
+
const store = new Store('single', [
|
|
918
|
+
{
|
|
919
|
+
text: 'test1'
|
|
920
|
+
},
|
|
921
|
+
{
|
|
922
|
+
text: 'test2',
|
|
923
|
+
value: 'test2'
|
|
924
|
+
},
|
|
925
|
+
{
|
|
926
|
+
text: 'test3'
|
|
927
|
+
}
|
|
928
|
+
])
|
|
929
|
+
|
|
930
|
+
const searchFilter = (opt: Option, search: string): boolean => {
|
|
931
|
+
return opt.text.toLowerCase().indexOf(search.toLowerCase()) !== -1
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
// Test empty search term
|
|
935
|
+
const searchResults = store.search('', searchFilter)
|
|
936
|
+
expect(searchResults).toHaveLength(3)
|
|
937
|
+
})
|
|
938
|
+
})
|
|
939
|
+
|
|
940
|
+
describe('filter', () => {
|
|
941
|
+
let store: Store
|
|
942
|
+
|
|
943
|
+
beforeAll(() => {
|
|
944
|
+
store = new Store('single', [
|
|
945
|
+
{
|
|
946
|
+
label: 'group 0',
|
|
947
|
+
options: [
|
|
948
|
+
{
|
|
949
|
+
text: 'opt 0',
|
|
950
|
+
class: 'filter-me'
|
|
951
|
+
},
|
|
952
|
+
{
|
|
953
|
+
text: 'opt 1'
|
|
954
|
+
}
|
|
955
|
+
]
|
|
956
|
+
},
|
|
957
|
+
{
|
|
958
|
+
text: 'opt 2',
|
|
959
|
+
class: 'filter-me'
|
|
960
|
+
}
|
|
961
|
+
])
|
|
962
|
+
})
|
|
963
|
+
|
|
964
|
+
test('empty filter function returns all options (with opt group)', () => {
|
|
965
|
+
const res = store.filter(null, true)
|
|
966
|
+
expect(res).toHaveLength(2)
|
|
967
|
+
expect(res[0]).toBeInstanceOf(Optgroup)
|
|
968
|
+
expect((res[0] as Optgroup).label).toBe('group 0')
|
|
969
|
+
expect((res[0] as Optgroup).options).toHaveLength(2)
|
|
970
|
+
expect(res[1]).toBeInstanceOf(Option)
|
|
971
|
+
})
|
|
972
|
+
|
|
973
|
+
test('empty filter function returns all options without optgroups flattens results', () => {
|
|
974
|
+
const res = store.filter(null, false)
|
|
975
|
+
expect(res).toHaveLength(3)
|
|
976
|
+
expect(res[0]).toBeInstanceOf(Option)
|
|
977
|
+
expect((res[0] as Option).text).toBe('opt 0')
|
|
978
|
+
expect(res[1]).toBeInstanceOf(Option)
|
|
979
|
+
expect((res[1] as Option).text).toBe('opt 1')
|
|
980
|
+
expect(res[2]).toBeInstanceOf(Option)
|
|
981
|
+
expect((res[2] as Option).text).toBe('opt 2')
|
|
982
|
+
})
|
|
983
|
+
|
|
984
|
+
test('filter function filters results accordingly', () => {
|
|
985
|
+
const res = store.filter((o) => o.class === 'filter-me', false)
|
|
986
|
+
expect(res).toHaveLength(2)
|
|
987
|
+
expect(res[0]).toBeInstanceOf(Option)
|
|
988
|
+
expect((res[0] as Option).text).toBe('opt 0')
|
|
989
|
+
expect(res[1]).toBeInstanceOf(Option)
|
|
990
|
+
expect((res[1] as Option).text).toBe('opt 2')
|
|
991
|
+
})
|
|
241
992
|
})
|
|
242
993
|
})
|