Skip to content

Commit 466055f

Browse files
committed
feat(emitted): add error handling to emitted and emittedByOrder
1 parent 4867519 commit 466055f

File tree

9 files changed

+121
-19
lines changed

9 files changed

+121
-19
lines changed

flow/wrapper.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ declare type Selector = string | Component
88
declare interface BaseWrapper { // eslint-disable-line no-undef
99
at(index: number): Wrapper | void,
1010
contains(selector: Selector): boolean | void,
11+
emitted(): { [name: string]: Array<Array<any>> } | void,
12+
emittedByOrder(): Array<{ name: string; args: Array<any> }> | void,
1113
exists(): boolean,
1214
hasAttribute(attribute: string, value: string): boolean | void,
1315
hasClass(className: string): boolean | void,

src/wrappers/error-wrapper.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ export default class ErrorWrapper implements BaseWrapper {
1616
throwError(`find did not return ${this.selector}, cannot call contains() on empty Wrapper`)
1717
}
1818

19+
emitted (): void {
20+
throwError(`find did not return ${this.selector}, cannot call emitted() on empty Wrapper`)
21+
}
22+
23+
emittedByOrder (): void {
24+
throwError(`find did not return ${this.selector}, cannot call emittedByOrder() on empty Wrapper`)
25+
}
26+
1927
exists (): boolean {
2028
return false
2129
}

src/wrappers/vue-wrapper.js

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,6 @@ function update () {
88
}
99

1010
export default class VueWrapper extends Wrapper implements BaseWrapper {
11-
_emitted: { [name: string]: Array<Array<any>> };
12-
_emittedByOrder: Array<{ name: string; args: Array<any> }>;
13-
1411
constructor (vm: Component, options: WrapperOptions) {
1512
super(vm._vnode, update.bind(vm), options)
1613

@@ -27,12 +24,4 @@ export default class VueWrapper extends Wrapper implements BaseWrapper {
2724

2825
logEvents(vm, this._emitted, this._emittedByOrder)
2926
}
30-
31-
emitted () {
32-
return this._emitted
33-
}
34-
35-
emittedByOrder () {
36-
return this._emittedByOrder
37-
}
3827
}

src/wrappers/wrapper-array.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,22 @@ export default class WrapperArray implements BaseWrapper {
2525

2626
return this.wrappers.every(wrapper => wrapper.contains(selector))
2727
}
28-
2928
exists (): boolean {
3029
return this.wrappers.length > 0
3130
}
3231

32+
emitted (): void {
33+
this.throwErrorIfWrappersIsEmpty('emitted')
34+
35+
throwError('emitted must be called on a single wrapper, use at(i) to access a wrapper')
36+
}
37+
38+
emittedByOrder (): void {
39+
this.throwErrorIfWrappersIsEmpty('emittedByOrder')
40+
41+
throwError('emittedByOrder must be called on a single wrapper, use at(i) to access a wrapper')
42+
}
43+
3344
hasAttribute (attribute: string, value: string): boolean {
3445
this.throwErrorIfWrappersIsEmpty('hasAttribute')
3546

src/wrappers/wrapper.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import { throwError } from '../lib/util'
1111
export default class Wrapper implements BaseWrapper {
1212
vnode: VNode;
1313
vm: Component | null;
14+
_emitted: { [name: string]: Array<Array<any>> };
15+
_emittedByOrder: Array<{ name: string; args: Array<any> }>;
1416
isVueComponent: boolean;
1517
element: HTMLElement;
1618
update: Function;
@@ -47,6 +49,26 @@ export default class Wrapper implements BaseWrapper {
4749
return false
4850
}
4951

52+
/**
53+
* Returns an object containing custom events emitted by the Wrapper vm
54+
*/
55+
emitted () {
56+
if (!this._emitted && !this.vm) {
57+
throwError('wrapper.emitted() can only be called on a Vue instance')
58+
}
59+
return this._emitted
60+
}
61+
62+
/**
63+
* Returns an Array containing custom events emitted by the Wrapper vm
64+
*/
65+
emittedByOrder () {
66+
if (!this._emittedByOrder && !this.vm) {
67+
throwError('wrapper.emittedByOrder() can only be called on a Vue instance')
68+
}
69+
return this._emittedByOrder
70+
}
71+
5072
/**
5173
* Utility to check wrapper exists. Returns true as Wrapper always exists
5274
*/

test/unit/specs/mount/Wrapper/emitted.spec.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@ describe('emitted', () => {
2121
expect(wrapper.emitted().foo).to.exist
2222
expect(wrapper.emitted().foo.length).to.equal(2)
2323
expect(wrapper.emitted().foo[1]).to.eql([2, 3, 4])
24+
})
25+
26+
it('throws error when called on non VueWrapper', () => {
27+
const wrapper = mount({
28+
template: '<div><p /></div>'
29+
})
30+
const message = '[vue-test-utils]: wrapper.emitted() can only be called on a Vue instance'
2431

25-
expect(wrapper.emittedByOrder()).to.eql([
26-
{ name: 'foo', args: [] },
27-
{ name: 'bar', args: [1, 2, 3] },
28-
{ name: 'foo', args: [2, 3, 4] }
29-
])
32+
const fn = () => wrapper.find('p').emitted()
33+
expect(fn).to.throw().with.property('message', message)
3034
})
3135
})
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import mount from '~src/mount'
2+
3+
describe('emittedByOrder', () => {
4+
it('captures emitted events in order', () => {
5+
const wrapper = mount({
6+
render: h => h('div')
7+
})
8+
9+
wrapper.vm.$emit('foo')
10+
wrapper.vm.$emit('bar', 1, 2, 3)
11+
wrapper.vm.$emit('foo', 2, 3, 4)
12+
expect(wrapper.emittedByOrder()).to.eql([
13+
{ name: 'foo', args: [] },
14+
{ name: 'bar', args: [1, 2, 3] },
15+
{ name: 'foo', args: [2, 3, 4] }
16+
])
17+
})
18+
19+
it('throws error when called on non VueWrapper', () => {
20+
const wrapper = mount({
21+
template: '<div><p /></div>'
22+
})
23+
const message = '[vue-test-utils]: wrapper.emittedByOrder() can only be called on a Vue instance'
24+
25+
const fn = () => wrapper.find('p').emittedByOrder()
26+
expect(fn).to.throw().with.property('message', message)
27+
})
28+
})

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,20 @@ describe('ErrorWrapper', () => {
1515
expect(() => error.contains()).to.throw().with.property('message', message)
1616
})
1717

18+
it('emitted throws error when called', () => {
19+
const selector = 'div'
20+
const message = `[vue-test-utils]: find did not return ${selector}, cannot call emitted() on empty Wrapper`
21+
const error = new ErrorWrapper(selector)
22+
expect(() => error.emitted()).to.throw().with.property('message', message)
23+
})
24+
25+
it('emittedByOrder throws error when called', () => {
26+
const selector = 'div'
27+
const message = `[vue-test-utils]: find did not return ${selector}, cannot call emittedByOrder() on empty Wrapper`
28+
const error = new ErrorWrapper(selector)
29+
expect(() => error.emittedByOrder()).to.throw().with.property('message', message)
30+
})
31+
1832
it('hasAttribute throws error when called', () => {
1933
const selector = 'div'
2034
const message = `[vue-test-utils]: find did not return ${selector}, cannot call hasAttribute() on empty Wrapper`

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

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,37 @@ describe('WrapperArray', () => {
2323
expect(() => wrapperArray.find()).to.throw().with.property('message', message)
2424
})
2525

26-
it('findAll throws error if wrapper is not empty', () => {
26+
it('emitted throws error if wrapper is not empty', () => {
27+
const wrapperArray = new WrapperArray([])
28+
const message = '[vue-test-utils]: emitted cannot be called on 0 items'
29+
expect(() => wrapperArray.emitted()).to.throw().with.property('message', message)
30+
})
31+
32+
it('emitted throws error if wrapper is empty', () => {
33+
const wrapperArray = new WrapperArray([1, 2, 3])
34+
const message = '[vue-test-utils]: emitted must be called on a single wrapper, use at(i) to access a wrapper'
35+
expect(() => wrapperArray.emitted()).to.throw().with.property('message', message)
36+
})
37+
38+
it('emittedByOrder throws error if wrapper is not empty', () => {
39+
const wrapperArray = new WrapperArray([])
40+
const message = '[vue-test-utils]: emittedByOrder cannot be called on 0 items'
41+
expect(() => wrapperArray.emittedByOrder()).to.throw().with.property('message', message)
42+
})
43+
44+
it('emittedByOrder throws error if wrapper is empty', () => {
45+
const wrapperArray = new WrapperArray([1, 2, 3])
46+
const message = '[vue-test-utils]: emittedByOrder must be called on a single wrapper, use at(i) to access a wrapper'
47+
expect(() => wrapperArray.emittedByOrder()).to.throw().with.property('message', message)
48+
})
49+
50+
it('findAll throws error if wrapper is empty', () => {
2751
const wrapperArray = new WrapperArray([])
2852
const message = '[vue-test-utils]: findAll cannot be called on 0 items'
2953
expect(() => wrapperArray.findAll()).to.throw().with.property('message', message)
3054
})
3155

32-
it('findAll throws error if wrapper is empty', () => {
56+
it('findAll throws error if wrapper is not empty', () => {
3357
const wrapperArray = new WrapperArray([1, 2, 3])
3458
const message = '[vue-test-utils]: findAll must be called on a single wrapper, use at(i) to access a wrapper'
3559
expect(() => wrapperArray.findAll()).to.throw().with.property('message', message)

0 commit comments

Comments
 (0)