Skip to content

Commit 9206c54

Browse files
authored
Merge pull request #41 from marmelab/add_array_support
[RFR] Add support for array in filters
2 parents 80ca4d6 + 8dd5d71 commit 9206c54

File tree

3 files changed

+203
-51
lines changed

3 files changed

+203
-51
lines changed

src/resolver/Query/all.spec.js

Lines changed: 0 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -85,46 +85,3 @@ describe('sort', () => {
8585
]);
8686
});
8787
});
88-
89-
describe('filter', () => {
90-
test('filters by string on all text fields using the q filter', () =>
91-
expect(all(data)(null, { filter: { q: 'Lorem' } })).toEqual([
92-
{ id: 1, title: 'Lorem Ipsum', user_id: 123, views: 254 },
93-
]));
94-
test('filters by string using the q filter in a case-insensitive way', () =>
95-
expect(all(data)(null, { filter: { q: 'lorem' } })).toEqual([
96-
{ id: 1, title: 'Lorem Ipsum', user_id: 123, views: 254 },
97-
]));
98-
test('filters by value on each field using the related filter', () => {
99-
expect(all(data)(null, { filter: { id: 2 } })).toEqual([
100-
{ id: 2, title: 'Ut enim ad minim', user_id: 456, views: 65 },
101-
]);
102-
expect(
103-
all(data)(null, { filter: { title: 'Sic Dolor amet' } })
104-
).toEqual([
105-
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76 },
106-
]);
107-
expect(all(data)(null, { filter: { views: 65 } })).toEqual([
108-
{ id: 2, title: 'Ut enim ad minim', user_id: 456, views: 65 },
109-
]);
110-
expect(all(data)(null, { filter: { user_id: 456 } })).toEqual([
111-
{ id: 2, title: 'Ut enim ad minim', user_id: 456, views: 65 },
112-
]);
113-
});
114-
test('filters by value range on each integer field using the related filters', () => {
115-
expect(all(data)(null, { filter: { views_lt: 76 } })).toEqual([
116-
{ id: 2, title: 'Ut enim ad minim', user_id: 456, views: 65 },
117-
]);
118-
expect(all(data)(null, { filter: { views_lte: 76 } })).toEqual([
119-
{ id: 2, title: 'Ut enim ad minim', user_id: 456, views: 65 },
120-
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76 },
121-
]);
122-
expect(all(data)(null, { filter: { views_gt: 76 } })).toEqual([
123-
{ id: 1, title: 'Lorem Ipsum', user_id: 123, views: 254 },
124-
]);
125-
expect(all(data)(null, { filter: { views_gte: 76 } })).toEqual([
126-
{ id: 1, title: 'Lorem Ipsum', user_id: 123, views: 254 },
127-
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76 },
128-
]);
129-
});
130-
});

src/resolver/Query/applyFilters.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
export default (entityData, filter = {}) => {
1+
export default (entityData = [], filter = {}) => {
22
let items = [...entityData];
33

44
if (filter.ids) {
5-
items = items.filter(d => filter.ids.includes(d.id.toString()));
5+
items = items.filter(d => filter.ids.some(id => id == d.id));
66
} else {
77
Object.keys(filter).filter(key => key !== 'q').forEach(key => {
88
if (key.indexOf('_lte') !== -1) {
@@ -30,12 +30,25 @@ export default (entityData, filter = {}) => {
3030
return;
3131
}
3232

33-
items = items.filter(
34-
d =>
35-
filter[key] instanceof Date
36-
? +d[key] == +filter[key]
37-
: d[key] == filter[key]
38-
);
33+
if (Array.isArray(filter[key])) {
34+
items = items.filter(item => {
35+
if (Array.isArray(item[key])) {
36+
// array filter and array item value: where all items in values
37+
return filter[key].every(v =>
38+
item[key].some(itemValue => itemValue == v)
39+
);
40+
}
41+
// where item in values
42+
return filter[key].filter(v => v == item[key]).length > 0;
43+
});
44+
} else {
45+
items = items.filter(
46+
d =>
47+
filter[key] instanceof Date
48+
? +d[key] == +filter[key]
49+
: d[key] == filter[key]
50+
);
51+
}
3952
});
4053

4154
if (filter.q) {
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
import applyFilters from './applyFilters';
2+
3+
const data = [
4+
{
5+
id: 1,
6+
title: 'Lorem Ipsum',
7+
user_id: 123,
8+
views: 254,
9+
tags: ['foo', 'bar'],
10+
},
11+
{
12+
id: 2,
13+
title: 'Ut enim ad minim',
14+
user_id: 456,
15+
views: 65,
16+
tags: ['foo'],
17+
},
18+
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76, tags: [] },
19+
];
20+
21+
test('returns empty array on empty datastore', () =>
22+
expect(applyFilters(undefined, {})).toEqual([]));
23+
24+
test('returns all entities by default', () =>
25+
expect(applyFilters(data, {})).toEqual([
26+
{
27+
id: 1,
28+
title: 'Lorem Ipsum',
29+
user_id: 123,
30+
views: 254,
31+
tags: ['foo', 'bar'],
32+
},
33+
{
34+
id: 2,
35+
title: 'Ut enim ad minim',
36+
user_id: 456,
37+
views: 65,
38+
tags: ['foo'],
39+
},
40+
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76, tags: [] },
41+
]));
42+
43+
test('filters by string on all text fields using the q filter', () =>
44+
expect(applyFilters(data, { q: 'Lorem' })).toEqual([
45+
{
46+
id: 1,
47+
title: 'Lorem Ipsum',
48+
user_id: 123,
49+
views: 254,
50+
tags: ['foo', 'bar'],
51+
},
52+
]));
53+
54+
test('filters by string using the q filter in a case-insensitive way', () =>
55+
expect(applyFilters(data, { q: 'lorem' })).toEqual([
56+
{
57+
id: 1,
58+
title: 'Lorem Ipsum',
59+
user_id: 123,
60+
views: 254,
61+
tags: ['foo', 'bar'],
62+
},
63+
]));
64+
65+
test('filters by value on each field using the related filter', () => {
66+
expect(applyFilters(data, { id: 2 })).toEqual([
67+
{
68+
id: 2,
69+
title: 'Ut enim ad minim',
70+
user_id: 456,
71+
views: 65,
72+
tags: ['foo'],
73+
},
74+
]);
75+
expect(applyFilters(data, { title: 'Sic Dolor amet' })).toEqual([
76+
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76, tags: [] },
77+
]);
78+
expect(applyFilters(data, { views: 65 })).toEqual([
79+
{
80+
id: 2,
81+
title: 'Ut enim ad minim',
82+
user_id: 456,
83+
views: 65,
84+
tags: ['foo'],
85+
},
86+
]);
87+
expect(applyFilters(data, { user_id: 456 })).toEqual([
88+
{
89+
id: 2,
90+
title: 'Ut enim ad minim',
91+
user_id: 456,
92+
views: 65,
93+
tags: ['foo'],
94+
},
95+
]);
96+
});
97+
98+
test('filters by value range on each integer field using the related filters', () => {
99+
expect(applyFilters(data, { views_lt: 76 })).toEqual([
100+
{
101+
id: 2,
102+
title: 'Ut enim ad minim',
103+
user_id: 456,
104+
views: 65,
105+
tags: ['foo'],
106+
},
107+
]);
108+
expect(applyFilters(data, { views_lte: 76 })).toEqual([
109+
{
110+
id: 2,
111+
title: 'Ut enim ad minim',
112+
user_id: 456,
113+
views: 65,
114+
tags: ['foo'],
115+
},
116+
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76, tags: [] },
117+
]);
118+
expect(applyFilters(data, { views_gt: 76 })).toEqual([
119+
{
120+
id: 1,
121+
title: 'Lorem Ipsum',
122+
user_id: 123,
123+
views: 254,
124+
tags: ['foo', 'bar'],
125+
},
126+
]);
127+
expect(applyFilters(data, { views_gte: 76 })).toEqual([
128+
{
129+
id: 1,
130+
title: 'Lorem Ipsum',
131+
user_id: 123,
132+
views: 254,
133+
tags: ['foo', 'bar'],
134+
},
135+
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76, tags: [] },
136+
]);
137+
});
138+
139+
test('should filter by id if filter contains an ids key', () => {
140+
expect(applyFilters(data, { ids: [2, 3] })).toEqual([
141+
{
142+
id: 2,
143+
title: 'Ut enim ad minim',
144+
user_id: 456,
145+
views: 65,
146+
tags: ['foo'],
147+
},
148+
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76, tags: [] },
149+
]);
150+
});
151+
152+
test('should filter by value if filter contains an array for the key', () => {
153+
expect(
154+
applyFilters(data, { title: ['Ut enim ad minim', 'Sic Dolor amet'] })
155+
).toEqual([
156+
{
157+
id: 2,
158+
title: 'Ut enim ad minim',
159+
user_id: 456,
160+
views: 65,
161+
tags: ['foo'],
162+
},
163+
{ id: 3, title: 'Sic Dolor amet', user_id: 123, views: 76, tags: [] },
164+
]);
165+
166+
expect(applyFilters(data, { tags: ['foo'] })).toEqual([
167+
{
168+
id: 1,
169+
title: 'Lorem Ipsum',
170+
user_id: 123,
171+
views: 254,
172+
tags: ['foo', 'bar'],
173+
},
174+
{
175+
id: 2,
176+
title: 'Ut enim ad minim',
177+
user_id: 456,
178+
views: 65,
179+
tags: ['foo'],
180+
},
181+
]);
182+
});

0 commit comments

Comments
 (0)