Skip to content

Commit

Permalink
feat: throw when mounted in incompatible apps
Browse files Browse the repository at this point in the history
  • Loading branch information
privatenumber committed Nov 25, 2020
1 parent e049389 commit 0faca3a
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 6 deletions.
8 changes: 8 additions & 0 deletions src/to-vue-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,17 @@ function resolveInjection(vm, key) {
}
}

const isVue2 = vm => vm._uid && vm._isVue;

const vue2WrapperBase = {
inheritAttrs: false,

beforeCreate() {
if (!isVue2(this)) {
throw new Error('toVue2 must be used to mount a component in a Vue 2 app');
}
},

provide() {
return {};
},
Expand Down
6 changes: 6 additions & 0 deletions src/to-vue-3.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,14 @@ function setFakeParentWhileUnmounted(node, fakeParent) {

const isConfigurableProperty = {configurable: true};

const isVue3 = vm => (vm._ && vm._.uid);

const vue3WrapperBase = {
created() {
if (!isVue3(this)) {
throw new Error('toVue3 must be used to mount a component in a Vue 3 app');
}

this.v2 = undefined;
},

Expand Down
34 changes: 32 additions & 2 deletions test/to-vue-2.spec.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,37 @@
const {toVue2} = require('vue-2-3');
const {provide, inject, nextTick} = require('vue3');
const {createApp, provide, inject, nextTick} = require('vue3');
const {mount} = require('@vue/test-utils');

describe('Error handling', () => {
test('throw error when used in vue 3 app', () => {
const Vue3Component = {
props: ['propWorks'],
template: `
I'm Vue 3
`,
};

const initApp = () => {
const app = createApp({
template: `
<div>
<vue3-component>
Default slot
</vue3-component>
</div>
`,
components: {
Vue3Component: toVue2(Vue3Component),
},
});
app.config.warnHandler = () => {};
app.mount(document.createElement('div'));
};

expect(initApp).toThrow('toVue2 must be used to mount a component in a Vue 2 app');
});
});

describe('Vue 3 component in a Vue 2 app', () => {
test('render w/ class, style, attrs, props, slots', () => {
const Vue3Component = {
Expand Down Expand Up @@ -353,5 +383,5 @@ describe('Vue 3 component in a Vue 2 app', () => {
});
});

// Test providing from Vue2 component to Vue 3
test.todo('providing from Vue 2 component to Vue 3');
});
44 changes: 40 additions & 4 deletions test/to-vue-3.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const {toVue3} = require('vue-2-3');
const {createApp, nextTick} = require('vue3');
const outdent = require('outdent');
const Vue = require('vue');

let mountTarget;
let app;
Expand All @@ -10,10 +11,12 @@ beforeEach(() => {
});

afterEach(() => {
app.unmount();
mountTarget.remove();
app = null;
mountTarget = null;
if (app) {
app.unmount();
mountTarget.remove();
app = null;
mountTarget = null;
}
});

function mount(_app) {
Expand All @@ -27,6 +30,39 @@ function mount(_app) {
};
}

describe('Error handling', () => {
test('throw error when used in vue 2 app', () => {
const Vue2Component = {
props: ['propWorks'],
template: `
I'm Vue 3
`,
};

const errorHandler = jest.fn();
Vue.config.errorHandler = errorHandler;

// eslint-disable-next-line no-new
new Vue({
template: `
<div>
<vue2-component>
Default slot
</vue2-component>
</div>
`,
components: {
Vue2Component: toVue3(Vue2Component),
},

el: document.createElement('div'),
});

expect(errorHandler).toBeCalled();
expect(errorHandler.mock.calls[0][0].message).toBe('toVue3 must be used to mount a component in a Vue 3 app');
});
});

describe('Vue 2 component in a Vue 3 app', () => {
test('render w/ class, style, attrs, props, slots', () => {
const Vue2Component = {
Expand Down

0 comments on commit 0faca3a

Please sign in to comment.