Skip to content

Commit 38f9e94

Browse files
author
sunecosuri
committed
Merge branch 'dev' of git://github.com/vuejs/vue-test-utils into translate-ja
2 parents ac3acc6 + 954c3c3 commit 38f9e94

File tree

106 files changed

+12529
-7911
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+12529
-7911
lines changed

.babelrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"presets": ["es2015", "stage-2", "flow-vue"],
2+
"presets": ["env", "stage-2", "flow-vue"],
33
"comments": false,
44
"env": {
55
"test": {

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,6 @@ dist
1919
# Docs
2020
_book
2121
.tmp
22-
tmp*
22+
tmp*
23+
24+
yarn.lock

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
# vue-test-utils
22

3-
## Currently not published on npm
4-
To use vue-test-utils pre-release:
3+
## Currently in beta
4+
To use vue-test-utils beta:
55
```
6-
npm install --save-dev https://github.com/vuejs/vue-test-utils/
6+
// npm
7+
npm install --save-dev vue-test-utils@1.0.0-beta.1
8+
9+
// yarn
10+
yarn add --dev vue-test-utils@1.0.0-beta.1
711
```
812

913
## Intro
@@ -12,13 +16,14 @@ npm install --save-dev https://github.com/vuejs/vue-test-utils/
1216

1317
## Documentation
1418

15-
Refer to [documentation](https://vuejs.github.io/vue-test-utils/)
19+
Refer to [documentation](https://vue-test-utils.vuejs.org/)
1620

1721
## Examples
1822

1923
- [example with Jest](https://github.com/eddyerburgh/vue-test-utils-jest-example)
20-
- [example with AVA](https://github.com/eddyerburgh/vue-test-utils-ava-example)
24+
- [example with Mocha](https://github.com/eddyerburgh/vue-test-utils-mocha-example)
2125
- [example with tape](https://github.com/eddyerburgh/vue-test-utils-tape-example)
26+
- [example with AVA](https://github.com/eddyerburgh/vue-test-utils-ava-example)
2227

2328
## Questions
2429

dist/vue-test-utils.amd.js

Lines changed: 151 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2592,6 +2592,9 @@ function getCoreProperties (component) {
25922592
}
25932593
}
25942594
function createStubFromString (templateString, originalComponent) {
2595+
if (!vueTemplateCompiler.compileToFunctions) {
2596+
throwError('vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined');
2597+
}
25952598
return Object.assign({}, getCoreProperties(originalComponent),
25962599
vueTemplateCompiler.compileToFunctions(templateString))
25972600
}
@@ -2634,6 +2637,9 @@ function stubComponents (component, stubs) {
26342637
}
26352638
} else {
26362639
if (typeof stubs[stub] === 'string') {
2640+
if (!vueTemplateCompiler.compileToFunctions) {
2641+
throwError('vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined');
2642+
}
26372643
component.components[stub] = Object.assign({}, vueTemplateCompiler.compileToFunctions(stubs[stub]));
26382644
stubLifeCycleEvents(component.components[stub]);
26392645
} else {
@@ -2817,11 +2823,22 @@ WrapperArray.prototype.contains = function contains (selector) {
28172823

28182824
return this.wrappers.every(function (wrapper) { return wrapper.contains(selector); })
28192825
};
2820-
28212826
WrapperArray.prototype.exists = function exists () {
28222827
return this.wrappers.length > 0
28232828
};
28242829

2830+
WrapperArray.prototype.emitted = function emitted () {
2831+
this.throwErrorIfWrappersIsEmpty('emitted');
2832+
2833+
throwError('emitted must be called on a single wrapper, use at(i) to access a wrapper');
2834+
};
2835+
2836+
WrapperArray.prototype.emittedByOrder = function emittedByOrder () {
2837+
this.throwErrorIfWrappersIsEmpty('emittedByOrder');
2838+
2839+
throwError('emittedByOrder must be called on a single wrapper, use at(i) to access a wrapper');
2840+
};
2841+
28252842
WrapperArray.prototype.hasAttribute = function hasAttribute (attribute, value) {
28262843
this.throwErrorIfWrappersIsEmpty('hasAttribute');
28272844

@@ -2943,6 +2960,14 @@ ErrorWrapper.prototype.contains = function contains () {
29432960
throwError(("find did not return " + (this.selector) + ", cannot call contains() on empty Wrapper"));
29442961
};
29452962

2963+
ErrorWrapper.prototype.emitted = function emitted () {
2964+
throwError(("find did not return " + (this.selector) + ", cannot call emitted() on empty Wrapper"));
2965+
};
2966+
2967+
ErrorWrapper.prototype.emittedByOrder = function emittedByOrder () {
2968+
throwError(("find did not return " + (this.selector) + ", cannot call emittedByOrder() on empty Wrapper"));
2969+
};
2970+
29462971
ErrorWrapper.prototype.exists = function exists () {
29472972
return false
29482973
};
@@ -3048,6 +3073,26 @@ Wrapper.prototype.contains = function contains (selector) {
30483073
return false
30493074
};
30503075

3076+
/**
3077+
* Returns an object containing custom events emitted by the Wrapper vm
3078+
*/
3079+
Wrapper.prototype.emitted = function emitted () {
3080+
if (!this._emitted && !this.vm) {
3081+
throwError('wrapper.emitted() can only be called on a Vue instance');
3082+
}
3083+
return this._emitted
3084+
};
3085+
3086+
/**
3087+
* Returns an Array containing custom events emitted by the Wrapper vm
3088+
*/
3089+
Wrapper.prototype.emittedByOrder = function emittedByOrder () {
3090+
if (!this._emittedByOrder && !this.vm) {
3091+
throwError('wrapper.emittedByOrder() can only be called on a Vue instance');
3092+
}
3093+
return this._emittedByOrder
3094+
};
3095+
30513096
/**
30523097
* Utility to check wrapper exists. Returns true as Wrapper always exists
30533098
*/
@@ -3067,7 +3112,7 @@ Wrapper.prototype.hasAttribute = function hasAttribute (attribute, value) {
30673112
throwError('wrapper.hasAttribute() must be passed value as a string');
30683113
}
30693114

3070-
return this.element && this.element.getAttribute(attribute) === value
3115+
return !!(this.element && this.element.getAttribute(attribute) === value)
30713116
};
30723117

30733118
/**
@@ -3078,7 +3123,7 @@ Wrapper.prototype.hasClass = function hasClass (className) {
30783123
throwError('wrapper.hasClass() must be passed a string');
30793124
}
30803125

3081-
return this.element.className.split(' ').indexOf(className) !== -1
3126+
return !!(this.element && this.element.classList.contains(className))
30823127
};
30833128

30843129
/**
@@ -3133,7 +3178,7 @@ Wrapper.prototype.hasStyle = function hasStyle (style, value) {
31333178

31343179
var elStyle = window.getComputedStyle(this.element)[style];
31353180
var mockNodeStyle = window.getComputedStyle(mockNode)[style];
3136-
return elStyle === mockNodeStyle
3181+
return !!(elStyle && mockNodeStyle && elStyle === mockNodeStyle)
31373182
};
31383183

31393184
/**
@@ -3219,7 +3264,10 @@ Wrapper.prototype.is = function is (selector) {
32193264
}
32203265
return vmCtorMatchesName(this.vm, selector.name)
32213266
}
3222-
return this.element.getAttribute && this.element.matches(selector)
3267+
3268+
return !!(this.element &&
3269+
this.element.getAttribute &&
3270+
this.element.matches(selector))
32233271
};
32243272

32253273
/**
@@ -3317,6 +3365,10 @@ Wrapper.prototype.setProps = function setProps (data) {
33173365
* Return text of wrapper element
33183366
*/
33193367
Wrapper.prototype.text = function text () {
3368+
if (!this.element) {
3369+
throwError('cannot call wrapper.text() on a wrapper without an element');
3370+
}
3371+
33203372
return this.element.textContent
33213373
};
33223374

@@ -3330,6 +3382,10 @@ Wrapper.prototype.trigger = function trigger (type, options) {
33303382
throwError('wrapper.trigger() must be passed a string');
33313383
}
33323384

3385+
if (!this.element) {
3386+
throwError('cannot call wrapper.trigger() on a wrapper without an element');
3387+
}
3388+
33333389
var modifiers = {
33343390
enter: 13,
33353391
tab: 9,
@@ -3367,6 +3423,18 @@ Wrapper.prototype.trigger = function trigger (type, options) {
33673423
this.update();
33683424
};
33693425

3426+
function logEvents (vm, emitted, emittedByOrder) {
3427+
var emit = vm.$emit;
3428+
vm.$emit = function (name) {
3429+
var args = [], len = arguments.length - 1;
3430+
while ( len-- > 0 ) args[ len ] = arguments[ len + 1 ];
3431+
3432+
(emitted[name] || (emitted[name] = [])).push(args);
3433+
emittedByOrder.push({ name: name, args: args });
3434+
return emit.call.apply(emit, [ vm, name ].concat( args ))
3435+
};
3436+
}
3437+
33703438
//
33713439

33723440
function update () {
@@ -3385,6 +3453,10 @@ var VueWrapper = (function (Wrapper$$1) {
33853453

33863454
this.vm = vm;
33873455
this.isVueComponent = true;
3456+
this._emitted = Object.create(null);
3457+
this._emittedByOrder = [];
3458+
3459+
logEvents(vm, this._emitted, this._emittedByOrder);
33883460
}
33893461

33903462
if ( Wrapper$$1 ) VueWrapper.__proto__ = Wrapper$$1;
@@ -3403,12 +3475,18 @@ function isValidSlot (slot) {
34033475
function addSlotToVm (vm, slotName, slotValue) {
34043476
if (Array.isArray(vm.$slots[slotName])) {
34053477
if (typeof slotValue === 'string') {
3478+
if (!vueTemplateCompiler.compileToFunctions) {
3479+
throwError('vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined');
3480+
}
34063481
vm.$slots[slotName].push(vm.$createElement(vueTemplateCompiler.compileToFunctions(slotValue)));
34073482
} else {
34083483
vm.$slots[slotName].push(vm.$createElement(slotValue));
34093484
}
34103485
} else {
34113486
if (typeof slotValue === 'string') {
3487+
if (!vueTemplateCompiler.compileToFunctions) {
3488+
throwError('vueTemplateCompiler is undefined, you must pass components explicitly if vue-template-compiler is undefined');
3489+
}
34123490
vm.$slots[slotName] = [vm.$createElement(vueTemplateCompiler.compileToFunctions(slotValue))];
34133491
} else {
34143492
vm.$slots[slotName] = [vm.$createElement(slotValue)]; // eslint-disable-line no-param-reassign
@@ -3434,14 +3512,30 @@ function addSlots (vm, slots) {
34343512

34353513
//
34363514

3437-
function createInterceptPlugin (interceptedProperties) {
3438-
return {
3439-
install: function (Vue$$1) {
3440-
Object.keys(interceptedProperties).forEach(function (key) {
3441-
Vue$$1.prototype[key] = interceptedProperties[key];
3442-
});
3443-
}
3515+
function addMocks (mockedProperties, Vue$$1) {
3516+
Object.keys(mockedProperties).forEach(function (key) {
3517+
Vue$$1.prototype[key] = mockedProperties[key];
3518+
});
3519+
}
3520+
3521+
function addAttrs (vm, attrs) {
3522+
Vue.config.silent = true;
3523+
if (attrs) {
3524+
vm.$attrs = attrs;
3525+
} else {
3526+
vm.$attrs = {};
3527+
}
3528+
Vue.config.silent = false;
3529+
}
3530+
3531+
function addListeners (vm, listeners) {
3532+
Vue.config.silent = true;
3533+
if (listeners) {
3534+
vm.$listeners = listeners;
3535+
} else {
3536+
vm.$listeners = {};
34443537
}
3538+
Vue.config.silent = false;
34453539
}
34463540

34473541
function addProvide (component, options) {
@@ -3460,6 +3554,12 @@ function addProvide (component, options) {
34603554

34613555
//
34623556

3557+
function compileTemplate (component) {
3558+
Object.assign(component, vueTemplateCompiler.compileToFunctions(component.template));
3559+
}
3560+
3561+
//
3562+
34633563
function createConstructor (component, options) {
34643564
var vue = options.localVue || Vue;
34653565

@@ -3487,17 +3587,21 @@ function createConstructor (component, options) {
34873587
stubComponents(component, options.stubs);
34883588
}
34893589

3590+
if (!component.render && component.template && !component.functional) {
3591+
compileTemplate(component);
3592+
}
3593+
34903594
var Constructor = vue.extend(component);
34913595

3492-
if (options.intercept) {
3493-
// creates a plugin that adds properties, and then install on local Constructor
3494-
// this does not affect the base Vue class
3495-
var interceptPlugin = createInterceptPlugin(options.intercept);
3496-
Constructor.use(interceptPlugin);
3596+
if (options.mocks) {
3597+
addMocks(options.mocks, Constructor);
34973598
}
34983599

34993600
var vm = new Constructor(options);
35003601

3602+
addAttrs(vm, options.attrs);
3603+
addListeners(vm, options.listeners);
3604+
35013605
if (options.slots) {
35023606
addSlots(vm, options.slots);
35033607
}
@@ -3541,7 +3645,11 @@ function mount (component, options) {
35413645
if ( options === void 0 ) options = {};
35423646

35433647
if (!window) {
3544-
throwError('window is undefined, vue-test-utils needs to be run in a browser environment.\n You can run the tests in node using JSDOM');
3648+
throwError(
3649+
'window is undefined, vue-test-utils needs to be run in a browser environment.\n' +
3650+
'You can run the tests in node using jsdom + jsdom-global.\n' +
3651+
'See https://vue-test-utils.vuejs.org/en/guides/general-tips.html for more details.'
3652+
);
35453653
}
35463654

35473655
var componentToMount = options.clone === false ? component : cloneDeep_1(component);
@@ -3580,15 +3688,35 @@ function shallow (component, options) {
35803688

35813689
function createLocalVue () {
35823690
var instance = Vue.extend();
3583-
instance.version = Vue.version;
3584-
instance._installedPlugins = [];
3691+
3692+
// clone global APIs
3693+
Object.keys(Vue).forEach(function (key) {
3694+
if (!instance.hasOwnProperty(key)) {
3695+
var original = Vue[key];
3696+
instance[key] = typeof original === 'object'
3697+
? cloneDeep_1(original)
3698+
: original;
3699+
}
3700+
});
3701+
3702+
// config is not enumerable
35853703
instance.config = cloneDeep_1(Vue.config);
3586-
instance.util = cloneDeep_1(Vue.util);
3587-
instance._use = instance.use;
3704+
3705+
// option merge strategies need to be exposed by reference
3706+
// so that merge strats registered by plguins can work properly
3707+
instance.config.optionMergeStrategies = Vue.config.optionMergeStrategies;
3708+
3709+
// make sure all extends are based on this instance.
3710+
// this is important so that global components registered by plugins,
3711+
// e.g. router-link are created using the correct base constructor
3712+
instance.options._base = instance;
3713+
3714+
// compat for vue-router < 2.7.1 where it does not allow multiple installs
3715+
var use = instance.use;
35883716
instance.use = function (plugin) {
35893717
plugin.installed = false;
35903718
plugin.install.installed = false;
3591-
instance._use(plugin);
3719+
use.call(instance, plugin);
35923720
};
35933721
return instance
35943722
}

0 commit comments

Comments
 (0)