Skip to content

Commit 1690ed2

Browse files
authored
feat: add filter method to WrapperArray (#388)
1 parent 92e211c commit 1690ed2

File tree

11 files changed

+60
-2
lines changed

11 files changed

+60
-2
lines changed

docs/en/SUMMARY.md

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
* [contains](api/wrapper-array/contains.md)
5454
* [exists](api/wrapper/exists.md)
5555
* [destroy](api/wrapper-array/destroy.md)
56+
* [filter](api/wrapper-array/filter.md)
5657
* [is](api/wrapper-array/is.md)
5758
* [isEmpty](api/wrapper-array/isEmpty.md)
5859
* [isVueInstance](api/wrapper-array/isVueInstance.md)

docs/en/api/wrapper-array/filter.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# filter(predicate)
2+
3+
Filter `WrapperArray` with a predicate function on `Wrapper` objects.
4+
5+
Behavior of this method is similar to [Array.prototype.filter](https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/Array/filter)
6+
7+
- **Arguments:**
8+
- `{function} predicate`
9+
10+
- **Returns:** `{WrapperArray}`
11+
12+
A new `WrapperArray` instance containing `Wrapper` instances that returns true for the predicate function.
13+
14+
- **Example:**
15+
16+
```js
17+
import { shallow } from 'vue-test-utils'
18+
import { expect } from 'chai'
19+
import Foo from './Foo.vue'
20+
21+
const wrapper = shallow(Foo)
22+
const filteredDivArray = wrapper.findAll('div', (w) => !w.hasClass('filtered'))
23+
```

flow/wrapper.flow.js

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ declare interface BaseWrapper { // eslint-disable-line no-undef
1313
emitted(event?: string): { [name: string]: Array<Array<any>> } | Array<Array<any>> | void,
1414
emittedByOrder(): Array<{ name: string; args: Array<any> }> | void,
1515
exists(): boolean,
16+
filter(predicate: Function): WrapperArray | void,
1617
visible(): boolean | void,
1718
hasAttribute(attribute: string, value: string): boolean | void,
1819
hasClass(className: string): boolean | void,

src/wrappers/error-wrapper.js

+4
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ export default class ErrorWrapper implements BaseWrapper {
3636
return false
3737
}
3838

39+
filter (): void {
40+
throwError(`find did not return ${this.selector}, cannot call filter() on empty Wrapper`)
41+
}
42+
3943
visible (): void {
4044
throwError(`find did not return ${this.selector}, cannot call visible() on empty Wrapper`)
4145
}

src/wrappers/wrapper-array.js

+4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ export default class WrapperArray implements BaseWrapper {
4242
return this.length > 0 && this.wrappers.every(wrapper => wrapper.exists())
4343
}
4444

45+
filter (predicate: Function): WrapperArray {
46+
return new WrapperArray(this.wrappers.filter(predicate))
47+
}
48+
4549
visible (): boolean {
4650
this.throwErrorIfWrappersIsEmpty('visible')
4751

src/wrappers/wrapper.js

+4
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,10 @@ export default class Wrapper implements BaseWrapper {
125125
return true
126126
}
127127

128+
filter () {
129+
throwError('filter() must be called on a WrapperArray')
130+
}
131+
128132
/**
129133
* Utility to check wrapper is visible. Returns false if a parent element has display: none or visibility: hidden style.
130134
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { compileToFunctions } from 'vue-template-compiler'
2+
import { mount } from '~vue-test-utils'
3+
4+
describe('filter', () => {
5+
it('throws an error', () => {
6+
const compiled = compileToFunctions('<div />')
7+
const wrapper = mount(compiled)
8+
const message = '[vue-test-utils]: filter() must be called on a WrapperArray'
9+
const fn = () => wrapper.filter()
10+
expect(fn).to.throw().with.property('message', message)
11+
})
12+
})

test/unit/specs/wrappers/error-wrapper.spec.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { compileToFunctions } from 'vue-template-compiler'
33

44
describe('ErrorWrapper', () => {
55
const methods = ['at', 'attributes', 'classes', 'contains', 'emitted', 'emittedByOrder', 'hasAttribute',
6-
'hasClass', 'hasProp', 'hasStyle', 'find', 'findAll', 'html', 'text', 'is', 'isEmpty', 'isVueInstance',
6+
'hasClass', 'hasProp', 'hasStyle', 'find', 'findAll', 'filter', 'html', 'text', 'is', 'isEmpty', 'isVueInstance',
77
'name', 'props', 'setComputed', 'setMethods', 'setData', 'setProps', 'trigger', 'update', 'destroy']
88
methods.forEach((method) => {
99
it(`${method} throws error when called`, () => {

test/unit/specs/wrappers/wrapper-array.spec.js

+8-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe('WrapperArray', () => {
1414
return wrapperArray
1515
}
1616

17-
it('returns class with length equal to lenght of wrappers passed in constructor', () => {
17+
it('returns class with length equal to length of wrappers passed in constructor', () => {
1818
const wrapperArray = getWrapperArray()
1919
expect(wrapperArray.length).to.equal(3)
2020
})
@@ -24,6 +24,13 @@ describe('WrapperArray', () => {
2424
expect(wrapperArray.at(0).text()).to.equal('1')
2525
})
2626

27+
it('returns filtered wrapper when filter is called', () => {
28+
const wrapperArray = getWrapperArray()
29+
expect(wrapperArray.filter(w => {
30+
return w.text() !== '2'
31+
}).length).to.equal(2)
32+
})
33+
2734
const methods = ['at', 'attributes', 'classes', 'contains', 'emitted', 'emittedByOrder', 'hasAttribute',
2835
'hasClass', 'hasProp', 'hasStyle', 'find', 'findAll', 'html', 'text', 'is', 'isEmpty', 'isVueInstance',
2936
'name', 'props', 'setComputed', 'setMethods', 'setData', 'setProps', 'trigger', 'update', 'destroy']

types/index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ interface WrapperArray<V extends Vue> extends BaseWrapper {
9999
readonly wrappers: Array<Wrapper<V>>
100100

101101
at (index: number): Wrapper<V>
102+
filter (predicate: Function): WrapperArray<Vue>
102103
}
103104

104105
interface WrapperOptions {

types/test/wrapper.ts

+1
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,4 @@ str = wrapper.name()
6767
*/
6868
let num: number = array.length
6969
found = array.at(1)
70+
array = array.filter((a: any) => a === true)

0 commit comments

Comments
 (0)