diff options
Diffstat (limited to 'misc/openlayers/tests/Control/SelectFeature.html')
-rw-r--r-- | misc/openlayers/tests/Control/SelectFeature.html | 632 |
1 files changed, 632 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Control/SelectFeature.html b/misc/openlayers/tests/Control/SelectFeature.html new file mode 100644 index 0000000..6e522e7 --- /dev/null +++ b/misc/openlayers/tests/Control/SelectFeature.html @@ -0,0 +1,632 @@ +<html> +<head> + <script src="../OLLoader.js"></script> + <script type="text/javascript"> + function test_Control_SelectFeature_constructor(t) { + t.plan(5); + var options = { +// geometryTypes: "foo" + }; + var layer = "bar"; + var control = new OpenLayers.Control.SelectFeature([layer], options); + t.ok(control instanceof OpenLayers.Control.SelectFeature, + "new OpenLayers.Control.SelectFeature returns an instance"); + t.eq(control.layers[0], "bar", + "constructor with array of layers sets layer correctly"); +// t.eq(control.handlers.feature.geometryTypes, "foo", +// "constructor sets options correctly on feature handler"); + t.ok(control.layer instanceof OpenLayers.Layer.Vector.RootContainer, "control has a root container layer if constructor was called with an array of layers"); + + control = new OpenLayers.Control.SelectFeature(layer, options); + t.eq(control.layers, null, "this.layers is null if constructor called with a single layer"); + t.eq(control.layer, layer, "this.layer holds the layer that was passed with the constructor if called with a single layer") + } + + function test_Control_SelectFeature_destroy(t) { + t.plan(2); + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer.Vector(); + map.addLayer(layer); + var control = new OpenLayers.Control.SelectFeature(layer, {box: true}); + control.handlers.feature.deactivate = function() { + t.ok(true, + "control.deactivate calls deactivate on feature handler"); + } + control.handlers.box.deactivate = function() { + t.ok(true, + "control.deactivate calls deactivate on box handler"); + } +// should nullify the layer property here + control.destroy(); + + } + + function test_Control_SelectFeature_select(t) { + t.plan(4); + var map = new OpenLayers.Map("map"); + var layer1 = new OpenLayers.Layer.Vector(); + var layer2 = new OpenLayers.Layer.Vector(); + map.addLayers([layer1, layer2]); + var control = new OpenLayers.Control.SelectFeature([layer1, layer2]); + var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,1)); + var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,0)); + layer1.addFeatures(feature1); + layer2.addFeatures(feature2); + var drawFeature = function(feature, style) { + feature.layer.styleMap.createSymbolizer(feature, style); + } + layer1.drawFeature = drawFeature; + layer2.drawFeature = drawFeature; + control.select(feature1); + t.eq(feature1.renderIntent, "select", "render intent is set to select"); + control.select(feature2); + t.eq(feature2.renderIntent, "select", "render intent is set to select"); + control.unselect(feature1); + t.eq(feature1.renderIntent, "default", "render intent is set back to default"); + control.unselect(feature2); + t.eq(feature2.renderIntent, "default", "render intent is set back to default"); + } + + function test_Control_SelectFeature_clickFeature(t) { + t.plan(6); + // mock up layer + var layer = { + selectedFeatures: [], + drawFeature: function() {}, + events: { + triggerEvent: function() {} + } + }; + // mock up active control + var control = new OpenLayers.Control.SelectFeature(layer); + control.handlers.feature = { + evt: {} + }; + // mock up features + var features = new Array(4); + for(var i=0; i<features.length; ++i) { + features[i] = { + id: Math.random(), + tested: 0, + style: "", + layer: layer + }; + } + + // test that onSelect gets called properly + control.onSelect = function(feature) { + feature.tested += 1; + t.eq(feature.id, features[feature.index].id, + "onSelect called with proper feature (" + feature.index + ")"); + t.eq(feature.tested, feature.test, + "onSelect called only once for feature (" + feature.index + ")"); + t.ok(this == control, "onSelect called in the scope of the control if control.scope is not provided"); + } + + // test that onUnselect gets called properly + control.onUnselect = function(feature) { + feature.tested += 1; + t.eq(feature.id, features[feature.index].id, + "onUnselect called with proper feature (" + feature.index + ")"); + t.eq(feature.tested, feature.test, + "onUnselect called only once for feature (" + feature.index + ")"); + t.ok(this == control, "onUnselect called in the scope of the control if control.scope is not provided"); + } + + // mock up first click on first feature (runs 3 tests from onSelect) + var feature = features[0]; + feature.index = 0; + feature.test = 1; + control.clickFeature(feature); + + // mock up second click on first feature (runs no tests - already selected) + control.toggle = false; + control.clickFeature(feature); + + // mock up second click on first feature (runs 3 tests from onUnselect) + control.toggle = true; + feature.test = 2; + control.clickFeature(feature); + + + } + + function test_box(t) { + t.plan(5); + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer.Vector(); + map.addLayer(layer); + map.setBaseLayer(layer); + map.setCenter(new OpenLayers.LonLat(1,1)); + var control = new OpenLayers.Control.SelectFeature(layer, {'multiple': true, box: true }); + var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0)); + var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1)); + var feature3 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-2,-2)); + var feature4 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([ + new OpenLayers.Geometry.Point(0, 0), new OpenLayers.Geometry.Point(1, 1) + ])); + layer.addFeatures([feature, feature2, feature3, feature4]); + control.setMap(map); + map.getLonLatFromPixel = function(arg) { + return new OpenLayers.LonLat(arg.x, arg.y); + } + control.selectBox(new OpenLayers.Bounds(-1, -1, 2, 2)); + t.eq(layer.selectedFeatures.length, 3, "box around all features selects 3 features"); + + control.selectBox(new OpenLayers.Bounds(-3, -3, -1, -1)); + t.eq(layer.selectedFeatures.length, 4, "box around other features doesn't turn off already selected features."); + + control.multipleSelect = function() { + return false; + }; + control.selectBox(new OpenLayers.Bounds(-3, -3, -1, -1)); + t.eq(layer.selectedFeatures.length, 1, "box around other features correctly turns off already selected features."); + + control.geometryTypes = null; + control.selectBox(new OpenLayers.Bounds(-100, -100, 100, 100)); + t.eq(layer.selectedFeatures.length, layer.features.length, "all features selected with no geometryTypes filter"); + + control.geometryTypes = ["OpenLayers.Geometry.Point"]; + control.selectBox(new OpenLayers.Bounds(-100, -100, 100, 100)); + t.eq(layer.selectedFeatures.length, 3, "3 features selected with geometryTypes filter"); + + + } + + + function test_selectBox_events(t){ + t.plan(8); + var map = new OpenLayers.Map("map"); + var layer1 = new OpenLayers.Layer.Vector(); + map.addLayer(layer1); + map.setBaseLayer(layer1); + var layer2 = new OpenLayers.Layer.Vector(); + map.addLayer(layer2); + map.setCenter(new OpenLayers.LonLat(1,1)); + var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1)); + layer1.addFeatures([feature]); + var control = new OpenLayers.Control.SelectFeature(layer1); + control.setMap(map); + map.getLonLatFromPixel = function(arg) { + return new OpenLayers.LonLat(arg.x, arg.y); + } + control.activate(); + var firesBoxselectionstart = false; + var beforeSelectingNumberOfFeatures = -1; + var firesBoxselectionend = false; + var afterSelectingNumberOfFeatures = -1; + control.events.register("boxselectionstart",null, function(e){ + firesBoxselectionstart=true; + t.eq(e.layers.length,1,"right number of layers in event boxselectionstart"); + t.eq(layer1.id, e.layers[0].id,"correct layer in event boxselectionstart"); + beforeSelectingNumberOfFeatures = e.layers[0].selectedFeatures.length; + }); + control.events.register("boxselectionend",null, function(e){ + firesBoxselectionend=true; + t.eq(e.layers.length,1,"right number of layers in event boxselectionend"); + t.eq(layer1.id, e.layers[0].id,"correct layer in event boxselectionend"); + afterSelectingNumberOfFeatures = e.layers[0].selectedFeatures.length; + }); + var bounds = new OpenLayers.Bounds(-1, -1, 2, 2); + control.selectBox(bounds); + t.ok(firesBoxselectionstart,"selectBox fires boxselectionstart event"); + t.eq(beforeSelectingNumberOfFeatures,0,"boxselectionstart fires before selection of feature"); + t.ok(firesBoxselectionend,"selectBox fires boxselectionend event"); + t.eq(afterSelectingNumberOfFeatures,1,"boxselectionend fires after feature selected"); + } + function test_Control_SelectFeature_activate(t) { + t.plan(4); + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer.Vector(); + map.addLayer(layer); + var control = new OpenLayers.Control.SelectFeature(layer, {box: true}); + map.addControl(control); + t.ok(!control.handlers.feature.active, + "feature handler is not active prior to activating control"); + t.ok(!control.handlers.box.active, + "box handler is not active prior to activating control"); + control.activate(); + t.ok(control.handlers.feature.active, + "feature handler is active after activating control"); + t.ok(control.handlers.box.active, + "box handler is active after activating control"); + } + + function test_Control_SelectFeature_deactivate(t) { + t.plan(2); + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer.Vector(); + map.addLayer(layer); + var control = new OpenLayers.Control.SelectFeature(layer, {box: true}); + map.addControl(control); + + control.activate(); + control.handlers.feature.deactivate = function() { + t.ok(true, + "control.deactivate calls deactivate on feature handler"); + OpenLayers.Handler.Feature.prototype.deactivate.apply(this, arguments); + } + control.handlers.box.deactivate = function() { + t.ok(true, + "control.deactivate calls deactivate on box handler"); + } + control.deactivate(); + } + + function test_highlighyOnly(t) { + t.plan(23); + + /* + * setup + */ + + var map, layer, ctrl1, ctrl2, _feature, feature, evt, _style; + + map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Vector("name", {isBaseLayer: true}); + map.addLayer(layer); + + ctrl1 = new OpenLayers.Control.SelectFeature(layer, { + highlightOnly: false, + hover: false + }); + map.addControl(ctrl1); + + ctrl2 = new OpenLayers.Control.SelectFeature(layer, { + highlightOnly: true, + hover: true + }); + map.addControl(ctrl2); + + ctrl2.activate(); + ctrl1.activate(); + + feature = new OpenLayers.Feature.Vector(); + feature.layer = layer; + + // override the layer's getFeatureFromEvent func so that it always + // returns the feature referenced to by _feature + layer.getFeatureFromEvent = function(evt) { return _feature; }; + + evt = {xy: new OpenLayers.Pixel(Math.random(), Math.random())}; + + map.zoomToMaxExtent(); + + /* + * tests + */ + + // with renderIntent + + ctrl1.renderIntent = "select"; + ctrl2.renderIntent = "temporary"; + + // mouse over feature, feature is drawn with "temporary" + _feature = feature; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "temporary", + "feature drawn with expected render intent after \"mouseover\""); + t.eq(feature._lastHighlighter, ctrl2.id, + "feature._lastHighlighter properly set after \"mouseover\""); + t.eq(feature._prevHighlighter, undefined, + "feature._prevHighlighter properly set after \"mouseover\""); + + // click in feature, feature is drawn with "select" + _feature = feature; + evt.type = "click"; + map.events.triggerEvent("click", evt); + t.eq(feature.renderIntent, "select", + "feature drawn with expected render intent after \"clickin\""); + t.eq(feature._lastHighlighter, ctrl1.id, + "feature._lastHighlighter properly set after \"clickin\""); + t.eq(feature._prevHighlighter, ctrl2.id, + "feature._prevHighlighter properly set after \"clickin\""); + + // mouse out of feature, feature is still drawn with "select" + _feature = null; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "select", + "feature drawn with expected render intent after \"mouseout\""); + t.eq(feature._lastHighlighter, ctrl1.id, + "feature._lastHighlighter properly set after \"nouseout\""); + t.ok(feature._prevHighlighter, ctrl2.id, + "feature._prevHighlighter properly set after \"mouseout\""); + + // mouse over feature again, feature is drawn with "temporary" + _feature = feature; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "temporary", + "feature drawn with expected render intent after \"mouseover\""); + t.eq(feature._lastHighlighter, ctrl2.id, + "feature._lastHighlighter properly set after \"mouseover\""); + t.eq(feature._prevHighlighter, ctrl1.id, + "feature._prevHighlighter properly set after \"mouseover\""); + + // mouve out of feature again, feature is still drawn with "select" + _feature = null; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "select", + "feature drawn with expected render intent after \"mouseout\""); + t.eq(feature._lastHighlighter, ctrl1.id, + "feature._lastHighlighter properly set after \"mouseout\""); + t.eq(feature._prevHighlighter, undefined, + "feature._prevHighlighter properly set after \"mouseout\""); + + // click out of feature, feature is drawn with "default" + _feature = null; + evt.type = "click"; + map.events.triggerEvent("click", evt); + t.eq(feature.renderIntent, "default", + "feature drawn with expected render intent after \"clickout\""); + t.eq(feature._lastHighlighter, undefined, + "feature._lastHighlighter properly set after \"clickout\""); + t.eq(feature._prevHighlighter, undefined, + "feature._prevHighlighter properly set after \"clickout\""); + + // with selectStyle + + ctrl1.selectStyle = OpenLayers.Feature.Vector.style["select"]; + ctrl2.selectStyle = OpenLayers.Feature.Vector.style["temporary"]; + + layer.renderer.drawFeature = function(f, s) { + var style = OpenLayers.Feature.Vector.style[_style]; + t.eq(s, style, "renderer drawFeature called with expected style obj (" + _style + ")"); + }; + + // mouse over feature, feature is drawn with "temporary" + _feature = feature; + _style = "temporary"; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + + // click in feature, feature is drawn with "select" + _feature = feature; + _style = "select"; + evt.type = "click"; + map.events.triggerEvent("click", evt); + + // mouse out of feature, feature is still drawn with "select" and + // the renderer drawFeature method should not be called + _feature = null; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + + // mouse over feature again, feature is drawn with "temporary" + _feature = feature; + _style = "temporary"; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + + // mouve out of feature again, feature is still drawn with "select" + _feature = null; + _style = "select"; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + + // click out of feature, feature is drawn with "default" + _feature = null; + _style = "default"; + evt.type = "click"; + map.events.triggerEvent("click", evt); + } + + // test for http://trac.openlayers.org/ticket/2812 + function test_highlightOnly_toggle(t) { + t.plan(8); + + /* + * setup + */ + + var map, layer, ctrl1, ctrl2, _feature, feature, evt, _style; + + map = new OpenLayers.Map("map"); + layer = new OpenLayers.Layer.Vector("name", {isBaseLayer: true}); + map.addLayer(layer); + + ctrl1 = new OpenLayers.Control.SelectFeature(layer, { + highlightOnly: false, + hover: false, + clickout: false, + toggle: true + }); + map.addControl(ctrl1); + + ctrl2 = new OpenLayers.Control.SelectFeature(layer, { + highlightOnly: true, + hover: true + }); + map.addControl(ctrl2); + + ctrl2.activate(); + ctrl1.activate(); + + feature = new OpenLayers.Feature.Vector(); + feature.layer = layer; + + // override the layer's getFeatureFromEvent func so that it always + // returns the feature referenced to by _feature + layer.getFeatureFromEvent = function(evt) { return _feature; }; + + evt = {xy: new OpenLayers.Pixel(Math.random(), Math.random())}; + + map.zoomToMaxExtent(); + + /* + * tests + */ + + // with renderIntent + + ctrl1.renderIntent = "select"; + ctrl2.renderIntent = "temporary"; + + // mouse over feature, feature is drawn with "temporary" + _feature = feature; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "temporary", + "feature drawn with expected render intent after \"mouseover\""); + + // click in feature, feature is drawn with "select" + _feature = feature; + evt.type = "click"; + map.events.triggerEvent("click", evt); + t.eq(feature.renderIntent, "select", + "feature drawn with expected render intent after \"clickin\""); + + // mouse out of feature, feature is still drawn with "select" + _feature = null; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "select", + "feature drawn with expected render intent after \"mouseout\""); + + // mouse over feature again, feature is drawn with "temporary" + _feature = feature; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "temporary", + "feature drawn with expected render intent after \"mouseover\""); + + // click in feature again, feature is drawn with "default" + _feature = feature; + evt.type = "click"; + map.events.triggerEvent("click", evt); + t.eq(feature.renderIntent, "default", + "feature drawn with expected render intent after \"clickin\""); + + // mouse out of feature again, feature is still drawn with "default" + _feature = null; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "default", + "feature drawn with expected render intent after \"mouseout\""); + + // mouse over feature again, feature is drawn with "temporary" + _feature = feature; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "temporary", + "feature drawn with expected render intent after \"mouseover\""); + + // mouse out of feature again, feature is still drawn with "default" + _feature = null; + evt.type = "mousemove"; + map.events.triggerEvent("mousemove", evt); + t.eq(feature.renderIntent, "default", + "feature drawn with expected render intent after \"mouseout\""); + } + + function test_setLayer(t) { + t.plan(5); + var map = new OpenLayers.Map("map"); + var layer1 = new OpenLayers.Layer.Vector(); + var layer2 = new OpenLayers.Layer.Vector(); + var layer3 = new OpenLayers.Layer.Vector(); + map.addLayer(layer1, layer2, layer3); + // initialize it with a single layer + var control = new OpenLayers.Control.SelectFeature(layer1); + map.addControl(control); + control.activate(); + control.setLayer([layer2, layer3]); + t.eq(control.layer instanceof OpenLayers.Layer.Vector.RootContainer, true, "Root container created correctly on setLayer with multiple layers"); + t.eq(control.active, true, "Control should be active still after using setLayer"); + t.eq((control.handlers.feature.layer === control.layer), true, "Feature handler layer set correctly"); + control.destroy(); + // initialize with an array of layers + control = new OpenLayers.Control.SelectFeature([layer1, layer2]); + t.eq((control.layers !== null), true, "Control has a layers property"); + control.setLayer(layer3); + t.eq((control.layers === null), true, "When using setLayer with a single layer, the layers property is removed if present before"); + map.destroy(); + } + + function test_setLayerWithRemoving(t) { + t.plan(2); + var map = new OpenLayers.Map("map"); + var layer1 = new OpenLayers.Layer.Vector(); + var layer2 = new OpenLayers.Layer.Vector(); + map.addLayer(layer1, layer2); + // initialize it with a single layer + var control = new OpenLayers.Control.SelectFeature(layer1); + map.addControl(control); + control.activate(); + var noError = null; + map.events.register("preremovelayer", this, function(e) { + try { + control.setLayer(layer2); + } catch (e) { + noError = e; + } + }); + layer1.destroy(); + t.eq(layer2.id, control.layer.id, "Layer is set correctly without error"); + t.eq(noError, null,"No error occured during setLayer. Error is: '"+noError+"'"); + control.destroy(); + map.destroy(); + } + + function test_destroy(t) { + t.plan(1); + var map = new OpenLayers.Map("map"); + var layer1 = new OpenLayers.Layer.Vector(); + map.addLayer(layer1); + var control = new OpenLayers.Control.SelectFeature([layer1]); + map.addControl(control); + control.activate(); + control.destroy(); + t.eq(layer1.renderer.getRenderLayerId(), layer1.id, + "Root container moved correctly when control is destroyed and layers was an array parameter"); + } + + function test_unselectAll(t) { + t.plan(2); + + var layer = new OpenLayers.Layer.Vector(); + + var control = new OpenLayers.Control.SelectFeature(layer); + + var feature1 = new OpenLayers.Feature.Vector(); + feature1.id = 1; + var feature2 = new OpenLayers.Feature.Vector(); + feature2.id = 2; + var feature3 = new OpenLayers.Feature.Vector(); + feature3.id = 3; + var feature4 = new OpenLayers.Feature.Vector(); + feature4.id = 4; + + layer.addFeatures([feature1, feature2, feature3, feature4]); + + control.select(feature1); + control.select(feature2); + control.select(feature3); + control.select(feature4); + + layer.events.on({ + featureunselected: function(e) { + // we change the selectedFeatures array while + // unselectAll is iterating over that array. + if(feature2.layer) { + layer.removeFeatures([feature2]); + } + } + }); + + control.unselectAll({except: feature3}); + t.eq(layer.selectedFeatures.length, 1, + 'unselectAll unselected all but one'); + t.eq(layer.selectedFeatures[0].id, 3, + 'the remaining selected features is the one expected'); + } + + </script> +</head> +<body> + <div id="map" style="width: 400px; height: 250px;"/> +</body> +</html> |