Skip to content

Commit 96b0b67

Browse files
author
Jess
committed
(fix) use custom keyCodes or codes when provided to trigger options
1 parent a05b499 commit 96b0b67

File tree

2 files changed

+76
-6
lines changed

2 files changed

+76
-6
lines changed

Diff for: packages/test-utils/src/create-dom-event.js

+35-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import eventTypes from 'dom-event-types'
2+
import { throwError } from 'shared/util'
23

34
const defaultEventType = {
45
eventInterface: 'Event',
@@ -24,6 +25,37 @@ const modifiers = {
2425
pagedown: 34
2526
}
2627

28+
/**
29+
* Fixing a bug where we listen to what keyCode the user passes in.
30+
* Previously the modifier's keyCode would win, or we would return "0"
31+
* This puts us at risk to break users' tests, so we should detect and notify them.
32+
* */
33+
function onModifierAndKeyCodeMismatch(type, modifier, finalKeyCode) {
34+
if (!modifier || !finalKeyCode) { return } // can't mismatch if nothing is passed in
35+
const fromModifiers = modifiers[modifier]
36+
const keysAreDifferent = fromModifiers != finalKeyCode // this will be true if the user is using modifiers and mismatched keyCodes. Coerce.
37+
if (fromModifiers && finalKeyCode && keysAreDifferent) {
38+
throwError(`wrapper.trigger('${type}.${modifier}') was called ` +
39+
`with options.code (or keyCode) of ${finalKeyCode}. ` +
40+
`This does not match the modifier's code (${fromModifiers}). ` +
41+
`Unable to decide which code to trigger. Please disambiguate.`)
42+
}
43+
}
44+
45+
function sanitizeOptions(type, modifier, { bubbles, cancelable }, options) {
46+
const keyCode = options.code || options.keyCode || modifiers[modifier]
47+
onModifierAndKeyCodeMismatch(type, modifier, keyCode)
48+
49+
const derivedOptions = { keyCode, code: keyCode }
50+
51+
return {
52+
bubbles,
53+
cancelable,
54+
...options, // What the user passed in as the second argument to #trigger
55+
...derivedOptions // Computed values, not necessarily the raw values that the user passed in
56+
}
57+
}
58+
2759
function createEvent(
2860
type,
2961
modifier,
@@ -35,14 +67,11 @@ function createEvent(
3567
? window[eventInterface]
3668
: window.Event
3769

38-
const event = new SupportedEventInterface(type, {
70+
const event = new SupportedEventInterface(type,
3971
// event properties can only be added when the event is instantiated
4072
// custom properties must be added after the event has been instantiated
41-
...options,
42-
bubbles,
43-
cancelable,
44-
keyCode: modifiers[modifier]
45-
})
73+
sanitizeOptions(type, modifier, { bubbles, cancelable }, options)
74+
)
4675

4776
return event
4877
}

Diff for: test/specs/wrapper/trigger.spec.js

+41
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,47 @@ describeWithShallowAndMount('trigger', mountingMethod => {
3737
expect(keydownHandler.calledOnce).to.equal(true)
3838
})
3939

40+
it('causes keydown handler to fire with the appropriate keyCode when wrapper.trigger("keydown", { keyCode: 65 }) is fired on a Component', () => {
41+
const keydownHandler = sandbox.stub()
42+
const wrapper = mountingMethod(ComponentWithEvents, {
43+
propsData: { keydownHandler }
44+
})
45+
wrapper.find('.keydown').trigger('keydown', { keyCode: 65 })
46+
47+
const keyboardEvent = keydownHandler.getCall(0).args[0]
48+
49+
// Unfortunately, JSDom will give different types than PhantomJS for the keyCodes.
50+
// parseInt to normalize. I can't find a matcher here https://www.chaijs.com/api/bdd/
51+
// that relies on (`==`) instead of strict equals (`===`)
52+
expect(parseInt(keyboardEvent.keyCode, 10)).to.equal(65)
53+
expect(parseInt(keyboardEvent.code, 10)).to.equal(65)
54+
})
55+
56+
it('causes keydown handler to throw a sensible error when a modifier does not match the keyCode option', () => {
57+
const keyCode = 404
58+
const keyCodeFromModifiers = 13
59+
const type = 'keydown'
60+
const modifier = 'enter'
61+
62+
const message =
63+
`[vue-test-utils]: wrapper.trigger('${type}.${modifier}') was called ` +
64+
`with options.code (or keyCode) of ${keyCode}. ` +
65+
`This does not match the modifier's code (${keyCodeFromModifiers}). ` +
66+
`Unable to decide which code to trigger. Please disambiguate.`
67+
68+
const keydownHandler = sandbox.stub()
69+
const wrapper = mountingMethod(ComponentWithEvents, {
70+
propsData: { keydownHandler }
71+
})
72+
73+
const fn = () =>
74+
wrapper.find('.keydown').trigger(`${type}.${modifier}`, { keyCode })
75+
76+
expect(fn)
77+
.to.throw()
78+
.with.property('message', message)
79+
})
80+
4081
it('causes keydown handler to fire when wrapper.trigger("keydown.enter") is fired on a Component', () => {
4182
const keydownHandler = sandbox.stub()
4283
const wrapper = mountingMethod(ComponentWithEvents, {

0 commit comments

Comments
 (0)