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/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 0cde8ace34..7e16f5eb85 100644 --- a/src/gl/vglRenderer.js +++ b/src/gl/vglRenderer.js @@ -169,19 +169,46 @@ 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(); + }; + + /** + * 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. */ 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 = 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(); }; 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 = $('