diff options
Diffstat (limited to 'misc/openlayers/tests/Layer/Vector.html')
-rw-r--r-- | misc/openlayers/tests/Layer/Vector.html | 879 |
1 files changed, 879 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Layer/Vector.html b/misc/openlayers/tests/Layer/Vector.html new file mode 100644 index 0000000..aa3e2f8 --- /dev/null +++ b/misc/openlayers/tests/Layer/Vector.html @@ -0,0 +1,879 @@ +<html> +<head> +<script src="../OLLoader.js"></script> + <script type="text/javascript"> + + var name = "Vector Layer"; + + function test_Layer_Vector_constructor(t) { + t.plan(5); + + var options = {protocol: new OpenLayers.Protocol(), + strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]} + var layer = new OpenLayers.Layer.Vector(name, options); + + t.ok(layer instanceof OpenLayers.Layer.Vector, "new OpenLayers.Layer.Vector returns correct object" ); + t.eq(layer.name, name, "layer name is correctly set"); + t.ok(layer.renderer.CLASS_NAME, "layer has a renderer"); + + t.ok((layer.name == layer.strategies[0].layer.name) && + (layer.strategies[0].layer.name == layer.strategies[1].layer.name), + "setLayer was called on strategies"); + + options.renderers = [OpenLayers.Renderer.SVG, OpenLayers.Renderer.VML, OpenLayers.Renderer.Canvas]; + layer.destroy(); + layer = new OpenLayers.Layer.Vector(name, options); + t.ok(layer.renderer.CLASS_NAME, "layer has a renderer when providing a function"); + layer.destroy(); + } + + function test_Layer_Vector_assignRenderer(t) { + t.plan(2); + + // create a dummy class in the global name space + My = { + Custom: { + Renderer: { + Supported: OpenLayers.Class(OpenLayers.Renderer, { + supported: OpenLayers.Function.True, + CLASS_NAME: 'My.Custom.Renderer.Supported' + }), + NotSupported: OpenLayers.Class(OpenLayers.Renderer, { + supported: OpenLayers.Function.False, + CLASS_NAME: 'My.Custom.Renderer.NotSupported' + }) + } + } + }; + var layer = new OpenLayers.Layer.Vector('vector', { + renderers: [My.Custom.Renderer.NotSupported, + My.Custom.Renderer.Supported, + OpenLayers.Renderer.Canvas] + }); + t.eq(layer.renderer.CLASS_NAME, 'My.Custom.Renderer.Supported', + 'layer has a valid renderer'); + + var layer = new OpenLayers.Layer.Vector('vector', { + renderers: ['SVG', 'VML', 'Canvas', My.Custom.Renderer.Supported] + }); + t.ok(layer.renderer.CLASS_NAME != 'My.Custom.Renderer.Supported', + 'renderers can be strings as well'); + } + + function test_Layer_Vector_refresh(t) { + t.plan(4); + + var obj = {"an": "object"}; + + var log; + var layer = new OpenLayers.Layer.Vector(name, { + eventListeners: { + refresh: function(o) { + log.obj = o; + } + } + }); + inRange = false; + layer.calculateInRange = function() { + return inRange; + }; + + log = {}; + inRange = false; + layer.visibility = false; + layer.refresh(obj); + t.eq(log.obj, undefined, "[false, false] refresh not triggered"); + + log = {}; + inRange = true; + layer.visibility = false; + layer.refresh(obj); + t.eq(log.obj, undefined, "[true, false] refresh not triggered"); + + log = {}; + inRange = false; + layer.visibility = true; + layer.refresh(obj); + t.eq(log.obj, undefined, "[false, true] refresh not triggered"); + + log = {}; + inRange = true; + layer.visibility = true; + layer.refresh(obj); + t.ok(log.obj === obj, "[true, true] refresh triggered with correct arg"); + } + + function test_Layer_Vector_addFeatures(t) { + t.plan(8); + + var layer = new OpenLayers.Layer.Vector(name); + + var point = new OpenLayers.Geometry.Point(-111.04, 45.68); + var pointFeature = new OpenLayers.Feature.Vector(point); + + layer.preFeatureInsert = function(feature) { + t.ok(feature == pointFeature, "OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert with the right arg"); + }; + layer.onFeatureInsert = function(feature) { + t.ok(feature == pointFeature, "OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert with the right arg"); + }; + layer.events.register('beforefeatureadded', null, function(obj) { + t.ok(pointFeature == obj.feature, "OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded with correct feature passed to callback"); + }); + layer.events.register('featureadded', null, function(obj) { + t.ok(pointFeature == obj.feature, "OpenLayers.Layer.Vector.addFeatures triggers featureadded with correct feature passed to callback"); + }); + layer.events.register('featuresadded', null, function(obj) { + t.ok(pointFeature == obj.features[0], "OpenLayers.Layer.Vector.addFeatures triggers featuresadded with correct features passed to callback"); + }); + + layer.addFeatures([pointFeature]); + + t.eq(layer.features.length, 1, "OpenLayers.Layer.Vector.addFeatures adds something to the array"); + t.ok(layer.features[0] == pointFeature, "OpenLayers.Layer.Vector.addFeatures returns an array of features"); + + layer.preFeatureInsert = function(feature) { + t.fail("OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert while it must not"); + }; + layer.onFeatureInsert = function(feature) { + t.fail("OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert while it must not"); + }; + layer.events.register('beforefeatureadded', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded while it must not"); + }); + layer.events.register('featureadded', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.addFeatures triggers featureadded while it must not"); + }); + layer.events.register('featuresadded', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.addFeatures triggers featuresadded while it must not"); + }); + + layer.addFeatures([pointFeature], {silent: true}); + + var extent = layer.getDataExtent(); + t.eq(extent.toBBOX(), "-111.04,45.68,-111.04,45.68", "extent from getDataExtent is correct"); + } + + function test_Layer_Vector_getFeature(t) { + t.plan(13); + + var layer = new OpenLayers.Layer.Vector(name); + var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-111.04, 45.68)); + + t.ok(layer.getFeatureById(feature.id) == null, + "OpenLayers.Layer.Vector.getFeatureById returns null while the layer is empty"); + t.ok(layer.getFeatureByFid('my_fid') == null, + "OpenLayers.Layer.Vector.getFeatureByFid returns null while the layer is empty"); + + layer.addFeatures([feature]); + + t.ok(layer.getFeatureByFid('my_fid') == null, + "OpenLayers.Layer.Vector.getFeatureByFid returns null on unset feature fid"); + + feature.fid = 'my_fid'; + + t.ok(layer.getFeatureById(feature.id) == feature, + "OpenLayers.Layer.Vector.getFeatureById returns the correct feature"); + t.ok(layer.getFeatureByFid(feature.fid) == feature, + "OpenLayers.Layer.Vector.getFeatureByFid returns the correct feature"); + t.ok(layer.getFeatureById('some_id_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureById returns null on non-existing feature id"); + t.ok(layer.getFeatureByFid('some_fid_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureByFid returns null on non-existing feature fid"); + t.ok(layer.getFeatureById(feature.fid) == null, + "OpenLayers.Layer.Vector.getFeatureById ignores the feature fid"); + t.ok(layer.getFeatureByFid(feature.id) == null, + "OpenLayers.Layer.Vector.getFeatureByFid ignores the feature id"); + + t.ok(layer.getFeatureBy('id', feature.id) == feature, + "OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on existing feature id"); + t.ok(layer.getFeatureBy('id', 'some_id_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on non-existing feature id"); + t.ok(layer.getFeatureBy('fid', feature.fid) == feature, + "OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on existing feature fid"); + t.ok(layer.getFeatureBy('fid', 'some_fid_that_does_not_exist') == null, + "OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on non-existing feature fid"); + } + + function test_Layer_Vector_getFeaturesByAttribute(t) { + t.plan( 9 ); + // setup layer + var layer = new OpenLayers.Layer.Vector(name); + + // feature_1 + var geometry_1 = new OpenLayers.Geometry.Point(-28.63, 153.64); + var attributes_1 = { + humpty: 'dumpty', + clazz: 1 + }; + var feature_1 = new OpenLayers.Feature.Vector(geometry_1, attributes_1); + feature_1.fid = 'f_01'; // to identify later + + // feature_2 + var geometry_2 = new OpenLayers.Geometry.Point(-27.48, 153.05); + var attributes_2 = { + // this feature has attribute humpty === undefined + clazz: '1' + }; + var feature_2 = new OpenLayers.Feature.Vector(geometry_2, attributes_2); + feature_2.fid = 'f_02'; // to identify later + + // feature_3 + var geometry_3 = new OpenLayers.Geometry.Point(-33.74, 150.3); + var attributes_3 = { + humpty: 'foobar', + clazz: 1 + }; + var feature_3 = new OpenLayers.Feature.Vector(geometry_3, attributes_3); + feature_3.fid = 'f_03'; // to identify later + + // Tests + + // don't find anything... no features added + // 1 test + t.ok(layer.getFeaturesByAttribute('humpty', 'dumpty').length === 0, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an empty array while the layer is empty"); + + layer.addFeatures([feature_1, feature_2, feature_3]); + + // simple use case: find 1 feature with an attribute and matching value + // 2 tests + var dumptyResults = layer.getFeaturesByAttribute('humpty', 'dumpty'); + t.ok(dumptyResults.length === 1, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'humpty' with value 'dumpty'"); + t.ok(dumptyResults[0].fid === 'f_01', + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'humpty' set to 'dumpty'"); + + // simple use case: find 1 feature with an attribute and matching value + // and respect data types + // 2 tests + var strOneResults = layer.getFeaturesByAttribute('clazz', '1'); + t.ok(strOneResults.length === 1, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'clazz' with value '1' (a string)"); + t.ok(strOneResults[0].fid === 'f_02', + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'clazz' set to the string '1'"); + + // simple use case: find 2 features with an attribute and matching value + // and respect data types + // 2 tests + var numOneResults = layer.getFeaturesByAttribute('clazz', 1); + t.ok(numOneResults.length === 2, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with two features for attribute 'clazz' with value 1 (a number)"); + var bothFound = !!((numOneResults[0].fid === 'f_01' && numOneResults[1].fid === 'f_03') || (numOneResults[0].fid === 'f_03' && numOneResults[1].fid === 'f_01')); + t.ok(bothFound, + "OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct features with attribute 'clazz' set to the number 1"); + + // advanced use case: find the 1 feature, that has an attribute not set + var undefined; + var humptyNotSet = layer.getFeaturesByAttribute('humpty', undefined); + t.ok(humptyNotSet.length === 1, + "OpenLayers.Layer.Vector.getFeaturesByAttribute can be used to find features that have certain attributes not set"); + t.ok(humptyNotSet[0].fid === 'f_02', + "OpenLayers.Layer.Vector.getFeaturesByAttribute found the correct featuren that has a certain attribute not set"); + } + + function test_Layer_Vector_getDataExtent(t) { + t.plan(1); + var layer = new OpenLayers.Layer.Vector(name); + + var point = new OpenLayers.Geometry.Point(-111.04, 45.68); + var pointFeature = new OpenLayers.Feature.Vector(point); + layer.addFeatures([pointFeature]); + var point = new OpenLayers.Geometry.Point(-111.04, 5.68); + var pointFeature = new OpenLayers.Feature.Vector(point); + layer.addFeatures([pointFeature]); + var extent = layer.getDataExtent(); + t.ok(extent.toBBOX() != layer.features[0].geometry.getBounds().toBBOX(), "extent from getDataExtent doesn't clobber first feature"); + } + + function test_Layer_Vector_getDataExtentEmpty(t) { + t.plan(1); + var layer = new OpenLayers.Layer.Vector(name); + layer.addFeatures([new OpenLayers.Feature.Vector(null), new OpenLayers.Feature.Vector(null)]); + var extent = layer.getDataExtent(); + t.eq(extent, null, "We expect null to be returned if there are no features with a geometry"); + } + + function test_Layer_Vector_removeFeatures(t) { + t.plan(17); + + var layer = new OpenLayers.Layer.Vector(name); + var features, log; + + var point1 = new OpenLayers.Geometry.Point(-111.04, 45.68); + var pointFeature1 = new OpenLayers.Feature.Vector(point1); + var point2 = new OpenLayers.Geometry.Point(-111.14, 45.78); + var pointFeature2 = new OpenLayers.Feature.Vector(point2); + + // 1 test + layer.addFeatures([pointFeature1, pointFeature2]); + features = layer.removeFeatures([pointFeature1]); + t.ok(layer.features.length == 1, "OpenLayers.Layer.Vector.removeFeatures removes a feature from the features array"); + + // 1 test + layer.addFeatures([pointFeature1.clone(), pointFeature2.clone()]); + layer.selectedFeatures.push(layer.features[0]); + layer.removeFeatures(layer.features[0]); + t.eq(layer.selectedFeatures, [], "Remove features removes selected features"); + + // 1 test + features = layer.removeFeatures(layer.features); + t.ok(layer.features.length == 0, + "OpenLayers.Layer.Vector.removeFeatures(layer.features) removes all feature from the features array"); + + // 4 tests + log = []; + layer.addFeatures([pointFeature1, pointFeature2]); + layer.events.register("featuresremoved", null, function(obj) { + log.push(obj); + }); + layer.removeFeatures(layer.features); + t.eq(log.length, 1, + "\"featuresremoved\" triggered once [0]"); + t.eq(log[0].features.length, 2, + "\"featuresremoved\" listener is passed two features [0]"); + t.ok(log[0].features[0] == pointFeature1, + "\"featuresremoved\" listener is passed the correct feature at index 0 [0]"); + t.ok(log[0].features[1] == pointFeature2, + "\"featuresremoved\" listener is passed the correct feature at index 1 [0]"); + layer.events.remove("featuresremoved"); + + // 4 tests + log = []; + layer.addFeatures([ + pointFeature1, pointFeature2, + pointFeature1.clone(), pointFeature2.clone() + ]); + layer.selectedFeatures.push(pointFeature1); + layer.selectedFeatures.push(pointFeature2); + layer.events.register("featuresremoved", null, function(obj) { + log.push(obj); + }); + layer.removeFeatures(layer.selectedFeatures); + t.eq(log.length, 1, + "\"featuresremoved\" triggered once [1]"); + t.eq(log[0].features.length, 2, + "\"featuresremoved\" listener is passed two features [1]"); + t.ok(log[0].features[0] == pointFeature1, + "\"featuresremoved\" listener is passed the correct feature at index 0 [1]"); + t.ok(log[0].features[1] == pointFeature2, + "\"featuresremoved\" listener is passed the correct feature at index 1 [1]"); + layer.events.remove("featuresremoved"); + layer.removeFeatures(layer.features); + + // 6 tests + layer.events.register('beforefeatureremoved', null, function(obj) { + t.ok(pointFeature1 == obj.feature, + "OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved with correct feature passed to callback"); + }); + layer.events.register('featureremoved', null, function(obj) { + t.ok(pointFeature1 == obj.feature, + "OpenLayers.Layer.Vector.removeFeatures triggers featureremoved with correct feature passed to callback"); + }); + layer.events.register('featuresremoved', null, function(obj) { + t.ok(pointFeature1 == obj.features[0], + "OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved with correct features passed to callback"); + }); + layer.addFeatures([pointFeature1]); + layer.removeFeatures([pointFeature1]); + layer.addFeatures([pointFeature1]); + layer.removeFeatures(layer.features); + + // 0 test + layer.events.register('beforefeatureremoved', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved while it must not"); + }); + layer.events.register('featureremoved', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.removeFeatures triggers featureremoved while it must not"); + }); + layer.events.register('featuresremoved', null, function(obj) { + t.fail("OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved while it must not"); + }); + layer.addFeatures([pointFeature1]); + layer.removeFeatures([pointFeature1], {silent: true}); + } + + function test_Layer_Vector_drawFeature(t) { + t.plan(7); + var layer = new OpenLayers.Layer.Vector("Test Layer", {isBaseLayer: true}); + var map = new OpenLayers.Map('map', { + maxExtent: new OpenLayers.Bounds(-100, -100, 100, 100) + }); + map.addLayer(layer); + var geometry = new OpenLayers.Geometry.Point(10, 10); + var feature = new OpenLayers.Feature.Vector(geometry); + + var f, s; + + // Bogus layer renderer needs some methods + // for functional tests. + layer.drawn = true; + layer.renderer = { + drawFeature: function(feature, style) { + f = feature; + s = style; + }, + root: document.createElement("div"), + destroy: function() { }, + eraseFeatures: function() {}, + setExtent: function() {} + }; + + + layer.drawFeature(feature); + t.ok(geometry.equals(f.geometry), + "calls layer.renderer.drawFeature() with feature.geometry"); + + feature.style = {foo: "bar"}; + layer.drawFeature(feature); + t.eq(feature.style, s, + "calls layer.renderer.drawFeature() with feature.style"); + + feature.style = null; + layer.style = {foo: "bar"}; + layer.drawFeature(feature); + t.eq(layer.style.foo, s.foo, + "given null feature style, uses layer style"); + + feature.style = {foo1: "bar1"}; + layer.style = {foo2: "bar2"}; + var customStyle = {foo: "bar"}; + layer.drawFeature(feature, customStyle); + t.eq(customStyle.foo, s.foo, + "given a custom style, renders with that"); + + // the real renderer's drawFeature method is tested in Renderer.html + layer.renderer.drawFeature = function(feature) { + return(feature.geometry.getBounds().intersectsBounds(map.getExtent())); + } + // reset the drawn to null as if the layer had never been rendered + layer.drawn = null; + + layer.drawFeature(feature); + t.ok(true, "Trying to draw a feature on an not drawn layer doesn't throw any error."); + + layer.addFeatures([feature]); + + map.setCenter(new OpenLayers.Bounds(0, 0, 0, 0), 6); + t.ok(layer.unrenderedFeatures[feature.id], "Did not render feature outside the viewport."); + map.panTo(new OpenLayers.LonLat(10, 10)); + t.ok(!layer.unrenderedFeatures[feature.id], "Rendered feature inside the viewport."); + + layer.features = []; + } + + function test_deleted_state(t) { + t.plan(9); + + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer.Vector(); + map.addLayer(layer); + var feature = new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(10, 10) + ); + var log; + layer.renderer = { + drawFeature: function(f, s) { + log = { + feature: f, + style: s + }; + }, + destroy: function() {} + }; + + // draw feature with no state + layer.drawn = true; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[no state] drawFeature called with correct feature"); + t.ok(log.style.display !== "none", "[no state] drawFeature called with style display not none"); + + // draw feature with delete style + feature.state = OpenLayers.State.DELETE; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[delete] drawFeature called with correct feature"); + t.eq(log.style.display, "none", "[delete] drawFeature called with style display none"); + + // undelete the feature and redraw + delete feature.state; + delete feature.renderIntent; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[undelete] drawFeature called with correct feature"); + t.ok(log.style.display !== "none", "[undelete] drawFeature called with style display not none"); + + // change deleted style + layer.styleMap.styles["delete"] = new OpenLayers.Style({fillOpacity: 0.1}); + + // draw feature with delete style + feature.state = OpenLayers.State.DELETE; + layer.drawFeature(feature); + t.ok(log.feature === feature, "[draw deleted] drawFeature called with correct feature"); + t.ok(log.style.display !== "none", "[draw deleted] drawFeature called with style display not none"); + t.eq(log.style.fillOpacity, 0.1,"[draw deleted] drawFeature called with correct fill opacity"); + + + } + + function test_Layer_Vector_eraseFeatures(t) { + t.plan(2); + var layer = new OpenLayers.Layer.Vector("Test Layer"); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + var geometry = new OpenLayers.Geometry.Point(10, 10); + var feature = new OpenLayers.Feature.Vector(geometry); + + var f; + layer.renderer = { + eraseFeatures: function(features) { + f = features[0]; + }, + destroy: function() { } + }; + + layer.eraseFeatures([feature]); + t.ok(f, "calls layer.renderer.eraseFeatures"); + t.ok(geometry.equals(f.geometry), + "calls layer.renderer.eraseFeatures() given an array of features"); + } + + function test_Layer_Vector_destroyFeatures (t) { + t.plan(8); + var layer = new OpenLayers.Layer.Vector(name); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + var features = [], i; + for (i = 0; i < 5; i++) { + features.push(new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(0,0))); + } + layer.addFeatures(features); + t.eq(layer.features.length, 5, "addFeatures adds 5 features"); + layer.selectedFeatures.push(features[0]); + layer.destroyFeatures(); + t.eq(layer.features.length, 0, "destroyFeatures triggers removal"); + t.eq(layer.selectedFeatures, [], "Destroy features removes selected features"); + var allDestroyed = true; + for (i = 0; i < 5; i++) { + if(features[i].geometry) { + allDestroyed = false; + } + } + t.ok(allDestroyed, "destroyFeatures actually destroys features"); + features = []; + for (i = 0; i < 5; i++) { + features.push(new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(0,0))); + } + layer.addFeatures(features); + layer.selectedFeatures.push(features[0]); + layer.selectedFeatures.push(features[1]); + layer.destroyFeatures([features[0], features[1]]); + t.eq(layer.features.length, 3, "destroyFeatures removes appropriate features"); + t.eq(layer.selectedFeatures, [], "destroyFeatures removes appropriate selected features"); + t.eq(features[0].geometry, null, "destroyFeatures destroys feature 0"); + t.eq(features[1].geometry, null, "destroyFeatures destroys feature 1"); + } + + function test_Layer_Vector_destroy (t) { + t.plan(6); + + var options = {protocol: new OpenLayers.Protocol(), + strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]} + var layer = new OpenLayers.Layer.Vector(name, options); + var map = new OpenLayers.Map('map'); + map.addLayer(layer); + layer.destroy(); + t.eq(layer.map, null, "layer.map is null after destroy"); + t.ok(!layer.renderer, "layer.renderer is falsey"); + var err; + try { + layer.getFeatureFromEvent({target: "map"}); + } catch (ex) { + err = ex; + } + t.ok(err, "Error thrown when calling getFeatureFromEvent on destroyed layer"); + + t.eq(layer.protocol, null, "layer.protocol is null after destroy"); + t.eq(layer.strategies, null, "layer.strategies is null after destroy"); + + // test that we can call layer.destroy a second time without trouble + try { + layer.destroy(); + layer.destroy(); + t.ok(true, "layer.destroy called twice without any issues"); + } catch(err) { + t.fail("calling layer.destroy twice triggers exception: " + err + " in " + err.fileName + " line " + err.lineNumber); + } + + } + + function test_Layer_Vector_clone(t) { + t.plan(5); + var original = new OpenLayers.Layer.Vector(name, {dummyOption: "foo"}); + original.addFeatures([new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2), {foo: "bar"})]); + var clone = original.clone(); + t.ok(clone instanceof OpenLayers.Layer.Vector, "clone is an instance of OpenLayers.Layer.Vector"); + t.ok(clone.name, original.name, "clone has the same name as the original"); + t.ok(clone.features[0] != original.features[0], "clone's feature does not equal the original's feature"); + t.eq(clone.features[0].attributes.foo, original.features[0].attributes.foo, "clone's feature has the same attributes as the original's feature"); + t.eq(clone.dummyOption, original.dummyOption, "clone's dummyOption equals the original's dummy option"); + } + + function test_Layer_Vector_externalGraphic(t) { + t.plan(11); + var layer = new OpenLayers.Layer.Vector("Test Layer", {isBaseLayer: true}); + var renderer = layer.renderer; + var map = new OpenLayers.Map('map'); + map.addLayers([layer]); + + var geometryX = 10; + var geometryY = 10; + var geometry = new OpenLayers.Geometry.Point(geometryX, geometryY); + var feature = new OpenLayers.Feature.Vector(geometry); + + map.zoomToMaxExtent(); + + var customStyle1 = new Object({ + externalGraphic: 'test.png', + pointRadius: 10 + }); + var customStyle2 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 12 + }); + var customStyle3 = new Object({ + externalGraphic: 'test.png', + graphicHeight: 14 + }); + var customStyle4 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicHeight: 16 + }); + var customStyle5 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicOpacity: 1 + }); + var customStyle6 = new Object({ + externalGraphic: 'test.png', + graphicWidth: 24, + graphicHeight: 16, + graphicXOffset: -24, + graphicYOffset: -16 + }); + + var root = renderer.vectorRoot; + if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') { + feature.style = customStyle1; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + (2*customStyle1.pointRadius).toString(), + "given a pointRadius, width equals 2*pointRadius"); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + (2*customStyle1.pointRadius).toString(), + "given a pointRadius, height equals 2*pointRadius"); + feature.style = customStyle2; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + root.firstChild.getAttributeNS(null, 'height'), + "given a graphicWidth, width equals height"); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + customStyle2.graphicWidth.toString(), + "width is set correctly"); + feature.style = customStyle3; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + root.firstChild.getAttributeNS(null, 'width'), + "given a graphicHeight, height equals width"); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + customStyle3.graphicHeight.toString(), + "height is set correctly"); + feature.style = customStyle4; + layer.drawFeature(feature); + t.eq(root.firstChild.getAttributeNS(null, 'height'), + customStyle4.graphicHeight.toString(), + "given graphicHeight and graphicWidth, both are set: height"); + t.eq(root.firstChild.getAttributeNS(null, 'width'), + customStyle4.graphicWidth.toString(), + "given graphicHeight and graphicWidth, both are set: width"); + feature.style = customStyle5; + layer.drawFeature(feature); + // we use startsWith here as some browsers (at least Safari 3 and FireFox 4) + // do not append a semi-colon to the opacity string + t.ok(OpenLayers.String.startsWith( + root.firstChild.getAttributeNS(null, 'style'), + "opacity: " + customStyle5.graphicOpacity.toString()), + "graphicOpacity correctly set"); + feature.style = customStyle6; + layer.drawFeature(feature); + var x = geometryX / renderer.getResolution() + renderer.left; + var y = geometryY / renderer.getResolution() - renderer.top; + // SVG setStyle() gets x and y using getAttributeNS(), which returns + // a value with only 3 decimal digits. To mimic this we use toFixed(3) here + x = x.toFixed(3); + y = y.toFixed(3); + // toFixed() returns a string + x = parseFloat(x); + y = parseFloat(y); + t.eq(root.firstChild.getAttributeNS(null, 'x'), + (x + customStyle6.graphicXOffset).toFixed().toString(), + "graphicXOffset correctly set"); + t.eq(root.firstChild.getAttributeNS(null, 'y'), + (-y + customStyle6.graphicYOffset).toFixed().toString(), + "graphicYOffset correctly set"); + } + if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.VML') { + feature.style = customStyle1; + layer.drawFeature(feature); + t.eq(root.firstChild.style.width, + (2*customStyle1.pointRadius).toString()+'px', + "given a pointRadius, width equals 2*pointRadius"); + t.eq(root.firstChild.style.height, + (2*customStyle1.pointRadius).toString()+'px', + "given a pointRadius, height equals 2*pointRadius"); + feature.style = customStyle2; + layer.drawFeature(feature); + t.eq(root.firstChild.style.width, + root.firstChild.style.height, + "given a graphicWidth, width equals height"); + t.eq(root.firstChild.style.width, + customStyle2.graphicWidth.toString()+'px', + "width is set correctly"); + feature.style = customStyle3; + layer.drawFeature(feature); + t.eq(root.firstChild.style.height, + root.firstChild.style.width, + "given a graphicHeight, height equals width"); + t.eq(root.firstChild.style.height, + customStyle3.graphicHeight.toString()+'px', + "height is set correctly"); + feature.style = customStyle4; + layer.drawFeature(feature); + var left = parseInt(root.firstChild.style.left); + var top = parseInt(root.firstChild.style.top); + t.eq(root.firstChild.style.height, + customStyle4.graphicHeight.toString()+'px', + "given graphicHeight and graphicWidth, both are set: height"); + t.eq(root.firstChild.style.width, + customStyle4.graphicWidth.toString()+'px', + "given graphicHeight and graphicWidth, both are set: width"); + feature.style = customStyle5; + layer.renderer.clear(); + layer.drawFeature(feature); + var fill = root.firstChild.getElementsByTagName("v:fill")[0]; + var opacity; + if(fill) { + opacity = fill.getAttribute('opacity'); + } + if(opacity === undefined) { + fill = root.firstChild.getElementsByTagName("fill")[0]; + opacity = fill.getAttribute('opacity'); + } + t.eq(opacity, + customStyle5.graphicOpacity, + "graphicOpacity correctly set"); + feature.style = customStyle6; + layer.drawFeature(feature); + var offsetLeft = parseInt(root.firstChild.style.left); + var offsetTop = parseInt(root.firstChild.style.top); + t.eq((offsetLeft-left)*2, customStyle6.graphicXOffset, "graphicXOffset correctly set"); + t.eq((top-offsetTop)*2, customStyle6.graphicYOffset, "graphicYOffset correctly set"); + + } + } + + function test_removeLayer_drawFeature(t) { + // test behaviour when features are redrawn while + // the layer has been removed from the map + + t.plan(1); + + // set up + + var map, layer, feature; + + map = new OpenLayers.Map("map"); + map.addLayer(new OpenLayers.Layer("base", {isBaseLayer: true})); + + layer = new OpenLayers.Layer.Vector("vector"); + map.addLayer(layer); + + map.zoomToMaxExtent(); + + feature = new OpenLayers.Feature.Vector( + new OpenLayers.Geometry.Point(1.0, 1.0)); + layer.addFeatures(feature); + + // test + + map.removeLayer(layer); + layer.drawFeature(feature); + layer.drawFeature(feature); + map.addLayer(layer); + + var count = 0, node; + while(node = document.getElementById(feature.geometry.id)) { + node.parentNode.removeChild(node); + count++; + } + + t.eq(count, 1, "one geometry added, one geometry removed"); + + // tear down + + map.destroy(); + } + + function test_vectorBeforeFeatureAddedVeto(t) { + t.plan( 4 ); + + var map = new OpenLayers.Map('map'); + layer = new OpenLayers.Layer.Vector(""); + map.addLayer(layer); + var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0)); + layer.addFeatures([feature]); + + var addedFeatures = []; + var beforefeatureadded_veto = function(evt) { return false; }; + layer.events.register("beforefeatureadded", layer, beforefeatureadded_veto); + layer.events.register("featuresadded", layer, function(evt) { + if (evt.features) { + for (var i = 0; i < evt.features.length; i++) { + addedFeatures.push(evt.features[i]); + } + } + }); + + var blankFeatures = [ + new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0)), + new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0))]; + layer.addFeatures(blankFeatures); + + t.eq(layer.features.length, 1, + "features not added to layer after beforefeatureadded veto"); + t.eq(addedFeatures.length, 0, + "no features sent to featuresadded on feature veto"); + + addedFeatures = []; + + layer.events.unregister("beforefeatureadded", layer, beforefeatureadded_veto); + beforefeatureadded_veto = function(evt) { return true; }; + layer.events.register("beforefeatureadded", layer, beforefeatureadded_veto); + + layer.addFeatures(blankFeatures); + + t.eq(layer.features.length, 3, + "features added to layer as expected"); + t.eq(addedFeatures.length, 2, + "featuresadded event received expected number of features"); + } + + + + </script> +</head> +<body> +<div id="map" style="width:500px;height:550px"></div> +</body> +</html> |