From b211096754194656c68e999a6101a5e5fe35f3c6 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Mon, 20 Nov 2017 10:05:10 -0500 Subject: [PATCH 1/2] Make maps better at exiting and reloading. Reduce repeated test code. This reuses or replaces the #map node in the headless tests rather than creating different named nodes for many different tests. This reduces the boiler-plate code for creating and destroying maps in the tests. Reusing elements exhibited some problems in map teardown and recreation. Specifically: (a) When the map was exiting some functions could be invoked with no-longer-valid renderer values. (b) An animation frame could fire after the vgl renderer had exited. (c) The scene object reset its children incorrectly. (d) The sliderWidget turned off all layer events for zoom rather than just its own. (e) Tests that mock VGL must clean up their maps before restoring VGL, or when the map is exited it may not have the appropriate state information. Fix some inconsistencies on widgets. For instance, if a widget is position relative to the screen and then changed to relative to the map, it wouldn't update on pan, but if it started as relative to the map, it would update on pan. Update jsdocs on widgets. --- src/canvas/heatmapFeature.js | 4 +- src/gl/vglRenderer.js | 19 +++-- src/map.js | 4 +- src/sceneObject.js | 2 +- src/ui/sliderWidget.js | 6 +- src/ui/widget.js | 121 +++++++++++++++++++---------- src/util/mockVGL.js | 1 - tests/cases/annotation.js | 28 +++---- tests/cases/annotationLayer.js | 29 +++---- tests/cases/choroplethFeature.js | 95 +++++++++++----------- tests/cases/colorLegend.js | 19 +---- tests/cases/contourWrap.js | 43 ++++++---- tests/cases/d3GraphFeature.js | 14 +--- tests/cases/d3PointFeature.js | 18 +---- tests/cases/d3VectorFeature.js | 15 ++-- tests/cases/discreteZoom.js | 15 +--- tests/cases/feature.js | 19 ++--- tests/cases/featureLayer.js | 17 +--- tests/cases/geojsonReader.js | 16 +--- tests/cases/heatmap.js | 67 ++++++++-------- tests/cases/layerReorder.js | 32 +------- tests/cases/lineFeature.js | 28 +++---- tests/cases/map.js | 94 +++++++++++----------- tests/cases/mapAttribution.js | 18 +---- tests/cases/osmLayer.js | 16 +--- tests/cases/pixelmapFeature.js | 30 +++---- tests/cases/pointFeature.js | 34 ++++---- tests/cases/polygonFeature.js | 30 ++++--- tests/cases/quadFeature.js | 35 ++++----- tests/cases/textFeature.js | 22 ++---- tests/cases/widgetApi.js | 20 +---- tests/cases/zoomSlider.js | 15 +--- tests/gl-cases/quadFeatureVideo.js | 17 +--- tests/test-utils.js | 35 ++++++++- 34 files changed, 427 insertions(+), 551 deletions(-) diff --git a/src/canvas/heatmapFeature.js b/src/canvas/heatmapFeature.js index 1469eafe2b..498b9e0f04 100644 --- a/src/canvas/heatmapFeature.js +++ b/src/canvas/heatmapFeature.js @@ -394,7 +394,9 @@ var canvas_heatmapFeature = function (arg) { * @protected */ this._setTransform = function () { - m_this.layer().canvas()[0].style.transform = m_heatMapTransform; + if (m_this.layer() && m_this.layer().canvas() && m_this.layer().canvas()[0]) { + m_this.layer().canvas()[0].style.transform = m_heatMapTransform; + } }; /** diff --git a/src/gl/vglRenderer.js b/src/gl/vglRenderer.js index 0cde8ace34..bfceb91055 100644 --- a/src/gl/vglRenderer.js +++ b/src/gl/vglRenderer.js @@ -169,19 +169,28 @@ var vglRenderer = function (arg) { * This clears the render timer and actually renders. */ this._renderFrame = function () { - if (m_updateCamera) { - m_updateCamera = false; - m_this._updateRendererCamera(); + if (m_viewer) { + if (m_updateCamera) { + m_updateCamera = false; + m_this._updateRendererCamera(); + } + m_viewer.render(); } - m_viewer.render(); }; /** * Exit. */ this._exit = function () { + m_this.layer().map().scheduleAnimationFrame(this._renderFrame, 'remove'); m_this.canvas().remove(); - m_viewer.exit(); + if (m_viewer) { + var renderState = new vgl.renderState(); + renderState.m_renderer = m_viewer; + renderState.m_context = m_viewer.renderWindow().context(); + m_viewer.exit(renderState); + } + m_viewer = null; s_exit(); }; diff --git a/src/map.js b/src/map.js index c56de83b9c..edeb3b4809 100644 --- a/src/map.js +++ b/src/map.js @@ -1482,7 +1482,9 @@ var map = function (arg) { if (m_discreteZoom) { m_this.zoom(Math.round(m_this.zoom())); } - m_this.interactor().options({discreteZoom: m_discreteZoom}); + if (m_this.interactor()) { + m_this.interactor().options({discreteZoom: m_discreteZoom}); + } } return m_this; }; diff --git a/src/sceneObject.js b/src/sceneObject.js index cf024a0e38..b62562a71f 100644 --- a/src/sceneObject.js +++ b/src/sceneObject.js @@ -178,7 +178,7 @@ var sceneObject = function (arg) { * Free all resources and destroy the object. */ this._exit = function () { - m_this.children = []; + m_children = []; delete m_this.parent; s_exit(); }; diff --git a/src/ui/sliderWidget.js b/src/ui/sliderWidget.js index 7a90152ce7..30a9ee9720 100644 --- a/src/ui/sliderWidget.js +++ b/src/ui/sliderWidget.js @@ -286,9 +286,7 @@ var sliderWidget = function (arg) { .on('mouseout', mouseOut); // Update the nub position on zoom - m_this.layer().geoOn(geo_event.zoom, function () { - m_this._update(); - }); + m_this.geoOn(geo_event.zoom, m_this._update); mouseOut(); m_this._update(); @@ -302,8 +300,8 @@ var sliderWidget = function (arg) { * @private */ this._exit = function () { + m_this.geoOff(geo_event.zoom, m_this._update); m_group.remove(); - m_this.layer().geoOff(geo_event.zoom); s_exit(); }; diff --git a/src/ui/widget.js b/src/ui/widget.js index 505db899f2..e89dad4371 100644 --- a/src/ui/widget.js +++ b/src/ui/widget.js @@ -16,9 +16,14 @@ var sceneObject = require('../sceneObject'); */ /** - * Create a new instance of class widget + * Create a new instance of class widget. * - * @class geo.gui.widget + * @class + * @alias geo.gui.widget + * @param {object} [arg] Options for the widget. + * @param {geo.layer} [arg.layer] Layer associated with the widget. + * @param {geo.gui.widget.position} [arg.position] Location of the widget. + * @param {geo.gui.widget} [arg.parent] Optional parent widget. * @extends {geo.sceneObject} * @returns {geo.gui.widget} */ @@ -35,18 +40,27 @@ var widget = function (arg) { var m_this = this, s_exit = this._exit, m_layer = arg.layer, - m_canvas = null; - - arg.position = arg.position === undefined ? { left: 0, top: 0 } : arg.position; + m_canvas = null, + m_position = arg.position === undefined ? { left: 0, top: 0 } : arg.position; if (arg.parent !== undefined && !(arg.parent instanceof widget)) { throw new Error('Parent must be of type geo.gui.widget'); } + /** + * Initialize the widget. + * + * @returns {this} + */ this._init = function () { m_this.modified(); + return m_this; }; + /** + * Clean up the widget. + * + */ this._exit = function () { m_this.children().forEach(function (child) { m_this._deleteFeature(child); @@ -58,9 +72,11 @@ var widget = function (arg) { }; /** - * Create feature give a name + * Create a new feature. * - * @returns {geo.Feature} Will return a new feature + * @param {string} featureName Name of the feature to create. + * @param {object} arg Options for the new feature. + * @returns {geo.feature} The new feature. */ this._createFeature = function (featureName, arg) { @@ -73,7 +89,10 @@ var widget = function (arg) { }; /** - * Delete feature + * Delete feature. + * + * @param {geo.feature} feature The feature to delete. + * @returns {this} */ this._deleteFeature = function (feature) { m_this.removeChild(feature); @@ -83,6 +102,8 @@ var widget = function (arg) { /** * Return the layer associated with this widget. + * + * @returns {geo.layer} */ this.layer = function () { return m_layer; @@ -96,54 +117,67 @@ var widget = function (arg) { }; /** - * Get/Set the canvas for the widget + * Get/Set the canvas for the widget. + * + * @param {HTMLElement} [val] If specified, set the canvas, otherwise get + * the canvas. + * @returns {HTMLElement|this} If getting the canvas, return the current + * value; otherwise, return this widget. */ this.canvas = function (val) { if (val === undefined) { return m_canvas; - } else { - m_canvas = val; } + m_canvas = val; + return m_this; }; /** - * Appends a child to the widget - * The widget determines how to append itself to a parent, the parent can either - * be another widget, or the UI Layer. + * Appends a child to the widget. + * The widget determines how to append itself to a parent, the parent can + * either be another widget, or the UI Layer. */ this._appendChild = function () { m_this.parentCanvas().appendChild(m_this.canvas()); }; /** - * Get the parent canvas (top level widgets define their layer as their parent canvas) + * Get the parent canvas (top level widgets define their layer as their + * parent canvas). + * + * @returns {HTMLElement} The canvas of the widget's parent. */ this.parentCanvas = function () { if (m_this.parent === undefined) { return m_this.layer().canvas(); - } else { - return m_this.parent().canvas(); } + return m_this.parent().canvas(); }; /** - * Gets the CSS positioning that a widget should be placed at. - * { top: 0, left: 0 } by default. + * Get or set the CSS positioning that a widget should be placed at. + * + * @param {geo.gui.widget.position} [pos] If unspecified, return the current + * position. Otherwise, set the current position. + * @param {boolean} [actualValue] If getting the position, if this is truthy, + * always return the stored value, not a value adjusted for display. + * @returns {geo.gui.widget.position|this} Either the position or the widget + * instance. If this is the position and `actualValue` is falsy, + * positions that specify an explicit `x` and `y` parameter will be + * converted to a value that can be used by the display css. */ - this.position = function (pos) { + this.position = function (pos, actualValue) { if (pos !== undefined) { - arg.position = pos; + this.layer().geoOff(geo_event.pan, m_this.repositionEvent); + m_position = pos; + if (m_position.hasOwnProperty('x') && m_position.hasOwnProperty('y')) { + this.layer().geoOn(geo_event.pan, m_this.repositionEvent); + } this.reposition(); return this; } - var position; - - if (arg && - arg.hasOwnProperty('position') && - arg.position.hasOwnProperty('x') && - arg.position.hasOwnProperty('y')) { - - position = m_this.layer().map().gcsToDisplay(arg.position); + if (m_position.hasOwnProperty('x') && m_position.hasOwnProperty('y') && !actualValue) { + var position = m_this.layer().map().gcsToDisplay(m_position); return { left: position.x, @@ -153,14 +187,15 @@ var widget = function (arg) { }; } - return arg.position; + return m_position; }; /** - * Repositions a widget based on the argument passed, or calling position on - * the widget itself. - * @param {object} position A position with the form: - * { top: m, left: n } + * Repositions a widget. + * + * @param {geo.gui.widget.position} [position] The new position for the + * widget. `undefined` uses the stored position value. + * @returns {this} */ this.reposition = function (position) { position = position || m_this.position(); @@ -171,21 +206,30 @@ var widget = function (arg) { // if the property is a number, add px to it, otherwise set it to the // specified value. Setting a property to null clears it. Setting to // undefined doesn't alter it. - if (/^\s*(\-|\+)?(\d+(\.\d*)?|\d*\.\d+)([eE](\-|\+)?\d+)?\s*$/.test(position[cssAttr])) { + if (/^\s*(-|\+)?(\d+(\.\d*)?|\d*\.\d+)([eE](-|\+)?\d+)?\s*$/.test(position[cssAttr])) { m_this.canvas().style[cssAttr] = ('' + position[cssAttr]).trim() + 'px'; } else { m_this.canvas().style[cssAttr] = position[cssAttr]; } } } + return m_this; }; + /** + * If the position is based on map coordinates, this gets called when the + * map is panned to resposition the widget. + * + * @returns {this} + */ this.repositionEvent = function () { return m_this.reposition(); }; /** - * Determines whether or not the widget is completely within the viewport. + * Report if the widget is completely within the viewport. + * + * @returns {boolean} True if the widget is completely within the viewport. */ this.isInViewport = function () { var position = m_this.position(); @@ -195,10 +239,7 @@ var widget = function (arg) { (position.left <= layer.width() && position.top <= layer.height())); }; - if (arg && - arg.hasOwnProperty('position') && - arg.position.hasOwnProperty('x') && - arg.position.hasOwnProperty('y')) { + if (m_position.hasOwnProperty('x') && m_position.hasOwnProperty('y')) { this.layer().geoOn(geo_event.pan, m_this.repositionEvent); } }; diff --git a/src/util/mockVGL.js b/src/util/mockVGL.js index a9baf261ad..5d610aa432 100644 --- a/src/util/mockVGL.js +++ b/src/util/mockVGL.js @@ -185,7 +185,6 @@ module.exports.restoreVGLRenderer = function () { vgl.renderWindow = _renderWindow; vglRenderer.supported = _supported; delete vgl._mocked; - // delete vgl._mockedRenderWindow; delete vgl.mockCounts; } }; diff --git a/tests/cases/annotation.js b/tests/cases/annotation.js index 17be841466..3407f681ca 100644 --- a/tests/cases/annotation.js +++ b/tests/cases/annotation.js @@ -5,6 +5,8 @@ describe('geo.annotation', function () { var $ = require('jquery'); var geo = require('../test-utils').geo; + var createMap = require('../test-utils').createMap; + var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; @@ -13,18 +15,10 @@ describe('geo.annotation', function () { }); afterEach(function () { + destroyMap(); restoreVGLRenderer(); }); - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('geo.annotation.annotation', function () { var map, layer, stateEvent = 0, lastStateEvent; it('create', function () { @@ -47,7 +41,7 @@ describe('geo.annotation', function () { expect(ann.mouseMove()).toBe(undefined); expect(ann._coordinates()).toEqual([]); expect(ann.geojson()).toBe(undefined); - map = create_map(); + map = createMap(); layer = map.createLayer('annotation', { annotations: geo.listAnnotations() }); @@ -328,7 +322,7 @@ describe('geo.annotation', function () { expect(actions.length).toBe(0); }); it('processAction', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { annotations: ['rectangle'] }); @@ -379,7 +373,7 @@ describe('geo.annotation', function () { expect(geojson.geometry.coordinates[0][2][1]).toBeCloseTo(1); }); it('mouseMove', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { annotations: ['rectangle'] }); @@ -391,7 +385,7 @@ describe('geo.annotation', function () { expect(ann.options('corners')).not.toEqual(corners); }); it('mouseClick', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { annotations: ['rectangle'] }); @@ -504,7 +498,7 @@ describe('geo.annotation', function () { expect(ann.options('vertices')).not.toEqual(vertices); }); it('mouseClick', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { annotations: ['polygon'] }); @@ -637,7 +631,7 @@ describe('geo.annotation', function () { expect(ann.state()).toBe(geo.annotation.state.done); }); it('scaled radius', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { annotations: ['point'] }); @@ -726,7 +720,7 @@ describe('geo.annotation', function () { expect(ann.options('vertices')).not.toEqual(vertices); }); it('mouseClick', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { annotations: ['line'] }); @@ -826,7 +820,7 @@ describe('geo.annotation', function () { expect(actions.length).toBe(0); }); it('processAction', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { annotations: ['line'] }); diff --git a/tests/cases/annotationLayer.js b/tests/cases/annotationLayer.js index fc7d129ecf..27cfa76fe8 100644 --- a/tests/cases/annotationLayer.js +++ b/tests/cases/annotationLayer.js @@ -3,37 +3,30 @@ describe('geo.annotationLayer', function () { 'use strict'; - var $ = require('jquery'); var geo = require('../test-utils').geo; + var createMap = require('../test-utils').createMap; + var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; - beforeEach(function () { + beforeAll(function () { mockVGLRenderer(); }); - afterEach(function () { + afterAll(function () { + destroyMap(); restoreVGLRenderer(); }); - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - it('Test initialization.', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { features: ['polygon', 'line', 'point'] }); expect(layer instanceof geo.annotationLayer).toBe(true); }); it('Test initialization without interactor.', function () { - var map = create_map({interactor: null}); + var map = createMap({interactor: null}); var layer = map.createLayer('annotation', { features: ['polygon', 'line', 'point'] }); @@ -43,7 +36,7 @@ describe('geo.annotationLayer', function () { describe('Check class accessors', function () { var map, layer, modeEvent = 0, lastModeEvent; it('options', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('annotation', { features: ['polygon', 'line', 'point'] }); @@ -116,7 +109,7 @@ describe('geo.annotationLayer', function () { removeAnnotationEvent = 0, lastRemoveAnnotationEvent, poly, rect; it('addAnnotation', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('annotation', { features: ['polygon', 'line', 'point'] }); @@ -334,7 +327,7 @@ describe('geo.annotationLayer', function () { it('_update', function () { /* Most of update is covered as a side effect of other code. This tests * some edge conditions */ - map = create_map(); + map = createMap(); layer = map.createLayer('annotation', { renderer: 'd3' }); @@ -675,7 +668,7 @@ describe('geo.annotationLayer', function () { }); }); it('Test destroy layer.', function () { - var map = create_map(); + var map = createMap(); var layer = map.createLayer('annotation', { features: ['polygon', 'line', 'point'] }); diff --git a/tests/cases/choroplethFeature.js b/tests/cases/choroplethFeature.js index 3130f004cf..2b1fae74fc 100644 --- a/tests/cases/choroplethFeature.js +++ b/tests/cases/choroplethFeature.js @@ -1,22 +1,14 @@ // Test geo.choroplethFeature and geo.gl.choroplethFeature -var $ = require('jquery'); var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; +var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; describe('geo.choroplethFeature', function () { 'use strict'; - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - var mpdata = [{ 'type': 'Feature', 'geometry': { @@ -90,50 +82,51 @@ describe('geo.choroplethFeature', function () { } }]; - describe('create', function () { - it('create function', function () { - mockVGLRenderer(); - var map, layer, choropleth; - map = create_map(); - layer = map.createLayer('feature', {renderer: 'vgl'}); - choropleth = layer.createFeature('choropleth'); - expect(choropleth instanceof geo.choroplethFeature).toBe(true); - restoreVGLRenderer(); - }); + beforeEach(function () { + mockVGLRenderer(); + }); + + afterEach(function () { + destroyMap(); + restoreVGLRenderer(); + }); - it('direct creation', function () { - mockVGLRenderer(); - var map, layer, choropleth; - map = create_map(); - layer = map.createLayer('feature', {renderer: 'vgl'}); - choropleth = geo.choroplethFeature({layer: layer}); - expect(choropleth instanceof geo.choroplethFeature).toBe(true); - restoreVGLRenderer(); - }); + it('create function', function () { + var map, layer, choropleth; + map = createMap(); + layer = map.createLayer('feature', {renderer: 'vgl'}); + choropleth = layer.createFeature('choropleth'); + expect(choropleth instanceof geo.choroplethFeature).toBe(true); + }); + + it('direct creation', function () { + var map, layer, choropleth; + map = createMap(); + layer = map.createLayer('feature', {renderer: 'vgl'}); + choropleth = geo.choroplethFeature({layer: layer}); + expect(choropleth instanceof geo.choroplethFeature).toBe(true); + }); - it('multipolygon', function () { - mockVGLRenderer(); - var map, layer, choropleth, scalarData = [ - {'id': 0, 'value': 10} - ]; + it('multipolygon', function () { + var map, layer, choropleth, scalarData = [ + {'id': 0, 'value': 10} + ]; - map = create_map(); - layer = map.createLayer('feature', {renderer: 'vgl'}); + map = createMap(); + layer = map.createLayer('feature', {renderer: 'vgl'}); - choropleth = layer.createFeature('choropleth') - .data(mpdata) - .scalar(scalarData); - choropleth.choropleth('name', 'multipolygon'); - expect(choropleth instanceof geo.choroplethFeature).toBe(true); - expect(choropleth.choropleth('name')).toBe('multipolygon'); - expect(choropleth.choropleth.get('accessors')() - .scalarValue(scalarData[0])).toBe(10); - expect(choropleth.choropleth.get('accessors')() - .geoId(mpdata[0])).toBe(0); - expect(Object.keys(choropleth.choropleth.get())).toEqual([ - 'colorRange', 'scale', 'accessors', 'scalar', - 'scalarAggregator', 'name']); - restoreVGLRenderer(); - }); + choropleth = layer.createFeature('choropleth') + .data(mpdata) + .scalar(scalarData); + choropleth.choropleth('name', 'multipolygon'); + expect(choropleth instanceof geo.choroplethFeature).toBe(true); + expect(choropleth.choropleth('name')).toBe('multipolygon'); + expect(choropleth.choropleth.get('accessors')() + .scalarValue(scalarData[0])).toBe(10); + expect(choropleth.choropleth.get('accessors')() + .geoId(mpdata[0])).toBe(0); + expect(Object.keys(choropleth.choropleth.get())).toEqual([ + 'colorRange', 'scale', 'accessors', 'scalar', + 'scalarAggregator', 'name']); }); }); diff --git a/tests/cases/colorLegend.js b/tests/cases/colorLegend.js index 310006a63c..9895d44c09 100644 --- a/tests/cases/colorLegend.js +++ b/tests/cases/colorLegend.js @@ -1,6 +1,6 @@ var $ = require('jquery'); +var createMap = require('../test-utils').createMap; var colorbrewer = require('colorbrewer'); -var geo = require('../test-utils').geo; describe('color legend', function () { 'use strict'; @@ -71,16 +71,8 @@ describe('color legend', function () { ]; beforeEach(function () { - container = $('
') - .css({ width: '500px', height: '400px' }).appendTo('body'); - map = geo.map({ - 'node': container, - 'center': [0, 0], - 'zoom': 2, - 'clampZoom': false, - 'clampBoundsX': false, - 'clampBoundsY': false - }); + map = createMap(); + container = map.node(); uiLayer = map.createLayer('ui'); legendWidget = uiLayer.createWidget('colorLegend', { categories: [allCategories[0]] @@ -88,11 +80,6 @@ describe('color legend', function () { map.draw(); }); - afterEach(function () { - map.exit(); - container.remove(); - }); - it('Create basic color legend widget', function () { expect($(container).find('.legend').length).toBe(1); }); diff --git a/tests/cases/contourWrap.js b/tests/cases/contourWrap.js index 92bc9d950b..ae0f31546e 100644 --- a/tests/cases/contourWrap.js +++ b/tests/cases/contourWrap.js @@ -1,35 +1,35 @@ -var $ = require('jquery'); - describe('Contour Feature', function () { 'use strict'; var map, layer; var geo = require('../test-utils').geo; + var createMap = require('../test-utils').createMap; + var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; beforeEach(function () { - $('
') - .css({width: '500px', height: '300px'}).appendTo('body'); - mockVGLRenderer(); - map = geo.map({ - 'node': '#map-contour-wrap', + map = createMap({ 'center': [0, 0], 'zoom': 3 - }); + }, {width: '500px', height: '300px'}); layer = map.createLayer('feature', {'renderer': 'vgl'}); }); afterEach(function () { - map.exit(); - $('#map-contour-wrap').remove(); + destroyMap(); restoreVGLRenderer(); }); it('Create a contour', function () { var contour1 = { - gridWidth: 7, gridHeight: 2, x0: -30, y0: -30, dx: 6, dy: 6, + gridWidth: 7, + gridHeight: 2, + x0: -30, + y0: -30, + dx: 6, + dy: 6, values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] }; var contour = layer.createFeature('contour').data( @@ -44,7 +44,12 @@ describe('Contour Feature', function () { it('Create a contour that will wrap and close', function () { var contour1 = { - gridWidth: 6, gridHeight: 2, x0: 30, y0: -30, dx: 60, dy: 60, + gridWidth: 6, + gridHeight: 2, + x0: 30, + y0: -30, + dx: 60, + dy: 60, values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] }; var contour = layer.createFeature('contour').data( @@ -59,7 +64,12 @@ describe('Contour Feature', function () { it('Create a contour and ask it to not wrap', function () { var contour1 = { - gridWidth: 6, gridHeight: 2, x0: 30, y0: -30, dx: 60, dy: 60, + gridWidth: 6, + gridHeight: 2, + x0: 30, + y0: -30, + dx: 60, + dy: 60, values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], wrapLongitude: false }; @@ -74,7 +84,12 @@ describe('Contour Feature', function () { it('Create a contour that will wrap but not close', function () { var contour1 = { - gridWidth: 6, gridHeight: 2, x0: 55, y0: -25, dx: 50, dy: 50, + gridWidth: 6, + gridHeight: 2, + x0: 55, + y0: -25, + dx: 50, + dy: 50, values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] }; var contour = layer.createFeature('contour').data( diff --git a/tests/cases/d3GraphFeature.js b/tests/cases/d3GraphFeature.js index 104b25392b..78b1135bb1 100644 --- a/tests/cases/d3GraphFeature.js +++ b/tests/cases/d3GraphFeature.js @@ -1,19 +1,9 @@ describe('d3 graph feature', function () { - var geo = require('../test-utils').geo; - var $ = require('jquery'); + var createMap = require('../test-utils').createMap; var mockAnimationFrame = require('../test-utils').mockAnimationFrame; var stepAnimationFrame = require('../test-utils').stepAnimationFrame; var unmockAnimationFrame = require('../test-utils').unmockAnimationFrame; - beforeEach(function () { - $('
') - .css({width: '500px', height: '400px'}).appendTo('body'); - }); - - afterEach(function () { - $('#map-d3-graph-feature').remove(); - }); - describe('d3 graph feature', function () { 'use strict'; @@ -21,7 +11,7 @@ describe('d3 graph feature', function () { it('Setup map', function () { mockAnimationFrame(); - map = geo.map({node: '#map-d3-graph-feature', center: [0, 0], zoom: 3}); + map = createMap({center: [0, 0], zoom: 3}); layer = map.createLayer('feature', {'renderer': 'd3'}); }); diff --git a/tests/cases/d3PointFeature.js b/tests/cases/d3PointFeature.js index cb778ac0a1..f8dcb7c98e 100644 --- a/tests/cases/d3PointFeature.js +++ b/tests/cases/d3PointFeature.js @@ -1,30 +1,18 @@ describe('d3 point feature', function () { - var geo = require('../test-utils').geo; - var $ = require('jquery'); + var createMap = require('../test-utils').createMap; var mockAnimationFrame = require('../test-utils').mockAnimationFrame; var stepAnimationFrame = require('../test-utils').stepAnimationFrame; var unmockAnimationFrame = require('../test-utils').unmockAnimationFrame; - beforeEach(function () { - $('
') - .css({width: '500px', height: '400px'}).appendTo('body'); - }); - - afterEach(function () { - $('#map-d3-point-feature').remove(); - }); - describe('d3 point feature', function () { 'use strict'; - var map, width = 800, height = 600, layer, feature1, feature2; + var map, layer, feature1, feature2; it('Setup map', function () { mockAnimationFrame(); - map = geo.map({node: '#map-d3-point-feature', center: [0, 0], zoom: 3}); + map = createMap({center: [0, 0], zoom: 3}, {width: '800px', height: '600px'}); layer = map.createLayer('feature', {'renderer': 'd3'}); - - map.size({width: width, height: height}); }); it('Add features to a layer', function () { diff --git a/tests/cases/d3VectorFeature.js b/tests/cases/d3VectorFeature.js index 357bf25cc5..fce3fcacf5 100644 --- a/tests/cases/d3VectorFeature.js +++ b/tests/cases/d3VectorFeature.js @@ -1,4 +1,4 @@ -var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; var d3 = require('d3'); var mockAnimationFrame = require('../test-utils').mockAnimationFrame; var stepAnimationFrame = require('../test-utils').stepAnimationFrame; @@ -11,8 +11,7 @@ describe('d3 vector feature', function () { it('Create a map with a d3 feature layer', function () { mockAnimationFrame(); - d3.select('body').append('div').attr('id', 'map-d3-vector'); - map = geo.map({node: '#map-d3-vector', + map = createMap({ center: [0, 0], zoom: 3, width: 100, @@ -60,7 +59,7 @@ describe('d3 vector feature', function () { .draw(); stepAnimationFrame(); - vectorLines = d3.select('#map-d3-vector svg').selectAll('line'); + vectorLines = d3.select('#map').selectAll('line'); expect(vectorLines.size()).toBe(3); featureGroup = d3.selectAll('g#' + feature1._d3id()); @@ -84,7 +83,7 @@ describe('d3 vector feature', function () { layer.deleteFeature(feature1).draw(); stepAnimationFrame(); - selection = d3.select('#map-d3-vector svg').selectAll('line'); + selection = d3.select('#map').selectAll('line'); expect(selection.size()).toBe(0); markers = d3.selectAll('markers'); @@ -119,7 +118,7 @@ describe('d3 vector feature', function () { .draw(); stepAnimationFrame(); - vectorLines = d3.select('#map-d3-vector svg').selectAll('line'); + vectorLines = d3.select('#map').selectAll('line'); expect(vectorLines.size()).toBe(3); vectorLines.each(function (v, i) { @@ -138,9 +137,7 @@ describe('d3 vector feature', function () { }); - it('Delete the map', function () { - map.exit(); - d3.select('#map-d3-vector').remove(); + it('Cleanup', function () { unmockAnimationFrame(); }); }); diff --git a/tests/cases/discreteZoom.js b/tests/cases/discreteZoom.js index b2b07090a6..6f1155b947 100644 --- a/tests/cases/discreteZoom.js +++ b/tests/cases/discreteZoom.js @@ -1,12 +1,10 @@ -var geo = require('../test-utils').geo; -var $ = require('jquery'); +var createMap = require('../test-utils').createMap; describe('DiscreteZoom and ParallelProjection', function () { 'use strict'; function makeMap() { - var map = geo.map({ - 'node': '#map-discrete-zoom', + var map = createMap({ 'center': [0, 0], 'zoom': 3, discreteZoom: true @@ -15,15 +13,6 @@ describe('DiscreteZoom and ParallelProjection', function () { return map; } - beforeEach(function () { - $('
') - .css({width: '800px', height: '800px'}).appendTo('body'); - }); - - afterEach(function () { - $('#map-discrete-zoom').remove(); - }); - it('Zoom to a non-integer value', function () { var map = makeMap(); expect(map.discreteZoom()).toBe(true); diff --git a/tests/cases/feature.js b/tests/cases/feature.js index 522610dae9..7c4cd79a72 100644 --- a/tests/cases/feature.js +++ b/tests/cases/feature.js @@ -1,7 +1,7 @@ // Test geo.feature var geo = require('../test-utils').geo; -var $ = require('jquery'); +var createMap = require('../test-utils').createMap; describe('geo.feature', function () { 'use strict'; @@ -13,19 +13,10 @@ describe('geo.feature', function () { console.warn.restore(); }); - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('create', function () { it('create function', function () { var map, layer, feat; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); feat = geo.feature.create(); @@ -60,7 +51,7 @@ describe('geo.feature', function () { var map, layer, feat, points = {index: [], found: []}, box = [], events = {}; it('_init', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); expect(function () { geo.feature(); @@ -163,7 +154,7 @@ describe('geo.feature', function () { describe('Check public class methods', function () { var map, layer, feat; it('pointSearch', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); feat = geo.feature({layer: layer, renderer: layer.renderer()}); expect(feat.pointSearch()).toEqual({index: [], found: []}); @@ -251,7 +242,7 @@ describe('geo.feature', function () { describe('Check class accessors', function () { var map, layer, feat; it('style', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); feat = geo.feature({layer: layer, renderer: layer.renderer()}); expect(feat.style()).toEqual({opacity: 1}); diff --git a/tests/cases/featureLayer.js b/tests/cases/featureLayer.js index 9dcfe3f239..808628cf8c 100644 --- a/tests/cases/featureLayer.js +++ b/tests/cases/featureLayer.js @@ -1,7 +1,7 @@ // Test geo.featureLayer var geo = require('../test-utils').geo; -var $ = require('jquery'); +var createMap = require('../test-utils').createMap; describe('geo.featureLayer', function () { 'use strict'; @@ -13,20 +13,11 @@ describe('geo.featureLayer', function () { console.log.restore(); }); - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('create', function () { it('create function', function () { var map, layer; - map = create_map(); + map = createMap(); layer = geo.featureLayer({map: map}); expect(layer instanceof geo.featureLayer).toBe(true); expect(layer.initialized()).toBe(false); @@ -39,7 +30,7 @@ describe('geo.featureLayer', function () { describe('Check private class methods', function () { var map, layer; it('_init', function () { - map = create_map(); + map = createMap(); layer = geo.featureLayer({map: map}); expect(layer.initialized()).toBe(false); layer._init(); @@ -68,7 +59,7 @@ describe('geo.featureLayer', function () { describe('Check public class methods', function () { var map, layer, feat1, feat2, feat3; it('createFeature', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); feat1 = layer.createFeature('point'); diff --git a/tests/cases/geojsonReader.js b/tests/cases/geojsonReader.js index c653859336..f586f821ba 100644 --- a/tests/cases/geojsonReader.js +++ b/tests/cases/geojsonReader.js @@ -1,15 +1,6 @@ describe('geojsonReader', function () { var geo = require('../test-utils').geo; - var $ = require('jquery'); - - beforeEach(function () { - $('
') - .css({width: '800px', height: '600px'}).appendTo('body'); - }); - - afterEach(function () { - $('#map-geojson-reader').remove(); - }); + var createMap = require('../test-utils').createMap; describe('geojsonReader', function () { 'use strict'; @@ -20,14 +11,13 @@ describe('geojsonReader', function () { var reader; beforeEach(function () { - map = geo.map({node: '#map-geojson-reader', center: [0, 0], zoom: 3}); + map = createMap({center: [0, 0], zoom: 3}); layer = map.createLayer('feature', {renderer: 'd3'}); sinon.stub(layer, 'createFeature'); reader = geo.createFileReader('jsonReader', {'layer': layer}); }); afterEach(function () { layer.createFeature.restore(); - map.exit(); }); describe('bare geometry', function () { @@ -277,7 +267,7 @@ describe('geojsonReader', function () { }); it('Setup map', function () { - map = geo.map({node: '#map-geojson-reader', center: [0, 0], zoom: 3}); + map = createMap({center: [0, 0], zoom: 3}); layer = map.createLayer('feature', {renderer: 'd3'}); obj = { diff --git a/tests/cases/heatmap.js b/tests/cases/heatmap.js index e1026a9066..4638d77418 100644 --- a/tests/cases/heatmap.js +++ b/tests/cases/heatmap.js @@ -1,16 +1,6 @@ // Test geo.core.heatmap describe('canvas heatmap', function () { - var geo = require('../test-utils').geo; - var $ = require('jquery'); - - beforeEach(function () { - $('
') - .css({width: '500px', height: '400px'}).appendTo('body'); - }); - - afterEach(function () { - $('#map-canvas-heatmap-feature').remove(); - }); + var createMap = require('../test-utils').createMap; describe('canvas heatmap feature', function () { 'use strict'; @@ -19,7 +9,7 @@ describe('canvas heatmap', function () { var stepAnimationFrame = require('../test-utils').stepAnimationFrame; var unmockAnimationFrame = require('../test-utils').unmockAnimationFrame; - var map, width = 800, height = 600, layer, feature1, + var map, layer, feature1, testData = [[0.6, 42.8584, -70.9301], [0.233, 42.2776, -83.7409], [0.2, 42.2776, -83.7409]]; @@ -33,9 +23,8 @@ describe('canvas heatmap', function () { it('Setup map', function () { mockAnimationFrame(); - map = geo.map({node: '#map-canvas-heatmap-feature', center: [0, 0], zoom: 3}); + map = createMap({center: [0, 0], zoom: 3}, {width: '800px', height: '600px'}); layer = map.createLayer('feature', {'renderer': 'canvas'}); - map.size({width: width, height: height}); }); it('Add feature to a layer', function () { @@ -77,11 +66,12 @@ describe('canvas heatmap', function () { }); it('Compute gradient', function () { - feature1.style('color', {0: {r: 0, g: 0, b: 0.0, a: 0.0}, - 0.25: {r: 0, g: 0, b: 1, a: 0.5}, - 0.5: {r: 0, g: 1, b: 1, a: 0.6}, - 0.75: {r: 1, g: 1, b: 0, a: 0.7}, - 1: {r: 1, g: 0, b: 0, a: 0.1}}); + feature1.style('color', { + 0: {r: 0, g: 0, b: 0.0, a: 0.0}, + 0.25: {r: 0, g: 0, b: 1, a: 0.5}, + 0.5: {r: 0, g: 1, b: 1, a: 0.6}, + 0.75: {r: 1, g: 1, b: 0, a: 0.7}, + 1: {r: 1, g: 0, b: 0, a: 0.1}}); feature1._computeGradient(); expect(layer.node()[0].children[0].getContext('2d') .getImageData(1, 0, 1, 1).data.length).toBe(4); @@ -187,7 +177,7 @@ describe('canvas heatmap', function () { var data = []; it('Setup map', function () { - map = geo.map({node: '#map-canvas-heatmap-feature', center: [0, 0], zoom: 3}); + map = createMap({center: [0, 0], zoom: 3}); layer = map.createLayer('feature', {'renderer': 'canvas'}); for (var i = 0; i < 100; i += 1) { data.push({a: i % 10, b: i % 9, c: i % 8}); @@ -247,9 +237,11 @@ describe('canvas heatmap', function () { })).toBe(heatmap); expect(heatmap.position()(data[0])).toEqual({x: 0, y: 0}); expect(heatmap.position()(data[84])).toEqual({x: 4, y: 3}); - heatmap = heatmapFeature({layer: layer, position: function (d) { - return {x: d.b, y: d.c}; - }}); + heatmap = heatmapFeature({ + layer: layer, + position: function (d) { + return {x: d.b, y: d.c}; + }}); expect(heatmap.position()(data[0])).toEqual({x: 0, y: 0}); expect(heatmap.position()(data[87])).toEqual({x: 6, y: 7}); }); @@ -261,20 +253,25 @@ describe('canvas heatmap', function () { })).toBe(heatmap); expect(heatmap.intensity()(data[0])).toEqual(0); expect(heatmap.intensity()(data[67])).toEqual(3); - heatmap = heatmapFeature({layer: layer, intensity: function (d) { - return d.a; - }}); + heatmap = heatmapFeature({ + layer: layer, + intensity: function (d) { + return d.a; + }}); expect(heatmap.intensity()(data[0])).toEqual(0); expect(heatmap.intensity()(data[67])).toEqual(7); }); }); describe('_build', function () { it('intensity ranges', function () { - var heatmap = heatmapFeature({layer: layer, position: function (d) { - return {x: d.a, y: d.b}; - }, intensity: function (d) { - return d.c; - }}).data(data); + var heatmap = heatmapFeature({ + layer: layer, + position: function (d) { + return {x: d.a, y: d.b}; + }, + intensity: function (d) { + return d.c; + }}).data(data); heatmap.gcs('EPSG:3857'); heatmap._build(); expect(heatmap.minIntensity()).toBe(0); @@ -286,9 +283,11 @@ describe('canvas heatmap', function () { expect(heatmap.maxIntensity()).toBe(2); }); it('gcsPosition', function () { - var heatmap = heatmapFeature({layer: layer, position: function (d) { - return {x: d.a, y: d.b}; - }}).data(data); + var heatmap = heatmapFeature({ + layer: layer, + position: function (d) { + return {x: d.a, y: d.b}; + }}).data(data); heatmap.gcs('EPSG:3857'); // we have to call build since we didn't attach this to the layer in the // normal way diff --git a/tests/cases/layerReorder.js b/tests/cases/layerReorder.js index f002d5472f..526ca9b64e 100644 --- a/tests/cases/layerReorder.js +++ b/tests/cases/layerReorder.js @@ -1,34 +1,4 @@ -var geo = require('../test-utils').geo; - -// Generate a new empty map -function createMap() { - 'use strict'; - - var $ = require('jquery'); - var node = $('
').css({ - width: '100px', - height: '100px' - }); - - $('#map').remove(); - $('body').append(node); - var map = geo.map({node: '#map', width: 100, height: 100}), - cl = map.createLayer; - // inject d3 renderer to let this work in phantom - map.createLayer = function (type, opts) { - opts = opts || {}; - opts.renderer = 'd3'; - return cl.call(map, type, opts); - }; - // over-ride map.displayToGcs to work with no base layer - map.displayToGcs = function (pt) { - return pt; - }; - map.gcsToDisplay = function (pt) { - return pt; - }; - return map; -} +var createMap = require('../test-utils').createMap; describe('Test the zIndex property of layers', function () { 'use strict'; diff --git a/tests/cases/lineFeature.js b/tests/cases/lineFeature.js index 431a9189e4..08c22fd22d 100644 --- a/tests/cases/lineFeature.js +++ b/tests/cases/lineFeature.js @@ -6,6 +6,8 @@ var mockAnimationFrame = require('../test-utils').mockAnimationFrame; var stepAnimationFrame = require('../test-utils').stepAnimationFrame; var unmockAnimationFrame = require('../test-utils').unmockAnimationFrame; var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; +var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; var vgl = require('vgl'); @@ -41,19 +43,10 @@ describe('geo.lineFeature', function () { } ]; - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('create', function () { it('create function', function () { var map, layer, line; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); line = geo.lineFeature.create(layer); expect(line instanceof geo.lineFeature).toBe(true); @@ -64,7 +57,7 @@ describe('geo.lineFeature', function () { var map, layer, line; var pos = [[[0, 0], [10, 5], [5, 10]]]; it('position', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); line = geo.lineFeature({layer: layer}); expect(line.position()('a')).toBe('a'); @@ -78,7 +71,7 @@ describe('geo.lineFeature', function () { }); it('line', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); line = geo.lineFeature({layer: layer}); expect(line.line()('a')).toBe('a'); @@ -95,7 +88,7 @@ describe('geo.lineFeature', function () { describe('Public utility methods', function () { it('pointSearch', function () { var map, layer, line, pt, p, data = testLines; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); line = layer.createFeature('line', {selectionAPI: true}); line.data(data) @@ -171,7 +164,7 @@ describe('geo.lineFeature', function () { }); it('boxSearch', function () { var map, layer, line, idx, data = testLines; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); line = layer.createFeature('line', {selectionAPI: true}); line.data(data) @@ -201,7 +194,7 @@ describe('geo.lineFeature', function () { var map, layer, line; it('basic usage', function () { mockAnimationFrame(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); line = layer.createFeature('line', { line: function (item) { @@ -244,7 +237,7 @@ describe('geo.lineFeature', function () { it('basic usage', function () { mockAnimationFrame(); logCanvas2D(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); line = layer.createFeature('line', { line: function (item) { @@ -283,7 +276,7 @@ describe('geo.lineFeature', function () { it('basic usage', function () { mockVGLRenderer(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'vgl'}); line = layer.createFeature('line', { line: function (item) { @@ -321,6 +314,7 @@ describe('geo.lineFeature', function () { expect(line.actors().length).toBe(0); line.data(testLines); map.draw(); + destroyMap(); restoreVGLRenderer(); }); }); diff --git a/tests/cases/map.js b/tests/cases/map.js index 08d330ecb9..f137cb2026 100644 --- a/tests/cases/map.js +++ b/tests/cases/map.js @@ -5,38 +5,30 @@ describe('geo.core.map', function () { var $ = require('jquery'); var geo = require('../test-utils').geo; + var createMap = require('../test-utils').createMap; var closeToEqual = require('../test-utils').closeToEqual; var mockAnimationFrame = require('../test-utils').mockAnimationFrame; var stepAnimationFrame = require('../test-utils').stepAnimationFrame; var unmockAnimationFrame = require('../test-utils').unmockAnimationFrame; - function create_map(opts) { - var node = $('
').css({width: '500px', height: '500px'}); - $('#map-create-map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - afterEach(function () { - $('#map-create-map').remove(); + $('#map').remove(); $(window).off('resize'); }); describe('create function', function () { it('basic create', function () { var map; - map = create_map(); + map = createMap(); expect(map instanceof geo.map).toBe(true); - expect(map.node().attr('id')).toBe('map-create-map'); + expect(map.node().attr('id')).toBe('map'); expect(map.gcs()).toBe('EPSG:3857'); expect(map.ingcs()).toBe('EPSG:4326'); expect(map.zoom()).toBe(4); expect(closeToEqual(map.center(), {x: 0, y: 0, z: 0})).toBe(true); expect(map.rotation()).toBe(0); expect(map.maxBounds().left).toBeLessThan(-179); - expect(map.size().width).toBe(500); + expect(map.size().width).toBe(640); expect(map.zoomRange().max).toEqual(16); expect(map.zoomRange().origMin).toEqual(0); expect(map.discreteZoom()).toBe(false); @@ -50,7 +42,7 @@ describe('geo.core.map', function () { }); it('create with options', function () { var map; - map = create_map({ + map = createMap({ ingcs: '+proj=longlat +axis=esu', gcs: '+proj=longlat +axis=enu', zoom: 6, @@ -67,7 +59,7 @@ describe('geo.core.map', function () { clampZoom: false }); expect(map instanceof geo.map).toBe(true); - expect(map.node().attr('id')).toBe('map-create-map'); + expect(map.node().attr('id')).toBe('map'); expect(map.gcs()).toBe('+proj=longlat +axis=enu'); expect(map.ingcs()).toBe('+proj=longlat +axis=esu'); expect(map.zoom()).toBe(6); @@ -75,7 +67,7 @@ describe('geo.core.map', function () { expect(map.rotation()).toBe(1); expect(map.maxBounds().left).toBe(0); expect(map.maxBounds().right).toBe(50000); - expect(map.size().width).toBe(500); + expect(map.size().width).toBe(640); expect(map.zoomRange().max).toEqual(9); expect(map.zoomRange().origMin).toEqual(3); expect(map.discreteZoom()).toBe(true); @@ -89,7 +81,7 @@ describe('geo.core.map', function () { describe('Check class accessors', function () { it('clampBounds', function () { - var m = create_map(); + var m = createMap(); var axes = {'X': false, 'Y': true}; $.each(axes, function (axis, defaultSetting) { var func = m['clampBounds' + axis]; @@ -103,10 +95,10 @@ describe('geo.core.map', function () { }); }); it('clampZoom and zoomRange', function () { - var m = create_map(), zr; + var m = createMap(), zr; expect(m.clampZoom()).toBe(true); zr = m.zoomRange(); - expect(zr.min).toBeCloseTo(Math.log2(500 / 256), 2); + expect(zr.min).toBeCloseTo(Math.log2(360 / 256), 2); expect(zr.origMin).toBe(0); expect(zr.max).toBe(16); m.clampZoom(false); @@ -114,7 +106,7 @@ describe('geo.core.map', function () { expect(m.zoomRange().min).toBe(0); m.clampZoom(true); expect(m.clampZoom()).toBe(true); - expect(zr.min).toBeCloseTo(Math.log2(500 / 256), 2); + expect(zr.min).toBeCloseTo(Math.log2(360 / 256), 2); m.zoomRange({min: 1, max: 2}); zr = m.zoomRange(); expect(zr.min).toBe(1); @@ -122,12 +114,12 @@ describe('geo.core.map', function () { expect(zr.max).toBe(2); m.zoomRange({min: 0}); zr = m.zoomRange(); - expect(zr.min).toBeCloseTo(Math.log2(500 / 256), 2); + expect(zr.min).toBeCloseTo(Math.log2(360 / 256), 2); expect(zr.origMin).toBe(0); expect(zr.max).toBe(2); }); it('allowRotation', function () { - var m = create_map(); + var m = createMap(); expect(m.allowRotation()).toBe(true); m.rotation(0); expect(m.rotation()).toBe(0); @@ -159,9 +151,9 @@ describe('geo.core.map', function () { expect(m.rotation()).toBeCloseTo(17 * Math.PI / 180); }); it('size and rotatedSize', function () { - var m = create_map(); - expect(m.size()).toEqual({width: 500, height: 500}); - expect(m.rotatedSize()).toEqual({width: 500, height: 500}); + var m = createMap(); + expect(m.size()).toEqual({width: 640, height: 360}); + expect(m.rotatedSize()).toEqual({width: 640, height: 360}); m.size({width: 400, height: 300}); expect(m.size()).toEqual({width: 400, height: 300}); expect(m.rotatedSize()).toEqual({width: 400, height: 300}); @@ -189,7 +181,7 @@ describe('geo.core.map', function () { })).toBe(true); }); it('unitsPerPixel', function () { - var m = create_map(), circEarth = 6378137 * Math.PI * 2; + var m = createMap(), circEarth = 6378137 * Math.PI * 2; m.createLayer('feature', {renderer: 'd3'}); expect(m.unitsPerPixel()).toBeCloseTo(circEarth / 256); expect(m.unitsPerPixel(0)).toBeCloseTo(circEarth / 256); @@ -204,7 +196,7 @@ describe('geo.core.map', function () { }); it('animationQueue', function () { mockAnimationFrame(); - var m = create_map(), queue = [], queue2 = [], + var m = createMap(), queue = [], queue2 = [], queue3 = [window.requestAnimationFrame(function () { })]; expect(m.animationQueue()).toEqual([]); expect(m.animationQueue()).not.toBe(queue); @@ -221,7 +213,7 @@ describe('geo.core.map', function () { unmockAnimationFrame(); }); it('autoResize', function () { - var m = create_map(); + var m = createMap(); expect(m.autoResize()).toBe(true); expect(m.autoResize(false)).toBe(m); expect(m.autoResize()).toBe(false); @@ -229,8 +221,10 @@ describe('geo.core.map', function () { expect(m.autoResize()).toBe(true); }); it('gcs and ingcs', function () { - var m = create_map(), units = m.unitsPerPixel(), bounds; - var error = console.error; + var m = createMap(undefined, {width: '500px', height: '500px'}), + units = m.unitsPerPixel(), + bounds, + error = console.error; expect(m.gcs()).toBe('EPSG:3857'); expect(m.ingcs()).toBe('EPSG:4326'); m.bounds({left: -180, top: 5, right: 180, bottom: -5}); @@ -316,7 +310,7 @@ describe('geo.core.map', function () { console.error = error; }); it('maxBounds', function () { - var m = create_map(); + var m = createMap(); expect(closeToEqual(m.maxBounds(), { left: -180, top: 85.05, right: 180, bottom: -85.05})).toBe(true); m.maxBounds({left: -90, right: 20, top: 40, bottom: -60}); @@ -324,7 +318,7 @@ describe('geo.core.map', function () { left: -90, right: 20, top: 40, bottom: -60})).toBe(true); }); it('zoom and discreteZoom', function () { - var m = create_map(); + var m = createMap(undefined, {width: '500px', height: '500px'}); expect(m.zoom()).toBe(4); expect(m.discreteZoom()).toBe(false); m.zoom(3.5); @@ -359,7 +353,7 @@ describe('geo.core.map', function () { expect(m.zoom()).toBe(2); }); it('rotation', function () { - var m = create_map(); + var m = createMap(); expect(m.rotation()).toBe(0); m.rotation(1); expect(m.rotation()).toBe(1); @@ -376,7 +370,7 @@ describe('geo.core.map', function () { expect(m.rotation()).toBeCloseTo(17 - Math.PI * 4); }); it('fileReader', function () { - var m = create_map(); + var m = createMap(); expect(m.fileReader()).toBe(null); var layerCount = m.layers().length; expect(m.fileReader('jsonReader')).toBe(m); @@ -413,21 +407,21 @@ describe('geo.core.map', function () { } it('exit', function () { - var m = create_map(); + var m = createMap(); m.updateAttribution('Sample'); expect(count_events(m.node(), 'geo')).toBeGreaterThan(0); m.exit(); expect(count_events(m.node(), 'geo')).toBe(0); - expect($('#map-create-map').children().length).toBe(0); + expect($('#map').children().length).toBe(0); }); it('pan, clampBoundsX, and clampBoundsY', function () { - var m = create_map({ + var m = createMap({ unitsPerPixel: 16, gcs: '+proj=longlat +axis=enu', ingcs: '+proj=longlat +axis=esu', maxBounds: {left: -2048, right: 2048, top: -2048, bottom: 2048}, max: 4 - }); + }, {width: '500px', height: '500px'}); expect(closeToEqual(m.center(), {x: 0, y: 0, z: 0})).toBe(true); m.pan({x: -128, y: 0}); expect(closeToEqual(m.center(), {x: 128, y: 0, z: 0})).toBe(true); @@ -481,13 +475,13 @@ describe('geo.core.map', function () { }); it('zoomAndCenterFromBounds', function () { var zc; - var m = create_map({ + var m = createMap({ unitsPerPixel: 16, gcs: '+proj=longlat +axis=enu', ingcs: '+proj=longlat +axis=esu', maxBounds: {left: -2048, right: 2048, top: -2048, bottom: 2048}, max: 4 - }); + }, {width: '500px', height: '500px'}); zc = m.zoomAndCenterFromBounds({ left: -250, top: -250, right: 250, bottom: 250}); expect(zc.zoom).toBeCloseTo(4); @@ -515,7 +509,7 @@ describe('geo.core.map', function () { }); it('transition', function () { mockAnimationFrame(); - var m = create_map(), start, wasCalled; + var m = createMap(), start, wasCalled; expect(m.transition()).toBe(null); start = new Date().getTime(); m.transition({ @@ -677,8 +671,8 @@ describe('geo.core.map', function () { unmockAnimationFrame(); }); it('node class and data attribute', function () { - var selector = '#map-create-map'; - var m = create_map(); + var selector = '#map'; + var m = createMap(); expect($(selector).hasClass('geojs-map')).toBe(true); expect($(selector).data('data-geojs-map')).toBe(m); m.createLayer('feature'); @@ -696,7 +690,7 @@ describe('geo.core.map', function () { var ss = {}; it('basic', function (done) { - m = create_map({ + m = createMap({ width: 64, height: 48, zoom: 2, center: {x: 7.5, y: 7.5}}); layer1 = m.createLayer('feature', {renderer: 'canvas'}); l1 = layer1.createFeature('line', { @@ -849,15 +843,15 @@ describe('geo.core.map', function () { describe('Internal methods', function () { it('resizeSelf', function () { - var m = create_map(); - expect(m.size()).toEqual({width: 500, height: 500}); - $('#map-create-map').css({width: '400px', height: '400px'}); - expect(m.size()).toEqual({width: 500, height: 500}); + var m = createMap(); + expect(m.size()).toEqual({width: 640, height: 360}); + $('#map').css({width: '400px', height: '400px'}); + expect(m.size()).toEqual({width: 640, height: 360}); $(window).trigger('resize'); expect(m.size()).toEqual({width: 400, height: 400}); }); it('dragover', function () { - var m = create_map(); + var m = createMap(); var evt = $.Event('dragover'); evt.originalEvent = new window.Event('dragover'); evt.originalEvent.dataTransfer = {}; @@ -871,7 +865,7 @@ describe('geo.core.map', function () { expect(evt.originalEvent.dataTransfer.dropEffect).toBe('copy'); }); it('drop', function () { - var m = create_map(); + var m = createMap(); m.fileReader('jsonReader', {renderer: 'd3'}); var evt = $.Event('drop'); evt.originalEvent = new window.Event('drop'); diff --git a/tests/cases/mapAttribution.js b/tests/cases/mapAttribution.js index 50b9e000d7..96ddcf3eb7 100644 --- a/tests/cases/mapAttribution.js +++ b/tests/cases/mapAttribution.js @@ -2,25 +2,11 @@ describe('Test adding and remove attribution via layers', function () { 'use strict'; var $ = require('jquery'); - var geo = require('../test-utils').geo; - - beforeEach(function () { - $('
') - .css({width: '500px', height: '400px'}).appendTo('body'); - }); - - afterEach(function () { - $('#map-attribution').remove(); - }); - - // Generate a new empty map - function createMap() { - return geo.map({node: '#map-attribution'}); - } + var createMap = require('../test-utils').createMap; // Return all attribution nodes function getAttribution() { - return $('#map-attribution > .geo-attribution > .geo-attribution-layer'); + return $('#map > .geo-attribution > .geo-attribution-layer'); } it('Attribution added via constructor argument', function () { diff --git a/tests/cases/osmLayer.js b/tests/cases/osmLayer.js index cf4b929a33..c80fe4fa93 100644 --- a/tests/cases/osmLayer.js +++ b/tests/cases/osmLayer.js @@ -12,6 +12,8 @@ describe('geo.core.osmLayer', function () { var submitNote = require('../test-utils').submitNote; // var logCanvas2D = require('../test-utils').logCanvas2D; var geo = require('../test-utils').geo; + var createMap = require('../test-utils').createMap; + var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; var vgl = require('vgl'); @@ -19,21 +21,11 @@ describe('geo.core.osmLayer', function () { function create_map(opts) { mockVGLRenderer(); - var node = $('
').css({width: '640px', height: '360px'}); - $('#map-osm-layer').remove(); - /* Prepend because we want the map to be the first item so that its - * position doesn't change when data is added to the html reporter div. */ - $('body').prepend(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); + return createMap(opts); } function destroy_map() { - if (map) { - map.exit(); - } - $('#map-osm-layer').remove(); + destroyMap(); restoreVGLRenderer(); } diff --git a/tests/cases/pixelmapFeature.js b/tests/cases/pixelmapFeature.js index 14136bf95c..a7a316d8e7 100644 --- a/tests/cases/pixelmapFeature.js +++ b/tests/cases/pixelmapFeature.js @@ -3,6 +3,7 @@ /* globals Image */ var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; var $ = require('jquery'); var waitForIt = require('../test-utils').waitForIt; var logCanvas2D = require('../test-utils').logCanvas2D; @@ -28,19 +29,10 @@ describe('geo.pixelmapFeature', function () { } } - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('create', function () { var map, layer, pixelmap; it('create function', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = geo.pixelmapFeature.create(layer); expect(pixelmap instanceof geo.pixelmapFeature).toBe(true); @@ -56,7 +48,7 @@ describe('geo.pixelmapFeature', function () { describe('_init', function () { var map, layer, pixelmap; it('defaults', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); pixelmap = geo.pixelmapFeature({layer: layer}); pixelmap._init(); @@ -79,7 +71,7 @@ describe('geo.pixelmapFeature', function () { }); it('_exit', function () { var map, layer, pixelmap; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = geo.pixelmapFeature({layer: layer}); pixelmap._init({ @@ -93,7 +85,7 @@ describe('geo.pixelmapFeature', function () { }); it('_preparePixelmap', function () { var map, layer, pixelmap; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = geo.pixelmapFeature({layer: layer}); pixelmap._init({ @@ -117,7 +109,7 @@ describe('geo.pixelmapFeature', function () { it('_computePixelmap', function () { var map, layer, pixelmap, prepared = 0; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = geo.pixelmapFeature({layer: layer}); pixelmap._init({ @@ -148,7 +140,7 @@ describe('geo.pixelmapFeature', function () { var map, layer, pixelmap, buildTime; it('loading image', function (done) { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = layer.createFeature('pixelmap', { position: position, @@ -201,7 +193,7 @@ describe('geo.pixelmapFeature', function () { var map, layer, pixelmap, buildTime, updateTime; it('loading image', function (done) { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = layer.createFeature('pixelmap', { position: position, @@ -233,7 +225,7 @@ describe('geo.pixelmapFeature', function () { it('position', function () { var pos = {lr: {x: 0, y: 0}, ul: {x: 10, y: 5}}; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = layer.createFeature('pixelmap', { url: testImageSrc @@ -272,7 +264,7 @@ describe('geo.pixelmapFeature', function () { it('basic usage', function () { var map, layer, pixelmap, pt; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = layer.createFeature('pixelmap', { position: position, @@ -297,7 +289,7 @@ describe('geo.pixelmapFeature', function () { describe('geo.canvas.pixelmapFeature', function () { var map, layer, pixelmap, buildTime, counts; it('basic usage', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); pixelmap = layer.createFeature('pixelmap', { position: position, diff --git a/tests/cases/pointFeature.js b/tests/cases/pointFeature.js index 3af2f8ef50..18267ba55f 100644 --- a/tests/cases/pointFeature.js +++ b/tests/cases/pointFeature.js @@ -5,6 +5,8 @@ var mockAnimationFrame = require('../test-utils').mockAnimationFrame; var stepAnimationFrame = require('../test-utils').stepAnimationFrame; var unmockAnimationFrame = require('../test-utils').unmockAnimationFrame; var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; +var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; var vgl = require('vgl'); @@ -22,19 +24,10 @@ describe('geo.pointFeature', function () { {x: 50, y: 10}, {x: 50, y: 10}, {x: 60, y: 10} ]; - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('create', function () { it('create function', function () { var map, layer, point; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); point = geo.pointFeature.create(layer); expect(point instanceof geo.pointFeature).toBe(true); @@ -45,7 +38,7 @@ describe('geo.pointFeature', function () { var map, layer, point; var pos = [[0, 0], [10, 5], [5, 10]]; it('position', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); point = geo.pointFeature({layer: layer}); point._init(); @@ -63,7 +56,7 @@ describe('geo.pointFeature', function () { }); it('data', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); point = geo.pointFeature({layer: layer}); point._init(); @@ -74,7 +67,7 @@ describe('geo.pointFeature', function () { it('clustering', function () { var count = 0; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); point = geo.pointFeature({layer: layer}); point._init(); @@ -100,7 +93,7 @@ describe('geo.pointFeature', function () { describe('Public utility methods', function () { it('pointSearch', function () { var map, layer, point, pt, p, data = testPoints; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); point = layer.createFeature('point', {selectionAPI: true}); point.data(data) @@ -152,7 +145,7 @@ describe('geo.pointFeature', function () { }); it('boxSearch', function () { var map, layer, point, data = testPoints, idx; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); point = layer.createFeature('point', {selectionAPI: true}); point.data(data); @@ -168,7 +161,7 @@ describe('geo.pointFeature', function () { describe('Private utility methods', function () { it('_clusterData', function () { var map, layer, point, data = testPoints, count = 0; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); point = layer.createFeature('point'); point.data(data); @@ -190,7 +183,7 @@ describe('geo.pointFeature', function () { }); it('_handleZoom', function () { var map, layer, point, data = testPoints; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); point = layer.createFeature('point'); point.data(data); @@ -205,7 +198,7 @@ describe('geo.pointFeature', function () { }); it('_updateRangeTree', function () { var map, layer, point, data = testPoints.slice(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); point = layer.createFeature('point'); point.data(data); @@ -232,7 +225,7 @@ describe('geo.pointFeature', function () { var map, layer, point; it('basic usage', function () { mockAnimationFrame(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); point = layer.createFeature('point', { style: { @@ -265,7 +258,7 @@ describe('geo.pointFeature', function () { } it('basic usage', function () { mockVGLRenderer(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'vgl'}); point = layer.createFeature('point', { style: { @@ -331,6 +324,7 @@ describe('geo.pointFeature', function () { expect(point.actors().length).toBe(0); point.data(testPoints); map.draw(); + destroyMap(); restoreVGLRenderer(); }); }); diff --git a/tests/cases/polygonFeature.js b/tests/cases/polygonFeature.js index dc18a6233f..699252aeef 100644 --- a/tests/cases/polygonFeature.js +++ b/tests/cases/polygonFeature.js @@ -2,6 +2,8 @@ var $ = require('jquery'); var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; +var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; var vgl = require('vgl'); @@ -58,23 +60,15 @@ describe('geo.polygonFeature', function () { } }; - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('create', function () { it('create function', function () { mockVGLRenderer(); var map, layer, polygon; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'vgl'}); polygon = geo.polygonFeature.create(layer); expect(polygon instanceof geo.polygonFeature).toBe(true); + destroyMap(); restoreVGLRenderer(); }); }); @@ -83,7 +77,7 @@ describe('geo.polygonFeature', function () { var map, layer, polygon; var pos = [[[0, 0], [10, 5], [5, 10]]]; it('position', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); polygon = geo.polygonFeature({layer: layer}); polygon._init(); @@ -99,7 +93,7 @@ describe('geo.polygonFeature', function () { }); it('polygon', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); polygon = geo.polygonFeature({layer: layer}); polygon._init(); @@ -115,7 +109,7 @@ describe('geo.polygonFeature', function () { }); it('data', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); polygon = geo.polygonFeature({layer: layer}); polygon._init(); @@ -130,7 +124,7 @@ describe('geo.polygonFeature', function () { it('style', function () { mockVGLRenderer(); - map = create_map(); + map = createMap(); // we have to use a valid renderer so that the stroke can be enabled. layer = map.createLayer('feature', {renderer: 'vgl'}); polygon = geo.polygonFeature({layer: layer}); @@ -144,6 +138,7 @@ describe('geo.polygonFeature', function () { expect(polygon.style().stroke).toBe(false); expect(polygon.dependentFeatures()).toEqual([]); map.deleteLayer(layer); + destroyMap(); restoreVGLRenderer(); }); }); @@ -152,7 +147,7 @@ describe('geo.polygonFeature', function () { describe('pointSearch', function () { it('basic usage', function () { var map, layer, polygon, data, pt; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); polygon = geo.polygonFeature({layer: layer}); polygon._init(); @@ -189,7 +184,7 @@ describe('geo.polygonFeature', function () { it('arg gets added to style', function () { var polygon; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); polygon = geo.polygonFeature({layer: layer}); /* init is not automatically called on the geo.polygonFeature (it is on @@ -208,7 +203,7 @@ describe('geo.polygonFeature', function () { it('basic usage', function () { stylesVisited.splice(0, stylesVisited.length); mockVGLRenderer(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature'); polygons = layer.createFeature('polygon', {style: testStyle, data: testPolygons}); buildTime = polygons.buildTime().getMTime(); @@ -282,6 +277,7 @@ describe('geo.polygonFeature', function () { polygons.data(testPolygons); map.draw(); expect(buildTime).toEqual(polygons.buildTime().getMTime()); + destroyMap(); restoreVGLRenderer(); }); }); diff --git a/tests/cases/quadFeature.js b/tests/cases/quadFeature.js index 6e6e3e07f0..d2e8055185 100644 --- a/tests/cases/quadFeature.js +++ b/tests/cases/quadFeature.js @@ -5,6 +5,8 @@ var $ = require('jquery'); var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; +var destroyMap = require('../test-utils').destroyMap; var mockVGLRenderer = geo.util.mockVGLRenderer; var restoreVGLRenderer = geo.util.restoreVGLRenderer; var vgl = require('vgl'); @@ -138,15 +140,6 @@ describe('geo.quadFeature', function () { } }; - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - function load_preview_image(done) { if (!previewImage.src) { previewImage.onload = function () { @@ -162,10 +155,11 @@ describe('geo.quadFeature', function () { it('create function', function () { mockVGLRenderer(); var map, layer, quad; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'vgl'}); quad = geo.quadFeature.create(layer); expect(quad instanceof geo.quadFeature).toBe(true); + destroyMap(); restoreVGLRenderer(); }); }); @@ -175,7 +169,7 @@ describe('geo.quadFeature', function () { it('position', function () { var pos = {ll: {x: 0, y: 0}, ur: {x: 1, y: 1}}, quad; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); quad = geo.quadFeature({layer: layer}); quad._init(); @@ -192,7 +186,7 @@ describe('geo.quadFeature', function () { describe('pointSearch', function () { it('basic usage', function () { var map, layer, quad, data, pt; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); quad = geo.quadFeature({layer: layer}); quad._init(); @@ -230,7 +224,7 @@ describe('geo.quadFeature', function () { describe('cacheQuads and cacheUpdate', function () { it('cacheQuads unspecified', function () { var map, layer, quad, data; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); quad = geo.quadFeature({layer: layer}); quad._init(); @@ -261,7 +255,7 @@ describe('geo.quadFeature', function () { }); it('cacheQuads false', function () { var map, layer, quad, data; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); quad = geo.quadFeature({layer: layer}); quad._init({cacheQuads: false}); @@ -285,7 +279,7 @@ describe('geo.quadFeature', function () { describe('_object_list methods', function () { var map, layer, quad, olist = []; it('_objectListStart', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); quad = geo.quadFeature({layer: layer}); quad._objectListStart(olist); @@ -331,7 +325,7 @@ describe('geo.quadFeature', function () { it('arg gets added to style', function () { var pos = {ll: {x: 0, y: 0}, ur: {x: 1, y: 1}}, quad; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); quad = geo.quadFeature({layer: layer}); /* init is not automatically called on the geo.quadFeature (it is on @@ -448,7 +442,7 @@ describe('geo.quadFeature', function () { it('load preview image', load_preview_image); it('overall generation', function () { - map = create_map({gcs: 'EPSG:4326'}); + map = createMap({gcs: 'EPSG:4326'}); layer = map.createLayer('feature', {renderer: null}); quad = geo.quadFeature({layer: layer}); quad._init({style: testStyle}); @@ -516,7 +510,7 @@ describe('geo.quadFeature', function () { delete quad._cachedQuad; }); mockVGLRenderer(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature'); quads = layer.createFeature('quad', {style: testStyle, data: testQuads}); buildTime = quads.buildTime().getMTime(); @@ -574,6 +568,7 @@ describe('geo.quadFeature', function () { quads.data(testQuads); map.draw(); expect(buildTime).toEqual(quads.buildTime().getMTime()); + destroyMap(); restoreVGLRenderer(); }); }); @@ -589,7 +584,7 @@ describe('geo.quadFeature', function () { delete quad._cachedQuad; }); logCanvas2D(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); quads = layer.createFeature('quad', {style: testStyle, data: testQuads}); buildTime = quads.buildTime().getMTime(); @@ -679,7 +674,7 @@ describe('geo.quadFeature', function () { $.each(testQuads, function (idx, quad) { delete quad._cachedQuad; }); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'd3'}); quads = layer.createFeature('quad', {style: testStyle, data: testQuads}); buildTime = quads.buildTime().getMTime(); diff --git a/tests/cases/textFeature.js b/tests/cases/textFeature.js index 69f7fe9a11..28b971040f 100644 --- a/tests/cases/textFeature.js +++ b/tests/cases/textFeature.js @@ -5,6 +5,7 @@ var mockAnimationFrame = require('../test-utils').mockAnimationFrame; var stepAnimationFrame = require('../test-utils').stepAnimationFrame; var unmockAnimationFrame = require('../test-utils').unmockAnimationFrame; var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; var logCanvas2D = require('../test-utils').logCanvas2D; describe('geo.textFeature', function () { @@ -99,19 +100,10 @@ describe('geo.textFeature', function () { } ]; - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - describe('create', function () { it('create function', function () { var map, layer, text; - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); text = geo.textFeature.create(layer); expect(text instanceof geo.textFeature).toBe(true); @@ -121,7 +113,7 @@ describe('geo.textFeature', function () { describe('Check private class mathods', function () { var map, layer, text; it('_init', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); text = geo.textFeature({layer: layer}); expect(text.style('font')).toBe('bold 16px sans-serif'); @@ -140,7 +132,7 @@ describe('geo.textFeature', function () { var map, layer, text; var pos = [[[0, 0], [10, 5], [5, 10]]]; it('position', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); text = geo.textFeature({layer: layer}); expect(text.position()('a')).toBe('a'); @@ -154,7 +146,7 @@ describe('geo.textFeature', function () { }); it('text', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: null}); text = geo.textFeature({layer: layer}); expect(text.text()({text: 'a'})).toBe('a'); @@ -174,7 +166,7 @@ describe('geo.textFeature', function () { it('basic usage', function () { mockAnimationFrame(); logCanvas2D(); - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); geo.textFeature.usedStyles.forEach(function (key) { style[key] = function (d, i) { @@ -195,7 +187,7 @@ describe('geo.textFeature', function () { unmockAnimationFrame(); }); it('getFontFromStyles', function () { - map = create_map(); + map = createMap(); layer = map.createLayer('feature', {renderer: 'canvas'}); geo.textFeature.usedStyles.forEach(function (key) { style[key] = function (d, i) { diff --git a/tests/cases/widgetApi.js b/tests/cases/widgetApi.js index e059a4833d..895e7bfc6a 100644 --- a/tests/cases/widgetApi.js +++ b/tests/cases/widgetApi.js @@ -1,35 +1,23 @@ var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; var $ = require('jquery'); describe('widget api', function () { 'use strict'; - beforeEach(function () { - $('
') - .css({width: '500px', height: '400px'}).appendTo('body'); - }); - - afterEach(function () { - $('#map-widget-api').remove(); - }); - function makeMap() { var map; - map = geo.map({ - node: '#map-widget-api', + map = createMap({ center: { x: -98.0, y: 39.5 }, zoom: 5 - }); - - map.createLayer('ui'); - map.draw(); + }, {width: '500px', height: '400px'}); var uiLayer = map.createLayer('ui'); - window.geoWidgets = []; + map.draw(); return {map: map, uiLayer: uiLayer}; } diff --git a/tests/cases/zoomSlider.js b/tests/cases/zoomSlider.js index 24de713991..50f73da135 100644 --- a/tests/cases/zoomSlider.js +++ b/tests/cases/zoomSlider.js @@ -1,6 +1,7 @@ var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; -describe('zoom slider', function () { +xdescribe('zoom slider', function () { 'use strict'; var d3 = require('d3'); @@ -8,25 +9,17 @@ describe('zoom slider', function () { var map; beforeEach(function () { - $('
') - .css({width: '500px', height: '400px'}).appendTo('body'); - map = geo.map({ - 'node': '#map-zoom-slider', + map = createMap({ 'center': [0, 0], 'zoom': 2, 'clampZoom': false, 'clampBoundsX': false, 'clampBoundsY': false - }); + }, {width: '500px', height: '400px'}); map.createLayer('ui').createWidget('slider'); map.draw(); }); - afterEach(function () { - map.exit(); - $('#map-zoom-slider').remove(); - }); - it('Zoom in button', function (done) { var eps; map.zoom(1); diff --git a/tests/gl-cases/quadFeatureVideo.js b/tests/gl-cases/quadFeatureVideo.js index 8a91c5c6d8..e594909cf3 100644 --- a/tests/gl-cases/quadFeatureVideo.js +++ b/tests/gl-cases/quadFeatureVideo.js @@ -2,8 +2,8 @@ /* global HTMLVideoElement */ -var $ = require('jquery'); var geo = require('../test-utils').geo; +var createMap = require('../test-utils').createMap; var waitForIt = require('../test-utils').waitForIt; describe('geo.util.isReadyVideo', function () { @@ -37,19 +37,10 @@ describe('geo.quadFeature video', function () { var map, layer, quads; - function create_map(opts) { - var node = $('
').css({width: '640px', height: '360px'}); - $('#map').remove(); - $('body').append(node); - opts = $.extend({}, opts); - opts.node = node; - return geo.map(opts); - } - it('single video quad', function (done) { var videoWidth = 640, videoHeight = 360; var params = geo.util.pixelCoordinateParams('#map', videoWidth, videoHeight); - map = create_map(params.map); + map = createMap(params.map); layer = map.createLayer('feature', {features: ['quad.video']}); quads = layer.createFeature('quad'); quads.data([{ @@ -82,7 +73,7 @@ describe('geo.quadFeature video', function () { it('video element', function (done) { var video = document.createElement('video'); video.onloadeddata = function () { - map = create_map({}); + map = createMap({}); layer = map.createLayer('feature', {features: ['quad.video']}); quads = layer.createFeature('quad'); quads.data([{ @@ -100,7 +91,7 @@ describe('geo.quadFeature video', function () { }); it('preview colors and bad urls', function (done) { - map = create_map({}); + map = createMap({}); layer = map.createLayer('feature', {features: ['quad.video']}); quads = layer.createFeature('quad'); quads.style({ diff --git a/tests/test-utils.js b/tests/test-utils.js index b33d4b87b3..c2702fb3ea 100644 --- a/tests/test-utils.js +++ b/tests/test-utils.js @@ -255,9 +255,10 @@ module.exports.advanceDate = function (delta) { startDate += delta; }; -/* Decode query components into a dictionary of values. +/** + * Decode query components into a dictionary of values. * - * @returns {object}: the query parameters as a dictionary. + * @returns {object} the query parameters as a dictionary. */ module.exports.getQuery = function () { var query = document.location.search.replace(/(^\?)/, '').split( @@ -270,3 +271,33 @@ module.exports.getQuery = function () { }.bind({}))[0]; return query; }; + +/** + * Destroy a map for testing. This removes any existing node called '#map'. + * It should be done if the VGL renderer was mocked before it is restored. + */ +function destroyMap() { + if ($('#map').data('data-geojs-map') && $.isFunction($('#map').data('data-geojs-map').exit)) { + $('#map').data('data-geojs-map').exit(); + } + $('#map').remove(); +} +module.exports.destroyMap = destroyMap; + +/** + * Create a map for testing. This removes any existing node called '#map' and + * creates a new one. + * + * @param {object} [opts] Additional options to pass to the map class creator. + * @param {object} [css] Additional css to apply to the map node. Default is + * width: 640px, height: 360px. + * @returns {geo.map} the created map. + */ +module.exports.createMap = function (opts, css) { + destroyMap(); + var node = $('
').css($.extend({}, {width: '640px', height: '360px'}, css)); + $('body').prepend(node); + opts = $.extend({}, opts); + opts.node = node; + return geo.map(opts); +}; From b1d234c097ed50042ffaa2e4fc3085acc810a9f4 Mon Sep 17 00:00:00 2001 From: David Manthey Date: Tue, 12 Dec 2017 13:30:51 -0500 Subject: [PATCH 2/2] Fix vgl quad's renderer context. Use the proper context for the vgl quads rather than the generic context. This makes cleaning up the layer's context more robust. This also tries to lose a context as soon as possible, if the browser supports doing so. --- src/gl/quadFeature.js | 12 +++++++----- src/gl/vglRenderer.js | 20 +++++++++++++++++++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/gl/quadFeature.js b/src/gl/quadFeature.js index 660fb9fe4f..fe96fd34a6 100644 --- a/src/gl/quadFeature.js +++ b/src/gl/quadFeature.js @@ -147,7 +147,7 @@ var gl_quadFeature = function (arg) { * Build this feature. */ this._build = function () { - var mapper, mat, prog, srctex, unicrop, geom; + var mapper, mat, prog, srctex, unicrop, geom, context; if (!m_this.position()) { return; @@ -174,10 +174,11 @@ var gl_quadFeature = function (arg) { unicrop = new vgl.uniform(vgl.GL.FLOAT_VEC2, 'crop'); unicrop.set([1.0, 1.0]); prog.addUniform(unicrop); + context = m_this.renderer()._glContext(); prog.addShader(vgl.getCachedShader( - vgl.GL.VERTEX_SHADER, vgl.GL, vertexShaderImageSource)); + vgl.GL.VERTEX_SHADER, context, vertexShaderImageSource)); prog.addShader(vgl.getCachedShader( - vgl.GL.FRAGMENT_SHADER, vgl.GL, fragmentShaderImageSource)); + vgl.GL.FRAGMENT_SHADER, context, fragmentShaderImageSource)); mat.addAttribute(prog); mat.addAttribute(new vgl.blend()); /* This is similar to vgl.planeSource */ @@ -214,9 +215,10 @@ var gl_quadFeature = function (arg) { prog.addUniform(new vgl.projectionUniform('projectionMatrix')); prog.addUniform(new vgl.floatUniform('opacity', 1.0)); prog.addUniform(new vgl.uniform(vgl.GL.FLOAT_VEC3, 'vertexColor')); + context = m_this.renderer()._glContext(); prog.addShader(vgl.getCachedShader( - vgl.GL.VERTEX_SHADER, vgl.GL, vertexShaderColorSource)); - prog.addShader(vgl.utils.createFragmentShader(vgl.GL)); + vgl.GL.VERTEX_SHADER, context, vertexShaderColorSource)); + prog.addShader(vgl.utils.createFragmentShader(context)); mat.addAttribute(prog); mat.addAttribute(new vgl.blend()); /* This is similar to vgl.planeSource */ diff --git a/src/gl/vglRenderer.js b/src/gl/vglRenderer.js index bfceb91055..7e16f5eb85 100644 --- a/src/gl/vglRenderer.js +++ b/src/gl/vglRenderer.js @@ -178,6 +178,19 @@ var vglRenderer = function (arg) { } }; + /** + * Get the GL context for this renderer. + * + * @returns {WebGLRenderingContext} The current context. If unavailable, + * falls back to the vgl generic context. + */ + this._glContext = function () { + if (m_viewer && m_viewer.renderWindow()) { + return m_viewer.renderWindow().context(); + } + return vgl.GL; + }; + /** * Exit. */ @@ -187,9 +200,14 @@ var vglRenderer = function (arg) { if (m_viewer) { var renderState = new vgl.renderState(); renderState.m_renderer = m_viewer; - renderState.m_context = m_viewer.renderWindow().context(); + renderState.m_context = this._glContext(); m_viewer.exit(renderState); + if (this._glContext() !== vgl.GL && this._glContext().getExtension('WEBGL_lose_context') && this._glContext().getExtension('WEBGL_lose_context').loseContext) { + this._glContext().getExtension('WEBGL_lose_context').loseContext(); + } } + // make sure we clear shaders associated with the generate context, too + vgl.clearCachedShaders(vgl.GL); m_viewer = null; s_exit(); };