Skip to content

Commit

Permalink
refactor(geojs): use Vue's provide/inject API in the geojs layer mixin
Browse files Browse the repository at this point in the history
This provides more flexibility in using the components compared to
accessing the `$parent` component directly.  This is particularly
relevant because newer versions of `@vue/test-utils` broke how we were
injecting the parent components in unit testing.

Note: This also updates `@vue/test-utils`, but not to the latest version
because there is a bug since `beta-18` causing props not to be updated.
This may (or may not) be related to the following issue:

vuejs/vue-test-utils#738
  • Loading branch information
jbeezley committed Jun 21, 2018
1 parent 948f6c3 commit c07fa0c
Show file tree
Hide file tree
Showing 12 changed files with 3,060 additions and 3,035 deletions.
5,910 changes: 2,955 additions & 2,955 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"devDependencies": {
"@commitlint/cli": "^6.2.0",
"@commitlint/config-conventional": "^6.1.3",
"@vue/test-utils": "^1.0.0-beta.16",
"@vue/test-utils": "1.0.0-beta.17",
"autoprefixer": "^8.5.0",
"axios-mock-adapter": "^1.15.0",
"babel-core": "^6.26.3",
Expand Down
9 changes: 9 additions & 0 deletions src/components/geojs/GeojsMapViewport.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,15 @@ export default {
ready: false,
};
},
provide() {
const provided = {
$geojs: geo,
};
Object.defineProperty(provided, '$geojsMap', {
get: () => this.$geojsMap,
});
return provided;
},
mounted() {
this.$geojsViewport = true;
this.$geojs = geo;
Expand Down
10 changes: 2 additions & 8 deletions src/mixins/geojsLayer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import bindWatchers from '../bindWatchers';

const layerMixin = {
inject: ['$geojs', '$geojsMap'],
props: {
zIndex: {
type: Number,
Expand All @@ -24,16 +25,9 @@ const layerMixin = {
this.$unwatch = new Map();
},
mounted() {
// This is in place purely for testing because there is no way
// in @vue/test-utils to put mocks in place *before* mount is called.
// https://github.com/vuejs/vue-test-utils/issues/560
this.$parent = this.$parent || this.$options.testParent;

if (!this.$parent || this.$parent.$geojsViewport !== true) {
if (!this.$geojs) {
throw new Error('A layer must be a child of a GeojsMapViewport');
}
this.$geojsMap = this.$parent.$geojsMap;
this.$geojs = this.$parent.$geojs;
},
methods: {
createLayer(type, options) {
Expand Down
36 changes: 36 additions & 0 deletions test/ProvideGeojs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import geo from 'geojs';
import { mount } from '@vue/test-utils';

class ProvideGeojs {
start() {
this.element = document.createElement('div');
this.element.style.width = '300px';
this.element.style.height = '200px';
document.body.appendChild(this.element);
this.geojsMap = geo.map({ node: this.element });
}

stop() {
this.geojsMap.exit();
this.element.remove();
this.element = null;
}

mountOptions() {
return {
provide: {
$geojs: geo,
$geojsMap: this.geojsMap,
},
};
}

mountLayer(component, options = {}) {
return mount(component, Object.assign(
this.mountOptions(),
options,
));
}
}

export default ProvideGeojs;
28 changes: 11 additions & 17 deletions test/specs/GeojsAnnotationLayer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,21 @@ import geojs from 'geojs';
import { mount } from '@vue/test-utils';
import last from 'lodash-es/last';

import GeojsMapViewport from '@/components/geojs/GeojsMapViewport';
import GeojsAnnotationLayer from '@/components/geojs/GeojsAnnotationLayer';

import ProvideGeojs from '../ProvideGeojs';

describe('GeojsAnnotationLayer.vue', () => {
let mapWrapper;
const provider = new ProvideGeojs();
let interactor;

function mountAnnotationLayer(options = {}) {
const wrapper = mount(GeojsAnnotationLayer, {
testParent: mapWrapper.vm,
...options,
});
return wrapper;
return provider.mountLayer(GeojsAnnotationLayer, options);
}

function interact(event, pt, button) {
interactor.simulateEvent(event, {
map: mapWrapper.vm.$geojsMap.gcsToDisplay(pt),
map: provider.geojsMap.gcsToDisplay(pt),
button,
});
}
Expand All @@ -42,13 +40,13 @@ describe('GeojsAnnotationLayer.vue', () => {
beforeEach(() => {
geojs.util.mockVGLRenderer();
sinon.stub(console, 'warn');
mapWrapper = mount(GeojsMapViewport);
interactor = mapWrapper.vm.$geojsMap.interactor();
provider.start();
interactor = provider.geojsMap.interactor();
});

afterEach(() => {
console.warn.restore(); // eslint-disable-line no-console
mapWrapper.destroy();
provider.stop();
geojs.util.restoreVGLRenderer();
});

Expand Down Expand Up @@ -87,9 +85,7 @@ describe('GeojsAnnotationLayer.vue', () => {
});

it('draw a point', () => {
const wrapper = mount(GeojsAnnotationLayer, {
testParent: mapWrapper.vm,
});
const wrapper = mount(GeojsAnnotationLayer, provider.mountOptions());
wrapper.setProps({ drawing: 'point' });
expect(wrapper.vm.$geojsLayer.mode()).to.equal('point');

Expand Down Expand Up @@ -211,9 +207,7 @@ describe('GeojsAnnotationLayer.vue', () => {
});

it('do not trigger state changes for empty annotations', () => {
const wrapper = mount(GeojsAnnotationLayer, {
testParent: mapWrapper.vm,
});
const wrapper = mount(GeojsAnnotationLayer, provider.mountOptions());
wrapper.setProps({ drawing: 'point' });
expect(wrapper.vm.$geojsLayer.mode()).to.equal('point');
expect(wrapper.vm.state).to.eql([]);
Expand Down
15 changes: 6 additions & 9 deletions test/specs/GeojsGeojsonLayer.spec.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
import geojs from 'geojs';
import { mount } from '@vue/test-utils';

import GeojsMapViewport from '@/components/geojs/GeojsMapViewport';
import GeojsGeojsonLayer from '@/components/geojs/GeojsGeojsonLayer';

import ProvideGeojs from '../ProvideGeojs';

describe('GeojsTileLayer.vue', () => {
let mapWrapper;
const provider = new ProvideGeojs();
function mountLayer(options = {}) {
return mount(GeojsGeojsonLayer, {
testParent: mapWrapper.vm,
...options,
});
return provider.mountLayer(GeojsGeojsonLayer, options);
}

beforeEach(() => {
geojs.util.mockVGLRenderer();
sinon.stub(console, 'warn');
mapWrapper = mount(GeojsMapViewport);
provider.start();
});
afterEach(() => {
console.warn.restore(); // eslint-disable-line no-console
mapWrapper.destroy();
provider.stop();
geojs.util.restoreVGLRenderer();
});

Expand Down
18 changes: 7 additions & 11 deletions test/specs/GeojsHeatmapLayer.spec.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,20 @@
import { mount } from '@vue/test-utils';

import GeojsMapViewport from '@/components/geojs/GeojsMapViewport';
import GeojsHeatmapLayer from '@/components/geojs/GeojsHeatmapLayer';

import ProvideGeojs from '../ProvideGeojs';

describe('GeojsTileLayer.vue', () => {
let mapWrapper;
const provider = new ProvideGeojs();
function mountLayer(options = {}) {
return mount(GeojsHeatmapLayer, {
testParent: mapWrapper.vm,
...options,
});
return provider.mountLayer(GeojsHeatmapLayer, options);
}

beforeEach(() => {
sinon.stub(console, 'warn');
mapWrapper = mount(GeojsMapViewport);
provider.start();
});
afterEach(() => {
console.warn.restore(); // eslint-disable-line no-console
mapWrapper.destroy();
provider.stop();
});

it('validate intensity (null)', () => {
Expand Down Expand Up @@ -78,7 +74,7 @@ describe('GeojsTileLayer.vue', () => {

it('removes on destroy', () => {
const wrapper = mountLayer();
const spy = sinon.spy(mapWrapper.vm.$geojsMap, 'deleteLayer');
const spy = sinon.spy(provider.geojsMap, 'deleteLayer');
const layer = wrapper.vm.$geojsLayer;
wrapper.destroy();
spy.should.have.been.calledOnce;
Expand Down
7 changes: 7 additions & 0 deletions test/specs/GeojsMapViewport.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ describe('GeojsMapViewport.vue', () => {
expect(map.rotation()).closeTo(0.5, delta);
});

it('provides properties to child elements', () => {
const wrapper = mount(GeojsMapViewport);
const provides = wrapper.vm.$options.provide();
expect(provides).to.have.property('$geojs');
expect(provides).to.have.property('$geojsMap');
});

it('respond to pan events (sync)', () => {
const wrapper = mount(GeojsMapViewport, {
propsData: {
Expand Down
35 changes: 15 additions & 20 deletions test/specs/GeojsTileLayer.spec.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
import { mount } from '@vue/test-utils';

import GeojsMapViewport from '@/components/geojs/GeojsMapViewport';
import GeojsTileLayer from '@/components/geojs/GeojsTileLayer';

import ProvideGeojs from '../ProvideGeojs';

describe('GeojsTileLayer.vue', () => {
let mapWrapper;
const provider = new ProvideGeojs();
function mountTileLayer(options) {
return provider.mountLayer(GeojsTileLayer, options);
}
beforeEach(() => {
sinon.stub(console, 'warn');
mapWrapper = mount(GeojsMapViewport);
provider.start();
});
afterEach(() => {
console.warn.restore(); // eslint-disable-line no-console
mapWrapper.destroy();
provider.stop();
});

it('url (string)', () => {
const wrapper = mount(GeojsTileLayer, {
propsData: {
url: '/data/white.jpg',
},
testParent: mapWrapper.vm,
const wrapper = mountTileLayer({
propsData: { url: '/data/white.jpg' },
});
expect(wrapper.vm.$geojsLayer.url()).equal('/data/white.jpg');

Expand All @@ -29,12 +28,11 @@ describe('GeojsTileLayer.vue', () => {

it('attribution', () => {
const attribution = '<a href="www.example.com"></a>';
const wrapper = mount(GeojsTileLayer, {
const wrapper = mountTileLayer({
propsData: {
url: '/data/osm.png',
attribution,
},
testParent: mapWrapper.vm,
});
expect(wrapper.vm.$geojsLayer.attribution()).equal(attribution);

Expand All @@ -43,12 +41,11 @@ describe('GeojsTileLayer.vue', () => {
});

it('opacity', () => {
const wrapper = mount(GeojsTileLayer, {
const wrapper = mountTileLayer({
propsData: {
url: '/data/osm.png',
opacity: 0.5,
},
testParent: mapWrapper.vm,
});
expect(wrapper.vm.$geojsLayer.opacity()).equal(0.5);

Expand All @@ -57,24 +54,22 @@ describe('GeojsTileLayer.vue', () => {
});

it('wrapX', () => {
const wrapper = mount(GeojsTileLayer, {
const wrapper = mountTileLayer({
propsData: {
url: '/data/osm.png',
wrapX: false,
},
testParent: mapWrapper.vm,
});
expect(wrapper.vm.$geojsLayer.options.wrapX).equal(false);
});

it('removes on destroy', () => {
const wrapper = mount(GeojsTileLayer, {
const wrapper = mountTileLayer({
propsData: {
url: '/data/osm.png',
},
testParent: mapWrapper.vm,
});
const spy = sinon.spy(mapWrapper.vm.$geojsMap, 'deleteLayer');
const spy = sinon.spy(wrapper.vm.$geojsMap, 'deleteLayer');
const layer = wrapper.vm.$geojsLayer;
wrapper.destroy();
spy.should.have.been.calledOnce;
Expand Down
19 changes: 8 additions & 11 deletions test/specs/GeojsWidgetLayer.spec.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { mount } from '@vue/test-utils';

import GeojsMapViewport from '@/components/geojs/GeojsMapViewport';
import GeojsWidgetLayer from '@/components/geojs/GeojsWidgetLayer';

import ProvideGeojs from '../ProvideGeojs';

const TestComponent = {
functional: true,
render(createElement) {
Expand All @@ -11,29 +11,26 @@ const TestComponent = {
};

describe('GeojsWidgetLayer.vue', () => {
const provider = new ProvideGeojs();
let displayPosition = { x: 10, y: 20 };
let mapWrapper;
let gcsToDisplay;

function mountLayer(options = {}) {
return mount(GeojsWidgetLayer, {
testParent: mapWrapper.vm,
slots: {
default: TestComponent,
},
return provider.mountLayer(GeojsWidgetLayer, {
slots: { default: TestComponent },
...options,
});
}

beforeEach(() => {
sinon.stub(console, 'warn');
mapWrapper = mount(GeojsMapViewport);
gcsToDisplay = sinon.stub(mapWrapper.vm.$geojsMap, 'gcsToDisplay').callsFake(() => displayPosition);
provider.start();
gcsToDisplay = sinon.stub(provider.geojsMap, 'gcsToDisplay').callsFake(() => displayPosition);
});
afterEach(() => {
console.warn.restore(); // eslint-disable-line no-console
gcsToDisplay.restore();
mapWrapper.destroy();
provider.stop();
});

it('mounted with default slot', () => {
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -323,9 +323,9 @@
source-map "^0.5.6"
vue-template-es2015-compiler "^1.6.0"

"@vue/test-utils@^1.0.0-beta.16":
version "1.0.0-beta.16"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.16.tgz#dcf7a30304391422e382b5f97db6eb9508112906"
"@vue/[email protected].17":
version "1.0.0-beta.17"
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-1.0.0-beta.17.tgz#cdf4213d6f0aded2416465fd4829c162a48b876d"
dependencies:
lodash "^4.17.4"

Expand Down

0 comments on commit c07fa0c

Please sign in to comment.