Skip to content

Commit 175e0a0

Browse files
committed
fix: use semver to get correct event
1 parent cae60ba commit 175e0a0

File tree

10 files changed

+88
-48
lines changed

10 files changed

+88
-48
lines changed

flow/modules.flow.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ declare module 'vue-server-renderer' {
2323
declare module 'cheerio' {
2424
declare module.exports: any;
2525
}
26+
27+
declare module 'semver' {
28+
declare module.exports: any;
29+
}

packages/create-instance/create-instance.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import { createSlotVNodes } from './create-slot-vnodes'
44
import addMocks from './add-mocks'
55
import { addEventLogger } from './log-events'
66
import { addStubs } from './add-stubs'
7-
import { throwError, vueVersion } from 'shared/util'
7+
import { throwError } from 'shared/util'
8+
import { VUE_VERSION } from 'shared/consts'
89
import {
910
compileTemplate,
1011
compileTemplateForSlots
@@ -42,7 +43,7 @@ export default function createInstance (
4243
_Vue.options._base = _Vue
4344

4445
if (
45-
vueVersion < 2.3 &&
46+
VUE_VERSION < 2.3 &&
4647
typeof component === 'function' &&
4748
component.options
4849
) {
@@ -110,7 +111,7 @@ export default function createInstance (
110111
if (
111112
options.provide &&
112113
typeof options.provide === 'object' &&
113-
vueVersion < 2.5
114+
VUE_VERSION < 2.5
114115
) {
115116
const obj = { ...options.provide }
116117
options.provide = () => obj

packages/create-instance/create-scoped-slots.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// @flow
22

33
import { compileToFunctions } from 'vue-template-compiler'
4-
import { throwError, vueVersion } from 'shared/util'
4+
import { throwError } from 'shared/util'
5+
import { VUE_VERSION } from 'shared/consts'
56

67
function isDestructuringSlotScope (slotScope: string): boolean {
78
return slotScope[0] === '{' && slotScope[slotScope.length - 1] === '}'
@@ -39,7 +40,7 @@ function getVueTemplateCompilerHelpers (
3940
}
4041

4142
function validateEnvironment (): void {
42-
if (vueVersion < 2.1) {
43+
if (VUE_VERSION < 2.1) {
4344
throwError(`the scopedSlots option is only supported in [email protected]+.`)
4445
}
4546
}

packages/create-instance/patch-render.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
11
import { createStubFromComponent } from './create-component-stubs'
2-
import { resolveComponent, semVerGreaterThan } from 'shared/util'
2+
import { resolveComponent } from 'shared/util'
33
import { isReservedTag } from 'shared/validators'
4-
import Vue from 'vue'
5-
import { BEFORE_RENDER_LIFECYCLE_HOOK } from 'shared/consts'
4+
import {
5+
BEFORE_RENDER_LIFECYCLE_HOOK,
6+
CREATE_ELEMENT_ALIAS
7+
} from 'shared/consts'
68

79
const isWhitelisted = (el, whitelist) => resolveComponent(el, whitelist)
810
const isAlreadyStubbed = (el, stubs) => stubs.has(el)
911
const isDynamicComponent = cmp => typeof cmp === 'function' && !cmp.cid
1012

11-
const CREATE_ELEMENT_ALIAS = semVerGreaterThan(Vue.version, '2.1.5')
12-
? '_c'
13-
: '_h'
14-
1513
function shouldExtend (component, _Vue) {
1614
return (
1715
(typeof component === 'function' && !isDynamicComponent(component)) ||

packages/shared/consts.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
11
import Vue from 'vue'
2-
import { semVerGreaterThan } from './util'
2+
import semver from 'semver'
33

44
export const NAME_SELECTOR = 'NAME_SELECTOR'
55
export const COMPONENT_SELECTOR = 'COMPONENT_SELECTOR'
66
export const REF_SELECTOR = 'REF_SELECTOR'
77
export const DOM_SELECTOR = 'DOM_SELECTOR'
88
export const INVALID_SELECTOR = 'INVALID_SELECTOR'
9+
910
export const VUE_VERSION = Number(
1011
`${Vue.version.split('.')[0]}.${Vue.version.split('.')[1]}`
1112
)
13+
1214
export const FUNCTIONAL_OPTIONS =
1315
VUE_VERSION >= 2.5 ? 'fnOptions' : 'functionalOptions'
1416

1517
export const BEFORE_RENDER_LIFECYCLE_HOOK =
16-
semVerGreaterThan(Vue.version, '2.1.8')
18+
semver.gt(Vue.version, '2.1.8')
1719
? 'beforeCreate'
1820
: 'beforeMount'
21+
22+
export const CREATE_ELEMENT_ALIAS = semver.gt(Vue.version, '2.1.5')
23+
? '_c'
24+
: '_h'

packages/shared/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
"name": "shared",
33
"version": "1.0.0-beta.27",
44
"private": true,
5+
"dependencies": {
6+
"semver": "^5.6.0"
7+
},
58
"peerDependencies": {
69
"vue": "2.x",
710
"vue-template-compiler": "^2.x"

packages/shared/util.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// @flow
22
import Vue from 'vue'
3+
import semver from 'semver'
34

45
export function throwError (msg: string): void {
56
throw new Error(`[vue-test-utils]: ${msg}`)
@@ -31,10 +32,6 @@ const hyphenateRE = /\B([A-Z])/g
3132
export const hyphenate = (str: string): string =>
3233
str.replace(hyphenateRE, '-$1').toLowerCase()
3334

34-
export const vueVersion = Number(
35-
`${Vue.version.split('.')[0]}.${Vue.version.split('.')[1]}`
36-
)
37-
3835
function hasOwnProperty (obj, prop) {
3936
return Object.prototype.hasOwnProperty.call(obj, prop)
4037
}
@@ -59,16 +56,30 @@ export function resolveComponent (id: string, components: Object) {
5956
return components[id] || components[camelizedId] || components[PascalCaseId]
6057
}
6158

62-
export function semVerGreaterThan (a: string, b: string) {
63-
const pa = a.split('.')
64-
const pb = b.split('.')
65-
for (let i = 0; i < 3; i++) {
66-
var na = Number(pa[i])
67-
var nb = Number(pb[i])
68-
if (na > nb) return true
69-
if (nb > na) return false
70-
if (!isNaN(na) && isNaN(nb)) return true
71-
if (isNaN(na) && !isNaN(nb)) return false
59+
const UA = typeof window !== 'undefined' &&
60+
'navigator' in window &&
61+
navigator.userAgent.toLowerCase()
62+
63+
export const isPhantomJS = UA && UA.includes &&
64+
UA.match(/phantomjs/i)
65+
66+
export const isEdge = UA && UA.indexOf('edge/') > 0
67+
export const isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge
68+
69+
export function getCheckedEvent () {
70+
const version = Vue.version
71+
72+
if (semver.satisfies(version, '2.0 - 2.1.8')) {
73+
return 'change'
7274
}
73-
return false
75+
76+
if (semver.satisfies(version, '2.1.9 - 2.1.10')) {
77+
return 'click'
78+
}
79+
80+
if (semver.satisfies(version, '2.2 - 2.4')) {
81+
return isChrome ? 'click' : 'change'
82+
}
83+
84+
return 'change'
7485
}

packages/test-utils/src/find.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ import findDOMNodes from './find-dom-nodes'
44
import {
55
DOM_SELECTOR,
66
REF_SELECTOR,
7-
COMPONENT_SELECTOR
7+
COMPONENT_SELECTOR,
8+
VUE_VERSION
89
} from 'shared/consts'
9-
import { throwError, vueVersion } from 'shared/util'
10+
import { throwError } from 'shared/util'
1011
import { matches } from './matches'
1112

1213
export function findAllInstances (rootVm: any) {
@@ -74,7 +75,7 @@ export default function find (
7475
(selector.value.options &&
7576
selector.value.options.functional)
7677
) &&
77-
vueVersion < 2.3
78+
VUE_VERSION < 2.3
7879
) {
7980
throwError(
8081
`find for functional components is not supported ` +

packages/test-utils/src/wrapper.js

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,18 @@ import Vue from 'vue'
44
import getSelector from './get-selector'
55
import {
66
REF_SELECTOR,
7-
FUNCTIONAL_OPTIONS
7+
FUNCTIONAL_OPTIONS,
8+
VUE_VERSION
89
} from 'shared/consts'
910
import config from './config'
1011
import WrapperArray from './wrapper-array'
1112
import ErrorWrapper from './error-wrapper'
12-
import { throwError, warn, vueVersion } from 'shared/util'
13+
import {
14+
throwError,
15+
warn,
16+
getCheckedEvent,
17+
isPhantomJS
18+
} from 'shared/util'
1319
import find from './find'
1420
import createWrapper from './create-wrapper'
1521
import { orderWatchers } from './order-watchers'
@@ -487,29 +493,34 @@ export default class Wrapper implements BaseWrapper {
487493
const tagName = this.element.tagName
488494
// $FlowIgnore
489495
const type = this.attributes().type
496+
const event = getCheckedEvent()
490497

491498
if (tagName === 'INPUT' && type === 'checkbox') {
492-
// $FlowIgnore
493-
this.element.checked = checked
494-
this.trigger('change')
499+
if (this.element.checked === checked) {
500+
return
501+
}
502+
if (event !== 'click' || isPhantomJS) {
503+
// $FlowIgnore
504+
this.element.checked = checked
505+
}
506+
this.trigger(event)
495507
return
496508
}
497509

498510
if (tagName === 'INPUT' && type === 'radio') {
499511
if (!checked) {
500512
throwError(
501513
`wrapper.setChecked() cannot be called with ` +
502-
`parameter false on a <input type="radio" /> ` +
503-
`element.`
514+
`parameter false on a <input type="radio" /> ` +
515+
`element.`
504516
)
505-
} else {
517+
}
518+
519+
if (event !== 'click' || isPhantomJS) {
506520
// $FlowIgnore
507-
if (!this.element.checked) {
508-
// $FlowIgnore
509-
this.element.checked = true
510-
this.trigger('change')
511-
}
521+
this.element.selected = true
512522
}
523+
this.trigger(event)
513524
return
514525
}
515526

@@ -568,7 +579,7 @@ export default class Wrapper implements BaseWrapper {
568579
)
569580

570581
Object.keys(computed).forEach(key => {
571-
if (vueVersion > 2.1) {
582+
if (VUE_VERSION > 2.1) {
572583
// $FlowIgnore : Problem with possibly null this.vm
573584
if (!this.vm._computedWatchers[key]) {
574585
throwError(
@@ -704,7 +715,7 @@ export default class Wrapper implements BaseWrapper {
704715
!this.vm.$options._propKeys ||
705716
!this.vm.$options._propKeys.some(prop => prop === key)
706717
) {
707-
if (vueVersion > 2.3) {
718+
if (VUE_VERSION > 2.3) {
708719
// $FlowIgnore : Problem with possibly null this.vm
709720
this.vm.$attrs[key] = data[key]
710721
return
@@ -766,7 +777,6 @@ export default class Wrapper implements BaseWrapper {
766777
tagName === 'TEXTAREA' ||
767778
tagName === 'SELECT'
768779
) {
769-
// $FlowIgnore
770780
const event = tagName === 'SELECT' ? 'change' : 'input'
771781
// $FlowIgnore
772782
this.element.value = value

yarn.lock

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8592,6 +8592,11 @@ semver-diff@^2.0.0:
85928592
version "5.5.0"
85938593
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
85948594

8595+
semver@^5.6.0:
8596+
version "5.6.0"
8597+
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
8598+
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==
8599+
85958600
semver@~4.3.3:
85968601
version "4.3.6"
85978602
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"

0 commit comments

Comments
 (0)