summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Control
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2014-08-12 21:56:44 +0200
committerChris Schlaeger <chris@linux.com>2014-08-12 21:56:44 +0200
commitea346a785dc1b3f7c156f6fc33da634e1f1a627b (patch)
treeaf67530553d20b6e82ad60fd79593e9c4abf5565 /misc/openlayers/tests/Control
parent59741cd535c47f25971bf8c32b25da25ceadc6d5 (diff)
downloadpostrunner-ea346a785dc1b3f7c156f6fc33da634e1f1a627b.zip
Adding jquery, flot and openlayers to be included with the GEM.v0.0.4
Diffstat (limited to 'misc/openlayers/tests/Control')
-rw-r--r--misc/openlayers/tests/Control/ArgParser.html26
-rw-r--r--misc/openlayers/tests/Control/Attribution.html60
-rw-r--r--misc/openlayers/tests/Control/Button.html17
-rw-r--r--misc/openlayers/tests/Control/CacheRead.html108
-rw-r--r--misc/openlayers/tests/Control/CacheWrite.html90
-rw-r--r--misc/openlayers/tests/Control/DragFeature.html383
-rw-r--r--misc/openlayers/tests/Control/DragPan.html104
-rw-r--r--misc/openlayers/tests/Control/DrawFeature.html160
-rw-r--r--misc/openlayers/tests/Control/EditingToolbar.html33
-rw-r--r--misc/openlayers/tests/Control/Geolocate.html129
-rw-r--r--misc/openlayers/tests/Control/GetFeature.html177
-rw-r--r--misc/openlayers/tests/Control/Graticule.html66
-rw-r--r--misc/openlayers/tests/Control/KeyboardDefaults.html173
-rw-r--r--misc/openlayers/tests/Control/LayerSwitcher.html249
-rw-r--r--misc/openlayers/tests/Control/Measure.html386
-rw-r--r--misc/openlayers/tests/Control/ModifyFeature.html828
-rw-r--r--misc/openlayers/tests/Control/MousePosition.html109
-rw-r--r--misc/openlayers/tests/Control/NavToolbar.html45
-rw-r--r--misc/openlayers/tests/Control/Navigation.html200
-rw-r--r--misc/openlayers/tests/Control/NavigationHistory.html245
-rw-r--r--misc/openlayers/tests/Control/OverviewMap.html266
-rw-r--r--misc/openlayers/tests/Control/Pan.html201
-rw-r--r--misc/openlayers/tests/Control/PanPanel.html61
-rw-r--r--misc/openlayers/tests/Control/PanZoom.html244
-rw-r--r--misc/openlayers/tests/Control/PanZoomBar.html245
-rw-r--r--misc/openlayers/tests/Control/Panel.html382
-rw-r--r--misc/openlayers/tests/Control/Permalink.html453
-rw-r--r--misc/openlayers/tests/Control/PinchZoom.html134
-rw-r--r--misc/openlayers/tests/Control/SLDSelect.html239
-rw-r--r--misc/openlayers/tests/Control/Scale.html54
-rw-r--r--misc/openlayers/tests/Control/ScaleLine.html187
-rw-r--r--misc/openlayers/tests/Control/SelectFeature.html632
-rw-r--r--misc/openlayers/tests/Control/Snapping.html448
-rw-r--r--misc/openlayers/tests/Control/Split.html319
-rw-r--r--misc/openlayers/tests/Control/TouchNavigation.html155
-rw-r--r--misc/openlayers/tests/Control/TransformFeature.html129
-rw-r--r--misc/openlayers/tests/Control/UTFGrid.html120
-rw-r--r--misc/openlayers/tests/Control/WMSGetFeatureInfo.html644
-rw-r--r--misc/openlayers/tests/Control/WMTSGetFeatureInfo.html334
-rw-r--r--misc/openlayers/tests/Control/Zoom.html83
-rw-r--r--misc/openlayers/tests/Control/ZoomBox.html54
-rw-r--r--misc/openlayers/tests/Control/ZoomIn.html101
-rw-r--r--misc/openlayers/tests/Control/ZoomOut.html100
-rw-r--r--misc/openlayers/tests/Control/ZoomToMaxExtent.html102
44 files changed, 9275 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Control/ArgParser.html b/misc/openlayers/tests/Control/ArgParser.html
new file mode 100644
index 0000000..34e9f5b
--- /dev/null
+++ b/misc/openlayers/tests/Control/ArgParser.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_getParameters(t) {
+ t.plan(4);
+
+ var c = new OpenLayers.Control.ArgParser(), p;
+
+ p = c.getParameters('http://example.com?fook=foov&bark=barv');
+ t.eq(p, {fook: 'foov', bark: 'barv'}, 'a) params are correct');
+
+ p = c.getParameters('http://example.com#fook=foov&bark=barv');
+ t.eq(p, {fook: 'foov', bark: 'barv'}, 'b) params are correct');
+
+ p = c.getParameters('http://example.com?a=b&b=c#fook=foov&bark=barv');
+ t.eq(p, {a: 'b', b: 'c', fook: 'foov', bark: 'barv'},
+ 'c) params are correct');
+
+ p = c.getParameters('http://example.com?a=b&b=c&fook=a&bark=b#fook=foov&bark=barv');
+ t.eq(p, {a: 'b', b: 'c', fook: 'foov', bark: 'barv'},
+ 'd) params are correct');
+ }
+ </script>
+</head>
+</html>
diff --git a/misc/openlayers/tests/Control/Attribution.html b/misc/openlayers/tests/Control/Attribution.html
new file mode 100644
index 0000000..04b85cf
--- /dev/null
+++ b/misc/openlayers/tests/Control/Attribution.html
@@ -0,0 +1,60 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map;
+ function test_Control_Attribution_constructor (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.Attribution();
+ t.ok( control instanceof OpenLayers.Control.Attribution, "new OpenLayers.Control returns object" );
+ t.eq( control.displayClass, "olControlAttribution", "displayClass is correct" );
+ }
+ function test_Control_Attribution_setBaseLayer (t) {
+ t.plan(1);
+ map = new OpenLayers.Map("map");
+ map.addControl(control);
+ map.addLayer(new OpenLayers.Layer("name",{'attribution':'My layer!', isBaseLayer: true}));
+ map.addLayer(new OpenLayers.Layer("name",{'attribution':'My layer 2!', isBaseLayer: true}));
+ map.setBaseLayer(map.layers[1]);
+ t.eq(control.div.innerHTML, 'My layer 2!', "Attribution correct with changed base layer");
+
+ }
+ function test_Control_Attribution_draw (t) {
+ t.plan(3);
+ control = new OpenLayers.Control.Attribution();
+ map = new OpenLayers.Map("map");
+ map.addControl(control);
+ map.addLayer(new OpenLayers.Layer("name",{'attribution':'My layer!'}));
+ t.eq(control.div.innerHTML, 'My layer!', "Attribution correct with one layer.");
+ map.addLayer(new OpenLayers.Layer("name", {'attribution':'My layer 2!'}));
+ t.eq(control.div.innerHTML, 'My layer!, My layer 2!', "Attribution correct with two layers.");
+ control.separator = '|';
+ control.template = "Map Copyright (c) 2012 by Foo Bar; ${layers}";
+ map.addLayer(new OpenLayers.Layer("name",{'attribution':'My layer 3!'}));
+ t.eq(control.div.innerHTML, 'Map Copyright (c) 2012 by Foo Bar; My layer!|My layer 2!|My layer 3!', "Attribution correct with three layers and diff seperator.");
+
+
+ }
+
+ function test_Control_Attribution_no_duplicates(t) {
+ t.plan(2);
+
+ map = new OpenLayers.Map("map");
+ map.addLayer(new OpenLayers.Layer("Company A: 1",{'attribution':'company A'}));
+ map.addLayer(new OpenLayers.Layer("Company A: 2",{'attribution':'company A'}));
+
+ control = new OpenLayers.Control.Attribution();
+ map.addControl(control);
+ t.eq(control.div.innerHTML, 'company A', "Attribution not duplicated.");
+
+ map.addLayer(new OpenLayers.Layer("Company B: 1",{'attribution':'company B'}));
+ map.addLayer(new OpenLayers.Layer("Company A: 3",{'attribution':'company A'}));
+ t.eq(control.div.innerHTML, 'company A, company B', "Attribution correct with four layers (3 with same attribution).");
+ }
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Button.html b/misc/openlayers/tests/Control/Button.html
new file mode 100644
index 0000000..8d5c036
--- /dev/null
+++ b/misc/openlayers/tests/Control/Button.html
@@ -0,0 +1,17 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_Control_Button_constructor (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.Button();
+ t.ok( control instanceof OpenLayers.Control.Button, "new OpenLayers.Control returns object" );
+ t.eq( control.displayClass, "olControlButton", "displayClass is correct" );
+ }
+
+ </script>
+</head>
+<body>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/CacheRead.html b/misc/openlayers/tests/Control/CacheRead.html
new file mode 100644
index 0000000..ae0addf
--- /dev/null
+++ b/misc/openlayers/tests/Control/CacheRead.html
@@ -0,0 +1,108 @@
+<html>
+<head>
+ <script>
+ /**
+ * Because browsers that implement requestAnimationFrame may not execute
+ * animation functions while a window is not displayed (e.g. in a hidden
+ * iframe as in these tests), we mask the native implementations here. The
+ * native requestAnimationFrame functionality is tested in Util.html and
+ * in PanZoom.html (where a popup is opened before panning). The tests
+ * here will test the fallback setTimeout implementation for animation.
+ */
+ window.requestAnimationFrame =
+ window.webkitRequestAnimationFrame =
+ window.mozRequestAnimationFrame =
+ window.oRequestAnimationFrame =
+ window.msRequestAnimationFrame = null;
+ </script>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_addLayer_removeLayer(t) {
+ t.plan(6);
+ var control = new OpenLayers.Control.CacheRead();
+ var map = new OpenLayers.Map({
+ div: "map",
+ controls: [control],
+ layers: [
+ new OpenLayers.Layer.WMS("One"),
+ new OpenLayers.Layer.WMS("Two")
+ ]
+ });
+ t.ok(map.layers[0].events.listeners.tileloadstart, "tileloadstart listener registered on layer One");
+ t.ok(map.layers[1].events.listeners.tileloadstart, "tileloadstart listener registered on layer Two");
+ control.destroy();
+ t.ok(!map.layers[1].events.listeners.tileloadstart.length, "tileloadstart listener unregistered");
+
+ control = new OpenLayers.Control.CacheRead({
+ fetchEvent: "tileerror",
+ layers: [map.layers[0]]
+ });
+ map.addControl(control);
+ t.ok(map.layers[0].events.listeners.tileerror, "tileerror listener registered on layer One");
+ t.ok(!map.layers[1].events.listeners.tileerror, "tileerror listener not registered on layer Two");
+ control.destroy();
+ t.ok(!map.layers[0].events.listeners.tileerror.length, "tileerror listener unregistered");
+
+ map.destroy();
+ }
+
+ function test_fetch(t) {
+
+ if (!window.localStorage) {
+ t.plan(1);
+ var scope = {active: true};
+ t.eq(OpenLayers.Control.CacheRead.prototype.fetch.call(scope), undefined, "no tiles fetched when localStorage is not supported.");
+ return;
+ }
+
+ t.plan(5);
+
+ var data = "data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
+ window.localStorage.setItem("olCache_foo/1/1/1", data);
+ window.localStorage.setItem("olCache_bar/1/1/1", data);
+
+ var layer1 = new OpenLayers.Layer.XYZ("One", "foo/${x}/${y}/${z}");
+ var layer2 = new OpenLayers.Layer.XYZ("Two", "bar/${x}/${y}/${z}", {isBaseLayer: false});
+ var control1 = new OpenLayers.Control.CacheRead({
+ layers: [layer1]
+ });
+ var control2 = new OpenLayers.Control.CacheRead({
+ layers: [layer2],
+ fetchEvent: "tileerror"
+ });
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ projection: "EPSG:900913",
+ controls: [control1, control2],
+ layers: [layer1, layer2],
+ zoom: 1,
+ center: [0, 0]
+ });
+
+ OpenLayers.ProxyHost = "proxy?url=";
+ var tile = new OpenLayers.Tile.Image(layer1, new OpenLayers.LonLat(0, 0), new OpenLayers.Bounds(0, 0, 1, 1), "proxy?url=foo/1/1/1");
+ OpenLayers.Control.CacheWrite.urlMap[tile.url] = "foo/1/1/1";
+
+ control1.fetch({tile: tile});
+ t.eq(tile.url, data, "proxied url replaced with data uri for original url");
+ delete OpenLayers.Control.CacheWrite.urlMap[tile.url];
+
+ t.delay_call(1, function() {
+ t.eq(layer1.grid[1][1].imgDiv.src, data, "[tileloadstart] tile content from cache");
+ t.ok(layer1.grid[0][0].imgDiv.src !== data, "[tileloadstart] tile content from remote resource");
+ t.eq(layer2.grid[1][1].imgDiv.src, data, "[tileerror] tile content from cache");
+ t.ok(layer2.grid[0][0].imgDiv.src !== data, "[tileerror] tile content from remote resource");
+
+ window.localStorage.removeItem("olCache_foo/1/1/1");
+ window.localStorage.removeItem("olCache_bar/1/1/1");
+ map.destroy();
+ });
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/CacheWrite.html b/misc/openlayers/tests/Control/CacheWrite.html
new file mode 100644
index 0000000..9922569
--- /dev/null
+++ b/misc/openlayers/tests/Control/CacheWrite.html
@@ -0,0 +1,90 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_addLayer_removeLayer(t) {
+ t.plan(6);
+ var control = new OpenLayers.Control.CacheWrite();
+ var map = new OpenLayers.Map({
+ div: "map",
+ controls: [control],
+ layers: [
+ new OpenLayers.Layer.WMS("One"),
+ new OpenLayers.Layer.WMS("Two")
+ ]
+ });
+ t.ok(map.layers[0].events.listeners.tileloaded, "tileloaded listener registered on layer One");
+ t.ok(map.layers[1].events.listeners.tileloaded, "tileloaded listener registered on layer Two");
+ control.destroy();
+ t.ok(!map.layers[1].events.listeners.tileloaded.length, "tileloaded listener unregistered");
+
+ control = new OpenLayers.Control.CacheWrite({
+ layers: [map.layers[0]]
+ });
+ map.addControl(control);
+ t.ok(map.layers[0].events.listeners.tileloaded.length, "tileloaded listener registered on layer One");
+ t.ok(!map.layers[1].events.listeners.tileloaded.length, "tileloaded listener not registered on layer Two");
+ control.destroy();
+ t.ok(!map.layers[0].events.listeners.tileloaded.length, "tileloaded listener unregistered");
+
+ map.destroy();
+ }
+
+ function test_cache_clearCache(t) {
+
+ if (!window.localStorage) {
+ t.plan(2);
+ var scope = {active: true};
+ t.eq(OpenLayers.Control.CacheWrite.prototype.cache.call(scope), undefined, "no tiles cached when localStorage is not supported.");
+ t.ok(!OpenLayers.Control.CacheWrite.clearCache(), "clearCache does nothing when localStorage is not supported.");
+ return;
+ }
+
+ t.plan(4);
+ OpenLayers.Control.CacheWrite.clearCache();
+ var length = window.localStorage.length;
+
+ var tiles = 0;
+ var layer = new OpenLayers.Layer.XYZ("One", "../../img/blank.gif?${x},${y},${z}", {
+ eventListeners: {
+ tileloaded: function() {
+ tiles++;
+ }
+ }
+ });
+ var control = new OpenLayers.Control.CacheWrite({autoActivate: true});
+ var map = new OpenLayers.Map({
+ div: "map",
+ projection: "EPSG:900913",
+ controls: [control],
+ layers: [layer],
+ zoom: 1,
+ center: [0, 0]
+ });
+ t.delay_call(1, function() {
+ var canvasContext = layer.grid[1][1].getCanvasContext();
+ t.eq(window.localStorage.length, length + (canvasContext ? tiles : 0), "cache filled with tiles");
+ var url = layer.grid[1][1].url;
+ // content will be null for browsers that have localStorage but no canvas support
+ var content = canvasContext ? canvasContext.canvas.toDataURL("image/png") : null;
+ t.eq(window.localStorage.getItem("olCache_"+url), content, "localStorage contains correct image data");
+
+ layer.events.triggerEvent('tileloaded', {aborted: true, tile: layer.grid[1][1]});
+ t.eq(window.localStorage.length, length + (canvasContext ? tiles-1 : 0), "tile aborted during load not cached");
+
+ var key = Math.random();
+ window.localStorage.setItem(key, "bar");
+ OpenLayers.Control.CacheWrite.clearCache();
+ t.eq(window.localStorage.length, length + 1, "cache cleared, but foreign entries left in localStorage");
+ window.localStorage.removeItem(key);
+
+ map.destroy();
+ });
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/DragFeature.html b/misc/openlayers/tests/Control/DragFeature.html
new file mode 100644
index 0000000..cfc3a63
--- /dev/null
+++ b/misc/openlayers/tests/Control/DragFeature.html
@@ -0,0 +1,383 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_Control_DragFeature_constructor(t) {
+ t.plan(3);
+
+ var options = {
+ geometryTypes: "foo"
+ };
+ var layer = "bar";
+ var control = new OpenLayers.Control.DragFeature(layer, options);
+ t.ok(control instanceof OpenLayers.Control.DragFeature,
+ "new OpenLayers.Control.DragFeature returns an instance");
+ t.eq(control.layer, "bar",
+ "constructor sets layer correctly");
+ t.eq(control.handlers.feature.geometryTypes, "foo",
+ "constructor sets options correctly on feature handler");
+ }
+
+ function test_Control_DragFeature_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.DragFeature(layer);
+ control.handlers.drag.destroy = function() {
+ t.ok(true,
+ "control.destroy calls destroy on drag handler");
+ }
+ control.handlers.feature.destroy = function() {
+ t.ok(true,
+ "control.destroy calls destroy on feature handler");
+ }
+
+ control.destroy();
+
+ }
+
+ function test_Control_DragFeature_activate(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer);
+ map.addControl(control);
+ t.ok(!control.handlers.feature.active,
+ "feature handler is not active prior to activating control");
+ control.activate();
+ t.ok(control.handlers.feature.active,
+ "feature handler is active after activating control");
+ }
+
+ function test_Control_DragFeature_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.DragFeature(layer);
+ map.addControl(control);
+
+ control.handlers.drag.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on drag handler");
+ }
+ control.handlers.feature.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on feature handler");
+ }
+ control.deactivate();
+ }
+
+ function test_Control_DragFeature_over(t) {
+ t.plan(5);
+ var log = [];
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer, {
+ onEnter: function(f) { log.push({feature: f}); }
+ });
+ map.addControl(control);
+
+ control.activate();
+ t.ok(!control.handlers.drag.active,
+ "drag handler is not active before over a feature");
+
+ // simulate a mouseover on a feature
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ layer.getFeatureFromEvent = function(evt) {
+ return feature;
+ }
+ map.events.triggerEvent("mousemove", {type: "mousemove"});
+
+ t.eq(control.feature.id, feature.id,
+ "control gets the proper feature from the feature handler");
+ t.ok(control.handlers.drag.active,
+ "drag handler activated when over a feature");
+ t.eq(log.length, 1,
+ "onEnter called exactly once");
+ t.eq(log[0].feature.id, feature.id,
+ "onEnter called with expected feature");
+ }
+
+ function test_Control_DragFeature_over_touch(t) {
+ t.plan(7);
+ var log = [];
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer, {
+ onEnter: function(f) { log.push({feature: f}); }
+ });
+ map.addControl(control);
+
+ control.activate();
+ t.ok(!control.handlers.drag.active,
+ "drag handler is not active before touch on a feature");
+
+ // simulate a touch on a feature
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ layer.getFeatureFromEvent = function(evt) {
+ return feature;
+ }
+ map.events.triggerEvent("touchstart", {type: "touchstart", touches: ['foo']});
+
+ t.eq(control.feature.id, feature.id,
+ "control gets the proper feature from the feature handler");
+ t.ok(control.handlers.drag.active,
+ "drag handler activated when touch on a feature");
+ t.ok(control.handlers.drag.started, "drag handler has started");
+ t.ok(!control.handlers.drag.stopDown, "drag handler is not stopping down");
+ t.eq(log.length, 1,
+ "onEnter called exactly once");
+ t.eq(log[0].feature.id, feature.id,
+ "onEnter called with expected feature");
+ }
+
+ function test_Control_DragFeature_down(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer);
+ map.addControl(control);
+
+ control.activate();
+
+ // simulate a mouseover on a feature
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ layer.getFeatureFromEvent = function(evt) {
+ return feature;
+ }
+ map.events.triggerEvent("mousemove", {type: "mousemove"});
+
+ // simulate a mousedown on a feature
+ control.onStart = function(feat, pixel) {
+ t.eq(feat.id, feature.id, "onStart called with the correct feature");
+ t.eq(pixel, "bar", "onStart called with the correct pixel");
+ }
+ map.events.triggerEvent("mousedown", {xy: "bar", which: 1, type: "mousemove"});
+
+ t.eq(control.lastPixel, "bar",
+ "mousedown sets the lastPixel correctly");
+ }
+
+ function test_Control_DragFeature_move(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer);
+ map.addControl(control);
+ map.getResolution = function() {
+ return 2;
+ }
+
+ control.activate();
+
+ // mock up a feature - for the sole purpose of testing mousemove
+ var uid = Math.random();
+ layer.getFeatureFromEvent = function() {
+ var geom = new OpenLayers.Geometry.Point(Math.random(),
+ Math.random());
+ geom.move = function(x, y) {
+ t.eq(x, 2, "move called with dx * res");
+ t.eq(y, -4, "move called with -dy * res");
+ };
+ var feature = new OpenLayers.Feature.Vector(geom);
+ feature.layer = layer;
+ feature.uid = uid;
+ return feature;
+ };
+ layer.drawFeature = function(feature) {
+ t.eq(feature.uid, uid,
+ "layer.drawFeature called with correct feature");
+ };
+
+ // simulate a mouseover on a feature
+ map.events.triggerEvent("mousemove", {type: "mousemove"});
+
+ // simulate a mousedown on a feature
+ var down = new OpenLayers.Pixel(0, 0);
+ map.events.triggerEvent("mousedown", {xy: down, which: 1, type: "mousemove"});
+
+ // simulate a mousemove on a feature
+ var move = new OpenLayers.Pixel(1, 2);
+ map.events.triggerEvent("mousemove", {xy: move, which: 1, type: "mousemove"});
+
+ }
+
+ function test_Control_DragFeature_up(t) {
+ t.plan(6);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer);
+ map.addControl(control);
+
+ control.activate();
+
+ // simulate a mouseover on a feature
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ layer.getFeatureFromEvent = function(evt) {
+ return feature;
+ }
+ map.events.triggerEvent("mousemove", {type: "mousemove"});
+ t.eq(control.over, true,
+ "mouseover on a feature sets the over property to true");
+ t.ok(OpenLayers.Element.hasClass(control.map.viewPortDiv, "olControlDragFeatureOver"),
+ "mouseover on a feature adds class name to map container");
+ t.eq(control.handlers.drag.active, true,
+ "mouseover on a feature activates drag handler");
+
+ // simulate a mouse-up on the map, with the mouse still
+ // over the dragged feature
+ control.handlers.drag.started = true;
+ map.events.triggerEvent("mouseup", {type: "mouseup"});
+ t.eq(control.handlers.drag.active, true,
+ "mouseup while still over dragged feature does not deactivate drag handler");
+
+ // simulate a mouse-up on the map, with the mouse out of
+ // the dragged feature
+ control.handlers.drag.started = true;
+ control.over = false;
+ map.events.triggerEvent("mouseup", {type: "mouseup"});
+ t.eq(control.handlers.drag.active, false,
+ "mouseup deactivates drag handler");
+
+ control.deactivate();
+ t.ok(!OpenLayers.Element.hasClass(control.map.viewPortDiv, "olControlDragFeatureOver"),
+ "deactivate removes class name from map container");
+ }
+
+ function test_Control_DragFeature_done(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer);
+ map.addControl(control);
+
+ control.activate();
+
+
+ // simulate a mouseover on a feature
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ layer.getFeatureFromEvent = function() {
+ return feature;
+ };
+ map.events.triggerEvent("mousemove", {type: "mousemove"});
+ t.eq(control.feature.id, feature.id,
+ "feature is set on mouse over");
+ control.doneDragging();
+ t.eq(control.feature.id, feature.id,
+ "feature sticks around after doneDragging is called.");
+
+ }
+
+ function test_Control_DragFeature_out(t) {
+ t.plan(4);
+ var log = [];
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer, {
+ onLeave: function(f) { log.push({feature: f}); }
+ });
+ map.addControl(control);
+
+ control.activate();
+
+
+ // simulate a mouseover on a feature
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ layer.getFeatureFromEvent = function() {
+ return feature;
+ };
+ map.events.triggerEvent("mousemove", {type: "mousemove"});
+ t.eq(control.feature.id, feature.id,
+ "feature is set on mouse over");
+
+ // simulate a mouseout on a feature
+ layer.getFeatureFromEvent = function() {
+ return null;
+ };
+ map.events.triggerEvent("mousemove", {type: "mousemove"});
+ t.ok(control.feature == null,
+ "feature is set to null on mouse out");
+ t.eq(log.length, 1,
+ "onLeave called exactly once");
+ t.eq(log[0].feature.id, feature.id,
+ "onLeave called with expected feature");
+ }
+
+ function test_Control_DragFeature_out_touch(t) {
+ t.plan(5);
+ var log = [];
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.DragFeature(layer, {
+ onLeave: function(f) { log.push({feature: f}); }
+ });
+ map.addControl(control);
+
+ control.activate();
+
+ // simulate a touch on a feature
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ layer.getFeatureFromEvent = function() {
+ return feature;
+ };
+ map.events.triggerEvent("touchstart", {type: "touchstart", touches: ['foo']});
+ t.eq(control.feature.id, feature.id,
+ "feature is set on mouse over");
+
+ // simulate a touch outside the feature
+ layer.getFeatureFromEvent = function() {
+ return null;
+ };
+ map.events.triggerEvent("touchstart", {type: "touchstart", touches: ['foo']});
+ t.ok(control.feature == null,
+ "feature is set to null on mouse out");
+ t.ok(control.handlers.drag.stopDown,
+ "drag handler is stopping down again");
+ t.eq(log.length, 1,
+ "onLeave called exactly once");
+ t.eq(log[0].feature.id, feature.id,
+ "onLeave called with expected feature");
+ }
+
+ function test_Control_DragFeature_click(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var feature = new OpenLayers.Feature.Vector();
+ feature.layer = layer;
+ var control = new OpenLayers.Control.DragFeature(layer);
+ map.addControl(control);
+
+ control.activate();
+
+ control.overFeature(feature);
+ control.handlers.feature.evt = {which: 1};
+ control.clickFeature(feature);
+ t.eq(control.handlers.drag.started, false, "click after over does not start drag handler");
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/DragPan.html b/misc/openlayers/tests/Control/DragPan.html
new file mode 100644
index 0000000..ba5224f
--- /dev/null
+++ b/misc/openlayers/tests/Control/DragPan.html
@@ -0,0 +1,104 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map, control, layer;
+
+ function init_map() {
+ control = new OpenLayers.Control.DragPan();
+ map = new OpenLayers.Map("map", {controls:[control]});
+ layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'} );
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ map.zoomIn();
+ control.activate();
+ return [map, control];
+ }
+ function test_Control_DragPan_constructor (t) {
+ t.plan( 1 );
+
+ control = new OpenLayers.Control.DragPan();
+ t.ok( control instanceof OpenLayers.Control.DragPan, "new OpenLayers.Control returns object" );
+ }
+ function test_Control_DragPan_drag (t) {
+ t.plan(4);
+ var data = init_map();
+ map = data[0]; control = data[1];
+ res = map.baseLayer.resolutions[map.getZoom()];
+ t.eq(map.center.lat, 0, "Lat is 0 before drag");
+ t.eq(map.center.lon, 0, "Lon is 0 before drag");
+ map.events.triggerEvent('mousedown', {'type':'mousedown', 'xy':new OpenLayers.Pixel(0,0), 'which':1});
+ map.events.triggerEvent('mousemove', {'type':'mousemove', 'xy':new OpenLayers.Pixel(5,5), 'which':1});
+ map.events.triggerEvent('mouseup', {'type':'mouseup', 'xy':new OpenLayers.Pixel(5,5), 'which':1});
+
+ t.eq(map.getCenter().lat, res * 5, "Lat is " + (res * 5) + " after drag");
+ t.eq(map.getCenter().lon, res * -5, "Lon is " + (res * -5) + " after drag");
+ }
+ function test_Control_DragPan_drag_documentDrag (t) {
+ t.plan(4);
+ control = new OpenLayers.Control.DragPan({documentDrag: true});
+ map = new OpenLayers.Map("map", {controls:[control]});
+ layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'} );
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ map.zoomIn();
+ control.activate();
+
+ res = map.baseLayer.resolutions[map.getZoom()];
+ t.eq(map.center.lat, 0, "Lat is 0 before drag");
+ t.eq(map.center.lon, 0, "Lon is 0 before drag");
+ map.events.triggerEvent('mousedown', {'type':'mousedown', 'xy':new OpenLayers.Pixel(0,0), 'which':1});
+ map.events.triggerEvent('mousemove', {'type':'mousemove', 'xy':new OpenLayers.Pixel(5,5), 'which':1});
+ map.events.triggerEvent('mouseup', {'type':'mouseup', 'xy':new OpenLayers.Pixel(5,5), 'which':1});
+
+ t.eq(map.getCenter().lat, res * 5, "Lat is " + (res * 5) + " after drag");
+ t.eq(map.getCenter().lon, res * -5, "Lon is " + (res * -5) + " after drag");
+ }
+ function test_Control_DragPan_click(t) {
+ t.plan(1);
+ var control = new OpenLayers.Control.DragPan();
+ var map = new OpenLayers.Map("map", {controls:[control]});
+ var layer = new OpenLayers.Layer.WMS("OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'});
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ map.zoomIn();
+ control.activate();
+ map.setCenter = function() {
+ t.ok(false, "map.setCenter should not be called here");
+ };
+ var xy = new OpenLayers.Pixel(0, 0);
+ var down = {
+ 'type': 'mousedown',
+ 'xy': xy,
+ 'which': 1
+ };
+ var move = {
+ 'type': 'mousemove',
+ 'xy': xy,
+ 'which': 1
+ };
+ var up = {
+ 'type': 'mouseup',
+ 'xy': xy,
+ 'which': 1
+ };
+ map.events.triggerEvent('mousedown', down);
+ map.events.triggerEvent('mousemove', move);
+ map.events.triggerEvent('mouseup', up);
+ t.ok(true, "clicking without moving the mouse does not call setCenter");
+ }
+
+
+ </script>
+</head>
+<body>
+ <a id="scale" href="">DragPan</a> <br />
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/DrawFeature.html b/misc/openlayers/tests/Control/DrawFeature.html
new file mode 100644
index 0000000..ef0be5a
--- /dev/null
+++ b/misc/openlayers/tests/Control/DrawFeature.html
@@ -0,0 +1,160 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(1);
+ var control = new OpenLayers.Control.DrawFeature("foo", function() {});
+ t.ok(control instanceof OpenLayers.Control.DrawFeature,
+ "constructor returns an instance");
+ }
+
+ function test_multi(t) {
+ t.plan(4);
+
+ var layer = new OpenLayers.Layer.Vector();
+ var control;
+
+ // multi false by default
+ control = new OpenLayers.Control.DrawFeature(
+ layer, OpenLayers.Handler.Polygon
+ );
+ t.ok(!control.multi, "control.multi false by default");
+ t.ok(!control.handler.multi, "handler.multi false by default");
+
+ // set on handler
+ control = new OpenLayers.Control.DrawFeature(
+ layer, OpenLayers.Handler.Polygon, {multi: true}
+ );
+ t.ok(control.handler.multi, "handler.multi set from control options");
+
+ // respect handlerOptions
+ control = new OpenLayers.Control.DrawFeature(
+ layer, OpenLayers.Handler.Polygon,
+ {multi: true, handlerOptions: {multi: false}}
+ );
+ t.ok(!control.handler.multi, "handlerOptions.multi respected");
+
+ }
+
+ function test_rendererOptions(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map("map");
+ var renderers = ["Canvas", "VML"];
+
+ var layer = new OpenLayers.Layer.Vector(null, {
+ renderers: renderers,
+ rendererOptions: {zIndexing: true},
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+
+ var control = new OpenLayers.Control.DrawFeature(
+ layer, OpenLayers.Handler.Polygon, {autoActivate: true}
+ );
+ map.addControl(control);
+
+ var sketchLayer = control.handler.layer;
+
+ t.eq(sketchLayer.renderers, renderers, "Preferred renderers");
+ t.eq(sketchLayer.rendererOptions.zIndexing, true, "renderer options");
+
+ map.destroy();
+
+ }
+
+ function test_drawFeature(t) {
+ t.plan(3);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.DrawFeature(layer, function() {});
+ var geom = {};
+
+ layer.addFeatures = function(features) {
+ t.ok(features[0].geometry == geom, "layer.addFeatures called");
+ t.eq(features[0].state, OpenLayers.State.INSERT, "layer state set");
+ };
+ function handlefeatureadded(event) {
+ t.ok(event.feature.geometry == geom, "featureadded triggered");
+ }
+ control.events.on({"featureadded": handlefeatureadded});
+ control.drawFeature(geom);
+ control.events.un({"featureadded": handlefeatureadded});
+
+ }
+
+ function test_sketch_events(t) {
+ t.plan(11);
+ var map = new OpenLayers.Map("map", {
+ resolutions: [1]
+ });
+ var layer = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+ var control = new OpenLayers.Control.DrawFeature(
+ layer, OpenLayers.Handler.Path, {
+ handlerOptions: {persist: true}
+ }
+ );
+ map.addLayer(layer);
+ map.addControl(control);
+ map.zoomToMaxExtent();
+
+ var log;
+ layer.events.on({
+ sketchstarted: function(event) {
+ log['sketchstarted'] = event;
+ },
+ sketchmodified: function(event) {
+ log['sketchmodified'] = event;
+ },
+ sketchcomplete: function(event) {
+ log['sketchcomplete'] = event;
+ }
+ });
+
+ // mock up draw/modify of a point
+ log = {};
+ control.activate();
+ t.eq(log, {}, "[activate] no event triggered");
+
+ log = {};
+ map.events.triggerEvent("mousemove", {xy: new OpenLayers.Pixel(0, 0)});
+ t.eq(log.sketchstarted.type, "sketchstarted", "[mousemove] sketchstarted triggered");
+ t.geom_eq(log.sketchstarted.vertex, new OpenLayers.Geometry.Point(-200, 125), "[mousemove] correct vertex");
+ t.eq(log.sketchmodified.type, "sketchmodified", "[mousemove] sketchmodified triggered");
+ t.geom_eq(log.sketchmodified.vertex, new OpenLayers.Geometry.Point(-200, 125), "[mousemove] correct vertex");
+
+ map.events.triggerEvent("mousedown", {xy: new OpenLayers.Pixel(0, 0)});
+
+ log = {};
+ map.events.triggerEvent("mouseup", {xy: new OpenLayers.Pixel(0, 0)});
+ t.eq(log.sketchmodified.type, "sketchmodified", "[mouseup] sketchmodified triggered");
+ t.geom_eq(log.sketchmodified.vertex, new OpenLayers.Geometry.Point(-200, 125), "[mouseup] correct vertex");
+
+ log = {};
+ map.events.triggerEvent("mousemove", {xy: new OpenLayers.Pixel(10, 10)});
+ t.eq(log.sketchmodified.type, "sketchmodified", "[mousemove] sketchmodified triggered");
+ t.geom_eq(log.sketchmodified.vertex, new OpenLayers.Geometry.Point(-190, 115), "[mousemove] correct vertex");
+
+ log = {};
+ map.events.triggerEvent("dblclick", {xy: new OpenLayers.Pixel(10, 10)});
+ t.eq(log.sketchcomplete.type, "sketchcomplete", "[dblclick] sketchcomplete triggered");
+ t.geom_eq(log.sketchcomplete.feature.geometry,
+ new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(-200, 125),
+ new OpenLayers.Geometry.Point(-190, 115)
+ ]),
+ "[dblclick] correct geometry");
+
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/EditingToolbar.html b/misc/openlayers/tests/Control/EditingToolbar.html
new file mode 100644
index 0000000..570986d
--- /dev/null
+++ b/misc/openlayers/tests/Control/EditingToolbar.html
@@ -0,0 +1,33 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_ctor_draw(t) {
+ t.plan(5);
+ var map = new OpenLayers.Map('map');
+ var vLayer = new OpenLayers.Layer.Vector();
+ map.addLayer(vLayer);
+
+ var editingToolbar = new OpenLayers.Control.EditingToolbar(vLayer, {
+ citeCompliant: "foo"
+ });
+ map.addControl(editingToolbar);
+
+ t.ok(editingToolbar instanceof OpenLayers.Control.EditingToolbar,
+ "new OpenLayers.Control.EditingToolbar returns object" );
+ t.ok(editingToolbar.controls[0] instanceof OpenLayers.Control.Navigation,
+ "EditingToolbar contains Control.Navigation object" );
+ t.eq(editingToolbar.controls[0].active, true,
+ "First control is active" );
+ t.eq(editingToolbar.controls.length, 4,
+ "EditingToolbar contains 4 Controls" );
+ t.eq(editingToolbar.controls[1].handler.citeCompliant, "foo", "citeCompliant option passed to handler correctly")
+
+ map.destroy();
+ }
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Geolocate.html b/misc/openlayers/tests/Control/Geolocate.html
new file mode 100644
index 0000000..4e43f39
--- /dev/null
+++ b/misc/openlayers/tests/Control/Geolocate.html
@@ -0,0 +1,129 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map, control, centerLL
+ watch = null,
+ geolocation= {
+ getCurrentPosition: function(f) {
+ f({
+ coords: { latitude: 10, longitude: 10 }
+ });
+ },
+ watchPosition: function(f) {
+ watch = true;
+ },
+ clearWatch: function() {
+ watch = null;
+ }
+ };
+
+ function test_initialize(t) {
+ t.plan(3);
+ control = new OpenLayers.Control.Geolocate({geolocationOptions: {foo: 'bar'}});
+ t.ok(control instanceof OpenLayers.Control.Geolocate,
+ "new OpenLayers.Control returns object" );
+ t.eq(control.displayClass, "olControlGeolocate", "displayClass is correct" );
+ t.eq(control.geolocationOptions.foo, 'bar',
+ 'provided geolocation options are set in the geolocationOptions prop');
+ }
+ function test_bind(t) {
+ t.plan(3);
+ var control = new OpenLayers.Control.Geolocate({
+ geolocation: geolocation
+ });
+ control.events.register('locationupdated', null, function() {
+ t.ok(true, 'locationupdated event is fired when bound');
+ });
+ map.addControl(control);
+ control.activate();
+ var center = map.getCenter();
+ t.eq(center.lon, 10, 'bound control sets the map lon');
+ t.eq(center.lat, 10, 'bound control sets the map lat');
+ control.deactivate();
+ map.removeControl(control);
+ map.setCenter(centerLL);
+ }
+ function test_unbind(t) {
+ t.plan(3);
+ var control = new OpenLayers.Control.Geolocate({
+ geolocation: geolocation,
+ bind: false
+ });
+ control.events.register('locationupdated', null, function() {
+ t.ok(true, 'locationupdated event is fired when unbound');
+ });
+ map.addControl(control);
+ control.activate();
+ var center = map.getCenter();
+ t.eq(center.lon, 0, 'unbound control doesnt sets the map lon');
+ t.eq(center.lat, 0, 'unbound control doesnt sets the map lat');
+ control.deactivate();
+ map.removeControl(control);
+ map.setCenter(centerLL);
+ }
+ function test_getCurrentLocation(t) {
+ t.plan(5);
+ var control = new OpenLayers.Control.Geolocate({
+ geolocation: geolocation
+ });
+ map.addControl(control);
+ t.eq(control.getCurrentLocation(), false, 'getCurrentLocation return false if control hasnt been activated');
+ control.activate();
+ map.setCenter(centerLL);
+ t.eq(control.getCurrentLocation(), true, 'getCurrentLocation return true if control has been activated');
+ var center = map.getCenter();
+ t.eq(center.lon, 10, 'bound control sets the map lon when calling getCurrentLocation');
+ t.eq(center.lat, 10, 'bound control sets the map lat when calling getCurrentLocation');
+ control.deactivate();
+ map.removeControl(control);
+ map.setCenter(centerLL);
+ var control2 = new OpenLayers.Control.Geolocate({
+ geolocation: geolocation
+ });
+ map.addControl(control2);
+ t.eq(control2.getCurrentLocation(), false, 'getCurrentLocation return false if control is in watch mode');
+ control2.deactivate();
+ map.removeControl(control2);
+ map.setCenter(centerLL);
+ }
+ function test_watch(t) {
+ t.plan(2);
+ var control = new OpenLayers.Control.Geolocate({
+ geolocation: geolocation,
+ watch: true
+ });
+ map.addControl(control);
+ control.activate();
+ t.eq(watch, true, 'watch option makes calls to watchPosition');
+ control.deactivate();
+ t.eq(watch, null, 'deactivate control calls the clearwatch');
+ map.removeControl(control);
+ map.setCenter(centerLL);
+ }
+ function test_destroy(t) {
+ t.plan(1);
+ var control = new OpenLayers.Control.Geolocate({
+ geolocation: geolocation,
+ watch: true
+ });
+ control.activate();
+ control.destroy();
+ t.ok(control.active === false, "control deactivated before being destroyed");
+ }
+
+ function loader() {
+ map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS("Test Layer",
+ "http://labs.metacarta.com/wms-c/Basic.py?",
+ {layers: "basic"});
+ map.addLayer(layer);
+ centerLL = new OpenLayers.LonLat(0,0);
+ map.setCenter(centerLL, 5);
+ }
+ </script>
+</head>
+<body onload="loader()">
+ <div id="map" style="width: 256px; height: 256px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/GetFeature.html b/misc/openlayers/tests/Control/GetFeature.html
new file mode 100644
index 0000000..bbdd0e4
--- /dev/null
+++ b/misc/openlayers/tests/Control/GetFeature.html
@@ -0,0 +1,177 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_Control_GetFeature_constructor(t) {
+ t.plan(3);
+ var protocol = "foo";
+ var control = new OpenLayers.Control.GetFeature({
+ protocol: protocol
+ });
+ t.ok(control instanceof OpenLayers.Control.GetFeature,
+ "new OpenLayers.Control.SelectFeature returns an instance");
+ t.eq(control.protocol, "foo",
+ "constructor sets protocol correctly");
+
+ control = new OpenLayers.Control.GetFeature({
+ filterType: OpenLayers.Filter.Spatial.INTERSECTS
+ });
+ t.eq(control.filterType, OpenLayers.Filter.Spatial.INTERSECTS,
+ "constructor sets filterType correctly");
+
+ }
+
+ function test_Control_GetFeature_select(t) {
+ t.plan(10);
+ var cssAdded;
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.WMS("foo", "wms", {
+ layers: "foo"
+ });
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(1,2));
+ var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));
+ var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(2,3));
+ var feature3 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(3,1));
+ var control = new OpenLayers.Control.GetFeature({
+ protocol: new OpenLayers.Protocol({
+ read: function(obj) {
+ cssAdded = OpenLayers.Element.hasClass(map.viewPortDiv,
+ "olCursorWait");
+ obj.callback.call(obj.scope, {
+ features: [feature1, feature2, feature3],
+ success: function() {return true;}
+ });
+ }
+ }),
+ box: true
+ });
+ map.addControl(control);
+
+ var singleTest = function(evt) {
+ t.eq(evt.feature.id, feature1.id, "featureselected callback called with closest feature");
+ }
+ cssAdded = false;
+ control.events.register("featureselected", this, singleTest);
+ control.selectClick({xy: new OpenLayers.Pixel(200, 125)});
+ t.ok(cssAdded,
+ "select adds CSS class (click)");
+ t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, "olCursorWait"),
+ "callback removes CSS class (click)");
+ control.events.unregister("featureselected", this, singleTest);
+
+ var count = 0;
+ var beforeFeatureSelected = function(evt) {
+ count++;
+ return count < 3;
+ }
+ var features = [];
+ var boxTest = function(evt) {
+ features.push(evt.feature);
+ }
+ var beforeFeaturesSelected = function(evt) {
+ t.eq(evt.features.length, 3, "3 features passed to the beforefeaturesselected handler");
+ }
+ var featuresSelected = function(evt) {
+ t.eq(evt.features.length, 2, "2 features passed to the featuresselected handler");
+ }
+ control.events.register("beforefeatureselected", this, beforeFeatureSelected);
+ control.events.register("featureselected", this, boxTest);
+ control.events.register("beforefeaturesselected", this, beforeFeaturesSelected);
+ control.events.register("featuresselected", this, featuresSelected);
+ cssAdded = false;
+ control.selectBox(new OpenLayers.Bounds(0,0,4,4));
+ control.events.unregister("beforefeatureselected", this, beforeFeatureSelected);
+ control.events.unregister("featureselected", this, boxTest);
+ control.events.unregister("beforefeaturesselected", this, beforeFeaturesSelected);
+ control.events.unregister("featuresselected", this, featuresSelected);
+ t.eq(features.length, 2, "2 features inside box selected");
+ t.eq(features[1].id, feature2.id, "featureselected callback called with multiple features");
+ t.ok(cssAdded,
+ "select adds CSS class (box)");
+ t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, "olCursorWait"),
+ "callback removes CSS class (box)");
+
+ // allow several features even for single click
+ control.single = false;
+ var multiplePointTest = function(evt) {
+ t.eq(evt.features.length, 3, "3 features passed to the featuresselected handler");
+ }
+ control.events.register("featuresselected", this, multiplePointTest);
+ control.selectClick({xy: new OpenLayers.Pixel(200, 125)});
+ control.events.unregister("featuresselected", this, multiplePointTest);
+ }
+
+ function test_Control_GetFeature_hover(t) {
+ t.plan(9);
+ var cssAdded;
+ var abortedResponse = null;
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.WMS("foo", "wms", {
+ layers: "foo"
+ });
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(1,2));
+ var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));
+ var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(2,3));
+ var response = new OpenLayers.Protocol.Response();
+ var control = new OpenLayers.Control.GetFeature({
+ protocol: new OpenLayers.Protocol({
+ read: function(obj){
+ cssAdded = OpenLayers.Element.hasClass(map.viewPortDiv,
+ "olCursorWait");
+ obj.callback.call(obj.scope, {
+ features: [feature1, feature2],
+ success: function() {return true;}
+ });
+ return response;
+ },
+ abort: function(response) {
+ abortedResponse = response;
+ }
+ }),
+ hover: true
+ });
+ map.addControl(control);
+
+ var hoverFeature;
+ var hoverTest = function(evt) {
+ t.eq(evt.feature.id, hoverFeature.id, "hoverfeature callback called with closest feature");
+ }
+ var outTest = function(evt) {
+ t.eq(evt.feature.id, feature1.id, "outfeature callback called with previously hovered feature");
+ }
+ control.events.register("hoverfeature", this, hoverTest);
+ control.events.register("outfeature", this, outTest);
+ hoverFeature = feature1;
+ control.selectHover({xy: new OpenLayers.Pixel(200, 125)});
+ t.ok(control.hoverResponse == response,
+ "selectHover stores the protocol response in the hoverResponse property");
+
+ hoverFeature = feature2;
+ cssAdded = false;
+ control.selectHover({xy: new OpenLayers.Pixel(400, 0)});
+ t.ok(cssAdded,
+ "select adds CSS class (hover)");
+ t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, "olCursorWait"),
+ "callback removes CSS class (hover)");
+
+ OpenLayers.Element.addClass(map.viewPortDiv, "olCursorWait");
+ control.cancelHover();
+ t.ok(abortedResponse == response,
+ "cancelHover calls protocol.abort() with the expected response");
+ t.eq(control.hoverResponse, null,
+ "cancelHover sets this.hoverResponse to null");
+ t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, "olCursorWait"),
+ "cancelHover removes CSS class");
+
+ control.events.unregister("hoverfeature", this, hoverTest);
+ control.events.unregister("outfeature", this, outTest);
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Graticule.html b/misc/openlayers/tests/Control/Graticule.html
new file mode 100644
index 0000000..4aa867f
--- /dev/null
+++ b/misc/openlayers/tests/Control/Graticule.html
@@ -0,0 +1,66 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script src="http://svn.osgeo.org/metacrs/proj4js/trunk/lib/proj4js-compressed.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(2);
+ var options = {};
+ var map = new OpenLayers.Map("map",{projection:"EPSG:4326"});
+ var layer = new OpenLayers.Layer.WMS();
+ map.addLayers([layer]);
+
+ var control = new OpenLayers.Control.Graticule(options);
+ map.addControl(control);
+ map.zoomToMaxExtent();
+
+ t.ok(control.gratLayer instanceof OpenLayers.Layer.Vector,
+ "constructor sets layer correctly");
+ t.ok(control.gratLayer.features.length > 0,
+ "graticule has features");
+ control.destroy();
+ }
+
+ function test_activate(t) {
+ t.plan(7);
+ var map = new OpenLayers.Map("map",{projection:"EPSG:4326"});
+ var layer = new OpenLayers.Layer.WMS();
+ map.addLayers([layer]);
+
+ var control = new OpenLayers.Control.Graticule({});
+ map.addControl(control);
+ map.zoomToMaxExtent();
+
+ t.ok(control.gratLayer.visibility, "Graticule layer is visible by default");
+ control.deactivate();
+ t.ok(control.gratLayer.map == null,
+ "Graticule layer is not in map when control is deactivated");
+ control.destroy();
+
+ var control2 = new OpenLayers.Control.Graticule({autoActivate:false});
+ map.addControl(control2);
+ t.ok(control2.gratLayer.map == null,
+ "Graticule layer is not in map when autoActivate:false");
+ t.ok(control2.gratLayer.features.length == 0,
+ "Graticule layer is empty when autoActivate:false");
+ control2.activate();
+ t.ok(control2.gratLayer.map != null,
+ "Graticule layer is on map when control is activated");
+ t.ok(control2.gratLayer.features.length > 0,
+ "Graticule features refreshed after control is activated");
+ control2.gratLayer.setVisibility(false);
+
+ control2.destroy();
+ t.ok(control2.gratLayer == null,
+ "Graticule layer is destroyed when control is destroyed");
+
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/KeyboardDefaults.html b/misc/openlayers/tests/Control/KeyboardDefaults.html
new file mode 100644
index 0000000..e190177
--- /dev/null
+++ b/misc/openlayers/tests/Control/KeyboardDefaults.html
@@ -0,0 +1,173 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map;
+ function test_Control_KeyboardDefaults_constructor (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.KeyboardDefaults();
+ t.ok( control instanceof OpenLayers.Control.KeyboardDefaults,
+ "new OpenLayers.Control.KeyboardDefaults returns object" );
+ t.eq( control.displayClass, "olControlKeyboardDefaults", "displayClass is correct" );
+ }
+
+ function test_Control_KeyboardDefaults_destroy (t) {
+ t.plan(2);
+
+ map = new OpenLayers.Map('map');
+ var control = new OpenLayers.Control.KeyboardDefaults();
+ map.addControl(control);
+ t.ok(control.handler != null, "control.handler is created");
+ control.destroy();
+ t.ok(control.handler == null, "control.handler is null after destroy");
+ map.destroy();
+ }
+
+ function test_Control_KeyboardDefaults_addControl (t) {
+ t.plan( 4 );
+
+ map = new OpenLayers.Map('map');
+ control = new OpenLayers.Control.KeyboardDefaults();
+ t.ok( control instanceof OpenLayers.Control.KeyboardDefaults,
+ "new OpenLayers.Control.KeyboardDefaults returns object" );
+ t.ok( map instanceof OpenLayers.Map,
+ "new OpenLayers.Map creates map" );
+ map.addControl(control);
+ t.ok( control.map === map, "Control.map is set to the map object" );
+ t.ok( OpenLayers.Util.indexOf(map.controls, control), "map.controls contains control" );
+ }
+
+ /* When interpretting
+ * the keycodes below (including the comments associated with them),
+ * consult the URL below. For instance, the Safari browser returns
+ * "IE keycodes", and so is supported by any keycode labeled "IE".
+ *
+ * Very informative URL:
+ * http://unixpapa.com/js/key.html
+ */
+ function test_Control_KeyboardDefaults_KeyDownEvent (t) {
+ t.plan( 25 );
+
+ var evt = {which: 1}, pans = [], zoomIns = 0, zoomOuts = 0;
+
+ map = new OpenLayers.Map('map');
+
+ // mock "pan", "zoomIn" and "zoomOut"
+ map.pan = function(dx, dy) {
+ pans.push({dx: dx, dy: dy});
+ };
+ map.zoomIn = function() {
+ zoomIns++;
+ };
+ map.zoomOut = function() {
+ zoomOuts++;
+ };
+
+ var layer = new OpenLayers.Layer.WMS("Test Layer",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+
+ var control = new OpenLayers.Control.KeyboardDefaults({
+ slideFactor: 100
+ });
+ map.addControl(control);
+
+ map.setCenter(new OpenLayers.LonLat(0, 0), 4);
+
+ // Start new test.
+ evt.keyCode = OpenLayers.Event.KEY_LEFT;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 1, '[KEY_LEFT] pan called once');
+ t.eq(pans[0], {dx: -100, dy: 0},
+ '[KEY LEFT] pan called with expected args');
+
+ evt.keyCode = OpenLayers.Event.KEY_RIGHT;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 2, '[KEY_RIGHT] pan called once');
+ t.eq(pans[1], {dx: 100, dy: 0},
+ '[KEY RIGHT] pan called with expected args');
+
+ evt.keyCode = OpenLayers.Event.KEY_UP;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 3, '[KEY_UP] pan called once');
+ t.eq(pans[2], {dx: 0, dy: -100},
+ '[KEY UP] pan called with expected args');
+
+ evt.keyCode = OpenLayers.Event.KEY_DOWN;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 4, '[KEY_DOWN] pan called once');
+ t.eq(pans[3], {dx: 0, dy: 100},
+ '[KEY DOWN] pan called with expected args');
+
+ evt.keyCode = 33;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 5, '[33] pan called once');
+ t.eq(pans[4], {dx: 0, dy: -384},
+ '[33] pan called with expected args');
+
+ evt.keyCode = 34;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 6, '[34] pan called once');
+ t.eq(pans[5], {dx: 0, dy: 384},
+ '[34] pan called with expected args');
+
+ evt.keyCode = 35;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 7, '[35] pan called once');
+ t.eq(pans[6], {dx: 768, dy: 0},
+ '[35] pan called with expected args');
+
+ evt.keyCode = 36;
+ control.defaultKeyPress(evt);
+ t.eq(pans.length, 8, '[36] pan called once');
+ t.eq(pans[7], {dx: -768, dy: 0},
+ '[36] pan called with expected args');
+
+ evt.keyCode = 43;
+ control.defaultKeyPress(evt);
+ t.eq(zoomIns, 1, '[43] zoomIn called once');
+
+ evt.keyCode = 61;
+ control.defaultKeyPress(evt);
+ t.eq(zoomIns, 2, '[61] zoomIn called once');
+
+ evt.keyCode = 187;
+ control.defaultKeyPress(evt);
+ t.eq(zoomIns, 3, '[187] zoomIn called once');
+
+ evt.keyCode = 107;
+ control.defaultKeyPress(evt);
+ t.eq(zoomIns, 4, '[107] zoomIn called once');
+
+ evt.keyCode = 107;
+ control.defaultKeyPress(evt);
+ t.eq(zoomIns, 5, '[107] zoomIn called once');
+
+ evt.keyCode = 45;
+ control.defaultKeyPress(evt);
+ t.eq(zoomOuts, 1, '[45] zoomOut called once');
+
+ evt.keyCode = 109;
+ control.defaultKeyPress(evt);
+ t.eq(zoomOuts, 2, '[109] zoomOut called once');
+
+ evt.keyCode = 189;
+ control.defaultKeyPress(evt);
+ t.eq(zoomOuts, 3, '[189] zoomOut called once');
+
+ evt.keyCode = 95;
+ control.defaultKeyPress(evt);
+ t.eq(zoomOuts, 4, '[95] zoomOut called once');
+
+ map.destroy();
+ }
+
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/LayerSwitcher.html b/misc/openlayers/tests/Control/LayerSwitcher.html
new file mode 100644
index 0000000..c81a779
--- /dev/null
+++ b/misc/openlayers/tests/Control/LayerSwitcher.html
@@ -0,0 +1,249 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map;
+ OpenLayers.Lang.setCode('en');
+
+ function test_Control_LayerSwitcher_constructor (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ t.ok( control instanceof OpenLayers.Control.LayerSwitcher, "new OpenLayers.Control.LayerSwitcher returns object" );
+ t.eq( control.displayClass, "olControlLayerSwitcher", "displayClass is correct" );
+ }
+
+ function test_Control_LayerSwitcher_draw (t) {
+ t.plan( 2 );
+
+ map = new OpenLayers.Map('map');
+ control = new OpenLayers.Control.LayerSwitcher();
+ map.addControl(control);
+
+ var div = control.draw();
+ t.ok( control.div != null, "draw makes a div" );
+ t.ok( div != null, "draw returns its div" );
+ }
+ function test_Control_LayerSwitcher_outsideViewport (t) {
+ t.plan( 4 );
+
+ map = new OpenLayers.Map('map');
+ control = new OpenLayers.Control.LayerSwitcher({'div':OpenLayers.Util.getElement('layerswitcher')});
+ map.addControl(control);
+ t.eq(control.div.style.width, "250px", "Div is not minimized when added.");
+ t.ok(control.events.element && control.events.listeners.buttonclick, "[outside] Events instance attached to div and has buttonclick event");
+ control = new OpenLayers.Control.LayerSwitcher();
+ map.addControl(control);
+ t.eq(control.div.style.width, "0px", "Div is minimized when added.");
+ t.ok(!control.events.element && map.events.listeners.buttonclick, "[inside] Events instance not attached to div and buttonclick event registered on map");
+ }
+
+ function test_Control_LayerSwitcher_loadContents(t) {
+
+ t.plan( 10 );
+
+ map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS("WMS",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+
+ markers = new OpenLayers.Layer.Markers("markers");
+ map.addLayer(markers);
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ map.addControl(control);
+
+ t.ok(control.layersDiv != null, "correctly makes layers div");
+ t.ok(OpenLayers.Element.hasClass(control.layersDiv, "layersDiv"),
+ "layers div has class layersDiv");
+ t.ok(control.baseLayersDiv != null, "correctly makes layers div");
+ t.ok(OpenLayers.Element.hasClass(control.baseLayersDiv, "baseLayersDiv"),
+ "base layers div has class baseLayersDiv");
+ t.ok(control.dataLayersDiv != null, "correctly makes layers div");
+ t.ok(OpenLayers.Element.hasClass(control.dataLayersDiv, "dataLayersDiv"),
+ "data layers div has class dataLayersDiv");
+ t.ok(control.maximizeDiv != null, "correctly makes resize div");
+ t.ok(OpenLayers.Element.hasClass(control.maximizeDiv, "maximizeDiv"),
+ "maximize div has class maximizeDiv");
+ t.ok(control.minimizeDiv != null, "correctly makes resize div");
+ t.ok(OpenLayers.Element.hasClass(control.minimizeDiv, "minimizeDiv"),
+ "minimize div has class minmizeDiv");
+ }
+
+
+ function test_Control_LayerSwitcher_redraw (t) {
+
+ t.plan( (OpenLayers.BROWSER_NAME == "opera" ? 9 : 19 ) );
+
+ map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS("WMS",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+
+ markers = new OpenLayers.Layer.Markers("markers");
+ map.addLayer(markers);
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ map.addControl(control);
+
+ var wmsInput = control.div.childNodes[0].childNodes[1].childNodes[0];
+ t.ok(wmsInput != null, "correctly makes an input for wms layer");
+ t.eq(wmsInput.type, "radio", "wms correctly made a radio button");
+ t.eq(wmsInput.name, control.id + "_baseLayers", "wms correctly named");
+ t.eq(wmsInput.value, layer.name, "wms correctly valued");
+
+ var markersInput = control.div.childNodes[0].childNodes[3].childNodes[0];
+ t.ok(markersInput != null, "correctly makes an input for markers layer");
+ t.eq(markersInput.type, "checkbox", "wms correctly made a radio button");
+ t.eq(markersInput.name, markers.name, "wms correctly named");
+ t.eq(markersInput.value, markers.name, "wms correctly valued");
+
+ t.eq(false, control.checkRedraw(), "check redraw is false");
+ if (OpenLayers.BROWSER_NAME != "opera") {
+ control = new OpenLayers.Control.LayerSwitcher();
+ var myredraw = control.redraw;
+ control.redraw = function() {
+ t.ok(true, "redraw called when setting vis");
+ }
+ map.addControl(control);
+ var func = OpenLayers.Function.bind(myredraw, control);
+ func();
+ markers.setVisibility(false);
+ t.eq(control.checkRedraw(), true, "check redraw is true after changing layer and not letting redraw happen.");
+ map.removeControl(control);
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ var myredraw = control.redraw;
+ control.redraw = function() {
+ t.ok(true, "redraw called when setting inRange");
+ }
+ map.addControl(control);
+ var func = OpenLayers.Function.bind(myredraw, control);
+ func();
+ markers.inRange = false;
+ t.eq(control.checkRedraw(), true, "check redraw is true after changing layer.inRange and not letting redraw happen.");
+ map.removeControl(control);
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ var myredraw = control.redraw;
+ control.redraw = function() {
+ t.ok(true, "redraw called when raising base layer ");
+ }
+
+ map.addControl(control);
+ var func = OpenLayers.Function.bind(myredraw, control);
+ func();
+ map.raiseLayer(layer, 1);
+ t.eq(control.checkRedraw(), true, "check redraw is true after changing layer.inRange and not letting redraw happen.");
+ map.removeControl(control);
+ } else {
+ t.debug_print("FIXME: Some LayerSwitcher tests fail in Opera.");
+ }
+
+ }
+ function test_Control_LayerSwitcher_ascending (t) {
+
+ t.plan( 4 );
+
+ map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS("WMS",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+
+ markers = new OpenLayers.Layer.Markers("markers");
+ map.addLayer(markers);
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ map.addControl(control);
+ control2 = new OpenLayers.Control.LayerSwitcher({'ascending':false});
+ map.addControl(control2);
+ t.ok(control.div.childNodes[0].childNodes[0].innerHTML.match("Base Layer"), "Base Layers first in LayerSwitcher with ascending true");
+ t.ok(control.div.childNodes[0].childNodes[2].innerHTML.match("Overlays"), "Overlays in LayerSwitcher with ascending true");
+ t.ok(control2.div.childNodes[0].childNodes[2].innerHTML.match("Base Layer"), "Base Layers last in LayerSwitcher with ascending false");
+ t.ok(control2.div.childNodes[0].childNodes[0].innerHTML.match("Overlays"), "Base Layers last in LayerSwitcher with ascending false");
+ }
+
+ function test_Control_LayerSwitcher_displayInLayerSwitcher (t) {
+
+ t.plan( 2 );
+
+ map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS("WMS",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"}, {'displayInLayerSwitcher': false});
+ map.addLayer(layer);
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ map.addControl(control);
+ t.eq(control.div.childNodes[0].childNodes[0].style.display, "none" , "Base layer display off when no visble base layer");
+
+ map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS("WMS",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+
+ control = new OpenLayers.Control.LayerSwitcher();
+ map.addControl(control);
+ t.eq(control.div.childNodes[0].childNodes[0].style.display, "" , "Base layer display on when visble base layer");
+ }
+
+ // See e.g. https://github.com/openlayers/openlayers/issues/866
+ function test_Control_LayerSwitcher_validIds(t){
+ t.plan(2);
+
+ // setup
+ var layername = "Name with spaces & illegal characters * + ~ ` ' ? )",
+ map = new OpenLayers.Map("map", {
+ controls: [
+ new OpenLayers.Control.LayerSwitcher()
+ ],
+ layers: [
+ new OpenLayers.Layer.WMS(
+ layername,
+ "../../img/blank.gif"
+ ),
+ // add another layer with the same name, the generated id
+ // must be different
+ new OpenLayers.Layer.WMS(
+ layername,
+ "../../img/blank.gif"
+ )
+ ]
+ });
+
+ var baselayerDiv = map.controls[0].div.childNodes[0].childNodes[1],
+ firstGeneratedInputId = baselayerDiv.childNodes[0].id,
+ secondGeneratedInputId = baselayerDiv.childNodes[1].id,
+ // legal ids start with a letter and are followed only by word
+ // characters (letters, digits, and underscores) plus the dash (-)
+ // This is only a subset of all allowed charcters inside of ids.
+ allowedIdChars = (/^[a-zA-Z]{1}[\w-]*$/g);
+
+ // tests
+ // validity
+ t.ok(
+ allowedIdChars.test(firstGeneratedInputId),
+ "id only contains letters, digits, underscores and dashes. It " +
+ "starts with a letter."
+ );
+ // uniqueness
+ t.ok(
+ firstGeneratedInputId !== secondGeneratedInputId,
+ "generated ids are different even for equal layernames"
+ );
+
+ // teardown
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+ <div id="layerswitcher" style="width:250px; height:256px;" />
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Measure.html b/misc/openlayers/tests/Control/Measure.html
new file mode 100644
index 0000000..ee6d192
--- /dev/null
+++ b/misc/openlayers/tests/Control/Measure.html
@@ -0,0 +1,386 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+
+ t.plan(1);
+
+ var map = new OpenLayers.Map("map");
+ var control = new OpenLayers.Control.Measure(
+ OpenLayers.Handler.Path, {persist: true}
+ );
+ map.addControl(control);
+
+ t.eq(control.persist, true, "passing persist to constructor sets persist on handler");
+
+ map.destroy();
+
+ }
+
+ function test_cancel(t) {
+
+ t.plan(4);
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer(null, {
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ var control = new OpenLayers.Control.Measure(
+ OpenLayers.Handler.Path, {persist: true}
+ );
+ map.addControl(control);
+
+ control.activate();
+
+ try {
+ control.cancel();
+ t.ok(true, "calling cancel before drawing works");
+ } catch(err) {
+ t.fail("calling cancel before drawing causes trouble: " + err);
+ }
+ t.eq(control.active, true, "control remains active after cancel");
+
+ // create a simple measurement
+ function trigger(type, x, y) {
+ map.events.triggerEvent(type, {
+ xy: new OpenLayers.Pixel(x, y)
+ })
+ };
+
+ trigger("mousemove", 0, 0);
+ // keep a reference to the line being drawn
+ var line = control.handler.line;
+ trigger("mousedown", 0, 0);
+ trigger("mouseup", 0, 0);
+ trigger("mousemove", 10, 10);
+ trigger("mousedown", 10, 10);
+ trigger("mouseup", 10, 10);
+ trigger("dblclick", 10, 10);
+
+ // the geometry is finalized, we first confirm that it is persisted
+ t.ok(line.layer === control.handler.layer, "feature persists");
+
+ // cancel and see that sketch is gone
+ control.cancel();
+ t.eq(line.layer, null, "feature is gone after cancel");
+
+ map.destroy();
+ }
+
+ // test for <http://trac.openlayers.org/ticket/2691>
+ function test_partial(t) {
+
+ t.plan(28);
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ units: "m",
+ resolutions: [1],
+ layers: [
+ new OpenLayers.Layer(null, {
+ isBaseLayer: true
+ })
+ ],
+ center: new OpenLayers.LonLat(0, 0)
+ });
+
+ var log = [];
+ var control = new OpenLayers.Control.Measure(
+ OpenLayers.Handler.Path, {persist: true,
+ eventListeners: {
+ measurepartial: function(evt) {
+ log.push(evt);
+ },
+ measure: function(evt){
+ log.push(evt);
+ }
+ },
+ handlerOptions: {
+ pixelTolerance: 0,
+ dblclickTolerance: 0
+ }
+ }
+ );
+ map.addControl(control);
+ control.activate();
+
+
+ // convenience function to trigger mouse events
+ function trigger(type, x, y) {
+ map.events.triggerEvent(type, {
+ xy: new OpenLayers.Pixel(x, y)
+ })
+ };
+
+ // delay in seconds
+ var delay = control.partialDelay / 1000;
+
+ // establish first point
+ trigger("mousemove", 0, 0);
+ trigger("mousedown", 0, 0);
+ trigger("mouseup", 0, 0);
+
+
+ // a) move 10 pixels and click
+ trigger("mousemove", 0, 10);
+ trigger("mousedown", 0, 10);
+ trigger("mouseup", 0, 10);
+
+ // confirm measurepartial is not fired before delay
+ t.eq(log.length, 0, "a) no event fired yet")
+
+ t.delay_call(
+ // wait for delay then confirm event was logged
+ delay, function() {
+ t.eq(log.length, 1, "a) event logged")
+ t.eq(log[0] && log[0].type, "measurepartial", "a) event logged");
+ t.eq(log[0] && log[0].measure, 10, "a) correct measure");
+
+ // b) move 10 pixels and click
+ trigger("mousemove", 0, 20);
+ trigger("mousedown", 0, 20);
+ trigger("mouseup", 0, 20);
+
+ // confirm measurepartial is not fired before delay
+ t.eq(log.length, 1, "b) no event fired yet")
+
+ },
+ delay, function() {
+ t.eq(log.length, 2, "b) event logged");
+ t.eq(log[1] && log[1].type, "measurepartial", "b) correct type");
+ t.eq(log[1] && log[1].measure, 20, "b) correct measure");
+
+ // c) move 10 pixels and click
+ trigger("mousemove", 0, 30);
+ trigger("mousedown", 0, 30);
+ trigger("mouseup", 0, 30);
+ },
+ // wait for half delay and confirm event not logged
+ delay / 2, function() {
+ // confirm measurepartial is not fired before delay
+ t.eq(log.length, 2, "c) no event fired yet")
+ },
+ // wait for rest of delay and confirm event logged
+ delay / 2, function() {
+ t.eq(log.length, 3, "c) event logged");
+ t.eq(log[2] && log[2].type, "measurepartial", "c) correct type");
+ t.eq(log[2] && log[2].measure, 30, "c) correct measure");
+
+ // d) move 10 pixels and click
+ trigger("mousemove", 0, 40);
+ trigger("mousedown", 0, 40);
+ trigger("mouseup", 0, 40);
+
+ // confirm measurepartial is not fired before delay
+ t.eq(log.length, 3, "d) no event fired yet")
+
+ // e) double click to finish
+ trigger("dblclick", 0, 40);
+
+ t.eq(log.length, 4, "e) event logged");
+ t.eq(log[3] && log[3].type, "measure", "e) correct type");
+ t.eq(log[3] && log[3].measure, 40, "e) correct measure");
+ },
+ // wait for rest of delay and confirm no measurepartial logged
+ delay, function() {
+ // confirm measurepartial is not fired after dblclick
+ t.eq(log.length, 4, "e) no additional event fired");
+
+ // change to freehand mode and confirm synchronous event dispatch
+ control.handler.freehand = true;
+ // clear log
+ log = [];
+
+ // f) establish first freehand point
+ trigger("mousemove", 0, 0);
+ trigger("mousedown", 0, 0);
+ t.eq(log.length, 0, "f) no event fired yet")
+
+ // g) move 10 pixels
+ trigger("mousemove", 10, 0);
+
+ t.eq(log.length, 1, "g) event logged");
+ t.eq(log[0] && log[0].type, "measurepartial", "g) correct type");
+ t.eq(log[0] && log[0].measure, 10, "g) correct measure");
+
+ // h) move 10 pixels
+ trigger("mousemove", 20, 0);
+
+ t.eq(log.length, 2, "h) event logged");
+ t.eq(log[1] && log[1].type, "measurepartial", "h) correct type");
+ t.eq(log[1] && log[1].measure, 20, "h) correct measure");
+
+ // i) mouse up to finish
+ trigger("mouseup", 20, 0);
+
+ t.eq(log.length, 3, "i) event logged");
+ t.eq(log[2] && log[2].type, "measure", "i) correct type");
+ t.eq(log[2] && log[2].measure, 20, "i) correct measure");
+
+ // j) clean up
+ log = [];
+ map.destroy();
+ },
+ // wait for delay and confirm event not logged
+ delay, function() {
+ t.eq(log.length, 0, "j) no event fired after destroy");
+ }
+ );
+
+ }
+
+ function test_immediate(t) {
+ t.plan(32);
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ units: "m",
+ resolutions: [1],
+ layers: [
+ new OpenLayers.Layer(null, {
+ isBaseLayer: true
+ })
+ ],
+ center: new OpenLayers.LonLat(0, 0)
+ });
+
+ var log = [];
+ var control = new OpenLayers.Control.Measure(
+ OpenLayers.Handler.Path, {
+ persist: true,
+ immediate: true,
+ eventListeners: {
+ measurepartial: function(evt) {
+ log.push(evt);
+ },
+ measure: function(evt){
+ log.push(evt);
+ }
+ },
+ handlerOptions: {
+ pixelTolerance: 0,
+ dblclickTolerance: 0
+ }
+ }
+ );
+ map.addControl(control);
+ control.activate();
+
+ // convenience function to trigger mouse events
+ function trigger(type, x, y) {
+ map.events.triggerEvent(type, {
+ xy: new OpenLayers.Pixel(x, y)
+ })
+ };
+
+ // delay in seconds
+ var delay = control.partialDelay / 1000;
+
+ // a) establish first point
+ trigger("mousemove", 0, 0);
+ trigger("mousedown", 0, 0);
+ trigger("mouseup", 0, 0);
+
+ // move 10 pixels
+ trigger("mousemove", 0, 10);
+
+ t.eq(log.length, 1, "a) has fired an event");
+
+ t.delay_call(
+ delay, function() {
+ // confirm measurepartial is fired
+ t.eq(log.length, 1, "a) one event logged");
+ t.ok(log[0] && log[0].type == "measurepartial", "a) correct type");
+ // mousemove within the partialDelay fires no event, so the
+ // measure below is the one of the initial point
+ t.eq(log[0]?log[0].measure:-1 , 10, "a) correct measure");
+
+ // b) move 10 pixels
+ trigger("mousemove", 0, 20);
+ // c) move 10 pixels again
+ trigger("mousemove", 0, 30);
+
+ // confirm measurepartial is fired 2 times
+ t.eq(log.length, 3, "b) event logged");
+ t.eq(log[1] && log[1].type, "measurepartial", "b) correct type");
+ t.eq(log[1] && log[1].measure, 20, "b) correct measure");
+ t.eq(log[2] && log[2].type, "measurepartial", "c) correct type");
+ t.eq(log[2] && log[2].measure, 30, "c) correct measure");
+
+ // d) switch immediate measurement off
+ control.setImmediate(false);
+ t.eq(control.immediate, false, "d) immediate is false");
+
+ // e) move 10 pixels and click
+ trigger("mousemove", 0, 40);
+ trigger("mousedown", 0, 40);
+ trigger("mouseup", 0, 40);
+ // confirm measurepartial is not fired before delay
+ t.eq(log.length, 3, "e) no event fired yet")
+ },
+ // wait for delay then confirm event was logged
+ delay, function() {
+ t.eq(log.length, 4, "e) event logged")
+ t.ok(log[3] && log[3].type == "measurepartial", "e) correct type");
+ t.ok(log[3] && log[3].measure == 40, "e) correct measure");
+
+ // f) switch immediate measurement on
+ control.setImmediate(true);
+ t.eq(control.immediate, true, "f) immediate is true");
+
+ // g) move 10 pixels
+ trigger("mousemove", 0, 50);
+ },
+ delay, function() {
+ t.eq(log.length, 5, "g) event logged");
+ t.ok(log[4] && log[4].type == "measurepartial", "g) correct type");
+ t.ok(log[4] && log[4].measure == 50, "g) correct measure");
+
+ // h) move 10 pixels
+ trigger("mousemove", 0, 60);
+
+ t.eq(log.length, 6, "h) event logged");
+ t.ok(log[5] && log[5].type == "measurepartial", "h) correct type");
+ t.ok(log[5] && log[5].measure == 60, "h) correct measure");
+
+ // i) double click to finish
+ trigger("mousedown", 0, 60);
+ t.eq(log.length, 7, "i) event logged");
+ t.eq(log[6] && log[6].type, "measurepartial", "i) correct type");
+ t.eq(log[6] && log[6].measure, 60, "i) correct measure");
+ trigger("mouseup", 0, 60);
+ t.eq(log.length, 7, "i) no event fired yet");
+ },
+ delay, function() {
+ t.eq(log.length, 8, "j) event logged");
+ t.eq(log[7] && log[7].type, "measurepartial", "j) correct type");
+ t.eq(log[7] && log[7].measure, 60, "j) correct measure");
+
+ trigger("dblclick", 0, 60);
+ t.eq(log.length, 9, "k) event logged");
+ t.eq(log[8] && log[8].type, "measure", "k) correct type");
+ t.eq(log[8] && log[8].measure, 60, "k) correct measure");
+ // clear log
+ log = [];
+
+ // l) clean up
+ map.destroy();
+ // wait for delay and confirm event not logged
+ },
+ delay, function() {
+ t.eq(log.length, 0, "l) no event fired after destroy");
+ }
+ );
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 512px; height: 256px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/ModifyFeature.html b/misc/openlayers/tests/Control/ModifyFeature.html
new file mode 100644
index 0000000..6226733
--- /dev/null
+++ b/misc/openlayers/tests/Control/ModifyFeature.html
@@ -0,0 +1,828 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(3);
+ var layer = {
+ styleMap: {createSymbolizer: function(){}},
+ events: {
+ on: function() {},
+ un: function() {}
+ }
+ };
+ var options = {
+ documentDrag: true
+ };
+ var control = new OpenLayers.Control.ModifyFeature(layer, options);
+
+ t.ok(control.layer == layer,
+ "constructor sets layer correctly");
+ t.eq(control.handlers.drag.documentDrag, true,
+ "constructor sets options correctly on drag handler");
+ t.eq(control.mode, OpenLayers.Control.ModifyFeature.RESHAPE,
+ "constructor initializes modification mode correctly");
+ control.destroy();
+ }
+
+ function test_destroy(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ control.destroy();
+ t.eq(control.layer, null, "Layer reference removed on destroy.");
+ map.destroy();
+ }
+
+ function test_activate(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ t.ok(!control.handlers.drag.active,
+ "drag handler is not active prior to activating control");
+ control.activate();
+ t.ok(control.handlers.drag.active,
+ "drag handler is active after activating control");
+
+ map.destroy();
+ }
+
+ function test_initDeleteCodes(t) {
+ t.plan(3);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.ModifyFeature(layer, {'deleteCodes': 46});
+ t.eq(control.deleteCodes[0], 46, "Delete code properly turned into an array.");
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ t.eq(control.deleteCodes[0], 46, "Default deleteCodes include delete");
+ t.eq(control.deleteCodes[1], 68, "Default deleteCodes include 'd'");
+
+ control.destroy();
+ layer.destroy();
+ }
+
+ function test_handleKeypress(t) {
+ t.plan(16);
+
+ /**
+ * There are two things that we want to test here
+ * 1) test that control.deleteCodes are respected
+ * 3) test that a vertex is properly deleted
+ *
+ * In the future, feature deletion may be added to the control.
+ */
+
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ var delKey = 46;
+ var dKey = 100;
+ control.deleteCodes = [delKey, dKey];
+
+ // test that a polygon vertex is deleted for all delete codes
+ var point = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point()
+ );
+ var poly = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Polygon()
+ );
+
+ // mock up vertex deletion
+ var origGetFeatureFromEvent = layer.getFeatureFromEvent;
+ layer.getFeatureFromEvent = function() { return point; };
+ control.feature = poly;
+ // we cannot use selectFeature since the control is not part of a map
+ control._originalGeometry = poly.geometry.clone();
+ control.vertices = [point];
+ point.geometry.parent = {
+ removeComponent: function(geometry) {
+ t.eq(geometry.id, point.geometry.id,
+ "vertex deletion: removeComponent called on parent with proper geometry");
+ }
+ };
+ layer.events.on({
+ "featuremodified": function(event) {
+ t.ok(event.feature.modified !== null, "modified property of feature should have been set");
+ t.eq(event.feature.id, poly.id, "vertex deletion: featuremodifed triggered");
+ },
+ "vertexremoved": function(evt) {
+ layer.events.unregister("vertexremoved", this, arguments.callee);
+ t.eq(evt.feature.id, poly.id, "vertexremoved triggered with correct feature");
+ t.eq(evt.vertex.id, point.geometry.id, "vertexremoved triggered with correct vertex");
+ t.eq(evt.pixel, "foo", "vertexremoved triggered with correct pixel");
+ }
+ });
+ layer.drawFeature = function(feature) {
+ t.eq(feature.id, poly.id,
+ "vertex deletion: drawFeature called with the proper feature");
+ };
+ control.resetVertices = function() {
+ t.ok(true, "vertex deletion: resetVertices called");
+ };
+ control.onModification = function(feature) {
+ t.eq(feature.id, poly.id,
+ "vertex deletion: onModification called with the proper feature");
+ };
+ // run the above four tests twice
+ control.handleKeypress({keyCode:delKey, xy: "foo"});
+ control.handleKeypress({keyCode:dKey});
+ t.eq(control.feature.state, OpenLayers.State.UPDATE, "feature state set to update");
+
+ // now make sure nothing happens if the vertex is mid-drag
+ control.handlers.drag.dragging = true;
+ control.handleKeypress({keyCode:delKey});
+
+ // clean up
+ layer.getFeatureFromEvent = origGetFeatureFromEvent;
+ control.destroy();
+ layer.destroy();
+ }
+
+
+ function test_onUnSelect(t) {
+ t.plan(5);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ var fakeFeature = {'id':'myid'};
+ control.vertices = 'a';
+ control.virtualVertices = 'b';
+ control.features = true;
+ layer.events.on({"afterfeaturemodified": function(event) {
+ t.eq(event.feature, fakeFeature, "afterfeaturemodified triggered");
+ }});
+ control.onModificationEnd = function (feature) { t.eq(feature.id, fakeFeature.id, "onModificationEnd got feature.") }
+ layer.removeFeatures = function(verts) {
+ t.ok(verts == 'a', "Normal verts removed correctly");
+ }
+ layer.destroyFeatures = function(verts) {
+ t.ok(verts == 'b', "Virtual verts destroyed correctly");
+ }
+ control.unselectFeature(fakeFeature);
+ t.eq(control.feature, null, "feature is set to null");
+
+ layer.destroyFeatures = function() {};
+ control.destroy();
+ layer.destroy();
+ }
+
+ function test_stop_modification(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.Vector("Vectors!", {isBaseLayer: true});
+ var feature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(0, 0)
+ );
+ layer.addFeatures([feature]);
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0));
+
+
+ // If a feature is to be modified, control.selectFeature gets called.
+ // We want this test to fail if selectFeature gets called.
+ var modified = false;
+
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+
+ // register a listener that will stop feature modification
+ layer.events.on({"beforefeaturemodified": function() {return false}});
+
+ // we can initiate feature modification by programmatically selecting
+ // a feature
+ control.selectFeature(feature);
+
+ if(modified) {
+ t.fail("selectFeature called, prepping feature for modification");
+ } else {
+ t.ok(true, "the beforefeaturemodified listener stopped feature modification");
+ }
+ }
+
+ function test_selectFeature(t) {
+ t.plan(12);
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.Vector("Vectors!", {isBaseLayer: true});
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0));
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ control.vertices = [];
+ control.virtualVertices = [];
+ var callback = function(obj) {
+ t.ok(obj.feature == fakeFeature, "beforefeaturemodified triggered");
+ };
+ layer.events.on({"beforefeaturemodified": callback});
+ control.onModificationStart = function(feature) { t.eq(feature.id, fakeFeature.id, "On Modification Start called with correct feature."); }
+
+ // Start of testing
+
+ control.collectVertices = function() { t.fail("Collect vertices called when geom is a point"); }
+ var fakeFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 0));
+
+ // Points don't call collectVertices
+ control.selectFeature(fakeFeature);
+ control.unselectFeature(fakeFeature);
+
+ control.collectVertices = function() {
+ t.ok(true, "collectVertices called");
+ this.vertices = 'a';
+ this.virtualVertices = 'd';
+ layer.addFeatures(this.vertices);
+ layer.addFeatures(this.virtualVertices);
+ }
+
+ layer.addFeatures = function(features) {
+ t.ok(features == 'a' || features == 'd', "features passed correctly");
+ }
+ layer.destroyFeatures = function() {};
+
+ fakeFeature.geometry = new OpenLayers.Geometry.Polygon([
+ new OpenLayers.Geometry.LinearRing([
+ new OpenLayers.Geometry.Point(0, 0),
+ new OpenLayers.Geometry.Point(1, 1)
+ ])
+ ]);
+
+ // OnSelect calls collectVertices and passes features to layer
+ control.selectFeature(fakeFeature);
+ control.unselectFeature(fakeFeature);
+ layer.destroyFeatures = OpenLayers.Layer.Vector.prototype.destroyFeatures;
+
+ control.vertices = ['a'];
+ control.virtualVertices = [{destroy: function() {}}];
+
+ layer.addFeatures = function(features) {}
+
+ layer.removeFeatures = function(features) {
+ t.eq(features.length, 1, "Correct feature length passed in");
+ }
+
+ // Features are removed whenever they exist
+ control.selectFeature(fakeFeature);
+
+ control.destroy();
+
+ // layer.destroy() will call removeFeatures with an empty array, make
+ // removeFeatures reference an empty function to prevent the above
+ // test to fail
+ layer.removeFeatures = function(features) {};
+ layer.destroy();
+ }
+
+ function test_resetVertices(t) {
+ t.plan(20);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ var point = new OpenLayers.Geometry.Point(5,6);
+ var point2 = new OpenLayers.Geometry.Point(7,8);
+ var point3 = new OpenLayers.Geometry.Point(9,10);
+
+ control.feature = new OpenLayers.Feature.Vector(point);
+ control.resetVertices();
+ t.eq(control.vertices.length, 0, "Correct vertices length");
+ t.eq(control.virtualVertices.length, 0, "Correct virtual vertices length.");
+
+ var multiPoint = new OpenLayers.Geometry.MultiPoint([point, point2]);
+ control.feature = new OpenLayers.Feature.Vector(multiPoint);
+ control.resetVertices();
+ t.eq(control.vertices.length, 2, "Correct vertices length with multipoint");
+ t.eq(control.virtualVertices.length, 0, "Correct virtual vertices length (multipoint).");
+
+ var line = new OpenLayers.Geometry.LineString([point, point2]);
+ control.feature = new OpenLayers.Feature.Vector(line);
+ control.resetVertices();
+ t.eq(control.vertices.length, 2, "Correct vertices length with line");
+ t.eq(control.virtualVertices.length, 1, "Correct virtual vertices length (linestring).");
+
+ var polygon = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([point, point2, point3])]);
+ control.feature = new OpenLayers.Feature.Vector(polygon);
+ control.resetVertices();
+ t.eq(control.vertices.length, 3, "Correct vertices length with polygon");
+ t.eq(control.virtualVertices.length, 3, "Correct virtual vertices length (polygon).");
+
+ control.mode = OpenLayers.Control.ModifyFeature.DRAG;
+ control.resetVertices();
+ t.ok(control.dragHandle != null, "Drag handle is set");
+ t.eq(control.vertices.length, 0, "Correct vertices length with polygon (DRAG)");
+
+ control.mode = OpenLayers.Control.ModifyFeature.ROTATE;
+ control.resetVertices();
+ t.ok(control.radiusHandle != null, "Radius handle is set");
+ t.eq(control.vertices.length, 0, "Correct vertices length with polygon (ROTATE)");
+
+ control.mode = OpenLayers.Control.ModifyFeature.RESIZE;
+ control.resetVertices();
+ t.ok(control.radiusHandle != null, "Radius handle is set");
+ t.eq(control.vertices.length, 0, "Correct vertices length with polygon (RESIZE)");
+
+ control.mode = OpenLayers.Control.ModifyFeature.RESHAPE;
+ control.resetVertices();
+ t.ok(control.radiusHandle == null, "Radius handle is not set (RESHAPE)");
+ t.eq(control.vertices.length, 3, "Correct vertices length with polygon (RESHAPE)");
+ t.eq(control.virtualVertices.length, 3, "Correct virtual vertices length (RESHAPE)");
+
+ control.mode = OpenLayers.Control.ModifyFeature.RESIZE | OpenLayers.Control.ModifyFeature.RESHAPE;
+ control.resetVertices();
+ t.ok(control.radiusHandle != null, "Radius handle is set (RESIZE|RESHAPE)");
+ t.eq(control.vertices.length, 0, "No vertices when both resizing and reshaping (RESIZE|RESHAPE)");
+ t.eq(control.virtualVertices.length, 0, "No virtual vertices when both resizing and reshaping (RESIZE|RESHAPE)");
+
+ control.destroy();
+ layer.destroy();
+ }
+
+ function test_dragVertex(t) {
+ t.plan(8);
+ var map = new OpenLayers.Map("map", {
+ resolutions: [1]
+ });
+ var layer = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+
+ map.zoomToMaxExtent();
+
+ var log = {};
+ layer.events.on({
+ "vertexmodified": function(event) {
+ log.event = event;
+ }
+ });
+
+ // pretend to drag a point
+ var feature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(0, 0)
+ );
+ control.feature = feature;
+ var pixel = new OpenLayers.Pixel(-100, 100);
+ control.dragVertex(feature, pixel);
+ t.eq(log.event.type, "vertexmodified", "[drag point] vertexmodified triggered");
+ t.geom_eq(log.event.vertex, feature.geometry, "[drag point] listeners receive correct vertex");
+ t.eq(log.event.feature.id, feature.id, "[drag point] listeners receive correct feature");
+ t.ok(log.event.pixel === pixel, "[drag point] listeners receive correct pixel");
+
+ // pretend to drag vertex of a linestring
+ var vert = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(0, 0)
+ );
+ var feature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.LineString([
+ vert.geometry, new OpenLayers.Geometry.Point(10, 0)
+ ])
+ );
+ control.feature = feature;
+ var pixel = new OpenLayers.Pixel(-100, 100);
+ control.dragVertex(vert, pixel);
+ t.eq(log.event.type, "vertexmodified", "[drag vertex] vertexmodified triggered");
+ t.geom_eq(log.event.vertex, vert.geometry, "[drag vertex] listeners receive correct vertex");
+ t.eq(log.event.feature.id, feature.id, "[drag vertex] listeners receive correct feature");
+ t.ok(log.event.pixel === pixel, "[drag vertex] listeners receive correct pixel");
+
+
+ map.destroy();
+ }
+ function test_collectDragHandle(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map("map", {
+ resolutions: [1]
+ });
+ var layer = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+ var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1));
+ layer.addFeatures([feature]);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+ control.feature = feature;
+ control.collectDragHandle();
+ t.ok(control.dragHandle != null, "Drag handle created");
+ t.ok(control.dragHandle._sketch == true, "Handle has _sketch true");
+ t.ok(control.dragHandle.renderIntent == control.vertexRenderIntent,"Render intent for handle set");
+ t.ok(control.layer.getFeatureById(control.dragHandle.id) != null, "Drag handle added to layer");
+ }
+ function test_collectRadiusHandle(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map("map", {
+ resolutions: [1]
+ });
+ var layer = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+ var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1));
+ layer.addFeatures([feature]);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+ control.feature = feature;
+ control.collectRadiusHandle();
+ t.ok(control.radiusHandle != null, "Radius handle created");
+ t.ok(control.radiusHandle._sketch == true, "Radius has _sketch true");
+ t.ok(control.radiusHandle.renderIntent == control.vertexRenderIntent,"Render intent for handle set");
+ t.ok(control.layer.getFeatureById(control.radiusHandle.id) != null, "Drag radius added to layer");
+ }
+ function test_onDrag(t) {
+ t.plan(1);
+ t.ok(true, "onDrag not tested yet.");
+ }
+
+ function test_dragComplete(t) {
+ t.plan(8);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+
+ var fakeFeature = {
+ 'geometry': { 'id':'myGeom'},
+ 'id': 'fakeFeature'
+ };
+ layer.addFeatures = function (verts) {
+ t.ok(verts == 'virtual' || verts == 'normal', verts + " verts correct");
+ }
+ layer.removeFeatures = function (verts) {
+ t.ok(verts == 'previous virtual' || verts == 'previous normal', verts + " verts correct");
+ }
+ layer.events.on({"featuremodified": function(event) {
+ t.eq(event.feature, fakeFeature, "featuremodified triggered");
+ }});
+ control.onModification = function(feat) {
+ t.eq(feat.id, fakeFeature.id, "onModification gets correct feat");
+ }
+ control.collectVertices = function() {
+ t.ok(true, "collectVertices called");
+ this.vertices = 'normal';
+ this.virtualVertices = 'virtual';
+ layer.addFeatures(this.vertices);
+ layer.addFeatures(this.virtualVertices);
+ }
+ control.feature = fakeFeature;
+ control.vertices = 'previous normal';
+ control.virtualVertices = 'previous virtual';
+ control.dragComplete();
+ t.eq(fakeFeature.state, OpenLayers.State.UPDATE, "feature state set to UPDATE");
+
+ control.destroy();
+
+ // layer.destroy() will call removeFeatures with an empty array, make
+ // removeFeatures reference an empty function to prevent the above
+ // test to fail
+ layer.removeFeatures = function(verts) {};
+ layer.destroy();
+ }
+
+ function test_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.ModifyFeature(layer);
+ map.addControl(control);
+
+ control.handlers.keyboard.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on keyboard handler");
+ }
+ control.handlers.drag.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on drag handler");
+ }
+ control.active = true;
+ control.deactivate();
+
+ control.handlers.keyboard.deactivate = OpenLayers.Handler.Keyboard.prototype.deactivate;
+ control.handlers.drag.deactivate = OpenLayers.Handler.Drag.prototype.deactivate;
+ map.destroy();
+ }
+
+ function test_onModificationStart(t) {
+ t.plan(5);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector(null, {
+ styleMap: new OpenLayers.StyleMap({
+ "vertex": new OpenLayers.Style({foo: "bar"})
+ }, {extendDefault: false})
+ });
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+
+ // make sure onModificationStart is called on feature selection
+ var testFeature = new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.fromWKT("LINESTRING(3 4,10 50,20 25)")
+ );
+ layer.addFeatures([testFeature]);
+ control.onModificationStart = function(feature) {
+ t.eq(feature.id, testFeature.id,
+ "onModificationStart called with the right feature");
+ };
+ control.selectFeature(testFeature);
+
+ // make sure styles are set correctly from default style
+ t.eq(control.virtualStyle, OpenLayers.Util.applyDefaults({
+ strokeOpacity: 0.3,
+ fillOpacity: 0.3
+ }, OpenLayers.Feature.Vector.style["default"]), "virtual style set correctly");
+ var vertex = layer.features[layer.features.length-1];
+ t.eq(vertex.renderIntent, null, "vertex style set correctly - uses default style");
+ control.unselectFeature(testFeature);
+
+ // make sure styles are set correctly with vertexRenderIntent
+ control = new OpenLayers.Control.ModifyFeature(layer, {vertexRenderIntent: "vertex"});
+ map.addControl(control);
+ control.activate();
+ control.selectFeature(testFeature);
+ t.eq(control.virtualStyle, {
+ strokeOpacity: 0.3,
+ fillOpacity: 0.3,
+ foo: "bar"
+ }, "virtual style set correctly");
+ var vertex = layer.features[layer.features.length-1];
+ t.eq(vertex.renderIntent, "vertex", "vertex style set correctly - uses 'vertex' renderIntent");
+ control.unselectFeature(testFeature);
+
+ map.destroy();
+ }
+
+ function test_onModification(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+
+ // make sure onModification is called on drag complete
+ var point = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(Math.random(), Math.random())
+ );
+ control.feature = point;
+ control.onModification = function(feature) {
+ t.eq(feature.id, point.id,
+ "onModification called with the right feature on drag complete");
+ };
+ control.dragComplete();
+
+ // make sure onModification is called on vertex deletion
+ var poly = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Polygon()
+ );
+ var oldDraw = layer.drawFeature;
+ layer.drawFeature = function() {
+ return;
+ };
+ control.feature = poly;
+ control.vertices = [point];
+ layer.events.on({"featuremodified": function(event) {
+ t.eq(event.feature.id, poly.id, "featuremodified triggered");
+ }});
+
+ control.onModification = function(feature) {
+ t.eq(feature.id, poly.id,
+ "onModification called with the right feature on vertex delete");
+ };
+ point.geometry.parent = poly.geometry;
+ origGetFeatureFromEvent = layer.getFeatureFromEvent;
+ layer.getFeatureFromEvent = function() { return point; };
+ control.handleKeypress({keyCode:46});
+ layer.drawFeature = oldDraw;
+ layer.getFeatureFromEvent = origGetFeatureFromEvent;
+
+ map.destroy();
+ }
+
+ function test_onModificationEnd(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+
+ // make sure onModificationEnd is called on unselect feature
+ var testFeature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(Math.random(), Math.random())
+ );
+ layer.events.on({"afterfeaturemodified": function(event) {
+ t.eq(event.feature.id, testFeature.id, "afterfeaturemodified triggered");
+ t.eq(event.modified, false, "afterfeaturemodified event given proper modified property (false - feature was not modified in this case)");
+ }});
+ control.onModificationEnd = function(feature) {
+ t.eq(feature.id, testFeature.id,
+ "onModificationEnd called with the right feature");
+ };
+ control.unselectFeature(testFeature);
+
+ map.destroy();
+ }
+
+ function test_events(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.ModifyFeature(layer);
+ map.addControl(control);
+ control.activate();
+
+ // make sure onModificationStart is called on feature selection
+ var testFeature = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(Math.random(), Math.random())
+ );
+
+ // test that beforefeatureselected is triggered
+ function handle_beforefeatureselected(event) {
+ t.ok(event.feature == testFeature, "beforefeatureselected called with the correct feature");
+ }
+ layer.events.on({
+ "beforefeatureselected": handle_beforefeatureselected
+ });
+ layer.events.triggerEvent("beforefeatureselected", {
+ feature: testFeature
+ });
+ layer.events.un({
+ "beforefeatureselected": handle_beforefeatureselected
+ });
+
+ // test that beforefeatureselected is triggered
+ function handle_featureselected(event) {
+ t.ok(event.feature == testFeature, "featureselected called with the correct feature");
+ }
+ layer.events.on({
+ "featureselected": handle_featureselected
+ });
+ layer.events.triggerEvent("featureselected", {
+ feature: testFeature
+ });
+ layer.events.un({
+ "featureselected": handle_featureselected
+ });
+
+ map.destroy();
+ }
+
+ function test_standalone(t) {
+
+ t.plan(17);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+
+ var f1 = new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.fromWKT("LINESTRING(3 4,10 50,20 25)")
+ );
+ var f2 = new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.fromWKT("POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2))")
+ );
+ var f3 = new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.fromWKT("POINT(10 15)")
+ );
+ var f4 = new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.fromWKT("POINT(15 10)")
+ );
+ layer.addFeatures([f1, f2, f3, f4]);
+
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.ModifyFeature(layer, {standalone: true});
+ map.addControl(control);
+
+ var log = [];
+ layer.events.on({
+ beforefeaturemodified: function(evt) {
+ layer.events.unregister("beforefeaturemodified", this, arguments.callee);
+ log.push(evt);
+ },
+ featuremodified: function(evt) {
+ log.push(evt);
+ },
+ afterfeaturemodified: function(evt) {
+ log.push(evt);
+ }
+ });
+
+ // activate control
+ control.activate();
+ t.eq(control.active, true, "[activate] control activated");
+
+ // manually select feature for editing
+ control.selectFeature(f1);
+ t.eq(log.length, 1, "[select f1] beforefeaturemodified triggered");
+ t.ok(control.feature === f1, "[select f1] control.feature set to f1");
+ log = []
+
+ // manually unselect feature for editing
+ control.unselectFeature(f1);
+ t.eq(control.feature, null, "[unselect f1] control.feature set to null");
+ t.eq(log.length, 1, "[unselect f1] event logged");
+ t.eq(log[0].type, "afterfeaturemodified", "[unselect f1] afterfeaturemodified triggered");
+ t.ok(log[0].feature === f1, "[unselect f1] correct feature");
+ t.eq(log[0].modified, false, "[unselect f1] feature not actually modified");
+
+ // clear log and select new feature for editing
+ log = [];
+ control.selectFeature(f2);
+ t.ok(control.feature === f2, "[select f2] control.feature set to f2");
+
+ // deactivate control and confirm feature is unselected
+ control.deactivate();
+ t.eq(log.length, 1, "[deactivate] event logged");
+ t.eq(log[0].type, "afterfeaturemodified", "[deactivate] afterfeaturemodified triggered");
+ t.ok(log[0].feature === f2, "[deactivate] correct feature");
+ t.eq(log[0].modified, false, "[deactivate] feature not actually modified");
+
+ // select the polygon feature to make sure that we can drag vertices and
+ // virtual vertices
+ control.selectFeature(f2);
+ var origGetFeatureFromEvent = layer.getFeatureFromEvent;
+ layer.getFeatureFromEvent = function() { return control.vertices[0]; };
+ control.handlers.drag.callbacks.down.call(control, new OpenLayers.Pixel(0,0));
+ t.ok(control.vertex === control.vertices[0], "can drag vertex of feature f2");
+ t.ok(control.feature === f2, "dragging a vertex does not change the selected feature");
+ layer.getFeatureFromEvent = function() { return control.virtualVertices[0]; };
+ control.handlers.drag.callbacks.down.call(control, new OpenLayers.Pixel(0,0));
+ t.ok(control.vertex === control.virtualVertices[0], "can drag virtual vertex of feature f2");
+ t.ok(control.feature === f2, "dragging a vertex does not change the selected feature");
+ layer.getFeatureFromEvent = origGetFeatureFromEvent;
+ control.deactivate();
+
+ map.destroy();
+
+ }
+
+ function test_setFeatureState(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector("vector", {isBaseLayer: true});
+ map.addLayer(layer);
+ var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));
+ layer.addFeatures([feature]);
+ var control = new OpenLayers.Control.ModifyFeature(layer, {standalone: true});
+ map.addControl(control);
+
+ control.selectFeature(feature);
+ var originalGeometry = feature.geometry;
+
+ t.ok(control._originalGeometry, "original geometry stored for later use in setFeatureState");
+
+ feature.geometry = new OpenLayers.Geometry.Point(2,3);
+ control.modified = true;
+ control.setFeatureState();
+
+ t.eq(feature.state, OpenLayers.State.UPDATE, "feature state set to UPDATE");
+ t.geom_eq(feature.modified.geometry, originalGeometry, "original geometry stored on the modified property");
+ t.eq(control._originalGeometry, undefined, "original geometry deleted once it is set on the modified property");
+ }
+
+ function test_createVertices(t) {
+ t.plan(2);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.ModifyFeature(layer, {
+ createVertices: false
+ });
+ var line = new OpenLayers.Geometry.LineString([
+ new OpenLayers.Geometry.Point(5, 6),
+ new OpenLayers.Geometry.Point(7, 8),
+ new OpenLayers.Geometry.Point(9, 10)
+ ]);
+ control.feature = new OpenLayers.Feature.Vector(line);
+ control.resetVertices();
+
+ t.eq(control.vertices.length, 3, "Correct vertices length with createVertices is false");
+ t.eq(control.virtualVertices.length, 0, "Correct virtual vertices length with createVertices is false");
+ control.destroy();
+ }
+
+ function test_moveLayerToTop_moveLayerBack(t) {
+ t.plan(2);
+ 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.ModifyFeature(layer1);
+ map.addControl(control);
+ control.activate();
+ t.ok(layer1.div.style.zIndex > layer2.div.style.zIndex, "layer raised so events don't get swallowed");
+ control.deactivate();
+ t.ok(layer1.div.style.zIndex < layer2.div.style.zIndex, 'layer order restored on deactivation');
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/MousePosition.html b/misc/openlayers/tests/Control/MousePosition.html
new file mode 100644
index 0000000..0695e16
--- /dev/null
+++ b/misc/openlayers/tests/Control/MousePosition.html
@@ -0,0 +1,109 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map, control;
+ function test_initialize (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.MousePosition();
+ t.ok( control instanceof OpenLayers.Control.MousePosition, "new OpenLayers.Control returns object" );
+ t.eq( control.displayClass, "olControlMousePosition", "displayClass is correct" );
+ }
+ function test_destroy(t) {
+ t.plan(1);
+
+ var map = new OpenLayers.Map('map');
+ var control = new OpenLayers.Control.MousePosition();
+ map.addControl(control);
+
+ var listeners = map.events.listeners.mousemove.length;
+ control.destroy();
+
+ t.eq(map.events.listeners.mousemove.length, listeners - 1, "mousemove event is unregistered");
+ map.destroy();
+ }
+ function test_addControl(t) {
+ t.plan(4);
+
+ var map = new OpenLayers.Map('map');
+ var control = new OpenLayers.Control.MousePosition();
+ map.addControl(control);
+
+ t.ok(control.map === map, "Control.map is set to the map object");
+ t.ok(map.controls[map.controls.length - 1] === control, "map.controls contains control");
+ t.eq(parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, "Control div zIndexed properly" );
+ t.eq(parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, "Viewport div contains control div");
+ map.destroy();
+ }
+ function test_redraw_noLayer_displayProjection(t) {
+ t.plan(4);
+ var control = new OpenLayers.Control.MousePosition({'emptyString':''});
+ var map = new OpenLayers.Map('map');
+ map.addControl(control);
+ var control2 = new OpenLayers.Control.MousePosition();
+ map.addControl(control2);
+ t.eq(control2.emptyString, null, "Emptystring is null");
+ t.eq(control.div.innerHTML, "", "innerHTML set correctly");
+ control.redraw({'xy': new OpenLayers.Pixel(10,10)});
+ control.redraw({'xy': new OpenLayers.Pixel(12,12)});
+ t.eq(control.div.innerHTML, "", "innerHTML set correctly");
+ var l = new OpenLayers.Layer('name', {'isBaseLayer': true});
+ map.addLayer(l);
+ map.zoomToMaxExtent();
+ control.redraw({'xy': new OpenLayers.Pixel(10,10)});
+ control.redraw({'xy': new OpenLayers.Pixel(12,12)});
+ t.eq(control.div.innerHTML, "-175.78125, 85.78125", "innerHTML set correctly when triggered.");
+ map.destroy();
+ }
+ function test_formatOutput(t) {
+ t.plan(1);
+ var control = new OpenLayers.Control.MousePosition({
+ prefix: 'prefix',
+ suffix: 'suffix',
+ separator: 'separator',
+ numDigits: 3
+ });
+ var lonlat = new OpenLayers.LonLat(0.75699, 0.37365);
+ var val = control.formatOutput(lonlat);
+ t.eq(val, 'prefix0.757separator0.374suffix', 'formatOutput correctly formats the mouse position output');
+ }
+ function test_deactivate(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer(null, {isBaseLayer: true});
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ // Auxiliary function
+ function trigger(type, x, y) {
+ map.events.triggerEvent(type, {
+ xy: new OpenLayers.Pixel(x, y)
+ })
+ };
+
+ var control = new OpenLayers.Control.MousePosition();
+ map.addControl(control);
+ trigger("mousemove", 0, 0);
+
+ trigger("mousemove", 0, 1);
+ t.ok(control.div.innerHTML != "",
+ "Shows the position after add control (with autoActivate) and move");
+ control.deactivate();
+ t.ok(control.div.innerHTML == "",
+ "Position is not displayed after deactivate and move");
+ trigger("mousemove", 0, 2);
+ t.ok(control.div.innerHTML == "",
+ "Position is not displayed after move when deactivate");
+ control.activate();
+ trigger("mousemove", 0, 3);
+ t.ok(control.div.innerHTML != "",
+ "Shows the position after activate and move");
+
+ map.destroy();
+ }
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/NavToolbar.html b/misc/openlayers/tests/Control/NavToolbar.html
new file mode 100644
index 0000000..9b3bbec
--- /dev/null
+++ b/misc/openlayers/tests/Control/NavToolbar.html
@@ -0,0 +1,45 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map;
+ function test_Control_NavToolbar_constructor (t) {
+ t.plan( 4 );
+ control = new OpenLayers.Control.NavToolbar();
+ t.ok( control instanceof OpenLayers.Control.NavToolbar, "new OpenLayers.Control.NavToolbar returns object" );
+ t.eq( control.displayClass, "olControlNavToolbar", "displayClass is correct" );
+ t.ok( control.controls[0] instanceof OpenLayers.Control.Navigation, "NavToolbar contains Control.Navigation object" );
+ t.ok( control.controls[1] instanceof OpenLayers.Control.ZoomBox, "NavToolbar contains Control.ZoomBox object" );
+ }
+ function test_Control_NavToolbar_addControl (t) {
+ t.plan( 6 );
+ map = new OpenLayers.Map('map');
+ control = new OpenLayers.Control.NavToolbar();
+ t.ok( control instanceof OpenLayers.Control.NavToolbar, "new OpenLayers.Control.NavToolbar returns object" );
+ t.ok( map instanceof OpenLayers.Map, "new OpenLayers.Map creates map" );
+ map.addControl(control);
+ t.ok( control.map === map, "Control.map is set to the map object" );
+ t.ok( map.controls[4] === control, "map.controls contains control" );
+ t.eq( parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 7, "Control div zIndexed properly" );
+ t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 7, "Viewport div contains control div" );
+ // t.eq( control.div.style.top, "6px", "Control div top located correctly by default");
+
+ }
+
+ function test_Control_NavToolbar_defaultControl (t) {
+ t.plan( 1 );
+ var map = new OpenLayers.Map('map');
+
+ var nav = new OpenLayers.Control.NavToolbar();
+ map.addControl(nav);
+
+ t.eq(nav.controls[0].active, true, "First control is active" );
+
+ map.destroy();
+ }
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Navigation.html b/misc/openlayers/tests/Control/Navigation.html
new file mode 100644
index 0000000..e73ee42
--- /dev/null
+++ b/misc/openlayers/tests/Control/Navigation.html
@@ -0,0 +1,200 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_Control_Navigation_constructor (t) {
+ t.plan( 3 );
+ var temp = OpenLayers.Control.prototype.initialize;
+ OpenLayers.Control.prototype.initialize = function() {
+ t.ok(true, "OpenLayers.Control's constructor called");
+ };
+
+ var control = new OpenLayers.Control.Navigation();
+ t.ok( control instanceof OpenLayers.Control.Navigation, "new OpenLayers.Control returns object" );
+
+ t.ok( !control.handleRightClicks, "'handleRightClicks' property is disabled by default");
+
+ OpenLayers.Control.prototype.initialize = temp;
+ }
+
+ function test_draw(t) {
+ t.plan(5);
+ var map = new OpenLayers.Map({div: 'map', controls: []});
+ var control = new OpenLayers.Control.Navigation();
+ map.addControl(control);
+ t.ok(control.handlers.click instanceof OpenLayers.Handler.Click,
+ "click handler set in instance");
+ t.ok(control.dragPan instanceof OpenLayers.Control.DragPan,
+ "drag pan control set in instance");
+ t.ok(control.zoomBox instanceof OpenLayers.Control.ZoomBox,
+ "zoom box control set in instance");
+ t.ok(control.handlers.wheel instanceof OpenLayers.Handler.MouseWheel,
+ "mousewheel handler set in instance");
+ t.ok(control.pinchZoom instanceof OpenLayers.Control.PinchZoom,
+ "pinch zoom control set in instance");
+ map.destroy();
+ }
+
+ function test_Control_Navigation_destroy (t) {
+ t.plan(12);
+
+ var temp = OpenLayers.Control.prototype.destroy;
+ OpenLayers.Control.prototype.destroy = function() {
+ t.ok(true, "OpenLayers.Control's destroy called");
+ temp.call(this);
+ };
+
+ var control = {
+ events: {
+ destroy: function() {
+ t.ok(true, "events destroyed");
+ }
+ },
+ 'deactivate': function() {
+ t.ok(true, "navigation control deactivated before being destroyed");
+ },
+ 'dragPan': {
+ 'destroy': function() {
+ t.ok(true, "dragPan destroyed");
+ }
+ },
+ 'zoomBox': {
+ 'destroy': function() {
+ t.ok(true, "zoomBox destroyed");
+ }
+ },
+ 'pinchZoom': {
+ 'destroy': function() {
+ t.ok(true, "pinchZoom destroyed");
+ }
+ },
+ handlers: {
+ 'wheel': {
+ 'destroy': function() {
+ t.ok(true, "wheelHandler destroyed");
+ }
+ },
+ 'click': {
+ 'destroy': function() {
+ t.ok(true, "clickHandler destroyed");
+ }
+ }
+ }
+ };
+
+ //this will also trigger one test by calling OpenLayers.Control's destroy
+ // and three more for the destruction of dragPan, zoomBox, and wheelHandler
+ OpenLayers.Control.Navigation.prototype.destroy.apply(control, []);
+
+ t.eq(control.dragPan, null, "'dragPan' set to null");
+ t.eq(control.zoomBox, null, "'zoomBox' set to null");
+ t.eq(control.pinchZoom, null, "'pinchZoom' set to null");
+ t.eq(control.handlers, null, "handlers set to null");
+
+ OpenLayers.Control.prototype.destroy = temp;
+ }
+
+ function test_Control_Navigation_disableZoomBox(t) {
+ t.plan(2);
+ var nav = new OpenLayers.Control.Navigation();
+ var zb = new OpenLayers.Control.ZoomBox({});
+ nav.zoomBox = zb;
+ zb.activate();
+ nav.disableZoomBox();
+ t.eq(nav.zoomBoxEnabled, false, "zoom box deactivated");
+ t.eq(zb.active, false, "zoom box control deactivated");
+ }
+
+ function test_Control_Navigation_enableZoomBox(t) {
+ t.plan(2);
+ var nav = new OpenLayers.Control.Navigation();
+ var zb = new OpenLayers.Control.ZoomBox({});
+ nav.zoomBox = zb;
+ nav.active = true;
+ nav.enableZoomBox();
+ t.eq(nav.zoomBoxEnabled, true, "zoom box activated");
+ t.eq(zb.active, true, "zoom box control activated");
+ }
+
+ function test_Control_Navigation_disableZoomWheel(t) {
+ t.plan(2);
+ var nav = new OpenLayers.Control.Navigation();
+ var wheel = new OpenLayers.Handler.MouseWheel(nav, {});
+ nav.handlers.wheel = wheel;
+ wheel.register = function() {};
+ wheel.unregister = function() {};
+ wheel.activate();
+ nav.disableZoomWheel();
+ t.eq(nav.zoomWheelEnabled, false, "mouse wheel deactivated");
+ t.eq(wheel.active, false, "mouse wheel handler deactivated");
+ }
+
+ function test_Control_Navigation_enableZoomWheel(t) {
+ t.plan(2);
+ var nav = new OpenLayers.Control.Navigation({zoomWheelEnabled: false});
+ nav.active = true;
+ var wheel = new OpenLayers.Handler.MouseWheel(nav, {});
+ wheel.register = function() {};
+ wheel.unregister = function() {};
+ nav.handlers.wheel = wheel;
+ nav.enableZoomWheel();
+ t.eq(nav.zoomWheelEnabled, true, "mouse wheel activated");
+ t.eq(wheel.active, true, "mouse wheel handler activated");
+ }
+
+ function test_touches_zoom(t) {
+ t.plan(3);
+ var nav = new OpenLayers.Control.Navigation({zoomWheelEnabled: false});
+ var map = new OpenLayers.Map({
+ div: "map",
+ zoomMethod: null,
+ controls: [nav],
+ layers: [
+ new OpenLayers.Layer(null, {isBaseLayer: true})
+ ],
+ center: new OpenLayers.LonLat(0, 0),
+ zoom: 3
+ });
+ t.eq(map.getZoom(), 3, "map zoom starts at 3");
+ nav.handlers.click.callback("click", [{lastTouches: ["foo", "bar"]}]);
+ t.eq(map.getZoom(), 2, "map zooms out with a two touch tap");
+ nav.handlers.click.callback("click", [{}]);
+ t.eq(map.getZoom(), 2, "map doesn't do anything with click");
+
+ map.destroy();
+ }
+
+ function test_documentDrag(t) {
+
+ t.plan(2);
+
+ /**
+ * These tests confirm that the documentDrag property is false by
+ * default and is passed on to the DragPan control. Tests of panning
+ * while dragging outside the viewport should go in the DragPan tests.
+ * Tests of the document events and appropriate callbacks from the
+ * handler should go in the Drag handler tests.
+ */
+
+ var nav = new OpenLayers.Control.Navigation();
+ t.eq(nav.documentDrag, false, "documentDrag false by default");
+ // nav.destroy(); // fails if called before draw
+
+ var map = new OpenLayers.Map({
+ div: document.body,
+ controls: [new OpenLayers.Control.Navigation({documentDrag: true})]
+ });
+ nav = map.controls[0];
+
+ t.eq(nav.dragPan.documentDrag, true, "documentDrag set on the DragPan control");
+ map.destroy();
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 256px; height: 256px"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/NavigationHistory.html b/misc/openlayers/tests/Control/NavigationHistory.html
new file mode 100644
index 0000000..c992ff2
--- /dev/null
+++ b/misc/openlayers/tests/Control/NavigationHistory.html
@@ -0,0 +1,245 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(4);
+ control = new OpenLayers.Control.NavigationHistory();
+ t.ok(control instanceof OpenLayers.Control.NavigationHistory,
+ "constructor returns correct instance");
+ t.eq(control.displayClass, "olControlNavigationHistory",
+ "displayClass is correct");
+ t.ok(control.next instanceof OpenLayers.Control.Button,
+ "constructor creates next control");
+ t.ok(control.previous instanceof OpenLayers.Control.Button,
+ "constructor creates previous control");
+ }
+
+ function test_destroy(t) {
+ t.plan(2);
+ control = new OpenLayers.Control.NavigationHistory();
+ control.next.destroy = function() {
+ t.ok(true, "destroy calls next.destroy");
+ }
+ control.previous.destroy = function() {
+ t.ok(true, "destroy calls previous.destroy");
+ }
+ control.destroy();
+ }
+
+ function test_previous(t) {
+ var numStates = 10;
+
+ t.plan(
+ numStates * 3 // for lon, lat, zoom
+ + 3 // for confirming that previous with empty stack works
+ );
+
+ var history = new Array(numStates);
+ for(var i=0; i<numStates; ++i) {
+ history[i] = {
+ center: new OpenLayers.LonLat(
+ (i * 360 / numStates) - 180, (i * 180 / numStates) - 90
+ ),
+ zoom: i
+ };
+ }
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer(
+ "test", {isBaseLayer: true}
+ );
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.NavigationHistory();
+ map.addControl(control);
+
+ // set previous states
+ for(i=0; i<numStates; ++i) {
+ map.setCenter(history[i].center, history[i].zoom);
+ }
+ // test previous states
+ for(i=numStates-1; i>=0; --i) {
+ t.eq(map.getCenter().lon, history[i].center.lon, "(step " + i + ") lon correct");
+ t.eq(map.getCenter().lat, history[i].center.lat, "(step " + i + ") lat correct");
+ t.eq(map.getZoom(), history[i].zoom, "(step " + i + ") zoom correct");
+ control.previous.trigger();
+ }
+ // test previous with empty stack
+ t.eq(map.getCenter().lon, history[0].center.lon, "(step 0 again) lon correct");
+ t.eq(map.getCenter().lat, history[0].center.lat, "(step 0 again) lat correct");
+ t.eq(map.getZoom(), history[0].zoom, "(step 0 again) zoom correct");
+ }
+
+ function test_next(t) {
+ var numStates = 10;
+
+ t.plan(
+ numStates * 3 // for lon, lat, zoom
+ + 3 // for confirming that next with empty stack works
+ );
+
+ var history = new Array(numStates);
+ for(var i=0; i<numStates; ++i) {
+ history[i] = {
+ center: new OpenLayers.LonLat(
+ (i * 360 / numStates) - 180, (i * 180 / numStates) - 90
+ ),
+ zoom: i
+ };
+ }
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer(
+ "test", {isBaseLayer: true}
+ );
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.NavigationHistory();
+ map.addControl(control);
+
+ // set previous states
+ for(i=0; i<numStates; ++i) {
+ map.setCenter(history[i].center, history[i].zoom);
+ }
+ // set next states
+ for(i=numStates-1; i>=0; --i) {
+ control.previous.trigger();
+ }
+ // test next states
+ for(i=0; i<numStates; ++i) {
+ t.eq(map.getCenter().lon, history[i].center.lon, "(step " + i + ") lon correct");
+ t.eq(map.getCenter().lat, history[i].center.lat, "(step " + i + ") lat correct");
+ t.eq(map.getZoom(), history[i].zoom, "(step " + i + ") zoom correct");
+ control.next.trigger();
+ }
+ // test next with empty stack
+ t.eq(map.getCenter().lon, history[numStates-1].center.lon, "(step " + (numStates-1) + " again) lon correct");
+ t.eq(map.getCenter().lat, history[numStates-1].center.lat, "(step " + (numStates-1) + " again) lat correct");
+ t.eq(map.getZoom(), history[numStates-1].zoom, "(step " + (numStates-1) + " again) zoom correct");
+ }
+
+ function test_limit(t) {
+ var numStates = 10;
+ var limit = 3;
+
+ t.plan(
+ numStates * 6 // for previous & next lon, lat, zoom
+ );
+
+ var history = new Array(numStates);
+ for(var i=0; i<numStates; ++i) {
+ history[i] = {
+ center: new OpenLayers.LonLat(
+ (i * 360 / numStates) - 180, (i * 180 / numStates) - 90
+ ),
+ zoom: i
+ };
+ }
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer(
+ "test", {isBaseLayer: true}
+ );
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.NavigationHistory({limit: limit});
+ map.addControl(control);
+
+ // set previous states
+ for(i=0; i<numStates; ++i) {
+ map.setCenter(history[i].center, history[i].zoom);
+ }
+ // test previous states (only up to limit should work)
+ var state;
+ for(i=numStates-1; i>=0; --i) {
+ state = Math.max(i, numStates - limit - 1);
+ t.eq(map.getCenter().lon, history[state].center.lon, "(previous step " + i + ") lon correct: state " + state);
+ t.eq(map.getCenter().lat, history[state].center.lat, "(previous step " + i + ") lat correct: state " + state);
+ t.eq(map.getZoom(), history[state].zoom, "(previous step " + i + ") zoom correct: state " + state);
+ control.previous.trigger();
+ }
+ // test next states
+ for(i=0; i<numStates; ++i) {
+ state = Math.min(numStates - 1, numStates - limit - 1 + i);
+ t.eq(map.getCenter().lon, history[state].center.lon, "(next step " + i + ") lon correct: state " + state);
+ t.eq(map.getCenter().lat, history[state].center.lat, "(next step " + i + ") lat correct: state " + state);
+ t.eq(map.getZoom(), history[state].zoom, "(next step " + i + ") zoom correct: state " + state);
+ control.next.trigger();
+ }
+
+ }
+
+ function test_clear(t) {
+ t.plan(7);
+ var map = new OpenLayers.Map("map", {zoomMethod: null});
+ var layer = new OpenLayers.Layer(
+ "test", {isBaseLayer: true}
+ );
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ var control = new OpenLayers.Control.NavigationHistory();
+ map.addControl(control);
+
+ t.ok(!control.previous.active, "previous control not active");
+ t.ok(!control.next.active, "next control not active");
+
+ map.zoomTo(4);
+ t.ok(control.previous.active, "previous control is active after a move");
+ t.ok(!control.next.active, "next control is not active after a move");
+
+ control.clear();
+ t.eq(control.previousStack.length + control.nextStack.length, 0, "stacks are empty after a clear");
+ t.ok(!control.previous.active, "previous control not active after a clear");
+ t.ok(!control.next.active, "next control not active after a clear");
+
+ control.destroy();
+ }
+
+ function test_reprojection(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer(
+ "test", {isBaseLayer: true}
+ );
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ var control = new OpenLayers.Control.NavigationHistory();
+ map.addControl(control);
+
+ map.zoomTo(4);
+ var bounds = map.getExtent().clone();
+ var expected = bounds.transform(new OpenLayers.Projection('EPSG:4326'),
+ new OpenLayers.Projection('EPSG:900913'));
+ // change the projection to EPSG:900913
+ var projSettings = {
+ units: "m",
+ maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508),
+ maxResolution: 156543.0339
+ };
+ map.setOptions(projSettings);
+ map.projection = 'EPSG:900913';
+ delete projSettings.maxResolution;
+ projSettings.projection = new OpenLayers.Projection('EPSG:900913');
+ layer.addOptions(projSettings);
+ layer.initResolutions();
+
+ map.zoomTo(7);
+
+ // go back one in the history
+ control.previous.trigger();
+
+ t.eq(map.getExtent().left.toFixed(3), expected.left.toFixed(3), "The extent [left] is reprojected correctly");
+ t.eq(map.getExtent().right.toFixed(3), expected.right.toFixed(3), "The extent [right] is reprojected correctly");
+ // top and bottom cannot be checked here since in EPSG:900913 the extent is not a rectangle so they are adjusted.
+
+ control.destroy();
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 100px; height: 100px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/OverviewMap.html b/misc/openlayers/tests/Control/OverviewMap.html
new file mode 100644
index 0000000..a5a598d
--- /dev/null
+++ b/misc/openlayers/tests/Control/OverviewMap.html
@@ -0,0 +1,266 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map, control;
+
+ function test_initialize(t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.OverviewMap();
+ t.ok( control instanceof OpenLayers.Control.OverviewMap,
+ "new OpenLayers.Control.OverviewMap returns object" );
+ t.eq( control.displayClass,
+ "olControlOverviewMap", "displayClass is correct" );
+ }
+
+ function test_divs_title(t) {
+ t.plan(2);
+
+ control = new OpenLayers.Control.OverviewMap({
+ maximizeTitle: "maximize title",
+ minimizeTitle: "minimize title"
+ });
+ map = new OpenLayers.Map('map', {
+ layers: [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ controls: [control]
+ });
+ map.zoomToMaxExtent();
+ t.eq(control.maximizeDiv.title, "maximize title", "maximizeDiv.title is correct");
+ t.eq(control.minimizeDiv.title, "minimize title", "minimizeDiv.title is correct");
+ map.destroy();
+ }
+
+ function test_setMap(t) {
+ t.plan(4);
+
+ var setMapTest = function(map) {
+ t.ok(true,
+ "Handler.setMap called for " + this.CLASS_NAME);
+ this.map = map;
+ };
+ var drag_setMap = OpenLayers.Handler.Drag.prototype.setMap;
+ OpenLayers.Handler.Drag.prototype.setMap = setMapTest;
+ var click_setMap = OpenLayers.Handler.Click.prototype.setMap;
+ OpenLayers.Handler.Click.prototype.setMap = setMapTest;
+
+ map = new OpenLayers.Map('map', {
+ layers : [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ controls: []
+ });
+ control = new OpenLayers.Control.OverviewMap();
+
+ map.addControl(control);
+
+ map.zoomToMaxExtent();
+ t.eq(control.handlers.drag.map.id, control.ovmap.id,
+ "drag.map is correct");
+ t.eq(control.handlers.click.map.id, control.ovmap.id,
+ "click.map is correct");
+
+ map.destroy();
+ OpenLayers.Handler.Drag.prototype.setMap = drag_setMap;
+ OpenLayers.Handler.Click.prototype.setMap = click_setMap;
+ }
+
+ function test_destroy(t) {
+ t.plan(6);
+
+ // set up
+
+ var log_drag = [], log_click = [], control;
+
+ map = new OpenLayers.Map('map');
+ map.addLayer(new OpenLayers.Layer("layer", {isBaseLayer: true}));
+
+ control = new OpenLayers.Control.OverviewMap();
+ map.addControl(control);
+
+ map.zoomToMaxExtent();
+
+ control.handlers.drag.destroy = function() {
+ log_drag.push({"map": !!this.map.events});
+ };
+ control.handlers.click.destroy = function() {
+ log_click.push({"map": !!this.map.events});
+ };
+
+ // test
+
+ control.destroy();
+ t.eq(log_drag.length, 2,
+ "destroy() destroys drag handler twice, expected");
+ if (log_drag.length == 2) {
+ t.eq(log_drag[0].map, true,
+ "destroy() destroys drag handler before ovmap is destroyed (0)");
+ t.eq(log_drag[1].map, false,
+ "destroy() destroys drag handler after ovmap is destroyed (1)");
+ }
+ t.eq(log_click.length, 2,
+ "destroy() destroys click handler twice, expected");
+ if (log_click.length == 2) {
+ t.eq(log_click[0].map, true,
+ "destroy() destroys click handler before ovmap is destroyed (0)");
+ t.eq(log_click[1].map, false,
+ "destroy() destroys click handler after ovmap is destroyed (1)");
+ }
+
+ // tear down
+ map.destroy();
+ }
+
+ function test_addControl (t) {
+ t.plan( 6 );
+ map = new OpenLayers.Map('map');
+ control = new OpenLayers.Control.OverviewMap();
+ t.ok( control instanceof OpenLayers.Control.OverviewMap,
+ "new OpenLayers.Control.OverviewMap returns object" );
+ t.ok( map instanceof OpenLayers.Map,
+ "new OpenLayers.Map creates map" );
+ map.addControl(control);
+ t.ok( control.map === map,
+ "Control.map is set to the map object" );
+ t.ok( map.controls[4] === control,
+ "map.controls contains control" );
+ t.eq( parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 5,
+ "Control div zIndexed properly" );
+ t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 5,
+ "Viewport div contains control div" );
+
+ map.destroy();
+ }
+
+ function test_control_events (t) {
+ t.plan( 10 );
+
+ map = new OpenLayers.Map('map', {
+ // when we recenter, don't waste time animating the panning
+ // without this, the test fails in Firefox 10.0.1 on Linux
+ panMethod: null,
+ layers: [ new OpenLayers.Layer('Test Layer', {isBaseLayer: true}) ]
+ });
+
+ control = new OpenLayers.Control.OverviewMap();
+ map.addControl(control, new OpenLayers.Pixel(20,20));
+
+ var centerLL = new OpenLayers.LonLat(-71,42);
+ map.setCenter(centerLL, 11);
+
+ t.delay_call(
+ 0.1,
+ function() {
+ var overviewCenter = control.ovmap.getCenter();
+ var overviewZoom = control.ovmap.getZoom();
+ t.eq(overviewCenter.lon, -71,
+ "OverviewMap center lon correct");
+ t.eq(overviewCenter.lat, 42,
+ "OverviewMap center lat correct");
+ t.eq(overviewZoom, 8,
+ "OverviewMap zoom correct");
+
+ control.mapDivClick({'xy':new OpenLayers.Pixel(5,5)});
+ },
+ 0.1,
+ function() {
+ var cent = map.getCenter();
+ t.eq(cent.lon, -71.3515625,
+ "Clicking on OverviewMap has correct effect on map lon");
+ t.eq(cent.lat, 42.17578125,
+ "Clicking on OverviewMap has correct effect on map lat");
+
+ control.handlers.drag = {
+ last: new OpenLayers.Pixel(5,5),
+ destroy: function() {}
+ };
+ control.rectDrag(new OpenLayers.Pixel(15, 15));
+ control.updateMapToRect();
+ },
+ 0.1,
+ function() {
+ var cent = map.getCenter();
+ t.eq(cent.lon, -71.2734375,
+ "Dragging on OverviewMap has correct effect on map lon");
+ t.eq(cent.lat, 42.09765625,
+ "Dragging on OverviewMap has correct effect on map lat");
+
+ map.setCenter(new OpenLayers.LonLat(0,0), 0);
+ var overviewCenter = control.ovmap.getCenter();
+ var overviewZoom = control.ovmap.getZoom();
+ t.eq(overviewCenter.lon, 0,
+ "OverviewMap center lon correct -- second zoom");
+ t.eq(overviewCenter.lat, 0,
+ "OverviewMap center lat correct -- second zoom");
+ t.eq(overviewZoom, 0,
+ "OverviewMap zoomcorrect -- second zoom");
+ map.destroy();
+ }
+ );
+ }
+
+ function test_initialize_maximized(t) {
+ t.plan(4);
+
+ control = new OpenLayers.Control.OverviewMap()
+ map = new OpenLayers.Map('map', {
+ layers : [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ controls: [control]
+ });
+
+ t.eq(control.maximized, false,
+ "OverviewMap is not maximized by default");
+ t.eq(control.element.style.display, 'none',
+ "OverviewMap.element is not visible");
+ map.destroy();
+
+ control = new OpenLayers.Control.OverviewMap({
+ maximized: true
+ })
+ map = new OpenLayers.Map('map', {
+ layers : [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ controls: [control]
+ });
+ t.eq(control.maximized, true,
+ "OverviewMap.maximized is set");
+ t.eq(control.element.style.display, '',
+ "OverviewMap.element is visible");
+
+ map.destroy();
+ }
+
+ function test_custom_div(t) {
+ t.plan(3);
+ var div = document.createElement('div');
+
+ control = new OpenLayers.Control.OverviewMap({
+ div: div
+ });
+
+ map = new OpenLayers.Map('map', {
+ layers : [new OpenLayers.Layer("layer", {isBaseLayer: true})],
+ controls: [control]
+ });
+
+ t.eq(control.maximizeDiv, null,
+ "OverviewMap does not create maximize div");
+ t.eq(control.minimizeDiv, null,
+ "OverviewMap does not create minimize div");
+
+ var exc;
+ try {
+ control.maximizeControl();
+ control.minimizeControl();
+ } catch(e) {
+ exc = e;
+ }
+
+ t.eq(exc, undefined, 'maximize and minimize do not trigger an exception');
+
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Pan.html b/misc/openlayers/tests/Control/Pan.html
new file mode 100644
index 0000000..0c9dfaf
--- /dev/null
+++ b/misc/openlayers/tests/Control/Pan.html
@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+function test_Pan_constructor (t) {
+ t.plan( 2 );
+
+ // setup
+ var control = new OpenLayers.Control.Pan(
+ "Gargoyle" // the direction, here mocked up
+ );
+
+ // tests
+ //
+ t.ok(
+ control instanceof OpenLayers.Control.Pan,
+ "new OpenLayers.Control.Pan returns object"
+ );
+ t.eq(
+ control.displayClass, "olControlPanGargoyle",
+ "displayClass is correct"
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_Pan_type (t) {
+ t.plan( 1 );
+
+ // setup
+ var control = new OpenLayers.Control.Pan();
+
+ // tests
+ //
+ t.eq(
+ control.type,
+ OpenLayers.Control.TYPE_BUTTON,
+ "Pan control is of type OpenLayers.Control.TYPE_BUTTON"
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_Pan_constants (t) {
+ var dirs = [
+ 'North',
+ 'East',
+ 'South',
+ 'West'
+ ],
+ numDirs = dirs.length,
+ dir, uc_dir;
+
+ t.plan(numDirs);
+
+ for ( ; numDirs > 0; numDirs-- ) {
+ dir = dirs[numDirs - 1 ];
+ uc_dir = dir.toUpperCase();
+
+ t.eq(
+ OpenLayers.Control.Pan[ uc_dir ],
+ dir,
+ "A constant 'OpenLayers.Control.Pan." + uc_dir + "' is defined "+
+ "and has the correct value of '" + dir + "'."
+ );
+ }
+}
+
+function test_Pan_trigger (t) {
+ t.plan( 12 );
+
+ // set up
+ var controls = {
+ n: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH),
+ e: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST),
+ s: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH),
+ w: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST)
+ },
+ controlKey, control,
+ zoomlevel = 5,
+ center = new OpenLayers.LonLat(25,25),
+ log = {
+ dx: null,
+ dy: null
+ },
+ map = new OpenLayers.Map("map", {
+ allOverlays: true,
+ layers: [
+ new OpenLayers.Layer.Vector()
+ ],
+ center: center,
+ zoom: zoomlevel
+ }),
+ oldZoom;
+
+ // overwrite native Map::pan
+ map.pan = function(dx, dy) {
+ log = {
+ dx: dx,
+ dy: dy
+ };
+ OpenLayers.Map.prototype.pan.apply(map, arguments);
+ };
+
+ oldCenter = map.getCenter().toString();
+
+ for (controlKey in controls) {
+ if (controls.hasOwnProperty(controlKey)) {
+ control = controls[controlKey];
+ // trigger the control; nothing should change, we aren't added yet.
+ control.trigger();
+
+ t.ok(
+ log.dx === null && log.dy === null,
+ 'Calling trigger on a non added control doesn\'t do anything.'
+ );
+
+ // reset log object
+ log = {
+ dx: null,
+ dy: null
+ };
+ }
+ }
+
+ // now lets add the controls, and trigger them again
+ for (controlKey in controls) {
+ if (controls.hasOwnProperty(controlKey)) {
+ control = controls[controlKey];
+ map.addControl(control);
+ // trigger again, now ...
+ control.trigger();
+
+ // ... the center should change ...
+ t.ok(
+ log.dx !== null && log.dy !== null,
+ 'Calling trigger on an added pan control calls map.pan()... '
+ );
+
+ // ... with sane arguments according to the passed direction.
+ switch (control.direction) {
+ case OpenLayers.Control.Pan.NORTH:
+ t.ok(
+ log.dx === 0 && log.dy < 0,
+ '... with sane arguments: pan north only results in ' +
+ 'negative delta y'
+ );
+ break;
+ case OpenLayers.Control.Pan.SOUTH:
+ t.ok(
+ log.dx === 0 && log.dy > 0,
+ '... with sane arguments: pan south only results in ' +
+ 'positive delta y'
+ );
+ break;
+ case OpenLayers.Control.Pan.WEST:
+ t.ok(
+ log.dx < 0 && log.dy === 0,
+ '... with sane arguments: pan west only results in ' +
+ 'negative delta x'
+ );
+ break;
+ case OpenLayers.Control.Pan.EAST:
+ t.ok(
+ log.dx > 0 && log.dy === 0,
+ '... with sane arguments: pan east only results in ' +
+ 'positive delta x'
+ );
+ break;
+ }
+
+ // reset log-object
+ log = {
+ dx: null,
+ dy: null
+ };
+ // always set to initial center and zoom:
+ map.setCenter(center, zoomlevel);
+ }
+ }
+
+ // tear down
+ for (controlKey in controls) {
+ if (controls.hasOwnProperty(controlKey)) {
+ control = controls[controlKey];
+ control.destroy();
+ }
+ }
+ map.destroy();
+}
+
+ </script>
+ </head>
+ <body>
+ <div id="map" style="width: 1000px; height: 1000px;"></div>
+ </body>
+</html>
diff --git a/misc/openlayers/tests/Control/PanPanel.html b/misc/openlayers/tests/Control/PanPanel.html
new file mode 100644
index 0000000..978a051
--- /dev/null
+++ b/misc/openlayers/tests/Control/PanPanel.html
@@ -0,0 +1,61 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_constructor (t) {
+ t.plan(2);
+
+ // set up
+ var control;
+
+ // tests
+ control = new OpenLayers.Control.PanPanel({slideFactor: 200});
+ t.ok(control.controls[0].slideFactor == 200 &&
+ control.controls[1].slideFactor == 200 &&
+ control.controls[2].slideFactor == 200 &&
+ control.controls[3].slideFactor == 200,
+ "ctor sets slideFactor in all Pan controls");
+
+ control.destroy();
+
+ control = new OpenLayers.Control.PanPanel({slideRatio: .5});
+ t.ok(control.controls[0].slideRatio == .5 &&
+ control.controls[1].slideRatio == .5 &&
+ control.controls[2].slideRatio == .5 &&
+ control.controls[3].slideRatio == .5,
+ "ctor sets slideRatio in all Pan controls");
+
+ control.destroy();
+ }
+
+ function test_slide(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map", {
+ panMethod: null,
+ controls: [
+ new OpenLayers.Control.PanPanel(),
+ new OpenLayers.Control.PanPanel({slideRatio: .5})
+ ],
+ layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
+ center: new OpenLayers.LonLat(0, 0),
+ zoom: 1
+ });
+
+ map.controls[0].controls[0].trigger();
+ map.controls[0].controls[2].trigger();
+ map.pan(-50, 50);
+ t.eq(map.getCenter().toShortString(), "0, 0", "correct pan distance with slideFactor");
+
+ map.controls[1].controls[0].trigger();
+ map.controls[1].controls[2].trigger();
+ map.pan(-128, 64);
+ t.eq(map.getCenter().toShortString(), "0, 0", "correct pan distance with slideRatio");
+
+ map.destroy();
+ }
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 256px; height: 128px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/PanZoom.html b/misc/openlayers/tests/Control/PanZoom.html
new file mode 100644
index 0000000..4982fb0
--- /dev/null
+++ b/misc/openlayers/tests/Control/PanZoom.html
@@ -0,0 +1,244 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map;
+ function test_Control_PanZoom_constructor (t) {
+ t.plan( 4 );
+
+ control = new OpenLayers.Control.PanZoom();
+ t.ok( control instanceof OpenLayers.Control.PanZoom, "new OpenLayers.Control.PanZoom returns object" );
+ t.eq( control.displayClass, "olControlPanZoom", "displayClass is correct" );
+ control = new OpenLayers.Control.PanZoom({position: new OpenLayers.Pixel(100,100)});
+ t.eq( control.position.x, 100, "PanZoom X Set correctly.");
+ t.eq( control.position.y, 100, "PanZoom y Set correctly.");
+ }
+ function test_Control_PanZoom_addControl (t) {
+ t.plan( 8 );
+ map = new OpenLayers.Map('map');
+ control = new OpenLayers.Control.PanZoom();
+ t.ok( control instanceof OpenLayers.Control.PanZoom, "new OpenLayers.Control.PanZoom returns object" );
+ t.ok( map instanceof OpenLayers.Map, "new OpenLayers.Map creates map" );
+ map.addControl(control);
+ t.ok( control.map === map, "Control.map is set to the map object" );
+ t.ok( map.controls[4] === control, "map.controls contains control" );
+ t.eq( parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, "Control div zIndexed properly" );
+ t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, "Viewport div contains control div" );
+ t.eq( control.div.style.top, "4px", "Control div top located correctly by default");
+
+ var control2 = new OpenLayers.Control.PanZoom();
+ map.addControl(control2, new OpenLayers.Pixel(100,100));
+ t.eq( control2.div.style.top, "100px", "2nd control div is located correctly");
+ }
+
+ function test_Control_PanZoom_removeButtons(t) {
+ t.plan(2);
+ map = new OpenLayers.Map("map");
+ control = new OpenLayers.Control.PanZoom();
+ map.addControl(control);
+ control.removeButtons();
+ t.eq(control.buttons.length, 0, "buttons array cleared correctly");
+ t.eq(control.div.childNodes.length, 0, "control div is empty");
+ }
+
+ function test_Control_PanZoom_control_events (t) {
+
+ // IE 9+ does support the standard document.createEvent,
+ // event.initMouseEvent, and elem.dispatchEvent calls, so it
+ // should be possible to simulate clicks in this browser.
+ // For example it looks like jQuery UI does simulate events
+ // using document.createElement in IE 9+. See
+ // https://github.com/jquery/jquery-ui/blob/master/tests/jquery.simulate.js.
+ // I haven't been able to make it work though.
+
+ if ( !window.document.createEvent ||
+ OpenLayers.BROWSER_NAME == "msie" ||
+ OpenLayers.BROWSER_NAME == "opera" ||
+ !t.open_window) {
+
+ t.plan(0);
+ t.debug_print("FIXME: This browser does not support the PanZoom test at this time.");
+ } else {
+ t.plan(35);
+ t.open_window( "Control/PanZoom.html", function( wnd ) {
+ t.delay_call( 3, function() {
+ var flag;
+ function setFlag(evt) {
+ flag[evt.type] = true;
+ }
+ function resetFlags() {
+ flag = {
+ mousedown: false,
+ mouseup: false,
+ click: false,
+ dblclick: false
+ };
+ }
+ resetFlags();
+
+ wnd.mapper.events.register("mousedown", mapper, setFlag);
+ wnd.mapper.events.register("mouseup", mapper, setFlag);
+ wnd.mapper.events.register("click", mapper, setFlag);
+ wnd.mapper.events.register("dblclick", mapper, setFlag);
+
+ simulateClick(wnd, wnd.control.buttons[0]);
+ t.delay_call(2, function() {
+ t.ok( wnd.mapper.getCenter().lat > wnd.centerLL.lat, "1) Pan up works correctly" );
+ t.ok(!flag.mousedown, "1) mousedown does not get to the map");
+ t.ok(!flag.mouseup, "1) mouseup does not get to the map");
+ t.ok(!flag.click, "1) click does not get to the map");
+ t.ok(!flag.dblclick, "1) dblclick does not get to the map");
+ resetFlags();
+
+ simulateClick(wnd, wnd.control.buttons[1]);
+ }, 2, function() {
+ t.ok( wnd.mapper.getCenter().lon < wnd.centerLL.lon, "2) Pan left works correctly" );
+ t.ok(!flag.mousedown, "2) mousedown does not get to the map");
+ t.ok(!flag.mouseup, "2) mouseup does not get to the map");
+ t.ok(!flag.click, "2) click does not get to the map");
+ t.ok(!flag.dblclick, "2) dblclick does not get to the map");
+ resetFlags();
+
+ simulateClick(wnd, wnd.control.buttons[2]);
+ }, 2, function() {
+ t.ok( wnd.mapper.getCenter().lon == wnd.centerLL.lon, "3) Pan right works correctly" );
+ t.ok(!flag.mousedown, "3) mousedown does not get to the map");
+ t.ok(!flag.mouseup, "3) mouseup does not get to the map");
+ t.ok(!flag.click, "3) click does not get to the map");
+ t.ok(!flag.dblclick, "3) dblclick does not get to the map");
+ resetFlags();
+
+ simulateClick(wnd, wnd.control.buttons[3]);
+ }, 2, function() {
+ t.ok( wnd.mapper.getCenter().lat == wnd.centerLL.lat, "4) Pan down works correctly" );
+ t.ok(!flag.mousedown, "4) mousedown does not get to the map");
+ t.ok(!flag.mouseup, "4) mouseup does not get to the map");
+ t.ok(!flag.click, "4) click does not get to the map");
+ t.ok(!flag.dblclick, "4) dblclick does not get to the map");
+ resetFlags();
+
+ simulateClick(wnd, wnd.control.buttons[4]);
+ }, 2, function() {
+ t.eq( wnd.mapper.getZoom(), 6, "5) zoomin works correctly" );
+ t.ok(!flag.mousedown, "5) mousedown does not get to the map");
+ t.ok(!flag.mouseup, "5) mouseup does not get to the map");
+ t.ok(!flag.click, "5) click does not get to the map");
+ t.ok(!flag.dblclick, "5) dblclick does not get to the map");
+ resetFlags();
+
+ simulateClick(wnd, wnd.control.buttons[6]);
+ }, 2, function() {
+ t.eq( wnd.mapper.getZoom(), 5, "6) zoomout works correctly" );
+ t.ok(!flag.mousedown, "6) mousedown does not get to the map");
+ t.ok(!flag.mouseup, "6) mouseup does not get to the map");
+ t.ok(!flag.click, "6) click does not get to the map");
+ t.ok(!flag.dblclick, "6) dblclick does not get to the map");
+ resetFlags();
+
+ simulateClick(wnd, wnd.control.buttons[5]);
+ }, 2, function() {
+ t.eq( wnd.mapper.getZoom(), 2, "7) zoomworld works correctly" );
+ t.ok(!flag.mousedown, "7) mousedown does not get to the map");
+ t.ok(!flag.mouseup, "7) mouseup does not get to the map");
+ t.ok(!flag.click, "7) click does not get to the map");
+ t.ok(!flag.dblclick, "7) dblclick does not get to the map");
+ resetFlags();
+ });
+ });
+ });
+ }
+ }
+
+ function test_slideRatio(t) {
+ t.plan(4);
+
+ var control = new OpenLayers.Control.PanZoom({
+ slideRatio: .5
+ });
+
+ var map = new OpenLayers.Map();
+
+ map.addControl(control);
+ control.draw();
+ control.activate();
+
+ map.getSize = function() {
+ return {
+ w: 250,
+ h: 100
+ }
+ };
+
+ var delta, dir;
+ var buttons = control.buttons;
+ map.pan = function(dx, dy){
+ t.eq([dx,dy],delta,"Panning " + dir + " sets right delta with slideRatio");
+ };
+
+ //up
+ var delta = [0, -50];
+ var dir = "up";
+ var evt = {buttonElement: buttons[0]};
+ control.onButtonClick.call(control, evt);
+
+ //left
+ var delta = [-125, 0];
+ var dir = "left";
+ evt.buttonElement = buttons[1];
+ control.onButtonClick.call(control, evt);
+
+ //right
+ var delta = [125, 0];
+ var dir = "right";
+ evt.buttonElement = buttons[2];
+ control.onButtonClick.call(control, evt);
+
+ //down
+ var delta = [0, 50];
+ var dir = "down";
+ evt.buttonElement = buttons[3];
+ control.onButtonClick.call(control, evt);
+
+ map.destroy();
+ }
+
+ function simulateClick(wnd, elem) {
+ var evt = wnd.document.createEvent("MouseEvents");
+ evt.initMouseEvent("mousedown", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ elem.dispatchEvent(evt);
+
+ evt = wnd.document.createEvent("MouseEvents");
+ evt.initMouseEvent("mouseup", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ elem.dispatchEvent(evt);
+
+ evt = wnd.document.createEvent("MouseEvents");
+ evt.initMouseEvent("click", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ elem.dispatchEvent(evt);
+
+ evt = wnd.document.createEvent("MouseEvents");
+ evt.initMouseEvent("dblclick", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
+ elem.dispatchEvent(evt);
+ }
+
+ function loader() {
+ control = new OpenLayers.Control.PanZoom();
+
+ mapper = new OpenLayers.Map('map', { controls: [control]});
+
+
+ var layer = new OpenLayers.Layer.WMS("Test Layer",
+ "http://labs.metacarta.com/wms-c/Basic.py?",
+ {layers: "basic"});
+ mapper.addLayer(layer);
+
+ centerLL = new OpenLayers.LonLat(0,0);
+ mapper.setCenter(centerLL, 5);
+ }
+
+
+ </script>
+</head>
+<body onload="loader()">
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/PanZoomBar.html b/misc/openlayers/tests/Control/PanZoomBar.html
new file mode 100644
index 0000000..5ed2833
--- /dev/null
+++ b/misc/openlayers/tests/Control/PanZoomBar.html
@@ -0,0 +1,245 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map;
+ function test_Control_PanZoomBar_constructor (t) {
+ t.plan( 4 );
+
+ control = new OpenLayers.Control.PanZoomBar({position: new OpenLayers.Pixel(100,100)});
+ t.ok( control instanceof OpenLayers.Control.PanZoomBar, "new OpenLayers.Control.PanZoomBar returns object" );
+ t.eq( control.displayClass, "olControlPanZoomBar", "displayClass is correct" );
+ t.eq( control.position.x, 100, "PanZoom X Set correctly.");
+ t.eq( control.position.y, 100, "PanZoom y Set correctly.");
+ }
+ function test_Control_PanZoomBar_addControl (t) {
+ t.plan( 8 );
+ map = new OpenLayers.Map('map', {controls:[]});
+ var layer = new OpenLayers.Layer.WMS("Test Layer",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+ control = new OpenLayers.Control.PanZoomBar();
+ t.ok( control instanceof OpenLayers.Control.PanZoomBar, "new OpenLayers.Control.PanZoomBar returns object" );
+ t.ok( map instanceof OpenLayers.Map, "new OpenLayers.Map creates map" );
+ map.addControl(control);
+ t.ok( control.map === map, "Control.map is set to the map object" );
+ t.ok( map.controls[0] === control, "map.controls contains control" );
+ t.eq( parseInt(control.div.style.zIndex), 1001, "Control div zIndexed properly" );
+ t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), 1001, "Viewport div contains control div" );
+ t.eq( control.div.style.top, "4px", "Control div top located correctly by default");
+
+ var control2 = new OpenLayers.Control.PanZoomBar();
+ map.addControl(control2, new OpenLayers.Pixel(100,100));
+ t.eq( control2.div.style.top, "100px", "2nd control div is located correctly");
+ }
+
+ function test_draw(t) {
+ t.plan(3);
+ map = new OpenLayers.Map('map', {controls:[]});
+ var layer = new OpenLayers.Layer.WMS("Test Layer",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ control = new OpenLayers.Control.PanZoomBar();
+ map.addControl(control);
+ t.eq(control.zoombarDiv.style.height, '176px', "Bar's height is correct.");
+
+ map.baseLayer.wrapDateLine = true;
+
+ control.redraw();
+ t.eq(control.zoombarDiv.style.height, '154px', "Bar's height is correct after minZoom restriction.");
+
+ map.div.style.width = "512px";
+ map.updateSize();
+ t.eq(control.zoombarDiv.style.height, '165px', "Bar's height is correct after resize and minZoom restriction.");
+
+ map.div.style.width = "1024px";
+ map.destroy();
+ }
+
+ function test_Control_PanZoomBar_clearDiv(t) {
+ t.plan(2);
+ map = new OpenLayers.Map('map', {controls:[]});
+ var layer = new OpenLayers.Layer.WMS("Test Layer",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+ control = new OpenLayers.Control.PanZoomBar();
+ map.addControl(control);
+ control.removeButtons();
+ var div = control.div;
+ map.destroy();
+ t.eq(div.childNodes.length, 0, "control's div cleared.");
+ t.eq(control.zoombarDiv, null, "zoombar div nullified.")
+ }
+
+ function test_Control_PanZoomBar_onButtonClick (t) {
+ t.plan(2);
+ map = new OpenLayers.Map('map', {controls:[], zoomMethod: null});
+ var layer = new OpenLayers.Layer.WMS("Test Layer",
+ "http://octo.metacarta.com/cgi-bin/mapserv?",
+ {map: "/mapdata/vmap_wms.map", layers: "basic"});
+ map.addLayer(layer);
+ control = new OpenLayers.Control.PanZoomBar();
+ map.addControl(control);
+ control.onButtonClick({'buttonXY': {'x': 0, 'y': 50}, buttonElement: control.zoombarDiv});
+ t.eq(map.zoom, 11, "zoom is correct on standard map");
+
+ map.fractionalZoom = true;
+ control.onButtonClick({'buttonXY': {'x': 0, 'y': 49}, buttonElement: control.zoombarDiv});
+ t.eq(map.zoom.toFixed(3), '10.545', "zoom is correct on fractional zoom map");
+
+ }
+
+ function test_Control_PanZoomBar_forceFixedZoomLevel_onButtonClick(t){
+ t.plan(1);
+ map = new OpenLayers.Map('map', {
+ controls: [],
+ fractionalZoom: true,
+ zoomMethod: null
+ });
+ var layer = new OpenLayers.Layer.WMS("Test Layer", "http://octo.metacarta.com/cgi-bin/mapserv?", {
+ map: "/mapdata/vmap_wms.map",
+ layers: "basic"
+ });
+ map.addLayer(layer);
+ control = new OpenLayers.Control.PanZoomBar({
+ forceFixedZoomLevel: true
+ });
+ map.addControl(control);
+
+ control.onButtonClick({
+ 'buttonXY': {
+ 'x': 0,
+ 'y': 49
+ },
+ buttonElement: control.zoombarDiv
+ });
+ t.eq(map.zoom, 11, "forceFixedZoomLevel makes sure that after a div click only fixed zoom levels are used even if the map has fractionalZoom");
+ }
+
+ function test_Control_PanZoomBar_forceFixedZoomLevel_zoomBarUp (t) {
+ var numRandomDrags = 25;
+ // plan one static recorded test and two for every random drag
+ t.plan(1 + (numRandomDrags * 2));
+
+
+ var map = new OpenLayers.Map('map', {
+ controls: [],
+ fractionalZoom: true,
+ zoomMethod: null
+ });
+ var layer = new OpenLayers.Layer.WMS("Test Layer", "http://octo.metacarta.com/cgi-bin/mapserv?", {
+ map: "/mapdata/vmap_wms.map",
+ layers: "basic"
+ });
+ map.addLayer(layer);
+
+ // zoom to a fractional ZoomLevel initially:
+ map.setCenter(new OpenLayers.LonLat(0, 0), 9.545);
+
+ control = new OpenLayers.Control.PanZoomBar({
+ forceFixedZoomLevel: true
+ });
+ map.addControl(control);
+
+ // The y values come from manually recording real values in an example
+ var evt = {
+ 'xy': {
+ 'x': 0,
+ 'y': -10.633
+ },
+ which: 1
+ };
+ control.zoomStart = {
+ 'x': 0,
+ 'y': 5.366
+ };
+ control.mouseDragStart = {
+ 'x': 0,
+ 'y': -10.633
+ };
+ control.deltaY = control.zoomStart.y - evt.xy.y
+ control.zoomBarUp(evt);
+ t.eq(map.zoom, 11, "forceFixedZoomLevel makes sure that after dragging of the handle only fixed zoom levels are used even if the map has fractionalZoom");
+
+ // randomly drag the handle around
+ // we should never get a zoom < 0 or a non-integer zoom, regardless of
+ // captured random values for start and end of the drag.
+ for (var i = 0; i < numRandomDrags; i++) {
+ var randStartY = Math.random() * 10 * ((i % 2 === 0) ? -1 : 1);
+ var randStopY = Math.random() * 160 * ((i % 2 === 1) ? -1 : 1);
+ var evt = {
+ 'xy': {
+ 'x': 0,
+ 'y': randStopY
+ },
+ which: 1
+ };
+ control.zoomStart = {
+ 'x': 0,
+ 'y': randStartY
+ };
+ control.mouseDragStart = {
+ 'x': 0,
+ 'y': randStopY
+ };
+ control.deltaY = control.zoomStart.y - evt.xy.y
+ control.zoomBarUp(evt);
+
+ t.eq(Math.floor(map.zoom), Math.ceil(map.zoom), 'Only integer zooms after random handle drag with forceFixedZoomLevel=true and fractionalZoom=true (current zoom was ' + map.zoom + ')');
+ t.ok(map.zoom >= 0, 'map.zoom is never < 0 after random handle drag with forceFixedZoomLevel=true and fractionalZoom=true');
+ }
+ }
+
+ function test_Control_PanZoomBar_shows (t) {
+ t.plan(22);
+
+ var control, map;
+
+ control = new OpenLayers.Control.PanZoomBar({panIcons: true, zoomWorldIcon: false});
+ map = new OpenLayers.Map('map', {controls: [control]});
+ t.eq(control.buttons.length, 6, "(a) pan, no world - expected number of buttons");
+ t.ok(control.buttons[0].id.match("_panup$"), "(a) pan, no world - pan up");
+ t.ok(control.buttons[1].id.match("_panleft$"), "(a) pan, no world - pan left");
+ t.ok(control.buttons[2].id.match("_panright$"), "(a) pan, no world - pan right");
+ t.ok(control.buttons[3].id.match("_pandown$"), "(a) pan, no world - pan down");
+ t.ok(control.buttons[4].id.match("_zoomin$"), "(a) pan, no world - zoom in");
+ t.ok(control.buttons[5].id.match("_zoomout$"), "(a) pan, no world - zoom out");
+ map.destroy();
+
+ control = new OpenLayers.Control.PanZoomBar({panIcons: true, zoomWorldIcon: true});
+ map = new OpenLayers.Map('map', {controls:[control]});
+ t.eq(control.buttons.length, 7, "(b) pan, world - expected number of buttons");
+ t.ok(control.buttons[0].id.match("_panup$"), "(b) pan, world - pan up");
+ t.ok(control.buttons[1].id.match("_panleft$"), "(b) pan, world - pan left");
+ t.ok(control.buttons[2].id.match("_zoomworld$"), "(b) pan, world - zoom world");
+ t.ok(control.buttons[3].id.match("_panright$"), "(b) pan, world - pan right");
+ t.ok(control.buttons[4].id.match("_pandown$"), "(b) pan, world - pan down");
+ t.ok(control.buttons[5].id.match("_zoomin$"), "(b) pan, world - zoom in");
+ t.ok(control.buttons[6].id.match("_zoomout$"), "(b) pan, world - zoom out");
+ map.destroy();
+
+ control = new OpenLayers.Control.PanZoomBar({panIcons: false, zoomWorldIcon: false});
+ map = new OpenLayers.Map('map', {controls:[control]});
+ t.eq(control.buttons.length, 2, "(c) no pan, no world - expected number of buttons");
+ t.ok(control.buttons[0].id.match("_zoomin$"), "(c) no pan, no world - zoom in");
+ t.ok(control.buttons[1].id.match("_zoomout$"), "(c) no pan, no world - zoom out");
+ map.destroy();
+
+ control = new OpenLayers.Control.PanZoomBar({panIcons: false, zoomWorldIcon: true});
+ map = new OpenLayers.Map('map', {controls:[control]});
+ t.eq(control.buttons.length, 3, "(d) no pan, world - expected number of buttons");
+ t.ok(control.buttons[0].id.match("_zoomin$"), "(d) no pan, world - zoom in");
+ t.ok(control.buttons[1].id.match("_zoomout$"), "(d) no pan, world - zoom out");
+ t.ok(control.buttons[2].id.match("_zoomworld$"), "(d) no pan, world - zoom world");
+ map.destroy();
+ }
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Panel.html b/misc/openlayers/tests/Control/Panel.html
new file mode 100644
index 0000000..f02e643
--- /dev/null
+++ b/misc/openlayers/tests/Control/Panel.html
@@ -0,0 +1,382 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ function test_Control_Panel_constructor (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.Panel();
+ t.ok( control instanceof OpenLayers.Control.Panel, "new OpenLayers.Control returns object" );
+ t.eq( control.displayClass, "olControlPanel", "displayClass is correct" );
+ }
+ function test_Control_Panel_constructor2 (t) {
+ t.plan(19);
+ var map = new OpenLayers.Map('map');
+ var toolControl = new OpenLayers.Control.ZoomBox();
+ var AnotherToolControl = OpenLayers.Class(OpenLayers.Control, {
+ CLASS_NAME: 'mbControl.TestTool',
+ type: OpenLayers.Control.TYPE_TOOL
+ });
+ var anotherToolControl = new AnotherToolControl();
+ var ToggleControl = OpenLayers.Class(OpenLayers.Control, {
+ CLASS_NAME: 'mbControl.TestToggle',
+ type: OpenLayers.Control.TYPE_TOGGLE
+ });
+
+ var toggleControl = new ToggleControl();
+ var buttonControl = new OpenLayers.Control.Button({
+ trigger: function () {
+ t.ok(true, "trigger function of button is called.");
+ }
+ });
+
+ var panel = new OpenLayers.Control.Panel(
+ {defaultControl: anotherToolControl});
+ t.ok(panel instanceof OpenLayers.Control.Panel,
+ "new OpenLayers.Control.Panel returns object");
+ panel.redraw = function(){
+ panel.redrawsCount++;
+ OpenLayers.Control.Panel.prototype.redraw.apply(this, arguments);
+ };
+
+ // To get length of events.listeners error-free
+ var getListenerLength= function(events,key){
+ if(!events) {
+ return -2; // events is destroyed
+ } else if(!events.listeners) {
+ return -1; // events is destroyed
+ } else if(!events.listeners[key]) {
+ return 0; // no listener in event
+ } else {
+ return events.listeners[key].length;
+ }
+ };
+ var toolEventListenerLength = getListenerLength(toolControl.events,"activate");
+ panel.addControls([toolControl, anotherToolControl, toggleControl]);
+ t.eq(panel.controls.length, 3,
+ "added three controls to the panel");
+ panel.addControls([buttonControl]);
+
+ panel.redrawsCount = 0;
+ map.addControl(panel);
+ t.eq(getListenerLength(toolControl.events,"activate"), toolEventListenerLength+1,
+ "toolControl additional listener for \"activate\" after adding Panel to the map.");
+ t.ok((panel.redrawsCount > 0), "Redraw called on add panel to map " +
+ panel.redrawsCount + " times.");
+ t.ok((panel.active),"Panel is active after add panel to map.");
+
+ panel.redrawsCount = 0;
+ panel.addControls(new AnotherToolControl());
+ t.ok((panel.redrawsCount > 0),
+ "Redraw called on add control to panel after add panel to map " +
+ panel.redrawsCount + " times.");
+
+ panel.deactivate();
+ panel.redrawsCount = 0;
+ panel.activate();
+ t.ok((panel.redrawsCount > 0),"Redraw called on activate panel " +
+ panel.redrawsCount + " times.");
+
+ panel.activateControl(toolControl);
+ t.ok(toolControl.active && !anotherToolControl.active && !toggleControl.active && !buttonControl.active,
+ "activated one tool control, the other one is inactive and the toggle & button controls also.");
+
+ panel.activateControl(toggleControl);
+ t.eq(toggleControl.panel_div.className,"mbControlTestToggleItemActive olButton",
+ "className of icon div for toggle control is active.");
+ t.ok(toolControl.active && !anotherToolControl.active && toggleControl.active,
+ "activated the toggle control, which has no influence on the tool & togggle controls.");
+ panel.activateControl(buttonControl);
+ t.ok(toolControl.active && !anotherToolControl.active && toggleControl.active,
+ "activateContol calling for button, which has no influence on the tool & togggle controls.");
+ t.ok(!buttonControl.active,
+ "activateContol calling for button, button remains inactive.");
+ buttonControl.activate();
+ t.ok(buttonControl.active && toolControl.active && !anotherToolControl.active && toggleControl.active,
+ "activated the button control, which has no influence on the tool & togggle controls.");
+
+ panel.activateControl(anotherToolControl);
+ t.eq(anotherToolControl.panel_div.className,"mbControlTestToolItemActive olButton",
+ "className of icon div for anotherToolControl is active.");
+ t.eq(toolControl.panel_div.className,"olControlZoomBoxItemInactive olButton",
+ "className of icon div for toolControl is inactive.");
+ t.ok(!toolControl.active && anotherToolControl.active && toggleControl.active,
+ "activated the other tool control, the first one is inactive and the toggle control still active.");
+ t.ok(buttonControl.active,
+ "activated the other tool control, the button control still active.");
+
+ panel.destroy();
+ t.eq(getListenerLength(toolControl.events,"activate"), toolEventListenerLength,
+ "toolControl additional listeners removed after destroy Panel.");
+ map.destroy();
+ }
+ function test_Control_Panel_titles (t) {
+ t.plan(2);
+ var panel = new OpenLayers.Control.Panel();
+ var toolControl = new OpenLayers.Control.ZoomBox({
+ title:"Zoom box: Selecting it you can zoom on an area by clicking and dragging."
+ });
+ panel.addControls([toolControl]);
+ t.eq(panel.controls.length, 1, "added a control to the panel");
+ t.eq(panel.controls[0].title, toolControl.panel_div.title, "the title is correctly set");
+ }
+
+ function test_Control_Panel_getBy(t) {
+
+ var panel = {
+ getBy: OpenLayers.Control.Panel.prototype.getBy,
+ getControlsBy: OpenLayers.Control.Panel.prototype.getControlsBy,
+ controls: [
+ {foo: "foo", id: Math.random()},
+ {foo: "bar", id: Math.random()},
+ {foo: "foobar", id: Math.random()},
+ {foo: "foo bar", id: Math.random()},
+ {foo: "foo", id: Math.random()}
+ ]
+ };
+
+ var cases = [
+ {
+ got: panel.getControlsBy("foo", "foo"),
+ expected: [panel.controls[0], panel.controls[4]],
+ message: "(string literal) got two controls matching foo"
+ }, {
+ got: panel.getControlsBy("foo", "bar"),
+ expected: [panel.controls[1]],
+ message: "(string literal) got one control matching foo"
+ }, {
+ got: panel.getControlsBy("foo", "barfoo"),
+ expected: [],
+ message: "(string literal) got empty array for no foo match"
+ }, {
+ got: panel.getControlsBy("foo", /foo/),
+ expected: [panel.controls[0], panel.controls[2], panel.controls[3], panel.controls[4]],
+ message: "(regexp literal) got three controls containing string"
+ }, {
+ got: panel.getControlsBy("foo", /foo$/),
+ expected: [panel.controls[0], panel.controls[4]],
+ message: "(regexp literal) got three controls ending with string"
+ }, {
+ got: panel.getControlsBy("foo", /\s/),
+ expected: [panel.controls[3]],
+ message: "(regexp literal) got control containing space"
+ }, {
+ got: panel.getControlsBy("foo", new RegExp("BAR", "i")),
+ expected: [panel.controls[1], panel.controls[2], panel.controls[3]],
+ message: "(regexp object) got layers ignoring case"
+ }, {
+ got: panel.getControlsBy("foo", {test: function(str) {return str.length > 3;}}),
+ expected: [panel.controls[2], panel.controls[3]],
+ message: "(custom object) got controls with foo length greater than 3"
+ }
+ ];
+ t.plan(cases.length);
+ for(var i=0; i<cases.length; ++i) {
+ t.eq(cases[i].got, cases[i].expected, cases[i].message);
+ }
+
+
+ }
+
+ function test_Control_Panel_saveState (t) {
+ t.plan(11);
+ var map = new OpenLayers.Map('map');
+
+ var defaultControl = new OpenLayers.Control();
+ var panel = new OpenLayers.Control.Panel({
+ defaultControl: defaultControl
+ });
+ panel.addControls([new OpenLayers.Control(), defaultControl]);
+ map.addControl(panel);
+ t.eq(defaultControl.active, true,
+ "After panel activation default control is active.");
+ t.ok(panel.defaultControl,
+ "defaultControl not nullified after initial panel activation");
+ // activate the 1st control
+ panel.activateControl(panel.controls[0]);
+ panel.deactivate();
+ t.ok(!panel.controls[0].active && !panel.controls[1].active,
+ "No controls are active after panel deactivation.");
+ panel.activate();
+ t.eq(panel.controls[0].active, false,
+ "After panel reactivation first control is inactive.");
+ t.eq(panel.controls[1].active, true,
+ "After panel reactivation default control is active again.");
+ panel.destroy();
+
+ defaultControl = new OpenLayers.Control();
+ panel = new OpenLayers.Control.Panel({
+ saveState: true,
+ defaultControl: defaultControl
+ });
+ panel.addControls([new OpenLayers.Control(), defaultControl]);
+ map.addControl(panel);
+ t.eq(defaultControl.active, true,
+ "After panel activation default control is active.");
+ t.eq(panel.defaultControl, null,
+ "defaultControl nullified after initial panel activation");
+ // activate the 1st control, which will deactivate the 2nd
+ panel.activateControl(panel.controls[0]);
+ t.eq(panel.controls[1].active, false,
+ "2nd control deactivated with activation of 1st");
+ panel.deactivate();
+ t.ok(!panel.controls[0].active && !panel.controls[1].active,
+ "No controls are active after panel deactivation.");
+ panel.activate();
+ t.eq(panel.controls[0].active, true,
+ "After panel reactivation first control is active.");
+ t.eq(panel.controls[1].active, false,
+ "After panel reactivation second control is inactive.");
+ panel.destroy();
+ map.destroy();
+ }
+
+ function test_Control_Panel_autoActivate (t) {
+ t.plan(1);
+ var map = new OpenLayers.Map('map');
+ var controlNoDeactive = new OpenLayers.Control({autoActivate:true});
+ var chkDeactivate = function () {
+ t.ok(false, "Tool control autoActivate:true was deactivated unnecessarily");
+ };
+ controlNoDeactive.events.on({deactivate: chkDeactivate});
+ var panel = new OpenLayers.Control.Panel();
+
+ map.addControl(panel);
+ panel.addControls([controlNoDeactive]);
+ controlNoDeactive.events.un({deactivate: chkDeactivate});
+ t.ok(!controlNoDeactive.active, "Tool control autoActivate:true is not active");
+
+ }
+
+ function test_Control_Panel_deactivate (t) {
+ t.plan(2);
+ var map = new OpenLayers.Map('map');
+ var control = new OpenLayers.Control();
+ var panel = new OpenLayers.Control.Panel();
+ map.addControl(panel);
+ panel.addControls([control]);
+ t.ok(panel.div.innerHTML != "", "Panel displayed after activate");
+
+ panel.deactivate();
+ t.ok(panel.div.innerHTML == "",
+ "Panel is not displayed after deactivate without any active control");
+
+ map.destroy();
+ }
+
+ function test_allowDepress (t) {
+ t.plan(2);
+ var map = new OpenLayers.Map('map');
+
+ var panel = new OpenLayers.Control.Panel();
+ panel.addControls([new OpenLayers.Control(),new OpenLayers.Control()]);
+ map.addControl(panel);
+
+ var control1 = panel.controls[1]
+
+ panel.activateControl(control1);
+
+ panel.allowDepress = false;
+ panel.activateControl(control1);
+ t.eq(control1.active, true,
+ "control1 remains active after calling again activateControl when allowDepress = false");
+ panel.allowDepress = true;
+ panel.activateControl(control1);
+ t.eq(control1.active, false,
+ "control1 is inactive after calling again activateControl when allowDepress = true");
+
+ // panel.deactivate();
+ map.destroy();
+ }
+
+ function test_iconOn_iconOff(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map('map');
+
+ var panel = new OpenLayers.Control.Panel();
+ var ctrl = new OpenLayers.Control({displayClass: 'ctrl'});
+ panel.addControls([ctrl]);
+
+ map.addControl(panel);
+
+ // add arbitrary classes to the panel div - we want to test
+ // than iconOn and iconOff do their jobs even when the panel
+ // div has application-specific classes.
+
+ ctrl.panel_div.className =
+ 'ctrlItemInactive fooItemActive fooItemInactive';
+
+ panel.iconOn.call(ctrl);
+ t.eq(ctrl.panel_div.className,
+ 'ctrlItemActive fooItemActive fooItemInactive',
+ 'iconOn behaves as expected');
+
+ ctrl.panel_div.className =
+ 'ctrlItemActive fooItemActive fooItemInactive';
+
+ panel.iconOff.call(ctrl);
+ t.eq(ctrl.panel_div.className,
+ 'ctrlItemInactive fooItemActive fooItemInactive',
+ 'iconOff behaves as expected');
+
+ map.destroy();
+ }
+
+ function test_buttonclick(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map('map');
+ var panel1 = new OpenLayers.Control.Panel();
+ var div = document.createElement("div");
+ var panel2 = new OpenLayers.Control.Panel({div: div});
+ map.addControls([panel1, panel2]);
+
+ t.ok(map.events.listeners.buttonclick, "buttonclick event registered on map's Events instance for panel inside map");
+ t.ok(!panel1.events.element, "Panel inside map has no element on its Events instance");
+ t.ok(panel2.events.listeners.buttonclick, "buttonclick event registered on panel's Events instance if outside map")
+ t.ok(panel2.events.element === div, "Panel outside map has the panel's div as element on its Events instance");
+
+ }
+
+ function test_iconOniconOff (t) {
+ t.plan(6);
+ var map = new OpenLayers.Map("map"),
+ navControl = new OpenLayers.Control.Navigation({autoActivate: true}),
+ zbControl = new OpenLayers.Control.ZoomBox(),
+ panel = new OpenLayers.Control.Panel({defaultControl: navControl}),
+ navActiveClass, navInactiveClass, zbActiveClass, zbInactiveClass;
+
+ panel.addControls([navControl, zbControl]);
+ map.addControl(panel);
+
+ navControl.panel_div.className += " foo";
+ zbControl.panel_div.className = "bar " + zbControl.panel_div.className;
+
+ t.eq(navControl.panel_div.className, "olControlNavigationItemActive olButton foo",
+ "defaultControl className is set to [displayClass]Active on panel instantiation");
+ t.eq(zbControl.panel_div.className, "bar olControlZoomBoxItemInactive olButton",
+ "non-defaultControl className is set to [displayClass]Inactive on panel instantiation");
+
+ panel.activateControl(zbControl);
+
+ t.eq(zbControl.panel_div.className, "bar olControlZoomBoxItemActive olButton",
+ "active control class name with preceding secondary class name is set to [displayClass]Active");
+ t.eq(navControl.panel_div.className, "olControlNavigationItemInactive olButton foo",
+ "inactive control class name with trailing secondary class name is set to [displayClass]Inactive");
+
+ panel.activateControl(navControl);
+
+ t.eq(navControl.panel_div.className, "olControlNavigationItemActive olButton foo",
+ "active control class name with trailing secondary class name is set to [displayClass]Active");
+ t.eq(zbControl.panel_div.className, "bar olControlZoomBoxItemInactive olButton",
+ "inactive control class name with preceding secondary class name is set to [displayClass]Inactive");
+
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Permalink.html b/misc/openlayers/tests/Control/Permalink.html
new file mode 100644
index 0000000..0b729da
--- /dev/null
+++ b/misc/openlayers/tests/Control/Permalink.html
@@ -0,0 +1,453 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var map;
+ function test_Control_Permalink_constructor (t) {
+ t.plan(42);
+
+ control = new OpenLayers.Control.Permalink();
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, document.location.href, "base is correct");
+ t.ok(!control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink('permalink', 'test.html');
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, 'test.html', "base is correct");
+ t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object");
+ t.ok(!control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink('permalink');
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, document.location.href, "base is correct");
+ t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object");
+ t.ok(!control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink(OpenLayers.Util.getElement('permalink'));
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, document.location.href, "base is correct");
+ t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object");
+ t.ok(!control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink({anchor: true});
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, document.location.href, "base is correct");
+ t.ok(control.element == null, "element is null");
+ t.ok(control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink({anchor: false});
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, document.location.href, "base is correct");
+ t.ok(!control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink({});
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, document.location.href, "base is correct");
+ t.ok(!control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink({element: 'permalink', base: 'test.html'});
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, 'test.html', "base is correct");
+ t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object");
+ t.ok(!control.anchor, "anchor is correct");
+ control.destroy();
+
+ control = new OpenLayers.Control.Permalink({element: 'permalink', base: 'test.html', anchor: true});
+ t.ok(control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object");
+ t.eq(control.displayClass, "olControlPermalink", "displayClass is correct");
+ t.eq(control.base, 'test.html', "base is correct");
+ t.ok(OpenLayers.Util.isElement(control.element), "element is a dom object");
+ t.ok(control.anchor, "anchor is correct");
+ control.destroy();
+ }
+ function test_Control_Permalink_uncentered (t) {
+ t.plan( 1 );
+
+ control = new OpenLayers.Control.Permalink('permalink');
+ map = new OpenLayers.Map('map');
+ map.addControl(control);
+ map.events.triggerEvent("changelayer", {});
+ t.ok(true, "permalink didn't bomb out.");
+ map.destroy();
+ }
+ function test_Control_Permalink_initwithelem (t) {
+ t.plan( 1 );
+
+ control = new OpenLayers.Control.Permalink(OpenLayers.Util.getElement('permalink'));
+ t.ok(true, "If the above line doesn't throw an error, we're safe.");
+ control.destroy();
+ }
+ function test_Control_Permalink_updateLinks (t) {
+ t.plan( 3 );
+
+ control = new OpenLayers.Control.Permalink('permalink');
+ t.ok( control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, {'isBaseLayer': false});
+ map.addLayer(layer);
+ layer.setVisibility(true);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+"?zoom=2&lat=0&lon=1.75781&layers=BT"), 'pan sets permalink');
+
+ map.layers[1].setVisibility(false);
+
+ t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+"?zoom=2&lat=0&lon=1.75781&layers=BF"), 'setVisibility sets permalink');
+ map.destroy();
+ }
+ function test_Control_Permalink_updateLinksBase (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html" );
+ t.ok( control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base");
+ map.destroy();
+ }
+ function test_Control_Permalink_noElement (t) {
+ t.plan( 2 );
+ control = new OpenLayers.Control.Permalink( );
+ t.ok( control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map');
+ map.addControl(control);
+ t.eq(map.controls[4].div.firstChild.nodeName, "A", "Permalink control creates div with 'a' inside." );
+ map.destroy();
+ }
+ function test_Control_Permalink_base_with_query (t) {
+ t.plan( 3 );
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html?foo=bar" );
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://example.com" );
+ map.addLayer(layer);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html?foo=bar&zoom=2&lat=0&lon=1.75781&layers=B';
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and querystring");
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html?foo=bar&" );
+ map.addControl(control);
+ map.pan(0, 0, {animate:false});
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and querystring ending with '&'");
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html?" );
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ map.pan(-5, 0, {animate:false});
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and querystring ending with '?'");
+ map.destroy();
+ }
+
+ function test_Control_Permalink_base_with_anchor (t) {
+ t.plan( 4 );
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html#foo" );
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://example.com" );
+ map.addLayer(layer);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B#foo';
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and anchor");
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html#" );
+ map.addControl(control);
+ map.pan(0, 0, {animate:false});
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B#';
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and an empty anchor");
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html?foo=bar#test" );
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html?foo=bar&zoom=2&lat=0&lon=1.75781&layers=B#test';
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ map.pan(-5, 0, {animate:false});
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base, querystring and an anchor");
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html#foo", {anchor : true} );
+ map.addControl(control);
+ map.pan(0, 0, {animate:false});
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html#zoom=2&lat=0&lon=1.75781&layers=B';
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with base and an empty anchor");
+ }
+
+ function test_Control_Permalink_nonRepeating (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.Permalink('permalink', "./edit.html?zoom=3" );
+ t.ok( control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';
+ t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, "Panning sets permalink with existing zoom in base");
+ map.destroy();
+ }
+
+ function test_Control_Permalink_customized(t) {
+ t.plan(2);
+
+ var argParserClass = OpenLayers.Class(OpenLayers.Control.ArgParser, {
+ CLASS_NAME: "CustomArgParser"
+ });
+
+ control = new OpenLayers.Control.Permalink(null, "./edit.html", {
+ argParserClass: argParserClass,
+ createParams: function(center, zoom, layers) {
+ var params = OpenLayers.Control.Permalink.prototype.createParams.apply(control, arguments);
+ params.customParam = "foo";
+ return params;
+ }
+ });
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+
+ t.eq(this.map.controls[this.map.controls.length-1].CLASS_NAME, "CustomArgParser", "Custom ArgParser added correctly.");
+ t.eq(control.div.firstChild.getAttribute("href"), "./edit.html?zoom=2&lat=0&lon=1.75781&layers=B&customParam=foo", "Custom parameter encoded correctly.");
+ map.destroy();
+ }
+
+ function test_Control_Permalink_createParams(t) {
+ t.plan(18);
+
+ var baseLayer = { 'isBaseLayer': true };
+
+ var m = {
+ 'getCenter': function() { return null; }
+ };
+
+ var pl = {
+ 'map': m,
+ 'base': {}
+ };
+
+ old_getParameters = OpenLayers.Util.getParameters;
+ OpenLayers.Util.getParameters = function(base) {
+ t.ok(base == pl.base, "correct base sent in to Util.getParameters()");
+ return g_Params;
+ };
+
+ //null center, null map.getCenter()
+ g_Params = {};
+ m.baseLayer = baseLayer;
+ var returnParams = OpenLayers.Control.Permalink.prototype.createParams.apply(pl, []);
+ t.ok(returnParams == g_Params, "correct params returned on null center");
+
+ //valid center, zoom, layers
+ g_Params = { 'test': {} };
+ var center = { 'lon': 1.2345678901, 'lat': 9.8765432109 };
+ var zoom = {};
+ var layers = [
+ { 'isBaseLayer': true },
+ baseLayer,
+ { 'isBaseLayer': false, 'getVisibility': function() { return true; } },
+ { 'isBaseLayer': false, 'getVisibility': function() { return false; } }
+ ];
+ var returnParams = OpenLayers.Control.Permalink.prototype.createParams.apply(pl, [center, zoom, layers]);
+
+ t.ok(returnParams.test == g_Params.test, "correct params returned from Util.getParameters() when valid center, zoom, layers");
+ t.ok(returnParams.zoom == zoom, "params.zoom set correctly when valid center, zoom, layers");
+ t.eq(returnParams.lon, 1.23457, "lon set and rounded correctly when valid center, zoom, layers");
+ t.eq(returnParams.lat, 9.87654, "lat set and rounded correctly when valid center, zoom, layers");
+ t.eq(returnParams.layers, "0BTF", "layers processed correctly when valid center, zoom, layers")
+
+
+ //null center, zoom, layers, with displayProjection
+ g_Params = { 'test': {} };
+ g_Projection = {};
+ m = {
+ 'baseLayer': baseLayer,
+ 'getProjectionObject': function() { return g_Projection; },
+ 'center': { 'lon': {}, 'lat': {} },
+ 'getCenter': function() { return this.center; },
+ 'zoom': {},
+ 'getZoom': function() { return this.zoom; },
+ 'layers': [
+ { 'isBaseLayer': false, 'getVisibility': function() { return true; } },
+ baseLayer,
+ { 'isBaseLayer': false, 'getVisibility': function() { return false; } },
+ { 'isBaseLayer': true }
+ ],
+ 'getLayers': function() { return this.layers; }
+ };
+ pl = {
+ 'base': {},
+ 'map': m,
+ 'displayProjection': {}
+ };
+
+ old_transform = OpenLayers.Projection.transform;
+ OpenLayers.Projection.transform = function(point, projObj, dispProj) {
+ t.ok(point.x = m.center.lon, "correct x value passed into transform");
+ t.ok(point.y = m.center.lat, "correct x value passed into transform");
+ t.ok(projObj == g_Projection, "correct projection object from map passed into transform");
+ t.ok(dispProj == pl.displayProjection, "correct displayProjection from control passed into transform");
+
+ return { 'x': 9.8765432109, 'y': 1.2345678901 };
+ };
+
+ center = zoom = layers = null;
+
+ var returnParams = OpenLayers.Control.Permalink.prototype.createParams.apply(pl, [center, zoom, layers]);
+ t.ok(returnParams.test == g_Params.test, "correct params returned from Util.getParameters() when null center, zoom, layers, with displayProjection");
+ t.ok(returnParams.zoom == m.zoom, "params.zoom set correctly when null center, zoom, layers, with displayProjection");
+ t.eq(returnParams.lon, 9.87654, "lon set, transformed, and rounded correctly when null center, zoom, layers, with displayProjection");
+ t.eq(returnParams.lat, 1.23457, "lat set, transformed, and rounded correctly when null center, zoom, layers, with displayProjection");
+ t.eq(returnParams.layers, "TBF0", "layers processed correctly when null center, zoom, layers, with displayProjection");
+
+ OpenLayers.Util.getParameters = old_getParameters;
+ OpenLayers.Projection.transform = old_transform;
+ }
+ function test_Control_Permalink_Anchor (t) {
+ t.plan(3);
+
+ control = new OpenLayers.Control.Permalink({anchor: true});
+ t.ok( control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, {'isBaseLayer': false});
+ map.addLayer(layer);
+ layer.setVisibility(true);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getParameterString(control.createParams()), "zoom=2&lat=0&lon=1.75781&layers=BT"), 'pan sets permalink');
+
+ map.layers[1].setVisibility(false);
+ t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getParameterString(control.createParams()), "zoom=2&lat=0&lon=1.75781&layers=BF"), 'setVisibility sets permalink');
+ map.destroy();
+ }
+
+ function test_Control_Permalink_AnchorBaseElement (t) {
+ t.plan(3);
+
+ control = new OpenLayers.Control.Permalink('permalink', document.location.href, {anchor: true});
+ t.ok( control instanceof OpenLayers.Control.Permalink, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map');
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, {'isBaseLayer': false});
+ map.addLayer(layer);
+ layer.setVisibility(true);
+ if (!map.getCenter()) map.zoomToMaxExtent();
+ map.addControl(control);
+ map.pan(5, 0, {animate:false});
+ t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+"#zoom=2&lat=0&lon=1.75781&layers=BT"), 'pan sets permalink');
+
+ map.layers[1].setVisibility(false);
+ t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+"#zoom=2&lat=0&lon=1.75781&layers=BF"), 'setVisibility sets permalink');
+ map.destroy();
+ }
+
+ function test_center_from_map(t) {
+ t.plan(7);
+
+ var previous = window.location.hash;
+ window.location.hash = "";
+
+ var err;
+ try {
+ var map = new OpenLayers.Map({
+ layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
+ controls: [
+ new OpenLayers.Control.Permalink({anchor: true})
+ ],
+ center: [1, 2],
+ zoom: 3
+ });
+ } catch (e) {
+ err = e;
+ }
+ if (err) {
+ t.fail("Map construction failure: " + err.message);
+ } else {
+ t.ok(true, "Map construction works");
+ }
+
+ // confirm that map center is correctly set
+ var center = map.getCenter();
+ t.eq(center.lon, 1, "map x");
+ t.eq(center.lat, 2, "map y")
+ t.eq(map.getZoom(), 3, "map z");
+
+ // confirm that location from map options has been added to url
+ var params = OpenLayers.Util.getParameters(window.location.hash.replace("#", "?"));
+ t.eq(params.lon, "1", "url x");
+ t.eq(params.lat, "2", "url y");
+ t.eq(params.zoom, "3", "url z");
+
+ map.destroy();
+ window.location.hash = previous;
+ }
+
+ function test_center_from_url(t) {
+ t.plan(6);
+
+ // In cases where the location is specified in the URL and given in
+ // the map options, we respect the location in the URL.
+ var previous = window.location.hash;
+ window.location.hash = "#zoom=6&lat=5&lon=4&layers=B"
+
+ var map = new OpenLayers.Map({
+ layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
+ controls: [new OpenLayers.Control.Permalink({anchor: true})],
+ center: [0, 0],
+ zoom: 0
+ });
+
+ // confirm that map center is correctly set
+ var center = map.getCenter();
+ t.eq(center.lon, 4, "map x");
+ t.eq(center.lat, 5, "map y")
+ t.eq(map.getZoom(), 6, "map z");
+
+ var params = OpenLayers.Util.getParameters(window.location.hash.replace("#", "?"));
+ t.eq(params.lon, "4", "x set");
+ t.eq(params.lat, "5", "y set");
+ t.eq(params.zoom, "6", "z set");
+
+ map.destroy();
+ window.location.hash = previous;
+ }
+
+ </script>
+</head>
+<body>
+ <a id="permalink" href="">Permalink</a> <br />
+ <a id="edit_permalink" href="">Edit</a> <br />
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/PinchZoom.html b/misc/openlayers/tests/Control/PinchZoom.html
new file mode 100644
index 0000000..22db6a5
--- /dev/null
+++ b/misc/openlayers/tests/Control/PinchZoom.html
@@ -0,0 +1,134 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_constructor(t) {
+ t.plan(2);
+ var control = new OpenLayers.Control.PinchZoom();
+ t.ok(control instanceof OpenLayers.Control.PinchZoom, "got an instance");
+ t.ok(control.handler instanceof OpenLayers.Handler.Pinch, "control has pinch handler");
+ control.destroy();
+ }
+
+ function test_destroy(t) {
+ t.plan(1);
+ var control = new OpenLayers.Control.PinchZoom();
+ control.destroy();
+ t.ok(!control.handler, "handler destroyed");
+ }
+
+ function test_activate(t) {
+ t.plan(3);
+ var control = new OpenLayers.Control.PinchZoom();
+ t.ok(!control.active, "control not activated after construction");
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ controls: [control]
+ });
+ t.ok(control.active, "control activated after being added to the map");
+
+ control.deactivate();
+ t.ok(!control.active, "control deactivated");
+
+ map.destroy();
+ }
+
+ function test_pinchMove(t) {
+
+ var control = new OpenLayers.Control.PinchZoom();
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ controls: [control]
+ });
+
+ var log = [];
+ map.applyTransform = function(x, y, scale) {
+ log.push([x, y, scale]);
+ }
+
+ map.layerContainerOriginPx = {
+ x: -50, y: -50
+ };
+
+ control.pinchOrigin = {
+ x: 100, y: 50
+ };
+
+ var cases = [
+ {x: 100, y: 60, scale: 1, transform: [-50, -40, 1]},
+ {x: 150, y: 60, scale: 1, transform: [0, -40, 1]},
+ {x: 150, y: 60, scale: 2, transform: [-150, -140, 2]},
+ {x: 50, y: 20, scale: 2.5, transform: [-325, -230, 2.5]},
+ {x: 150, y: 60, scale: 2, transform: [-150, -140, 2]},
+ {x: 50, y: 20, scale: 0.25, transform: [13, -5, 0.25]}
+ ];
+
+ var len = cases.length;
+ t.plan(len*2);
+
+ var c;
+ for (var i=0; i<len; ++i) {
+ c = cases[i];
+ control.pinchMove({xy: {x: c.x, y: c.y}}, {scale: c.scale});
+ t.eq(log.length, i+1, i + " called once");
+ t.eq(log[i], c.transform, i + " correct transform");
+ }
+
+ }
+
+ function test_pinchMove_preservecenter(t) {
+
+ var control = new OpenLayers.Control.PinchZoom({
+ preserveCenter: true
+ });
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ controls: [control],
+ layers: [new OpenLayers.Layer('fake', {isBaseLayer: true})]
+ });
+ map.zoomToMaxExtent();
+
+ var centerPx = map.getPixelFromLonLat(map.getCenter());
+
+ control.pinchStart = function(evt, pinchData) {
+ t.eq(map.layerContainerOriginPx, {x: 0, y: 0}, "center preserved");
+ t.eq(map.getPixelFromLonLat(map.getCenter()), centerPx, "center preserved");
+ }
+
+ control.pinchStart(null);
+
+ var log = [];
+ map.applyTransform = function(x, y, scale) {
+ log.push([x, y, scale]);
+ }
+ control.pinchOrigin = map.getPixelFromLonLat(map.getCenter());
+
+ var cases = [
+ {scale: 1, transform: [0, 0, 1]},
+ {scale: 2, transform: [-128, -128, 2]},
+ {scale: 2.5, transform: [-192, -192, 2.5]},
+ {scale: 0.25, transform: [96, 96, 0.25]}
+ ];
+
+ var len = cases.length;
+ t.plan(2 + len*2);
+
+ var c;
+ for (var i=0; i<len; ++i) {
+ c = cases[i];
+ control.pinchMove(null, {scale: c.scale});
+ t.eq(log.length, i+1, i + " called once");
+ t.eq(log[i], c.transform, i + " correct transform");
+ }
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 256px; height: 256px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/SLDSelect.html b/misc/openlayers/tests/Control/SLDSelect.html
new file mode 100644
index 0000000..03b871c
--- /dev/null
+++ b/misc/openlayers/tests/Control/SLDSelect.html
@@ -0,0 +1,239 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(11);
+ var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.Click);
+ t.eq(control.handler instanceof OpenLayers.Handler.Click, true, "Click handler created");
+ t.ok(control.handler.callbacks["click"] === control.select, "Click callback correctly set");
+ control.destroy();
+ control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon, {handlerOptions: {irregular: true}});
+ t.eq(control.handler instanceof OpenLayers.Handler.RegularPolygon, true, "RegularPolygon handler created");
+ t.eq(control.handler.irregular, true, "RegularPolygon handler is irregular");
+ t.eq(control.handler.persist, false, "RegularPolygon handler is not persistant");
+ t.ok(control.handler.callbacks["done"] === control.select, "Done callback correctly set");
+ control.destroy();
+ control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.Polygon);
+ t.eq(control.handler instanceof OpenLayers.Handler.Polygon, true, "Polygon handler created");
+ t.ok(control.handler.callbacks["done"] === control.select, "Done callback correctly set");
+ control.destroy();
+ control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.Path);
+ t.eq(control.handler instanceof OpenLayers.Handler.Path, true, "Path handler created");
+ t.ok(control.handler.callbacks["done"] === control.select, "Done callback correctly set");
+ control.destroy();
+ var layer = new OpenLayers.Layer.WMS('Foo', 'http://foo', {LAYERS: 'A'});
+ control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon, {layers: [layer]});
+ t.eq(control.layers.length, 1, "Layers property correctly set");
+ control.destroy();
+ layer.destroy();
+ }
+
+ function test_select(t) {
+ t.plan(9);
+ var parser = new OpenLayers.Format.WFSDescribeFeatureType();
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('Foo', 'http://foo', {LAYERS: 'AAA64'});
+ map.addLayer(layer);
+
+ var text =
+ '<?xml version="1.0" encoding="ISO-8859-1" ?>' +
+ '<schema' +
+ ' targetNamespace="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:rws="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:ogc="http://www.opengis.net/ogc"' +
+ ' xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' elementFormDefault="qualified" version="0.1" >' +
+ ' <import namespace="http://www.opengis.net/gml"' +
+ ' schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd" />' +
+ ' <element name="AAA64" ' +
+ ' type="rws:AAA64Type" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="AAA64Type">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiLineStringPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' <element name="OBJECTID" type="string"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ '</schema>';
+
+ OpenLayers.Control.SLDSelect.prototype.wfsCache[layer.id] = parser.read(text);
+ var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon,
+ {layers: [layer], clearOnDeactivate: true, handlerOptions: {irregular: true} });
+
+ var testEvent = function(evt) {
+ t.eq(evt.filters.length, 1, "Event has a filters array set");
+ t.eq(evt.filters[0] instanceof OpenLayers.Filter.Spatial, true, "Spatial filter has been created");
+ };
+
+ control.events.register("selected", this, testEvent);
+ map.addControl(control);
+ var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(
+ new OpenLayers.Geometry.Point(0, 0), 5, 4);
+ control.select(geometry);
+ control.events.unregister("selected", this, testEvent);
+ t.eq(map.layers.length, 2, "Selection layer has been created and added to the map");
+ t.eq(map.layers[1] instanceof OpenLayers.Layer.WMS, true, "A WMS layer has been created as the selection layer");
+ t.eq(map.layers[1].tileOptions.maxGetUrlLength, 2048, "Selection layer will automatically switch to HTTP Post if content gets longer than 2048");
+ var expected_sld = '<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><sld:NamedLayer><sld:Name>AAA64</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:coordinates decimal="." cs="," ts=" ">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:LineSymbolizer><sld:Stroke><sld:CssParameter name="stroke">#FF0000</sld:CssParameter><sld:CssParameter name="stroke-width">2</sld:CssParameter></sld:Stroke></sld:LineSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';
+
+ t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, "SLD generated correctly");
+
+ var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(
+ new OpenLayers.Geometry.Point(0, 0), 7, 4);
+ control.select(geometry);
+ t.eq(map.layers.length, 2, "Selection layer is reused when new selection is performed");
+
+ map.layers[0].setVisibility(false);
+ t.eq(map.layers[1].getVisibility(), false, "Visibility of selection layer is synchronized with source layer");
+ // activate would issue a SLD WMS DescribeLayer request and we are bypassing this here
+ control.active = true;
+ control.deactivate();
+ t.eq(map.layers.length, 1, "Selection layer is removed on deactive if clearOnDeactivate is set to true");
+ map.destroy();
+ }
+
+ function test_filterModificationOnSelected(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.WFSDescribeFeatureType();
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('Foo', 'http://foo', {LAYERS: 'AAA64'});
+ map.addLayer(layer);
+
+ var text =
+ '<?xml version="1.0" encoding="ISO-8859-1" ?>' +
+ '<schema' +
+ ' targetNamespace="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:rws="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:ogc="http://www.opengis.net/ogc"' +
+ ' xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' elementFormDefault="qualified" version="0.1" >' +
+ ' <import namespace="http://www.opengis.net/gml"' +
+ ' schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd" />' +
+ ' <element name="AAA64" ' +
+ ' type="rws:AAA64Type" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="AAA64Type">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiLineStringPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' <element name="OBJECTID" type="string"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ '</schema>';
+
+ OpenLayers.Control.SLDSelect.prototype.wfsCache[layer.id] = parser.read(text);
+ var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon,
+ {layers: [layer], clearOnDeactivate: true, handlerOptions: {irregular: true} });
+
+ var testEvent = function(evt) {
+ // manipulate filter
+ var bbox = OpenLayers.Bounds.fromString('1,2,3,4');
+ evt.filters[0].value = bbox;
+ };
+ control.events.register("selected", this, testEvent);
+ map.addControl(control);
+ var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(
+ new OpenLayers.Geometry.Point(0, 0), 5, 4);
+ control.select(geometry);
+ control.events.unregister("selected", this, testEvent);
+
+ var expected_sld = '<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><sld:NamedLayer><sld:Name>AAA64</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:coordinates decimal="." cs="," ts=" ">1,2 3,4</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:LineSymbolizer><sld:Stroke><sld:CssParameter name="stroke">#FF0000</sld:CssParameter><sld:CssParameter name="stroke-width">2</sld:CssParameter></sld:Stroke></sld:LineSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';
+
+ t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, "Filter / SLD manipulated in select-callback correctly");
+
+ }
+
+ function test_multiselect(t) {
+ t.plan(2);
+
+ var parser = new OpenLayers.Format.WFSDescribeFeatureType();
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('Multi', 'http://foo', {LAYERS: 'KGNAT.VKUNSTWERK,KGNAT.LKUNSTWERK,KGNAT.PKUNSTWERK'});
+ map.addLayer(layer);
+
+ var text =
+ '<?xml version="1.0" encoding="ISO-8859-1" ?>' +
+ '<schema' +
+ ' targetNamespace="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:rws="http://mapserver.gis.umn.edu/mapserver" ' +
+ ' xmlns:ogc="http://www.opengis.net/ogc"' +
+ ' xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns="http://www.w3.org/2001/XMLSchema"' +
+ ' xmlns:gml="http://www.opengis.net/gml"' +
+ ' elementFormDefault="qualified" version="0.1" >' +
+ ' <import namespace="http://www.opengis.net/gml"' +
+ ' schemaLocation="http://schemas.opengis.net/gml/2.1.2/feature.xsd" />' +
+ ' <element name="KGNAT.VKUNSTWERK" ' +
+ ' type="rws:KGNAT.VKUNSTWERKType" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="KGNAT.VKUNSTWERKType">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiPolygonPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ ' <element name="KGNAT.LKUNSTWERK" ' +
+ ' type="rws:KGNAT.LKUNSTWERKType" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="KGNAT.LKUNSTWERKType">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiLineStringPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ ' <element name="KGNAT.PKUNSTWERK" ' +
+ ' type="rws:KGNAT.PKUNSTWERKType" ' +
+ ' substitutionGroup="gml:_Feature" />' +
+ ' <complexType name="KGNAT.PKUNSTWERKType">' +
+ ' <complexContent>' +
+ ' <extension base="gml:AbstractFeatureType">' +
+ ' <sequence>' +
+ ' <element name="geometry" type="gml:MultiPointPropertyType" minOccurs="0" maxOccurs="1"/>' +
+ ' </sequence>' +
+ ' </extension>' +
+ ' </complexContent>' +
+ ' </complexType>' +
+ '</schema>';
+
+ OpenLayers.Control.SLDSelect.prototype.wfsCache[layer.id] = parser.read(text);
+ var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon, {handlerOptions: {irregular: true}, layers: [layer]});
+ var testEvent = function(evt) {
+ t.eq(evt.filters.length, 3, "Event has a filters array set with length tree");
+ };
+ control.events.register("selected", this, testEvent);
+
+ map.addControl(control);
+ var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(
+ new OpenLayers.Geometry.Point(0, 0), 5, 4);
+ control.select(geometry);
+ var expected_sld = '<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" version="1.0.0" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><sld:NamedLayer><sld:Name>KGNAT.VKUNSTWERK</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:coordinates decimal="." cs="," ts=" ">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:PolygonSymbolizer><sld:Fill><sld:CssParameter name="fill">#FF0000</sld:CssParameter></sld:Fill></sld:PolygonSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer><sld:NamedLayer><sld:Name>KGNAT.LKUNSTWERK</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:coordinates decimal="." cs="," ts=" ">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:LineSymbolizer><sld:Stroke><sld:CssParameter name="stroke">#FF0000</sld:CssParameter><sld:CssParameter name="stroke-width">2</sld:CssParameter></sld:Stroke></sld:LineSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer><sld:NamedLayer><sld:Name>KGNAT.PKUNSTWERK</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml="http://www.opengis.net/gml" srsName="EPSG:4326"><gml:coordinates decimal="." cs="," ts=" ">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:PointSymbolizer><sld:Graphic><sld:Mark><sld:WellKnownName>square</sld:WellKnownName><sld:Fill><sld:CssParameter name="fill">#FF0000</sld:CssParameter></sld:Fill><sld:Stroke/></sld:Mark><sld:Size>10</sld:Size></sld:Graphic></sld:PointSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';
+
+ t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, "SLD generated correctly");
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 100px; height: 100px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Scale.html b/misc/openlayers/tests/Control/Scale.html
new file mode 100644
index 0000000..1d43b25
--- /dev/null
+++ b/misc/openlayers/tests/Control/Scale.html
@@ -0,0 +1,54 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ OpenLayers.Lang.setCode('en');
+ var map;
+ function test_Control_Scale_constructor (t) {
+ t.plan( 2 );
+
+ control = new OpenLayers.Control.Scale();
+ t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
+ t.eq( control.displayClass, "olControlScale", "displayClass is correct" );
+ }
+ function test_Control_Scale_initwithelem (t) {
+ t.plan( 1 );
+
+ control = new OpenLayers.Control.Scale(OpenLayers.Util.getElement('scale'));
+ t.ok(true, "If this happens, then we passed. (FF throws an error above otherwise)");
+ }
+ function test_Control_Scale_updateScale (t) {
+ t.plan( 4 );
+
+ control = new OpenLayers.Control.Scale('scale');
+ t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map', {zoomMethod: null});
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.eq(OpenLayers.Util.getElement('scale').innerHTML, "Scale = 1 : 443M", "Scale set by default." );
+ map.zoomIn();
+ t.eq(OpenLayers.Util.getElement('scale').innerHTML, "Scale = 1 : 221M", "Zooming in changes scale" );
+ map.baseLayer.resolutions = [OpenLayers.Util.getResolutionFromScale(110)];
+ map.zoomTo(0);
+ t.eq(OpenLayers.Util.getElement('scale').innerHTML, "Scale = 1 : 110", "Scale of 100 isn't rounded" );
+ }
+ function test_Control_Scale_internalScale (t) {
+ t.plan(2);
+ control = new OpenLayers.Control.Scale();
+ t.ok( control instanceof OpenLayers.Control.Scale, "new OpenLayers.Control returns object" );
+ map = new OpenLayers.Map('map', {zoomMethod: null});
+ layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.eq(control.div.firstChild.innerHTML, "Scale = 1 : 443M", "Internal scale displayed properly.");
+ }
+ </script>
+</head>
+<body>
+ <a id="scale" href="">Scale</a> <br />
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/ScaleLine.html b/misc/openlayers/tests/Control/ScaleLine.html
new file mode 100644
index 0000000..e863fd9
--- /dev/null
+++ b/misc/openlayers/tests/Control/ScaleLine.html
@@ -0,0 +1,187 @@
+<html>
+<head>
+ <script type="text/javascript">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script>
+ <!-- this gmaps key generated for http://openlayers.org/dev/ -->
+ <script src='http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAA9XNhd8q0UdwNC7YSO4YZghSPUCi5aRYVveCcVYxzezM4iaj_gxQ9t-UajFL70jfcpquH5l1IJ-Zyyw'></script>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+ var validkey = (window.location.protocol == "file:") ||
+ (window.location.host == "localhost") ||
+ (window.location.host == "openlayers.org");
+
+ function test_initialize(t) {
+ t.plan(2);
+ var control = new OpenLayers.Control.ScaleLine();
+ t.ok(control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
+ t.eq(control.displayClass, "olControlScaleLine", "displayClass is correct" );
+ control.destroy();
+ }
+
+ function test_initwithelem(t) {
+ t.plan(1);
+ var control = new OpenLayers.Control.ScaleLine({"div":OpenLayers.Util.getElement('ScaleLine')});
+ t.ok(true, "If this happens, then we passed. (FF throws an error above otherwise)");
+ control.destroy();
+ }
+
+ function test_calcDegrees(t) {
+ t.plan(5);
+ var control = new OpenLayers.Control.ScaleLine();
+ t.ok(control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
+ t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
+ t.eq(control.div.firstChild.innerHTML, "10000 km", "top scale has correct text.");
+ t.eq(control.div.lastChild.innerHTML, "5000 mi", "bottom scale has correct text.");
+ map.destroy();
+ }
+
+ function test_calcsOther (t) {
+ t.plan(5);
+ var control = new OpenLayers.Control.ScaleLine();
+ t.ok(control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
+ var map = new OpenLayers.Map('map');
+ map.units = "mi";
+ var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
+ t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
+ t.eq(control.div.firstChild.innerHTML, "100 km", "top scale has correct text.");
+ t.eq(control.div.lastChild.innerHTML, "100 mi", "bottom scale has correct text.");
+ map.destroy();
+ }
+
+ function test_calcMeters (t) {
+ t.plan(5);
+ // this example is taken from the projected-map.html OpenLayers example
+ var lat = 900863;
+ var lon = 235829;
+ var zoom = 6;
+ var map = new OpenLayers.Map( 'map' );
+ var basemap = new OpenLayers.Layer.WMS( "Boston",
+ "http://boston.freemap.in/cgi-bin/mapserv?",
+ {
+ map: '/www/freemap.in/boston/map/gmaps.map',
+ layers: 'border,water,roads,rapid_transit,buildings',
+ format: 'png',
+ transparent: 'off'
+ },
+
+ {
+ maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656),
+ maxResolution: 296985/1024,
+ projection:"EPSG:2805", // Used in WMS/WFS requests.
+ units: "m" // Only neccesary for working with scales.
+ } );
+
+ map.addLayer(basemap);
+ map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);
+ map.addControl(new OpenLayers.Control.LayerSwitcher());
+ var control = new OpenLayers.Control.ScaleLine();
+ t.ok( control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
+ map.addControl(control);
+ t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
+ t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
+ t.eq(control.div.firstChild.innerHTML, "200 m", "top scale has correct text.");
+ t.eq(control.div.lastChild.innerHTML, "1000 ft", "bottom scale has correct text.");
+ map.destroy();
+ }
+
+ function test_useArguments (t) {
+ t.plan(5);
+ var control = new OpenLayers.Control.ScaleLine({topOutUnits: 'dd'} );
+ t.ok( control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.eq(control.div.firstChild.style.visibility, "visible", "top scale is present.");
+ t.eq(control.div.lastChild.style.visibility, "visible", "bottom scale is present.");
+ t.eq(control.div.firstChild.innerHTML, "100 dd", "top scale has correct text.");
+ t.eq(control.div.lastChild.innerHTML, "5000 mi", "bottom scale has correct text.");
+ map.destroy();
+ }
+
+ function test_respectZoom (t) {
+ if(validkey) {
+ t.plan( 4 );
+ } else {
+ t.plan( 3 );
+ }
+ // ok, switch the units we use for zoomed in values. This will test that we're both
+ // correctly respecting all specified parameters and that we're switching to the
+ // "in" units when zoomed in
+ var control = new OpenLayers.Control.ScaleLine({topOutUnits : "mi", bottomOutUnits: "km", topInUnits: 'ft', bottomInUnits: 'm'});
+ t.ok( control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('Test Layer', "http://octo.metacarta.com/cgi-bin/mapserv", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ var widthIsOk = true;
+ for (var i=0; i<map.numZoomLevels && widthIsOk; i++) {
+ map.zoomTo(i);
+ var w1 = parseInt(control.eTop.style.width);
+ var w2 = parseInt(control.eBottom.style.width);
+ widthIsOk = w1 <= control.maxWidth && w2 <= control.maxWidth;
+ }
+ t.ok(widthIsOk, "respects maxWidth at all zoom levels in dd");
+
+ widthIsOk = true;
+ control.maxWidth = 200;
+ for (var i=0; i<map.numZoomLevels && widthIsOk; i++) {
+ map.zoomTo(i);
+ var w1 = parseInt(control.eTop.style.width);
+ var w2 = parseInt(control.eBottom.style.width);
+ widthIsOk = w1 <= control.maxWidth && w2 <= control.maxWidth;
+ }
+ t.ok(widthIsOk, "respects modified maxWidth at all zoom levels in dd");
+
+ if (validkey) {
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.Google('Goog Layer');
+ var control = new OpenLayers.Control.ScaleLine({topOutUnits : "mi", bottomOutUnits: "km", topInUnits: 'ft', bottomInUnits: 'm'});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ var widthIsOk = true;
+ for (var i=0; i<map.numZoomLevels && widthIsOk; i++) {
+ map.zoomTo(i);
+ var w1 = parseInt(control.eTop.style.width);
+ var w2 = parseInt(control.eBottom.style.width);
+ widthIsOk = w1 <= control.maxWidth && w2 <= control.maxWidth;
+ }
+ t.ok(widthIsOk, "respects maxWidth at all zoom levels in m");
+ } else {
+ t.debug_print("Google tests can't be run from " +
+ window.location.host);
+ }
+
+ map.destroy();
+ }
+ function test_ie_oneunit(t) {
+ t.plan(2);
+ var control = new OpenLayers.Control.ScaleLine({bottomOutUnits:'',bottomInUnits:'',maxWidth:150});
+ t.ok(control instanceof OpenLayers.Control.ScaleLine, "new OpenLayers.Control returns object" );
+ var map = new OpenLayers.Map('map');
+ var layer = new OpenLayers.Layer.WMS('Test Layer', "bogus", {});
+ map.addLayer(layer);
+ map.zoomTo(0);
+ map.addControl(control);
+ t.ok(true, "invisible bottom scale doesn't cause scaleline failure (IE only)");
+ map.destroy();
+ }
+ </script>
+</head>
+<body>
+ <a id="ScaleLine" href="">ScaleLine</a> <br/>
+ <div id="map" style="width: 1024px; height: 512px;"/>
+</body>
+</html>
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>
diff --git a/misc/openlayers/tests/Control/Snapping.html b/misc/openlayers/tests/Control/Snapping.html
new file mode 100644
index 0000000..f065f66
--- /dev/null
+++ b/misc/openlayers/tests/Control/Snapping.html
@@ -0,0 +1,448 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+
+ t.plan(5);
+
+ // construct with a single layer
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.Snapping({
+ layer: layer
+ });
+
+ t.ok(control.layer === layer, "[a] source layer properly set");
+ t.eq(control.targets.length, 1, "[a] one target layer");
+ t.ok(control.targets[0].layer === layer, "[a] target set");
+ control.destroy();
+
+ // construct with a different target, default target config
+ var layer2 = new OpenLayers.Layer.Vector();
+ control = new OpenLayers.Control.Snapping({
+ layer: layer,
+ targets: [layer2]
+ });
+
+ t.eq(control.targets.length, 1, "[b] one target layer");
+ t.ok(control.targets[0].layer == layer2, "[b] target set");
+ control.destroy();
+ }
+
+ function test_setLayer(t) {
+
+ t.plan(4);
+
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.Snapping();
+ control.setLayer(layer);
+
+ t.ok(control.layer === layer, "layer properly set");
+
+ // confirm that the control is deactivated and reactivated when setting new layer
+ var log = {
+ activated: 0,
+ deactivated: 0
+ };
+ control.activate = function() {
+ log.activated++;
+ }
+ control.deactivate = function() {
+ log.deactivated++;
+ }
+ control.active = true;
+
+ var layer2 = new OpenLayers.Layer.Vector();
+ control.setLayer(layer2);
+
+ t.eq(log.deactivated, 1, "control deactivated");
+ t.ok(control.layer === layer2, "layer properly reset");
+ t.eq(log.activated, 1, "control reactivated");
+
+ control.destroy();
+ }
+
+ function test_setTargets(t) {
+
+ t.plan(4);
+
+ var layer1 = new OpenLayers.Layer.Vector();
+ var layer2 = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.Snapping();
+
+ var log = {
+ addTarget: [],
+ addTargetLayer: []
+ };
+ control.addTarget = function(target) {
+ log.addTarget.push(target);
+ };
+ control.addTargetLayer = function(target) {
+ log.addTargetLayer.push(target);
+ };
+
+ control.setTargets([layer1, {layer: layer2}]);
+
+ t.eq(log.addTargetLayer.length, 1, "setTargetLayer called once");
+ t.ok(log.addTargetLayer[0] === layer1, "setTargetLayer called with layer1");
+ t.eq(log.addTarget.length, 1, "setTarget called once");
+ t.ok(log.addTarget[0].layer === layer2, "setTarget called with layer2");
+
+ control.destroy();
+ }
+
+ function test_addTarget(t) {
+ t.plan(5);
+
+ var layer = new OpenLayers.Layer.Vector();
+
+ var control = new OpenLayers.Control.Snapping({
+ defaults: {
+ nodeTolerance: 30,
+ tolerance: 40
+ }
+ });
+
+ var log = {};
+ control.addTarget({layer: layer});
+
+ t.eq(control.targets.length, 1, "single target");
+ var target = control.targets[0];
+ t.ok(target.layer === layer, "correct target layer");
+ t.eq(target.nodeTolerance, 30, "correct nodeTolerance");
+ t.eq(target.edgeTolerance, 40, "correct edgeTolerance");
+ t.eq(target.vertexTolerance, 40, "correct vertexTolerance");
+
+ control.destroy();
+ }
+
+ function test_removeTargetLayer(t) {
+
+ t.plan(3);
+
+ var layer1 = new OpenLayers.Layer.Vector();
+ var layer2 = new OpenLayers.Layer.Vector();
+ var layer3 = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.Snapping({
+ targets: [layer1, layer2, layer3]
+ });
+
+ control.removeTargetLayer(layer2);
+
+ t.eq(control.targets.length, 2, "correct targets length");
+ t.ok(control.targets[0].layer === layer1, "layer1 remains");
+ t.ok(control.targets[1].layer === layer3, "layer3 remains");
+
+ control.destroy();
+
+ }
+
+ function test_activate(t) {
+
+ t.plan(4);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.Snapping({
+ layer: layer
+ });
+
+ control.activate();
+
+ t.eq(layer.events.listeners.sketchmodified.length, 1, "one sketchmodified listener");
+ t.ok(layer.events.listeners.sketchmodified[0].func === control.onSketchModified, "correct sketchmodified listener");
+ t.eq(layer.events.listeners.vertexmodified.length, 1, "one vertexmodified listener");
+ t.ok(layer.events.listeners.vertexmodified[0].func === control.onVertexModified, "correct vertexmodified listener");
+
+ control.destroy();
+ }
+
+ function test_deactivate(t) {
+
+ t.plan(2);
+ var layer = new OpenLayers.Layer.Vector();
+ var control = new OpenLayers.Control.Snapping({
+ layer: layer
+ });
+
+ control.activate();
+ control.deactivate();
+
+ t.eq(layer.events.listeners.sketchmodified.length, 0, "no sketchmodified listeners");
+ t.eq(layer.events.listeners.vertexmodified.length, 0, "no vertexmodified listeners");
+
+ control.destroy();
+ }
+
+ function test_resolution_limits(t) {
+ t.plan(7);
+
+ var map = new OpenLayers.Map("map", {
+ resolutions: [1],
+ maxExtent: new OpenLayers.Bounds(0, 0, 100, 100)
+ });
+
+ var layer = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true
+ });
+ layer.addFeatures([
+ new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+ "POINT(50 50)"
+ ))
+ ]);
+
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ var control = new OpenLayers.Control.Snapping({layer: layer});
+
+ var result;
+ var loc = new OpenLayers.Geometry.Point(49, 49);
+
+ // 1) test a target with no constraints
+ control.setTargets([{layer: layer}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result !== null, "1) target is eligible");
+
+ // 2) test a target with minResolution < map.resolution
+ control.setTargets([{layer: layer, minResolution: 0.5}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result !== null, "2) target is eligible");
+
+ // 3) test a target with minResolution === map.resolution
+ control.setTargets([{layer: layer, minResolution: 1}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result !== null, "3) target is eligible");
+
+ // 4) test a target with minResolution > map.resolution
+ control.setTargets([{layer: layer, minResolution: 1.5}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result === null, "4) target is not eligible");
+
+ // 5) test a target with maxResolution < map.resolution
+ control.setTargets([{layer: layer, maxResolution: 0.5}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result === null, "5) target is not eligible");
+
+ // 6) test a target with maxResolution === map.resolution
+ control.setTargets([{layer: layer, maxResolution: 1}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result === null, "6) target is not eligible");
+
+ // 7) test a target with maxResolution > map.resolution
+ control.setTargets([{layer: layer, maxResolution: 1.5}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result !== null, "7) target is eligible");
+
+ map.destroy();
+
+ }
+
+ function test_filter(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map("map", {
+ resolutions: [1],
+ maxExtent: new OpenLayers.Bounds(0, 0, 100, 100)
+ });
+
+ var layer1 = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true
+ });
+ var f1 = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+ "LINESTRING(0 0, 10 10, 20 20, 30 30)"
+ ), {foo: 'bar'});
+ f1.fid = "FID1";
+ var f2 = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+ "LINESTRING(11 10, 20 10, 30 10)"
+ ), {foo: 'bar'});
+ f2.fid = "FID2";
+ layer1.addFeatures([f1, f2]);
+ map.addLayers([layer1]);
+ map.zoomToMaxExtent();
+
+ var control = new OpenLayers.Control.Snapping({
+ layer: layer1,
+ targets: [layer1],
+ defaults: {tolerance: 4}
+ });
+ control.activate();
+
+ var result;
+ var loc = new OpenLayers.Geometry.Point(1, 1);
+
+ control.setTargets([{layer: layer1}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result !== null, "target is eligible without a filter set");
+ var filter = new OpenLayers.Filter.Logical({
+ type: OpenLayers.Filter.Logical.NOT,
+ filters: [
+ new OpenLayers.Filter.FeatureId({fids: ["FID1", "FID2"]})
+ ]
+ });
+ control.setTargets([{layer: layer1, filter: filter}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result === null, "target is not eligible with a filter set which excludes the target's features");
+ filter = new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, value: 'bar', property: 'foo'});
+ control.setTargets([{layer: layer1, filter: filter}]);
+ result = control.testTarget(control.targets[0], loc);
+ t.ok(result === null, "target is not eligible with a filter set which excludes the target's features using a comparison filter");
+ }
+
+ function test_snapping(t) {
+
+ t.plan(46);
+
+ var map = new OpenLayers.Map("map", {
+ resolutions: [1],
+ maxExtent: new OpenLayers.Bounds(0, 0, 100, 100)
+ });
+
+ var layer1 = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true
+ });
+ layer1.addFeatures([
+ new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+ "LINESTRING(0 0, 10 10, 20 20, 30 30)"
+ )),
+ new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+ "LINESTRING(11 10, 20 10, 30 10)"
+ ))
+ ]);
+
+ var layer2 = new OpenLayers.Layer.Vector();
+ layer2.addFeatures([
+ new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+ "LINESTRING(10 10, 20 20, 30 30)"
+ )),
+ new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(
+ "LINESTRING(21 10, 20 20, 20 30)"
+ ))
+ ]);
+
+ map.addLayers([layer1, layer2]);
+ map.zoomToMaxExtent();
+
+ var control = new OpenLayers.Control.Snapping({
+ layer: layer1,
+ targets: [layer1, layer2],
+ defaults: {tolerance: 4}
+ });
+ control.activate();
+ map.addControl(control);
+
+ // log beforesnap, snap, and unsnap events
+ var events = [];
+ function listener(event) {
+ events.push(event);
+ }
+ control.events.on({
+ beforesnap: listener,
+ snap: listener,
+ unsnap: listener
+ });
+
+ // create a vertex and a convenience method for mocking the drag
+ var vertex = new OpenLayers.Geometry.Point(-100, -100);
+ function drag(x, y) {
+ var px = map.getPixelFromLonLat(new OpenLayers.LonLat(x, y));
+ layer1.events.triggerEvent("vertexmodified", {
+ vertex: vertex, pixel: px
+ });
+ }
+
+ // mock up drag far from features
+ drag(-100, -100);
+ t.eq(events.length, 0, "no snapping");
+
+ // mock up drag near first node of first feature
+ drag(0, 1);
+ t.eq(events.length, 2, "[a] 2 events triggered");
+ t.eq(events[0].type, "beforesnap", "[a] beforesnap triggered");
+ t.eq(events[0].snapType, "node", "[a] beforesnap triggered for node");
+ t.ok(events[0].point === vertex, "[a] beforesnap triggered with vertex");
+ t.eq(events[0].x, 0, "[a] beforesnap triggered correct x");
+ t.eq(events[0].y, 0, "[a] beforesnap triggered with correct y");
+ t.eq(events[1].type, "snap", "[a] snap triggered");
+ t.eq(events[1].snapType, "node", "[a] snap triggered for node");
+ t.ok(events[1].point === vertex, "[a] snap triggered with point");
+ t.eq(events[1].distance, 1, "[a] snap triggered correct distance");
+ t.ok(events[1].layer === layer1, "[a] snap triggered with correct target layer");
+ t.eq(vertex.x, 0, "[a] vertex x modified");
+ t.eq(vertex.y, 0, "[a] vertex y modified");
+ events = [];
+
+ // mock up drag that unsnaps
+ drag(-100, -50);
+ t.eq(events.length, 1, "[b] 1 event triggered");
+ t.eq(events[0].type, "unsnap", "[b] unsnap triggered");
+ t.ok(events[0].point === vertex, "[b] unsnap triggered with vertex");
+ t.eq(vertex.x, -100, "[b] vertex x unsnapped");
+ t.eq(vertex.y, -50, "[b] vertex y unsnapped");
+ events = [];
+
+ // drag near node of second feature in first layer to demonstrate precedence of node snapping
+ drag(9, 10);
+ t.eq(events.length, 2, "[c] 2 events triggered");
+ t.eq(events[0].type, "beforesnap", "[c] beforesnap triggered first");
+ t.eq(events[1].type, "snap", "[c] snap triggered second");
+ t.eq(events[1].snapType, "node", "[c] snap to node");
+ // unsnap & reset
+ drag(-100, -50);
+ events = [];
+
+ // drag near node of second feature in second layer to demonstrate greedy property
+ // with greedy true (default) the best target from the first layer with eligible targets is used
+ drag(22, 10);
+ t.eq(events.length, 2, "[d] 2 events triggered");
+ t.eq(events[1].type, "snap", "[d] snap triggered second");
+ t.eq(events[1].snapType, "vertex", "[d] snap to vertex");
+ t.ok(events[1].layer === layer1, "[d] snap to vertex in first layer");
+ t.eq(vertex.x, 20, "[d] vertex x modified");
+ t.eq(vertex.y, 10, "[d] vertex y modified");
+ // unsnap & reset
+ drag(-100, -50);
+ events = [];
+
+ // do the same drag but with greedy false - this will look for best target in all layers
+ control.greedy = false;
+ drag(22, 10);
+ t.eq(events.length, 2, "[d] 2 events triggered");
+ t.eq(events[1].type, "snap", "[d] snap triggered second");
+ t.eq(events[1].snapType, "node", "[d] snap to node");
+ t.ok(events[1].layer === layer2, "[d] snap to node in second layer");
+ // unsnap & reset
+ drag(-100, -50);
+ control.greedy = true;
+ events = [];
+
+ // demonstrate snapping on sketchstarted
+ var p = new OpenLayers.Geometry.Point(0, 1);
+ layer1.events.triggerEvent("sketchstarted", {
+ vertex: p,
+ feature: new OpenLayers.Feature.Vector(p)
+ });
+ t.eq(events.length, 2, "[sketchstarted] 2 events triggered");
+ t.eq(events[0].type, "beforesnap", "[sketchstarted] beforesnap triggered");
+ t.eq(events[0].snapType, "node", "[sketchstarted] beforesnap triggered for node");
+ t.ok(events[0].point === p, "[sketchstarted] beforesnap triggered with vertex");
+ t.eq(events[0].x, 0, "[sketchstarted] beforesnap triggered correct x");
+ t.eq(events[0].y, 0, "[sketchstarted] beforesnap triggered with correct y");
+ t.eq(events[1].type, "snap", "[sketchstarted] snap triggered");
+ t.eq(events[1].snapType, "node", "[sketchstarted] snap triggered for node");
+ t.ok(events[1].point === p, "[sketchstarted] snap triggered with point");
+ t.eq(events[1].distance, 1, "[sketchstarted] snap triggered correct distance");
+ t.ok(events[1].layer === layer1, "[sketchstarted] snap triggered with correct target layer");
+ t.eq(p.x, 0, "[sketchstarted] vertex x modified");
+ t.eq(p.y, 0, "[sketchstarted] vertex y modified");
+ // reset
+ events = [];
+
+ map.destroy();
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 100px; height: 100px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Split.html b/misc/openlayers/tests/Control/Split.html
new file mode 100644
index 0000000..e3a6eac
--- /dev/null
+++ b/misc/openlayers/tests/Control/Split.html
@@ -0,0 +1,319 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+
+ t.plan(4);
+
+ var layer = new OpenLayers.Layer.Vector();
+ var control;
+
+ // construct with nothing
+ control = new OpenLayers.Control.Split();
+ t.ok(control instanceof OpenLayers.Control, "instanceof OpenLayers.Control");
+ t.ok(control instanceof OpenLayers.Control, "instanceof OpenLayers.Control.Split")
+ control.destroy();
+
+ // construct with a single target layer
+ control = new OpenLayers.Control.Split({
+ layer: layer
+ });
+ t.ok(control.layer === layer, "target layer properly set");
+ control.destroy();
+
+ // construct with same target and source
+ control = new OpenLayers.Control.Split({
+ layer: layer,
+ source: layer
+ });
+ t.ok(control.source === layer, "source layer properly set");
+ control.destroy();
+ }
+
+ function test_setSource(t) {
+ t.plan(5);
+
+ var layer1 = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+ var layer2 = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+
+ var control = new OpenLayers.Control.Split({layer: layer1});
+
+ var map = new OpenLayers.Map("map");
+ map.addLayers([layer1, layer2]);
+ map.zoomToMaxExtent();
+ map.addControl(control);
+ control.activate();
+
+ // confirm sketch hander created
+ t.ok(control.handler, "sketch handler created");
+ t.eq(control.handler.active, true, "sketch handler active");
+
+ control.setSource(layer1);
+ t.ok(control.source === layer1, "layer1 properly set");
+ t.ok(!control.handler, "no more sketch handler");
+
+ // activate and switch to new source layer
+ control.setSource(layer2);
+ t.ok(control.source === layer2, "layer2 properly set");
+
+ map.destroy();
+
+ }
+
+ function test_activate(t) {
+ t.plan(8);
+
+ var layer = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+ var control = new OpenLayers.Control.Split({layer: layer});
+ var map = new OpenLayers.Map("map");
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+ map.addControl(control);
+
+ // test activation with no source layer
+ control.activate();
+ t.eq(control.active, true, "control is active");
+ t.ok(control.handler instanceof OpenLayers.Handler.Path, "line sketch handler created");
+ t.ok(control.handler.callbacks.done, "done callback set on sketch handler");
+ t.eq(control.handler.active, true, "sketch handler is active");
+
+ // change the source layer - this should call activate again
+ control.setSource(layer);
+
+ t.eq(control.active, true, "control is still active");
+ t.ok(control.source === layer, "source layer set");
+ t.ok(layer.events.listeners.sketchcomplete, "sketchcomplete listener registered");
+ t.ok(layer.events.listeners.afterfeaturemodified, "afterfeaturemodified listener registered");
+
+ map.destroy();
+
+ }
+
+ function test_deactivate(t) {
+
+ t.plan(7);
+
+ var layer1 = new OpenLayers.Layer.Vector("foo", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: true
+ });
+ var layer2 = new OpenLayers.Layer.Vector("bar", {
+ maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),
+ isBaseLayer: false
+ });
+ var control = new OpenLayers.Control.Split({layer: layer1});
+ var map = new OpenLayers.Map("map");
+ map.addLayer(layer1);
+ map.addLayer(layer2);
+ map.zoomToMaxExtent();
+ map.addControl(control);
+
+ // activate and check sketch handler
+ control.activate();
+ t.ok(control.handler, "sketch handler present");
+ t.eq(control.handler.active, true, "sketch handler active");
+
+ // deactivate and check sketch handler
+ control.deactivate();
+ t.eq(control.handler.active, false, "sketch handler deactivated");
+
+ // set a source layer
+ control.setSource(layer2);
+
+ // activate and check that listeners are registered
+ control.activate();
+ t.ok(layer2.events.listeners.sketchcomplete, "sketchcomplete listener registered");
+ t.ok(layer2.events.listeners.afterfeaturemodified, "afterfeaturemodified listener registered");
+
+ // deactivate and confirm no draw related events
+ control.deactivate();
+ t.eq(layer2.events.listeners.sketchcomplete.length, 0, "no sketchcomplete listeners");
+ t.eq(layer2.events.listeners.afterfeaturemodified.length, 0, "no afterfeaturemodified listeners");
+
+ map.destroy();
+ }
+
+ function test_isEligible(t) {
+
+ t.plan(10);
+
+ var control = new OpenLayers.Control.Split();
+ var geometry = OpenLayers.Geometry.fromWKT("LINESTRING(0 1, 1 2)");
+ var feature = new OpenLayers.Feature.Vector(
+ geometry,
+ {foo: "bar"}
+ );
+
+ t.eq(control.isEligible(feature), true, "plain old feature is eligible");
+
+ feature.state = OpenLayers.State.DELETE;
+ t.eq(control.isEligible(feature), false, "feature slated for deletion is not eligible");
+ delete feature.state;
+ t.eq(control.isEligible(feature), true, "feature with no state is eligible");
+
+ feature.geometry = new OpenLayers.Geometry.Point(1, 1);
+ t.eq(control.isEligible(feature), false, "feature with point geometry is not eligible");
+ feature.geometry = new OpenLayers.Geometry.MultiLineString([geometry]);
+ t.eq(control.isEligible(feature), true, "feature with multilinestring geometry is eligible");
+
+ control.feature = feature;
+ t.eq(control.isEligible(feature), false, "source feature is not eligible as target");
+ control.feature = new OpenLayers.Feature.Vector();
+ t.eq(control.isEligible(feature), true, "feature is eligible if different than source feature");
+
+ control.targetFilter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ });
+ t.eq(control.isEligible(feature), false, "feature is not eligible unless it matches filter");
+ control.targetFilter.value = "baz";
+ t.eq(control.isEligible(feature), true, "feature is eligible if it matches filter");
+
+ delete feature.geometry;
+ t.eq(control.isEligible(feature), false, "feature with no geometry is not eligible");
+
+ control.destroy();
+
+ }
+
+ function test_considerSplit(t) {
+
+ var layer = new OpenLayers.Layer.Vector();
+
+ var wkt = OpenLayers.Geometry.fromWKT;
+ var geoms = {
+ abc: wkt("LINESTRING(0 0, 2 2)"),
+ ab: wkt("LINESTRING(0 0, 1 1)"),
+ bc: wkt("LINESTRING(1 1, 2 2)"),
+ dbe: wkt("LINESTRING(2 0, 0 2)"),
+ db: wkt("LINESTRING(2 0, 1 1)"),
+ be: wkt("LINESTRING(1 1, 0 2)")
+ };
+
+ var Feature = OpenLayers.Feature.Vector;
+ var feats = {
+ abc: new Feature(geoms.abc),
+ ab: new Feature(geoms.ab),
+ bc: new Feature(geoms.bc),
+ dbe: new Feature(geoms.dbe),
+ db: new Feature(geoms.db),
+ be: new Feature(geoms.be)
+ };
+
+ function feature(id, options) {
+ var f = OpenLayers.Util.extend(feats[id].clone(), options);
+ // for testing, we want to check when features are destroyed
+ f.destroy = function() {
+ f.state = "destroyed";
+ }
+ return f;
+ }
+ var DELETE = OpenLayers.State.DELETE;
+ var INSERT = OpenLayers.State.INSERT;
+ var UPDATE = OpenLayers.State.UPDATE;
+
+ var cases = [{
+ targets: [
+ feature("abc")
+ ],
+ source: feature("dbe"),
+ splits: [{
+ original: feature("abc", {state: "destroyed"}),
+ features: [feature("ab", {state: INSERT}), feature("bc", {state: INSERT})]
+ }, {
+ original: feature("dbe", {state: "destroyed"}),
+ features: [feature("db", {state: INSERT}), feature("be", {state: INSERT})]
+ }]
+ }, {
+ options: {deferDelete: true},
+ targets: [
+ feature("abc", {state: INSERT})
+ ],
+ source: feature("dbe"),
+ splits: [{
+ original: feature("abc", {state: "destroyed"}),
+ features: [feature("ab", {state: INSERT}), feature("bc", {state: INSERT})]
+ }, {
+ original: feature("dbe", {state: DELETE}),
+ features: [feature("db", {state: INSERT}), feature("be", {state: INSERT})]
+ }]
+ }, {
+ options: {deferDelete: true},
+ targets: [
+ feature("abc", {state: UPDATE})
+ ],
+ source: feature("dbe", {state: INSERT}),
+ splits: [{
+ original: feature("abc", {state: DELETE}),
+ features: [feature("ab", {state: INSERT}), feature("bc", {state: INSERT})]
+ }, {
+ original: feature("dbe", {state: "destroyed"}),
+ features: [feature("db", {state: INSERT}), feature("be", {state: INSERT})]
+ }]
+ }];
+
+ var count = 0;
+ var c, control, options, log, event, split;
+ for(var i=0; i<cases.length; ++i) {
+ c = cases[i];
+ ++count; // test number of splits
+ for(var j=0; j<c.splits.length; ++j) {
+ split = c.splits[j];
+ ++count; // test original state
+ ++count; // test original geometry
+ ++count; // test number of parts
+ for(var k=0; k<split.features.length; ++k) {
+ ++count; // test part state
+ ++count; // test part geometry
+ }
+ }
+ }
+ t.plan(count);
+
+ for(var i=0; i<cases.length; ++i) {
+ c = cases[i];
+ log = {events: []};
+ options = OpenLayers.Util.extend({layer: layer, source: layer}, c.options);
+ control = new OpenLayers.Control.Split(options);
+ control.events.on({
+ split: function(e) {
+ log.events.push(e);
+ }
+ });
+ layer.features = c.targets;
+ control.considerSplit(c.source);
+ t.eq(log.events.length, c.splits.length, "case " + i + ": correct number of split events");
+ for(var j=0; j<log.events.length; ++j) {
+ event = log.events[j];
+ split = c.splits[j];
+ t.eq(event.original.state, split.original.state, "case " + i + " split " + j + ": correct original state");
+ t.geom_eq(event.original.geometry, split.original.geometry, "case " + i + " split " + j + ": correct original geometry");
+ t.eq(event.features.length, split.features.length, "case " + i + " split " + j + ": correct number of parts");
+ for(var k=0; k<split.features.length; ++k) {
+ t.eq(event.features[k].state, split.features[k].state, "case " + i + " split " + j + " feature " + k + ": correct state");
+ t.geom_eq(event.features[k].geometry, split.features[k].geometry, "case " + i + " split " + j + " feature " + k + ": correct geometry");
+ }
+ }
+ control.destroy();
+ }
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 100px; height: 100px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/TouchNavigation.html b/misc/openlayers/tests/Control/TouchNavigation.html
new file mode 100644
index 0000000..bffc225
--- /dev/null
+++ b/misc/openlayers/tests/Control/TouchNavigation.html
@@ -0,0 +1,155 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_Control_TouchNavigation_constructor (t) {
+ t.plan( 2 );
+ var options = {bar: "foo"};
+ var temp = OpenLayers.Control.prototype.initialize;
+ OpenLayers.Control.prototype.initialize = function(opt) {
+ t.eq(opt, options,
+ "constructor calls parent with the correct options");
+ };
+
+ var control = new OpenLayers.Control.TouchNavigation(options);
+ t.ok(control instanceof OpenLayers.Control.TouchNavigation,
+ "new OpenLayers.Control returns object");
+
+ OpenLayers.Control.prototype.initialize = temp;
+ }
+
+ function test_Control_TouchNavigation_destroy(t) {
+ t.plan(6);
+
+ var control = {
+ events: {
+ destroy: function() {
+ t.ok(true, "events destroyed");
+ }
+ },
+ deactivate: function() {
+ t.ok(true, "navigation control deactivated before being destroyed");
+ },
+ dragPan: {
+ destroy: function() {
+ t.ok(true, "dragPan destroyed");
+ }
+ },
+ handlers: {
+ click: {
+ destroy: function() {
+ t.ok(true, "clickHandler destroyed");
+ }
+ }
+ }
+ };
+
+ //this will also trigger one test by calling OpenLayers.Control's destroy
+ // and three more for the destruction of dragPan, zoomBox, and wheelHandler
+ OpenLayers.Control.TouchNavigation.prototype.destroy.apply(control, []);
+
+ t.eq(control.dragPan, null, "'dragPan' set to null");
+ t.eq(control.handlers, null, "handlers set to null");
+ }
+
+ function test_documentDrag(t) {
+
+ t.plan(2);
+
+ /**
+ * These tests confirm that the documentDrag property is false by
+ * default and is passed on to the DragPan control. Tests of panning
+ * while dragging outside the viewport should go in the DragPan tests.
+ * Tests of the document events and appropriate callbacks from the
+ * handler should go in the Drag handler tests.
+ */
+
+ var nav = new OpenLayers.Control.TouchNavigation();
+ t.eq(nav.documentDrag, false, "documentDrag false by default");
+
+ var map = new OpenLayers.Map({
+ div: document.body,
+ controls: [new OpenLayers.Control.TouchNavigation({documentDrag: true})]
+ });
+ nav = map.controls[0];
+
+ t.eq(nav.dragPan.documentDrag, true, "documentDrag set on the DragPan control");
+ map.destroy();
+
+ }
+
+ function test_dragPanOptions(t) {
+
+ t.plan(2);
+
+ var nav = new OpenLayers.Control.TouchNavigation();
+ t.eq(nav.dragPanOptions, null, "dragPanOptions null by default");
+
+ var map = new OpenLayers.Map({
+ div: document.body,
+ controls: [
+ new OpenLayers.Control.TouchNavigation({
+ dragPanOptions: {foo: 'bar'}
+ })
+ ]
+ });
+ nav = map.controls[0];
+
+ t.eq(nav.dragPan.foo, 'bar',
+ "foo property is set on the DragPan control");
+ map.destroy();
+
+ }
+
+ function test_clickHandlerOptions(t) {
+
+ t.plan(3);
+
+ var nav = new OpenLayers.Control.TouchNavigation();
+ t.eq(nav.clickHandlerOptions, null, "clickHandlerOptions null by default");
+
+ var map = new OpenLayers.Map({
+ div: document.body,
+ controls: [
+ new OpenLayers.Control.TouchNavigation({
+ clickHandlerOptions: {foo: "bar"}
+ })
+ ]
+ });
+ nav = map.controls[0];
+
+ t.eq(nav.handlers.click.foo, "bar", "foo property is set on the click handler");
+ t.eq(nav.handlers.click.pixelTolerance, 2, "pixelTolerance is 2 by default");
+ map.destroy();
+
+ }
+
+ function test_zoomOut(t) {
+ t.plan(1);
+
+ var map = new OpenLayers.Map('map', {zoomMethod: null});
+ var layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+ "http://labs.metacarta.com/wms/vmap0",
+ {layers: 'basic'} );
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 5);
+ var origSetTimeout = window.setTimeout;
+ window.setTimeout = function(fn) { fn(); return 'id'; };
+ var control = new OpenLayers.Control.TouchNavigation();
+ map.addControl(control);
+ var handler = control.handlers.click;
+ handler.touchstart({xy: new OpenLayers.Pixel(1 ,1), touches: ["foo", "bar"]});
+ handler.touchend({});
+ t.eq(map.getZoom(), 4, "Did we zoom out?");
+ // tear down
+ map.destroy();
+ window.setTimeout = origSetTimeout;
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width:512px;height:256px"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/TransformFeature.html b/misc/openlayers/tests/Control/TransformFeature.html
new file mode 100644
index 0000000..3279867
--- /dev/null
+++ b/misc/openlayers/tests/Control/TransformFeature.html
@@ -0,0 +1,129 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(6);
+ var layer = "foo";
+ var control = new OpenLayers.Control.TransformFeature(layer);
+
+ t.ok(control.layer == layer,
+ "constructor sets layer correctly");
+ t.ok(control.dragControl instanceof OpenLayers.Control.DragFeature,
+ "constructor sets the drag control correctly");
+ t.ok(control.box instanceof OpenLayers.Feature.Vector,
+ "box feature created");
+ t.eq(control.handles.length, 8, "8 handles created");
+ t.eq(control.rotationHandles.length, 4, "4 rotation handles created")
+ t.eq(typeof control.rotationHandleSymbolizer, "object",
+ "rotationHandleSymbolizer initialized");
+ control.destroy();
+ }
+
+ function test_destroy(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.TransformFeature(layer);
+ control.dragControl.destroy = function() {
+ t.ok(true,
+ "control.destroy calls destroy on drag control");
+ };
+ control.destroy();
+ map.destroy();
+ }
+
+ function test_activate(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector();
+ map.addLayer(layer);
+ var control = new OpenLayers.Control.TransformFeature(layer);
+ map.addControl(control);
+
+ t.ok(!control.dragControl.active,
+ "drag control is not active prior to activating control");
+ control.activate();
+ t.ok(control.dragControl.active,
+ "drag control is active after activating control");
+ t.ok(control.box.layer === layer, "box added to layer");
+
+ map.destroy();
+ }
+
+ function test_setFeature(t) {
+ t.plan(6);
+ var map = new OpenLayers.Map("map", {allOverlays: true});
+ var layer = new OpenLayers.Layer.Vector();
+ var feature = new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.fromWKT("POLYGON((-1 -1, 1 -1, 1 1, -1 1))"));
+ layer.addFeatures([feature]);
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 18);
+ var control = new OpenLayers.Control.TransformFeature(layer);
+ map.addControl(control);
+ var log = [];
+ control.events.on({
+ "beforesetfeature": function(e) { log.push(e); },
+ "setfeature": function(e) { log.push(e); }
+ });
+ control.setFeature(feature);
+
+ t.eq(log[0].type, "beforesetfeature", "beforesetfeature event fired with correct event type");
+ t.eq(log[1].type, "setfeature", "setfeature event fired with correct event type");
+
+ t.ok(control.active, "control activated on setFeature");
+ t.ok(feature.geometry.getBounds().equals(control.box.geometry.getBounds()), "box positioned correctly");
+ t.geom_eq(control.handles[0].geometry, control.box.geometry.components[0], "handle positioned with box");
+
+ var center = new OpenLayers.LonLat(1, 1);
+ control.box.move(center);
+ t.geom_eq(control.handles[0].geometry, control.box.geometry.components[0], "handle moved with box");
+ }
+
+ function test_handleMove(t) {
+ t.plan(16);
+ var map = new OpenLayers.Map("map", {allOverlays: true});
+ var layer = new OpenLayers.Layer.Vector();
+ var feature = new OpenLayers.Feature.Vector(
+ OpenLayers.Geometry.fromWKT("POLYGON((-1 -1, 1 -1, 1 1, -1 1))"));
+ layer.addFeatures([feature]);
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 18);
+ var control = new OpenLayers.Control.TransformFeature(layer);
+ map.addControl(control);
+ control.setFeature(feature);
+
+ var bottomLeft = new OpenLayers.LonLat(-2, -2);
+ control.handles[0].move(bottomLeft);
+ t.geom_eq(control.handles[0].geometry, new OpenLayers.Geometry.Point(-2, -2), "bottom left handle at -2,-2");
+ t.geom_eq(control.handles[1].geometry, new OpenLayers.Geometry.Point(0, -2), "bottom handle at 0,-2");
+ t.geom_eq(control.handles[2].geometry, new OpenLayers.Geometry.Point(2, -2), "bottom right handle at 2,-2");
+ t.geom_eq(control.handles[3].geometry, new OpenLayers.Geometry.Point(2, 0), "right handle at 2,0");
+ t.geom_eq(control.handles[4].geometry, new OpenLayers.Geometry.Point(2, 2), "top right handle at 2,2");
+ t.geom_eq(control.handles[5].geometry, new OpenLayers.Geometry.Point(0, 2), "top handle at 0,2");
+ t.geom_eq(control.handles[6].geometry, new OpenLayers.Geometry.Point(-2, 2), "top left handle at -2,2");
+ t.geom_eq(control.handles[7].geometry, new OpenLayers.Geometry.Point(-2, 0), "left handle at -2,0");
+
+ control.irregular = true;
+
+ var bottomLeft = new OpenLayers.LonLat(-3, -3);
+ control.handles[0].move(bottomLeft);
+ t.geom_eq(control.handles[0].geometry, new OpenLayers.Geometry.Point(-3, -3), "bottom left handle at -3,-3");
+ t.geom_eq(control.handles[1].geometry, new OpenLayers.Geometry.Point(-0.5, -3), "bottom handle at 0,-3");
+ t.geom_eq(control.handles[2].geometry, new OpenLayers.Geometry.Point(2, -3), "bottom right handle at 2,-3");
+ t.geom_eq(control.handles[3].geometry, new OpenLayers.Geometry.Point(2, -0.5), "right handle at 2,0");
+ t.geom_eq(control.handles[4].geometry, new OpenLayers.Geometry.Point(2, 2), "top right handle at 2,2");
+ t.geom_eq(control.handles[5].geometry, new OpenLayers.Geometry.Point(-0.5, 2), "top handle at 0,2");
+ t.geom_eq(control.handles[6].geometry, new OpenLayers.Geometry.Point(-3, 2), "top left handle at -3,2");
+ t.geom_eq(control.handles[7].geometry, new OpenLayers.Geometry.Point(-3, -0.5), "left handle at -3,0");
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/UTFGrid.html b/misc/openlayers/tests/Control/UTFGrid.html
new file mode 100644
index 0000000..74b4b99
--- /dev/null
+++ b/misc/openlayers/tests/Control/UTFGrid.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+ <script>
+ /**
+ * Because browsers that implement requestAnimationFrame may not execute
+ * animation functions while a window is not displayed (e.g. in a hidden
+ * iframe as in these tests), we mask the native implementations here. The
+ * native requestAnimationFrame functionality is tested in Util.html and
+ * in PanZoom.html (where a popup is opened before panning). The panTo tests
+ * here will test the fallback setTimeout implementation for animation.
+ */
+ window.requestAnimationFrame =
+ window.webkitRequestAnimationFrame =
+ window.mozRequestAnimationFrame =
+ window.oRequestAnimationFrame =
+ window.msRequestAnimationFrame = null;
+ </script>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var map, layer, control;
+ var log;
+ function setUp() {
+ layer = new OpenLayers.Layer.UTFGrid({
+ url: "../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json",
+ isBaseLayer: true,
+ utfgridResolution: 4
+ });
+ map = new OpenLayers.Map({
+ div: "map",
+ tileManager: null,
+ projection: "EPSG:900913",
+ layers: [layer],
+ center: [0, 0],
+ zoom: 1
+ });
+ log = [];
+ control = new OpenLayers.Control.UTFGrid({
+ callback: function(infoLookup, loc, pixel) {
+ log.push([infoLookup, loc, pixel]);
+ }
+ });
+ map.addControl(control);
+ }
+
+ function tearDown() {
+ map.destroy();
+ map = null;
+ layer = null;
+ control = null;
+ log = [];
+ }
+
+ function test_constructor(t) {
+ t.plan(2);
+
+ var control = new OpenLayers.Control.UTFGrid();
+ t.ok(control instanceof OpenLayers.Control.UTFGrid, "utfgrid instance");
+ t.eq(control.handlerMode, "click", "control mode");
+
+ control.destroy();
+
+ }
+
+ function test_handleEvent(t) {
+ setUp();
+
+ var cases = [{
+ evt: {xy: {x: 100, y: 70}},
+ lookup: {
+ "0": {
+ id: "207",
+ data: {
+ NAME: "United States",
+ POP2005: 299846449
+ }
+ }
+ }
+ }, {
+ evt: {xy: {x: 350, y: 20}},
+ lookup: {
+ "0": {
+ id: "245",
+ data: {
+ NAME: "Russia",
+ POP2005: 143953092
+ }
+ }
+ }
+ }];
+
+ var len = cases.length;
+ t.plan(4*len);
+
+ // wait for tile loading to finish
+ t.delay_call(0.5, function() {
+ var c, arg;
+ for (var i=0; i<len; ++i) {
+ c = cases[i];
+ t.eq(log.length, i, i + ": log length before");
+ control.handleEvent(c.evt);
+ t.eq(log.length, i+1, i + ": log length after");
+ t.eq(log[i][0], c.lookup, i + ": callback infoLookup");
+ t.eq(log[i][2], c.evt.xy, i + ": callback pixel");
+ }
+
+ tearDown();
+ });
+
+ }
+
+ </script>
+</head>
+<body>
+<div id="map" style="height: 256px; width: 512px"></div>
+</body>
+</html>
+
diff --git a/misc/openlayers/tests/Control/WMSGetFeatureInfo.html b/misc/openlayers/tests/Control/WMSGetFeatureInfo.html
new file mode 100644
index 0000000..b5e6d5d
--- /dev/null
+++ b/misc/openlayers/tests/Control/WMSGetFeatureInfo.html
@@ -0,0 +1,644 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(5);
+
+ var options = {
+ url: 'http://localhost/wms',
+ layers: ["foo"],
+ formatOptions: {
+ foo: "bar"
+ }
+ };
+ var control = new OpenLayers.Control.WMSGetFeatureInfo(options);
+ t.ok(control instanceof OpenLayers.Control.WMSGetFeatureInfo,
+ "new OpenLayers.Control.WMSGetFeatureInfo returns an instance");
+ t.eq(control.url, 'http://localhost/wms',
+ "constructor sets url correctly");
+ t.eq(control.layers, ["foo"],
+ "constructor layers"
+ );
+ t.ok(control.format instanceof OpenLayers.Format.WMSGetFeatureInfo, "format created");
+ t.eq(control.format.foo, "bar", "format options used")
+ }
+
+ function test_clickCallBack_option(t) {
+ t.plan(9);
+
+ var control;
+
+ control = new OpenLayers.Control.WMSGetFeatureInfo({
+ hover: true
+ });
+ t.ok(control.handler instanceof OpenLayers.Handler.Hover,
+ 'constructor creates hover handler');
+ t.ok(control.handler.callbacks["move"] === control.cancelHover,
+ 'constructor registers proper "move" callback in handler');
+ t.ok(control.handler.callbacks["pause"] === control.getInfoForHover,
+ 'constructor registers proper "pause" callback in handler');
+
+ control = new OpenLayers.Control.WMSGetFeatureInfo();
+ t.ok(control.handler instanceof OpenLayers.Handler.Click,
+ 'constructor creates click handler');
+ t.ok(control.handler.callbacks["click"] === control.getInfoForClick,
+ 'constructor registers proper "click" callback in handler');
+
+ control = new OpenLayers.Control.WMSGetFeatureInfo({
+ clickCallback: "rightclick"
+ });
+ t.ok(control.handler.callbacks["rightclick"] === control.getInfoForClick,
+ 'constructor registers proper "rightclick" callback in handler');
+
+ control = new OpenLayers.Control.WMSGetFeatureInfo({
+ clickCallback: "dblclick",
+ handlerOptions: {
+ click: {
+ "single": false,
+ "double": true
+ }
+ }
+ });
+ t.ok(control.handler.callbacks["dblclick"] === control.getInfoForClick,
+ 'constructor registers proper "dblclick" callback in handler');
+ t.eq(control.handler["single"], false,
+ 'constructor sets "single" to false in handler');
+ t.eq(control.handler["double"], true,
+ 'constructor sets "double" to true in handler');
+ }
+
+ function test_destroy(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var click = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ layers: ["foo"]
+ });
+
+ var hover = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ layers: ["foo"],
+ hover: true
+ });
+
+ click.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on click handler");
+ };
+ hover.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on hover handler");
+ };
+ click.destroy();
+ hover.destroy();
+ }
+
+ function test_click(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map('map');
+
+ // mock up active control
+ var control = new OpenLayers.Control.WMSGetFeatureInfo();
+ map.addControl(control);
+ control.activate();
+
+ control.request = function(position) {
+ t.eq(position.x, 50,
+ "x position is as expected");
+ t.eq(position.y, 50,
+ "y position is as expected");
+ };
+
+ control.getInfoForClick({xy: {x: 50, y: 50}});
+ control.getInfoForHover({xy: {x: 50, y: 50}});
+ }
+
+ function test_getfeatureinfo_event(t) {
+
+ t.plan(5);
+
+ var text =
+ '<?xml version="1.0" encoding="UTF-8" ?>' +
+ '<FeatureInfoResponse>' +
+ ' <FIELDS OBJECTID="1188" HECTARES="1819.734" ZONENR="5854" NULZONES=" " AREA="18197340.1426" PERIMETER="19177.4073627" SHAPE="NULL" SE_ANNO_CAD_DATA="NULL" SHAPE.AREA="0" SHAPE.LEN="0"/>' +
+ '</FeatureInfoResponse>';
+
+ var map = new OpenLayers.Map('map');
+
+ var xy;
+ var url = "http://foo";
+
+ // mock up a control with output "object" and drillDown true
+ var control = new OpenLayers.Control.WMSGetFeatureInfo({
+ output: "object",
+ drillDown: true,
+ request: function(position) {},
+ eventListeners: {
+ getfeatureinfo: function(evt) {
+ t.ok(evt.features[0].url === url, "features is an object with a property url when output is object");
+ var features = evt.features[0].features;
+ t.ok(features.length === 1, "features properties has a length of 1");
+ t.ok(features[0] instanceof OpenLayers.Feature.Vector, "Feature array contains 1 feature");
+ }
+ }
+ });
+
+ // mock up a control with output "features" and drillDown true
+ var control2 = new OpenLayers.Control.WMSGetFeatureInfo({
+ autoActivate: true,
+ drillDown: true,
+ request: function(position) {},
+ eventListeners: {
+ getfeatureinfo: function(evt) {
+ var features = evt.features;
+ t.ok(features.length === 1, "features properties has a length of 1");
+ t.ok(features[0] instanceof OpenLayers.Feature.Vector, "Feature array contains 1 feature");
+ }
+ }
+ });
+
+ map.addControls([control, control2]);
+ control.activate();
+
+ xy = {x: 50, y: 50};
+ control._requestCount = control2._requestCount = 0;
+ control._numRequests = control2._numRequests = 1;
+ control.handleResponse({xy: xy}, {responseText: text}, url);
+ control2.handleResponse({xy: xy}, {responseText: text}, url);
+ map.destroy();
+ }
+
+ function test_beforegetfeatureinfo_event(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map('map');
+
+ var xy, mode;
+
+ // mock up active control
+ var control = new OpenLayers.Control.WMSGetFeatureInfo({
+ request: function(position) {},
+ eventListeners: {
+ beforegetfeatureinfo: function(evt) {
+ t.eq(evt.xy, xy,
+ "beforegetfeatureinfo listener gets " +
+ "expected xy (" + mode + ")");
+ }
+ }
+ });
+ map.addControl(control);
+ control.activate();
+
+ // 1 test
+ mode = "click";
+ xy = {x: 50, y: 50};
+ control.getInfoForClick({xy: xy});
+
+ // 1 test
+ mode = "hover";
+ xy = {x: 70, y: 70};
+ control.getInfoForHover({xy: xy});
+ }
+
+ function test_nogetfeatureinfo_event(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map('map');
+ // mock up active control
+ var control = new OpenLayers.Control.WMSGetFeatureInfo({
+ eventListeners: {
+ nogetfeatureinfo: function(evt) {
+ t.ok((evt.type == "nogetfeatureinfo"), "nogetfeatureinfo listener gets called when there are no queryable layers");
+ }
+ }
+ });
+ map.addControl(control);
+ control.activate();
+
+ // 1 test
+ mode = "click";
+ xy = {x: 50, y: 50};
+ control.getInfoForClick({xy: xy});
+ }
+
+ function test_activate(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map("map");
+ var click = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ featureType: 'type',
+ featureNS: 'http://localhost/ns',
+ layers: 'ns:type'
+ });
+ var hover = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ featureType: 'type',
+ featureNS: 'http://localhost/ns',
+ layers: 'ns:type',
+ hover: true
+ });
+ map.addControl(click);
+ map.addControl(hover);
+ t.ok(!click.handler.active,
+ "click handler is not active prior to activating control");
+ t.ok(!hover.handler.active,
+ "hover handler is not active prior to activating control");
+ click.activate();
+ hover.activate();
+ t.ok(click.handler.active,
+ "click handler is active after activating control");
+ t.ok(hover.handler.active,
+ "hover handler is active after activating control");
+ }
+
+ function test_deactivate(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var click = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ featureType: 'type',
+ featureNS: 'http://localhost/ns',
+ layers: 'ns:type'
+ });
+ var hover = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ featureType: 'type',
+ featureNS: 'http://localhost/ns',
+ layers: 'ns:type'
+ });
+ map.addControl(click);
+ map.addControl(hover);
+ click.activate();
+ hover.activate();
+
+ click.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on click handler");
+ OpenLayers.Handler.Click.prototype.deactivate.apply(this, arguments);
+ };
+ hover.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on hover handler");
+ OpenLayers.Handler.Hover.prototype.deactivate.apply(this, arguments);
+ };
+ click.deactivate();
+ hover.deactivate();
+ }
+
+ // Verify that things work all right when we combine different types for the STYLES and LAYERS
+ // params in the WMS Layers involved
+ function test_mixedParams(t) {
+ t.plan(5);
+ var map = new OpenLayers.Map("map", {
+ getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}
+ });
+ var geographic = new OpenLayers.Projection("EPSG:4326");
+
+ var a = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
+ layers: "a,b,c,d",
+ styles: "a,b,c,d"
+ }, {projection: geographic});
+
+ var b = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
+ layers: ["a","b","c","d"],
+ styles: ["a","b","c","d"]
+ }, {projection: geographic});
+
+ var c = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
+ layers: ["a","b","c","d"]
+ });
+
+ var d = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
+ layers: "a,b,c,d"
+ }, {projection: geographic});
+
+ var click = new OpenLayers.Control.WMSGetFeatureInfo({
+ featureType: 'type',
+ featureNS: 'ns',
+ layers: [a, b, c, d]
+ }, {projection: geographic});
+
+ map.addControl(click);
+
+ var log = {};
+ var _request = OpenLayers.Request.GET;
+ OpenLayers.Request.GET = function(options) {
+ log.options = options;
+ };
+ click.activate();
+ click.getInfoForClick({xy: {x: 50.2, y: 50.1}});
+ OpenLayers.Request.GET = _request;
+
+ t.eq(
+ log.options && log.options.params.X,
+ 50,
+ "X should be an integer"
+ );
+
+ t.eq(
+ log.options && log.options.params.Y,
+ 50,
+ "Y should be an integer"
+ );
+
+ t.eq(
+ log.options && log.options.url,
+ "http://localhost/wms",
+ "url from first layer used"
+ );
+ t.eq(
+ log.options && log.options.params.STYLES.join(","),
+ ",,,,,,,,a,b,c,d,a,b,c,d",
+ "Styles merged correctly"
+ );
+
+ t.eq(
+ log.options && log.options.params.FORMAT,
+ "image/jpeg",
+ "Required 'format' parameter included"
+ );
+
+ }
+
+ function test_urlMatches(t) {
+
+ t.plan(5);
+
+ var control = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: "http://host/wms?one=1&two=2"
+ });
+
+ t.ok(!control.urlMatches("foo"), "doesn't match garbage");
+ t.ok(control.urlMatches("http://host:80/wms?two=2&one=1"), "matches equivalent url");
+
+ // give the control more urls to match from
+ control.layerUrls = ["http://a.host/wms", "http://b.host/wms"];
+
+ t.ok(control.urlMatches("http://host:80/wms?two=2&one=1"), "still matches equivalent url");
+ t.ok(control.urlMatches("http://a.host:80/wms"), "matches equivalent of first of layerUrls");
+ t.ok(control.urlMatches("http://b.host:80/wms"), "matches equivalent of second of layerUrls");
+
+ }
+
+ function test_layerUrls(t) {
+
+ t.plan(4);
+ var map = new OpenLayers.Map({
+ div: "map",
+ getExtent: function() {
+ return new OpenLayers.Bounds(-180,-90,180,90);
+ }
+ });
+
+ var a = new OpenLayers.Layer.WMS(
+ null, "http://a.mirror/wms", {layers: "a"}
+ );
+ var b = new OpenLayers.Layer.WMS(
+ null, "http://b.mirror/wms", {layers: "b"}
+ );
+ var c = new OpenLayers.Layer.WMS(
+ null, ["http://c.mirror/wms", "http://d.mirror/wms"], {layers: "c"}
+ );
+ map.addLayers([a, b, c]);
+
+ var control = new OpenLayers.Control.WMSGetFeatureInfo({
+ url: "http://host/wms",
+ layers: [a, b, c]
+ });
+ map.addControl(control);
+ control.activate();
+
+ // log calls to GET
+ var log;
+ var _request = OpenLayers.Request.GET;
+ OpenLayers.Request.GET = function(options) {
+ log.options = options;
+ };
+
+ // control url doesn't match layer urls, no request issued
+ log = {};
+ control.getInfoForClick({xy: {x: 50, y: 50}});
+ t.ok(!log.options, "no url match, no request issued");
+
+ // give control a list of urls to match
+ log = {};
+ control.layerUrls = ["http://a.mirror/wms", "http://b.mirror/wms"];
+ control.getInfoForClick({xy: {x: 50, y: 50}});
+ t.eq(log.options && log.options.url, "http://host/wms", "some match, request issued");
+ t.eq(log.options && log.options.params["QUERY_LAYERS"].join(","), "b,a", "selected layers queried");
+
+ // show that a layer can be matched if it has a urls array itself (first needs to be matched)
+ log = {};
+ control.layerUrls = ["http://c.mirror/wms"];
+ control.getInfoForClick({xy: {x: 50, y: 50}});
+ t.eq(log.options && log.options.params["QUERY_LAYERS"].join(","), "c", "layer with urls array can be queried");
+
+ // clean up
+ OpenLayers.Request.GET = _request;
+ map.destroy();
+
+ }
+
+ function test_hover(t) {
+
+ t.plan(2);
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ layers: [
+ new OpenLayers.Layer.WMS(null, "/dummywms", {layers: "one"})
+ ],
+ center: new OpenLayers.LonLat(0, 0),
+ zoom: 1
+ });
+
+ var control = new OpenLayers.Control.WMSGetFeatureInfo({
+ hover: true
+ });
+ map.addControl(control);
+ control.activate();
+
+ // mock up a mousemove
+ control.getInfoForHover({xy: new OpenLayers.Pixel(10, 10)});
+ t.ok(!!control.hoverRequest, "hoverRequest set");
+
+ // confirm that request is canceled on next move
+ var called = 0;
+ control.hoverRequest.abort = function() {
+ ++called;
+ };
+ control.handler.px = null;
+ control.handler.mousemove({xy: new OpenLayers.Pixel(20, 20)});
+ t.eq(called, 1, "hover request aborted");
+
+ map.destroy();
+
+ }
+
+ function test_exceptions(t) {
+ t.plan(1);
+ var map = new OpenLayers.Map("map", {
+ getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}
+ }
+ );
+
+ var a = new OpenLayers.Layer.WMS("dummy","http://myhost/wms", {
+ layers: "x",
+ exceptions: "text/xml"
+ });
+
+ map.addLayer(a);
+
+ var click = new OpenLayers.Control.WMSGetFeatureInfo({
+ });
+
+ map.addControl(click);
+
+ var _request = OpenLayers.Request.GET;
+ OpenLayers.Request.GET = function(options) {
+ t.eq(options.params["EXCEPTIONS"], "text/xml", "Exceptions parameter taken from the WMS layer if provided");
+ };
+ click.activate();
+ click.getInfoForClick({xy: {x: 50, y: 50}});
+ OpenLayers.Request.GET = _request;
+ map.destroy();
+ }
+
+ function test_drillDown(t) {
+ t.plan(6);
+ var map = new OpenLayers.Map("map", {
+ getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}
+ }
+ );
+
+ var a = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
+ layers: "a"
+ });
+
+ var b = new OpenLayers.Layer.WMS("dummy","http://localhost/wms", {
+ layers: "c"
+ });
+
+ // this service does not support application/vnd.ogc.gml for GetFeatureInfo, only text/xml
+ var c = new OpenLayers.Layer.WMS("dummy","http://myhost/wms", {
+ layers: "x",
+ info_format: "text/xml"
+ });
+
+ map.addLayers([a, b, c]);
+
+ var click = new OpenLayers.Control.WMSGetFeatureInfo({
+ drillDown: true,
+ infoFormat: "application/vnd.ogc.gml"
+ });
+
+ map.addControl(click);
+
+ var count = 0;
+ var _request = OpenLayers.Request.GET;
+ OpenLayers.Request.GET = function(options) {
+ count++;
+ if (count == 2) {
+ t.eq(options.params["INFO_FORMAT"], "application/vnd.ogc.gml", "Default info format of the control is used");
+ t.eq(options.params["QUERY_LAYERS"].join(","), "c,a", "Layers should be grouped by service url");
+ t.eq(options.url, "http://localhost/wms", "Correct url used for second request");
+ } else if (count == 1) {
+ t.eq(options.params["INFO_FORMAT"], "text/xml", "Overridden info format is used instead of the control's infoFormat");
+ t.eq(options.url, "http://myhost/wms", "Correct url used for first request");
+ }
+ };
+ click.activate();
+ click.getInfoForClick({xy: {x: 50, y: 50}});
+ OpenLayers.Request.GET = _request;
+ t.eq(count, 2, "We expect 2 requests to go off");
+ map.destroy();
+ }
+
+ function test_GetFeatureInfo_buildWMSOptions(t) {
+ t.plan(3);
+
+ var map = new OpenLayers.Map("map", {
+ getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));},
+ projection: "EPSG:900913"
+ });
+ var a = new OpenLayers.Layer.WMS("dummy", "http://localhost/wms", {
+ layers: "a"
+ }, {projection: "EPSG:3857"});
+ var b = new OpenLayers.Layer.WMS("dummy", "http://localhost/wms", {
+ layers: "b"
+ });
+ var c = new OpenLayers.Layer.WMS("dummy", "http://localhost/wms", {
+ layers: "c"
+ }, {projection: "EPSG:4326"});
+ map.addLayers([a, b, c]);
+ var gfi = new OpenLayers.Control.WMSGetFeatureInfo();
+ map.addControl(gfi);
+ gfi.activate();
+
+ var options = gfi.buildWMSOptions("http://localhost/wms", [a], {xy: {x: 50, y: 50}}, "text/html");
+ t.eq(options.params.SRS, "EPSG:3857", "layer projection used if provided and equal map projection");
+
+ options = gfi.buildWMSOptions("http://localhost/wms", [b], {xy: {x: 50, y: 50}}, "text/html");
+ t.eq(options.params.SRS, "EPSG:900913", "map projection used if layer has no projection configured");
+
+ options = gfi.buildWMSOptions("http://localhost/wms", [b], {xy: {x: 50, y: 50}}, "text/html");
+ t.eq(options.params.SRS, "EPSG:900913", "map projection used if layer configured with an incompatible projection");
+ }
+
+ function test_GetFeatureInfo_WMS13(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map("map", {
+ getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}
+ }
+ );
+
+ var a = new OpenLayers.Layer.WMS(null, "http://localhost/wms", {
+ layers: "a",
+ version: "1.3.0"
+ });
+ map.addLayer(a);
+
+ var click = new OpenLayers.Control.WMSGetFeatureInfo({
+ });
+
+ map.addControl(click);
+ var log = {};
+ var _request = OpenLayers.Request.GET;
+ OpenLayers.Request.GET = function(options) {
+ log.options = options;
+ };
+ click.activate();
+ click.getInfoForClick({xy: {x: 50.1, y: 60.2}});
+ OpenLayers.Request.GET = _request;
+ t.eq(
+ log.options && log.options.params.CRS,
+ "EPSG:4326",
+ "Since it is WMS 1.3 use CRS parameter instead of SRS in the GetFeatureInfo request"
+ );
+
+ t.eq(
+ log.options && log.options.params.I,
+ 50,
+ "Since it is WMS 1.3 use I parameter instead of X in the GetFeatureInfo request"
+ );
+
+ t.eq(
+ log.options && log.options.params.J,
+ 60,
+ "Since it is WMS 1.3 use J parameter instead of Y in the GetFeatureInfo request"
+ );
+
+ t.eq(
+ log.options && log.options.params.BBOX,
+ "-90,-180,90,180",
+ "Since it is WMS 1.3 the BBOX should respect axis order"
+ );
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/WMTSGetFeatureInfo.html b/misc/openlayers/tests/Control/WMTSGetFeatureInfo.html
new file mode 100644
index 0000000..c7be78c
--- /dev/null
+++ b/misc/openlayers/tests/Control/WMTSGetFeatureInfo.html
@@ -0,0 +1,334 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(4);
+
+ var options = {
+ url: "http://localhost/wmts",
+ layers: ["foo"],
+ formatOptions: {
+ foo: "bar"
+ }
+ };
+ var control = new OpenLayers.Control.WMTSGetFeatureInfo(options);
+ t.ok(control instanceof OpenLayers.Control.WMTSGetFeatureInfo,
+ "new OpenLayers.Control.WMTSGetFeatureInfo returns an instance");
+ t.eq(control.layers, ["foo"],
+ "constructor layers"
+ );
+ t.ok(control.format instanceof OpenLayers.Format.WMSGetFeatureInfo, "format created");
+ t.eq(control.format.foo, "bar", "format options used")
+ }
+
+ function test_clickCallBack_option(t) {
+ t.plan(9);
+
+ var control;
+
+ control = new OpenLayers.Control.WMTSGetFeatureInfo({
+ hover: true
+ });
+ t.ok(control.handler instanceof OpenLayers.Handler.Hover,
+ 'constructor creates hover handler');
+ t.ok(control.handler.callbacks["move"] === control.cancelHover,
+ 'constructor registers proper "move" callback in handler');
+ t.ok(control.handler.callbacks["pause"] === control.getInfoForHover,
+ 'constructor registers proper "pause" callback in handler');
+
+ control = new OpenLayers.Control.WMTSGetFeatureInfo();
+ t.ok(control.handler instanceof OpenLayers.Handler.Click,
+ 'constructor creates click handler');
+ t.ok(control.handler.callbacks["click"] === control.getInfoForClick,
+ 'constructor registers proper "click" callback in handler');
+
+ control = new OpenLayers.Control.WMTSGetFeatureInfo({
+ clickCallback: "rightclick"
+ });
+ t.ok(control.handler.callbacks["rightclick"] === control.getInfoForClick,
+ 'constructor registers proper "rightclick" callback in handler');
+
+ control = new OpenLayers.Control.WMTSGetFeatureInfo({
+ clickCallback: "dblclick",
+ handlerOptions: {
+ click: {
+ "single": false,
+ "double": true
+ }
+ }
+ });
+ t.ok(control.handler.callbacks["dblclick"] === control.getInfoForClick,
+ 'constructor registers proper "dblclick" callback in handler');
+ t.eq(control.handler["single"], false,
+ 'constructor sets "single" to false in handler');
+ t.eq(control.handler["double"], true,
+ 'constructor sets "double" to true in handler');
+ }
+
+ function test_destroy(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var click = new OpenLayers.Control.WMTSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ layers: ["foo"]
+ });
+
+ var hover = new OpenLayers.Control.WMTSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ layers: ["foo"],
+ hover: true
+ });
+
+ click.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on click handler");
+ };
+ hover.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on hover handler");
+ };
+ click.destroy();
+ hover.destroy();
+ }
+
+ function test_click(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map('map');
+
+ // mock up active control
+ var control = new OpenLayers.Control.WMTSGetFeatureInfo();
+ map.addControl(control);
+ control.activate();
+
+ control.request = function(position) {
+ t.eq(position.x, 200,
+ "x position is as expected");
+ t.eq(position.y, 125,
+ "y position is as expected");
+ };
+
+ control.getInfoForClick({xy: {x: 200, y: 125}});
+ control.getInfoForHover({xy: {x: 200, y: 125}});
+ }
+
+ function test_beforegetfeatureinfo_event(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map({
+ div: "map",
+ allOverlays: true,
+ layers: [
+ new OpenLayers.Layer.WMTS({
+ name: "Test WMTS 1",
+ url: "/testwmts/",
+ layer: "test1",
+ style: "",
+ matrixSet: "set-id",
+ isBaseLayer: false
+ }),
+ new OpenLayers.Layer.WMTS({
+ name: "Test WMTS 2",
+ url: "/testwmts/",
+ layer: "test2",
+ style: "",
+ matrixSet: "set-id",
+ isBaseLayer: false
+ })
+ ],
+ center: new OpenLayers.LonLat(0, 0),
+ zoom: 0
+ });
+
+ var log = [];
+
+ // test click
+ var click = new OpenLayers.Control.WMTSGetFeatureInfo({
+ drillDown: true,
+ eventListeners: {
+ beforegetfeatureinfo: function(evt) {
+ log.push({xy: evt.xy});
+ }
+ }
+ });
+ map.addControl(click);
+ click.activate();
+ click.getInfoForClick({xy: {x: 200, y: 125}});
+ t.eq(log.length, 2, "click: beforegetfeatureinfo triggered twice");
+ log = [];
+ click.deactivate();
+
+ // test hover
+ var hover = new OpenLayers.Control.WMTSGetFeatureInfo({
+ hover: true,
+ eventListeners: {
+ beforegetfeatureinfo: function(evt) {
+ log.push({xy: evt.xy});
+ }
+ }
+ });
+ map.addControl(hover);
+ hover.activate();
+ xy = {x: 70, y: 70};
+ hover.getInfoForHover({xy: {x: 70, y: 70}});
+ t.eq(log.length, 1, "hover: beforegetfeatureinfo triggered once");
+ log = [];
+ hover.deactivate();
+
+ map.destroy();
+ }
+
+ function test_activate(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map("map");
+ var click = new OpenLayers.Control.WMTSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ layers: ['ns:type']
+ });
+ var hover = new OpenLayers.Control.WMTSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ featureType: 'type',
+ featureNS: 'http://localhost/ns',
+ layers: 'ns:type',
+ hover: true
+ });
+ map.addControl(click);
+ map.addControl(hover);
+ t.ok(!click.handler.active,
+ "click handler is not active prior to activating control");
+ t.ok(!hover.handler.active,
+ "hover handler is not active prior to activating control");
+ click.activate();
+ hover.activate();
+ t.ok(click.handler.active,
+ "click handler is active after activating control");
+ t.ok(hover.handler.active,
+ "hover handler is active after activating control");
+ }
+
+ function test_deactivate(t) {
+ t.plan(2);
+ var map = new OpenLayers.Map("map");
+ var click = new OpenLayers.Control.WMTSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ featureType: 'type',
+ featureNS: 'http://localhost/ns',
+ layers: 'ns:type'
+ });
+ var hover = new OpenLayers.Control.WMTSGetFeatureInfo({
+ url: 'http://localhost/wms',
+ featureType: 'type',
+ featureNS: 'http://localhost/ns',
+ layers: 'ns:type'
+ });
+ map.addControl(click);
+ map.addControl(hover);
+ click.activate();
+ hover.activate();
+
+ click.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on click handler");
+ OpenLayers.Handler.Click.prototype.deactivate.apply(this, arguments);
+ };
+ hover.handler.deactivate = function() {
+ t.ok(true,
+ "control.deactivate calls deactivate on hover handler");
+ OpenLayers.Handler.Hover.prototype.deactivate.apply(this, arguments);
+ };
+ click.deactivate();
+ hover.deactivate();
+ }
+
+ function test_getInfoForClick(t) {
+
+ t.plan(13);
+ var map = new OpenLayers.Map({
+ div: "map",
+ getExtent: function() {
+ return new OpenLayers.Bounds(-180,-90,180,90);
+ }
+ });
+
+ var a = new OpenLayers.Layer.WMTS({
+ url: "http://a.example.com/wmts",
+ layer: "a",
+ matrixSet: "bar",
+ style: "default"
+ });
+
+ var b = new OpenLayers.Layer.WMTS({
+ url: "http://b.example.com/wmts",
+ layer: "b",
+ matrixSet: "bar",
+ style: "default",
+ isBaseLayer: false
+ });
+
+ var c = new OpenLayers.Layer.WMTS({
+ url: ["http://c1.example.com/wmts", "http://c2.example.com"],
+ layer: "c",
+ matrixSet: "bar",
+ style: "default",
+ isBaseLayer: false
+ });
+ map.addLayers([a, b, c]);
+ map.zoomToMaxExtent();
+
+ var control = new OpenLayers.Control.WMTSGetFeatureInfo({
+ layers: [a, b, c]
+ });
+ map.addControl(control);
+ control.activate();
+
+ // log calls to GET
+ var log;
+ var _request = OpenLayers.Request.GET;
+ OpenLayers.Request.GET = function(options) {
+ log.push(options);
+ };
+
+ // query first layer (drillDown false)
+ log = [];
+ control.drillDown = false;
+ control.queryVisible = false;
+ control.getInfoForClick({xy: {x: 200, y: 125}});
+ t.eq(log.length, 1, "one requests issued");
+ t.eq(log[0].url, "http://c1.example.com/wmts", "{drillDown: false} correct url");
+ t.eq(log[0].params["LAYER"], "c", "{drillDown: false} correct layer parameter");
+
+ // query all layers
+ log = [];
+ control.drillDown = true;
+ control.queryVisible = false;
+ control.getInfoForClick({xy: {x: 200, y: 125}});
+ t.eq(log.length, 3, "three requests issued");
+ t.eq(log[0].url, "http://c1.example.com/wmts", "[c] correct url");
+ t.eq(log[0].params["LAYER"], "c", "[c] correct layer parameter");
+ t.eq(log[1].url, "http://b.example.com/wmts", "[b] correct url");
+ t.eq(log[1].params["LAYER"], "b", "[b] correct layer parameter");
+ t.eq(log[2].url, "http://a.example.com/wmts", "[a] correct url");
+ t.eq(log[2].params["LAYER"], "a", "[a] correct layer parameter");
+
+ // query only visible layers
+ log = [];
+ control.drillDown = true;
+ control.queryVisible = true;
+ b.setVisibility(false);
+ control.getInfoForClick({xy: {x: 200, y: 125}});
+ t.eq(log.length, 2, "two requests issued");
+ t.eq(log[0].url, "http://c1.example.com/wmts", "correct url for second visible layer");
+ t.eq(log[1].url, "http://a.example.com/wmts", "correct url for first visible layer");
+
+ // clean up
+ OpenLayers.Request.GET = _request;
+ map.destroy();
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 250px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/Zoom.html b/misc/openlayers/tests/Control/Zoom.html
new file mode 100644
index 0000000..cfeb082
--- /dev/null
+++ b/misc/openlayers/tests/Control/Zoom.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_constructor(t) {
+ t.plan(5);
+
+ var control = new OpenLayers.Control.Zoom();
+ t.ok(control instanceof OpenLayers.Control, "instance of Control");
+ t.ok(control instanceof OpenLayers.Control.Zoom, "instance of Zoom");
+ t.eq(control.displayClass, "olControlZoom", "displayClass");
+ control.destroy();
+
+ control = new OpenLayers.Control.Zoom({
+ zoomInText: "zoom in!",
+ zoomOutText: "zoom out!"
+ });
+ t.eq(control.zoomInText, "zoom in!", "zoomInText");
+ t.eq(control.zoomOutText, "zoom out!", "zoomOutText");
+ control.destroy();
+ }
+
+ function test_addControl(t) {
+ t.plan(3);
+ var map = new OpenLayers.Map("map");
+ var control = new OpenLayers.Control.Zoom();
+ map.addControl(control);
+ t.ok(control.map === map, "Control.map set");
+ t.ok(!!~OpenLayers.Util.indexOf(map.controls, control), "map.controls contains control");
+
+ control = new OpenLayers.Control.Zoom({zoomInId: "in", zoomOutId: "out"});
+ map.addControl(control);
+ var eventsEl = document.getElementById("out").parentNode;
+ t.ok(control.events.element === eventsEl, "Events instance listens to custom div's parentNode");
+
+ map.destroy();
+ }
+
+ function test_zoomIn(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
+ zoomMethod: null
+ });
+ var control = new OpenLayers.Control.Zoom();
+ map.addControl(control);
+ map.setCenter([0, 0], 0);
+
+ t.eq(map.getZoom(), 0, "initial center");
+ map.events.triggerEvent("buttonclick", {buttonElement: control.zoomInLink});
+ t.eq(map.getZoom(), 1, "after zoom in");
+ map.destroy();
+ }
+
+ function test_zoomOut(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],
+ zoomMethod: null
+ });
+ var control = new OpenLayers.Control.Zoom();
+ map.addControl(control);
+ map.setCenter([0, 0], 1);
+
+ t.eq(map.getZoom(), 1, "initial center");
+ map.events.triggerEvent("buttonclick", {buttonElement: control.zoomOutLink});
+ t.eq(map.getZoom(), 0, "after zoom out");
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 512px; height: 256px;"/>
+ <div id="in">in</div><div id="out">out</out>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/ZoomBox.html b/misc/openlayers/tests/Control/ZoomBox.html
new file mode 100644
index 0000000..7763bcf
--- /dev/null
+++ b/misc/openlayers/tests/Control/ZoomBox.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_constructor(t) {
+ t.plan(4);
+
+ var control = new OpenLayers.Control.ZoomBox();
+ t.ok(control instanceof OpenLayers.Control, "instance of Control");
+ t.ok(control instanceof OpenLayers.Control.ZoomBox, "instance of ZoomBox");
+ t.eq(control.displayClass, "olControlZoomBox", "displayClass");
+ control.destroy();
+
+ control = new OpenLayers.Control.ZoomBox({
+ zoomOnClick: false
+ });
+ t.eq(control.zoomOnClick, false, "zoomOnClick");
+ control.destroy();
+ }
+
+ function test_zoomBox(t) {
+ t.plan(4);
+ var map = new OpenLayers.Map("map", {
+ zoomMethod: null,
+ layers: [new OpenLayers.Layer("", {isBaseLayer: true})],
+ center: [0, 0],
+ zoom: 1
+ });
+ var control = new OpenLayers.Control.ZoomBox();
+ map.addControl(control);
+ control.zoomBox(new OpenLayers.Pixel(50, 60));
+ t.eq(map.getZoom(), 2, "zoomed on click");
+
+ control.zoomOnClick = false;
+ control.zoomBox(new OpenLayers.Pixel(-50, -60));
+ t.eq(map.getZoom(), 2, "not zoomed with zoomOnClick set to false");
+
+ map.zoomToMaxExtent();
+ // pixel bounds bottom > top
+ control.zoomBox(new OpenLayers.Bounds(128, 128, 256, 64));
+ t.eq(map.getCenter().toShortString(), "-45, 22.5", "centered to box center");
+ t.eq(map.getZoom(), 3, "zoomed to box extent");
+
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 512px; height: 256px;"/>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Control/ZoomIn.html b/misc/openlayers/tests/Control/ZoomIn.html
new file mode 100644
index 0000000..844ded5
--- /dev/null
+++ b/misc/openlayers/tests/Control/ZoomIn.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+function test_ZoomIn_constructor (t) {
+ t.plan( 2 );
+
+ // setup
+ var control = new OpenLayers.Control.ZoomIn();
+
+ // tests
+ //
+ t.ok(
+ control instanceof OpenLayers.Control.ZoomIn,
+ "new OpenLayers.Control.ZoomIn returns object"
+ );
+ t.eq(
+ control.displayClass, "olControlZoomIn",
+ "displayClass is correct"
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_ZoomIn_type (t) {
+ t.plan( 1 );
+
+ // setup
+ var control = new OpenLayers.Control.ZoomIn();
+
+ // tests
+ //
+ t.eq(
+ control.type,
+ OpenLayers.Control.TYPE_BUTTON,
+ "ZoomIn control is of type OpenLayers.Control.TYPE_BUTTON"
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_ZoomIn_trigger (t) {
+ t.plan( 2 );
+
+ // set up
+ var control = new OpenLayers.Control.ZoomIn(),
+ zoomlevel = 5,
+ map = new OpenLayers.Map("map", {
+ allOverlays: true,
+ layers: [
+ new OpenLayers.Layer.Vector()
+ ],
+ center: new OpenLayers.LonLat(1,1),
+ zoom: zoomlevel
+ }),
+ oldZoom;
+
+ oldZoom = map.getZoom();
+
+ // tests
+ //
+ // trigger the control before it is being added,
+ // nothing should change
+ control.trigger();
+
+ t.eq(
+ oldZoom,
+ zoomlevel,
+ 'Calling trigger on a non added control doesn\'t do anything ' +
+ '(map zoom is ' + oldZoom + ').'
+ );
+
+ // now lets add the control
+ map.addControl(control);
+
+ // trigger it again, now the map should have a different extent
+ control.trigger();
+
+ t.eq(
+ map.getZoom(),
+ zoomlevel + 1,
+ 'Calling trigger on a added control changes the map zoom ' +
+ '(map zoom was ' + zoomlevel +
+ ' and is now ' + map.getZoom() + ').'
+ );
+
+ // tear down
+ control.destroy();
+ map.destroy();
+}
+
+ </script>
+ </head>
+ <body>
+ <div id="map" style="width: 1000px; height: 1000px;"></div>
+ </body>
+</html>
diff --git a/misc/openlayers/tests/Control/ZoomOut.html b/misc/openlayers/tests/Control/ZoomOut.html
new file mode 100644
index 0000000..5345c55
--- /dev/null
+++ b/misc/openlayers/tests/Control/ZoomOut.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+function test_ZoomOut_constructor (t) {
+ t.plan( 2 );
+
+ // setup
+ var control = new OpenLayers.Control.ZoomOut();
+
+ // tests
+ //
+ t.ok(
+ control instanceof OpenLayers.Control.ZoomOut,
+ "new OpenLayers.Control.ZoomOut returns object"
+ );
+ t.eq(
+ control.displayClass, "olControlZoomOut",
+ "displayClass is correct"
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_ZoomOut_type(t){
+ t.plan( 1 );
+
+ // setup
+ var control = new OpenLayers.Control.ZoomOut();
+
+ // check that the type of the control equals OpenLayers.Control.TYPE_BUTTON
+ t.eq(
+ control.type,
+ OpenLayers.Control.TYPE_BUTTON,
+ 'ZoomOut-control is of type "OpenLayers.Control.TYPE_BUTTON".'
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_ZoomOut_trigger (t) {
+ t.plan( 2 );
+
+ // set up
+ var control = new OpenLayers.Control.ZoomOut(),
+ zoomlevel = 5,
+ map = new OpenLayers.Map("map", {
+ allOverlays: true,
+ layers: [
+ new OpenLayers.Layer.Vector()
+ ],
+ center: new OpenLayers.LonLat(1,1),
+ zoom: zoomlevel
+ }),
+ oldZoom;
+
+ oldZoom = map.getZoom();
+
+ // tests
+ //
+ // trigger the control before it is being added,
+ // nothing should change
+ control.trigger();
+
+ t.eq(
+ oldZoom,
+ zoomlevel,
+ 'Calling trigger on a non added control doesn\'t do anything ' +
+ '(map zoom is ' + oldZoom + ').'
+ );
+
+ // now lets add the control
+ map.addControl(control);
+
+ // trigger it again, now the map should have a different extent
+ control.trigger();
+
+ t.eq(
+ map.getZoom(),
+ zoomlevel - 1,
+ 'Calling trigger on a added control changes the map zoom ' +
+ '(map zoom was ' + zoomlevel +
+ ' and is now ' + map.getZoom() + ').'
+ );
+
+ // tear down
+ control.destroy();
+ map.destroy();
+}
+
+ </script>
+ </head>
+ <body>
+ <div id="map" style="width: 1000px; height: 1000px;"></div>
+ </body>
+</html>
diff --git a/misc/openlayers/tests/Control/ZoomToMaxExtent.html b/misc/openlayers/tests/Control/ZoomToMaxExtent.html
new file mode 100644
index 0000000..8ed5512
--- /dev/null
+++ b/misc/openlayers/tests/Control/ZoomToMaxExtent.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+function test_ZoomToMaxExtent_constructor (t) {
+ t.plan( 2 );
+
+ // setup
+ var control = new OpenLayers.Control.ZoomToMaxExtent();
+
+ // tests
+ //
+ t.ok(
+ control instanceof OpenLayers.Control.ZoomToMaxExtent,
+ "new OpenLayers.Control.ZoomToMaxExtent returns object"
+ );
+ t.eq(
+ control.displayClass, "olControlZoomToMaxExtent",
+ "displayClass is correct"
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_ZoomToMaxExtent_type (t) {
+ t.plan( 1 );
+
+ // setup
+ var control = new OpenLayers.Control.ZoomToMaxExtent();
+
+ // check that the type of the control equals OpenLayers.Control.TYPE_BUTTON
+ t.eq(
+ control.type,
+ OpenLayers.Control.TYPE_BUTTON,
+ 'ZoomToMaxExtent-control is of type "OpenLayers.Control.TYPE_BUTTON".'
+ );
+
+ // tear down
+ control.destroy();
+}
+
+function test_ZoomToMaxExtent_trigger (t) {
+ t.plan( 2 );
+
+ // set up
+ var mapsMaxExtent = new OpenLayers.Bounds(0, 0, 45, 45),
+ mapsInitialExtent = new OpenLayers.Bounds(5, 5, 7, 7),
+ control = new OpenLayers.Control.ZoomToMaxExtent(),
+ map = new OpenLayers.Map("map", {
+ maxExtent: mapsMaxExtent,
+ allOverlays: true,
+ fractionalZoom: true,
+ layers: [
+ new OpenLayers.Layer.Vector()
+ ]
+ }),
+ oldExtent;
+
+ map.zoomToExtent(mapsInitialExtent);
+
+ oldExtent = map.getExtent().toString();
+
+ // tests
+ //
+ // trigger the control before it is being added,
+ // nothing should change
+ control.trigger();
+ t.eq(
+ oldExtent,
+ map.getExtent().toString(),
+ 'Calling trigger on a non added control doesn\'t do anything ' +
+ '(map extent is "' + oldExtent + '").'
+ );
+
+ // now lets add the control
+ map. addControl(control);
+
+ // trigger it again, now the map should have a different extent
+ control.trigger();
+
+ t.eq(
+ map.getExtent().toString(),
+ mapsMaxExtent.toString(),
+ 'Calling trigger on a added control changes the map extent ' +
+ '(map extent was "' + oldExtent + '"' +
+ ' and is now "' + mapsMaxExtent.toString() + '").'
+ );
+
+ // tear down
+ control.destroy();
+ map.destroy();
+}
+
+ </script>
+ </head>
+ <body>
+ <div id="map" style="width: 1000px; height: 1000px;"></div>
+ </body>
+</html>