Skip to content

Commit a249992

Browse files
committed
tests for array filters
1 parent 336d06d commit a249992

File tree

6 files changed

+173
-16
lines changed

6 files changed

+173
-16
lines changed

src/compiler.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ CompilerProto.createBinding = function (key, directive) {
572572
} else {
573573
compiler.defineMeta(key, binding)
574574
}
575-
} else if (computed && computed[key.split('.')[0]]) {
575+
} else if (computed && computed[utils.baseKey(key)]) {
576576
// nested path on computed property
577577
compiler.defineExp(key, binding)
578578
} else {
@@ -725,7 +725,7 @@ CompilerProto.execHook = function (event) {
725725
* Check if a compiler's data contains a keypath
726726
*/
727727
CompilerProto.hasKey = function (key) {
728-
var baseKey = key.split('.')[0]
728+
var baseKey = utils.baseKey(key)
729729
return hasOwn.call(this.data, baseKey) ||
730730
hasOwn.call(this.vm, baseKey)
731731
}

src/filters.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ var filters = module.exports = {
117117

118118
filterBy: function (arr, searchKey, delimiter, dataKey) {
119119

120+
// allow optional `in` delimiter
121+
// because why not
122+
if (delimiter && delimiter !== 'in') {
123+
dataKey = delimiter
124+
}
125+
120126
// get the search string
121127
var search = stripQuotes(searchKey) || get(this, searchKey)
122128
if (!search) return arr
@@ -152,8 +158,8 @@ var filters = module.exports = {
152158

153159
// sort on a copy to avoid mutating original array
154160
return arr.slice().sort(function (a, b) {
155-
a = a[key]
156-
b = b[key]
161+
a = get(a, key)
162+
b = get(b, key)
157163
return a === b ? 0 : a > b ? order : -order
158164
})
159165

src/utils.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ var config = require('./config'),
33
win = window,
44
console = win.console,
55
timeout = win.setTimeout,
6-
THIS_RE = /[^\w]this[\.\[]/,
6+
THIS_RE = /[^\w]this[^\w]/,
77
hasClassList = 'classList' in document.documentElement,
88
ViewModel // late def
99

@@ -43,6 +43,15 @@ var utils = module.exports = {
4343
obj[path[d]] = val
4444
},
4545

46+
/**
47+
* return the base segment of a keypath
48+
*/
49+
baseKey: function (key) {
50+
return key.indexOf('.') > 0
51+
? key.split('.')[0]
52+
: key
53+
},
54+
4655
/**
4756
* Create a prototype-less object
4857
* which is a better hash/map

test/functional/fixtures/array-filters.html

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33

44
<div id="test">
55
Sort by
6-
<select v-model="sortKey">
6+
<select id="sortby" v-model="sortKey">
77
<option>name</option>
88
<option>phone</option>
99
</select>
1010
<br>
11-
<input type="checkbox" v-model="reverse"> Reverse
11+
<input id="reverse" type="checkbox" v-model="reverse"> Reverse
1212
<hr></hr>
13-
Filter by <input v-model="searchText"> in name only
13+
Filter by <input id="search" name="search" v-model="searchText"> in name only
1414
<table id="t1">
1515
<tr><th>Name</th><th>Phone</th></tr>
16-
<tr v-repeat="friends | filterBy searchText in 'name' | orderBy sortKey reverse">
16+
<tr v-repeat="friends | filterBy searchText in 'name' | orderBy sortKey reverse" class="item">
1717
<td>{{name}}</td>
1818
<td>{{phone}}</td>
1919
</tr>
@@ -22,20 +22,21 @@
2222
Filter by input in all fields and reversed
2323
<table id="t2">
2424
<tr><th>Name</th><th>Phone</th></tr>
25-
<tr v-repeat="friends | filterBy searchText | orderBy sortKey !reverse">
25+
<tr v-repeat="friends | filterBy searchText | orderBy sortKey !reverse" class="item">
2626
<td>{{name}}</td>
2727
<td>{{phone}}</td>
2828
</tr>
2929
</table>
3030
<hr></hr>
3131
Filter by "Julie" in
32-
<select v-model="filterKey">
32+
<select id="filterby" v-model="filterKey">
3333
<option>name</option>
3434
<option>phone</option>
3535
</select>
36+
and reversed with literal -1
3637
<table id="t3">
3738
<tr><th>Name</th><th>Phone</th></tr>
38-
<tr v-repeat="friends | filterBy 'Julie' in filterKey | orderBy sortKey -1">
39+
<tr v-repeat="friends | filterBy 'Julie' in filterKey | orderBy sortKey -1" class="item">
3940
<td>{{name}}</td>
4041
<td>{{phone}}</td>
4142
</tr>
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
casper.test.begin('Array Filters', 53, function (test) {
2+
3+
var names = ['Adam', 'John', 'Julie', 'Juliette', 'Mary', 'Mike'],
4+
namesReversed = names.slice().reverse(),
5+
numbers = ['555-1276', '555-4321', '555-5678', '555-5678', '555-8765', '800-BIG-MARY'],
6+
numbersReversed = numbers.slice().reverse(),
7+
julie = ['Juliette', 'Julie'],
8+
julieRevesed = julie.slice().reverse()
9+
10+
casper
11+
.start('./fixtures/array-filters.html')
12+
.then(function () {
13+
// count
14+
test.assertElementCount('#t1 .item', 6)
15+
test.assertElementCount('#t2 .item', 6)
16+
test.assertElementCount('#t3 .item', 2)
17+
18+
assertOrder(names, 1)
19+
assertOrder(namesReversed, 2)
20+
assertOrder(julie, 3)
21+
})
22+
// reverse
23+
.thenClick('#reverse', function () {
24+
assertOrder(namesReversed, 1)
25+
assertOrder(names, 2)
26+
})
27+
// change sort key
28+
.thenEvaluate(function () {
29+
var dropdown = document.getElementById('sortby')
30+
dropdown.selectedIndex = 1
31+
var e = document.createEvent('HTMLEvents')
32+
e.initEvent('change', true, true)
33+
dropdown.dispatchEvent(e)
34+
})
35+
.then(function () {
36+
assertOrder(numbersReversed, 1)
37+
assertOrder(numbers, 2)
38+
assertOrder(julieRevesed, 3)
39+
})
40+
// enter search filter
41+
.then(function () {
42+
this.sendKeys('#search', 'julie')
43+
})
44+
.then(function () {
45+
test.assertElementCount('#t1 .item', 2)
46+
test.assertElementCount('#t2 .item', 2)
47+
test.assertElementCount('#t3 .item', 2)
48+
assertOrder(julieRevesed, 1)
49+
assertOrder(julie, 2)
50+
})
51+
// enter search filter for numbers
52+
.then(function () {
53+
this.sendKeys('#search', '555', { reset: true })
54+
})
55+
.then(function () {
56+
test.assertElementCount('#t1 .item', 0)
57+
test.assertElementCount('#t2 .item', 5)
58+
})
59+
// change filterkey
60+
.thenEvaluate(function () {
61+
var dropdown = document.getElementById('filterby')
62+
dropdown.selectedIndex = 1
63+
var e = document.createEvent('HTMLEvents')
64+
e.initEvent('change', true, true)
65+
dropdown.dispatchEvent(e)
66+
})
67+
.then(function () {
68+
test.assertElementCount('#t3 .item', 0)
69+
})
70+
.run(function () {
71+
test.done()
72+
})
73+
74+
function assertOrder (list, id) {
75+
list.forEach(function (n, i) {
76+
test.assertSelectorHasText('#t' + id + ' .item:nth-child('+ (i+2) + ')', n)
77+
})
78+
}
79+
80+
})

test/unit/specs/filters.js

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,25 +130,86 @@ describe('Filters', function () {
130130

131131
describe('filterBy', function () {
132132

133-
var filter = filters.filterBy
133+
var filter = filters.filterBy,
134+
arr = [
135+
{ a: 1, b: { c: 'hello' }},
136+
{ a: 1, b: 'hello'},
137+
{ a: 1, b: 2 }
138+
],
139+
vm = { search: { key: 'hello', datakey: 'b.c' }}
134140

135141
it('should be computed', function () {
136142
assert.ok(filter.computed)
137143
})
138144

139-
// TODO
145+
it('should recursively check for searchKey if no dataKey is provided', function () {
146+
var res = filter.call(vm, arr, 'search.key')
147+
assert.strictEqual(res.length, 2)
148+
assert.deepEqual(res, arr.slice(0, 2))
149+
})
150+
151+
it('should check for datakey only if provided', function () {
152+
var res = filter.call(vm, arr, 'search.key', 'search.datakey')
153+
assert.strictEqual(res.length, 1)
154+
assert.strictEqual(res[0], arr[0])
155+
})
156+
157+
it('should use literal searchKey if in single quotes', function () {
158+
var res = filter.call(vm, arr, "'hello'", "'b.c'")
159+
assert.strictEqual(res.length, 1)
160+
assert.strictEqual(res[0], arr[0])
161+
})
162+
163+
it('should accept optional delimiter', function () {
164+
var res = filter.call(vm, arr, 'search.key', 'in', 'search.datakey')
165+
assert.strictEqual(res.length, 1)
166+
assert.strictEqual(res[0], arr[0])
167+
})
140168

141169
})
142170

143171
describe('orderBy', function () {
144172

145-
var filter = filters.orderBy
173+
var filter = filters.orderBy,
174+
arr = [
175+
{ a: { b: 0 }, c: 'b'},
176+
{ a: { b: 2 }, c: 'c'},
177+
{ a: { b: 1 }, c: 'a'}
178+
]
146179

147180
it('should be computed', function () {
148181
assert.ok(filter.computed)
149182
})
150183

151-
// TODO
184+
it('should sort based on sortKey', function () {
185+
var vm = { sortby: 'a.b' }
186+
var res = filter.call(vm, arr, 'sortby')
187+
assert.strictEqual(res[0].a.b, 0)
188+
assert.strictEqual(res[1].a.b, 1)
189+
assert.strictEqual(res[2].a.b, 2)
190+
})
191+
192+
it('should sort based on sortKey and reverseKey', function () {
193+
var vm = { sortby: 'a.b', reverse: true }
194+
var res = filter.call(vm, arr, 'sortby', 'reverse')
195+
assert.strictEqual(res[0].a.b, 2)
196+
assert.strictEqual(res[1].a.b, 1)
197+
assert.strictEqual(res[2].a.b, 0)
198+
})
199+
200+
it('should sort with literal args and special -1 syntax', function () {
201+
var res = filter.call({}, arr, "'c'", '-1')
202+
assert.strictEqual(res[0].c, 'c')
203+
assert.strictEqual(res[1].c, 'b')
204+
assert.strictEqual(res[2].c, 'a')
205+
})
206+
207+
it('should accept negate reverse key', function () {
208+
var res = filter.call({ reverse: true }, arr, "'c'", '!reverse')
209+
assert.strictEqual(res[0].c, 'a')
210+
assert.strictEqual(res[1].c, 'b')
211+
assert.strictEqual(res[2].c, 'c')
212+
})
152213

153214
})
154215

0 commit comments

Comments
 (0)