diff options
Diffstat (limited to 'misc/openlayers/tests/Map.html')
-rw-r--r-- | misc/openlayers/tests/Map.html | 2255 |
1 files changed, 2255 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Map.html b/misc/openlayers/tests/Map.html new file mode 100644 index 0000000..9693fb1 --- /dev/null +++ b/misc/openlayers/tests/Map.html @@ -0,0 +1,2255 @@ +<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 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 isMozilla = (navigator.userAgent.indexOf("compatible") == -1); + var map; + + function test_Map_constructor (t) { + t.plan( 11 ); + + map = new OpenLayers.Map('map'); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + + t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class"); + + t.ok( map instanceof OpenLayers.Map, "new OpenLayers.Map returns object" ); + if (!isMozilla) { + t.ok( true, "skipping element test outside of Mozilla"); + t.ok( true, "skipping element test outside of Mozilla"); + t.ok( true, "skipping element test outside of Mozilla"); + } else { + t.ok( map.div instanceof HTMLDivElement, "map.div is an HTMLDivElement" ); + t.ok( map.viewPortDiv instanceof HTMLDivElement, "map.viewPortDiv is an HTMLDivElement" ); + t.ok( map.layerContainerDiv instanceof HTMLDivElement, "map.layerContainerDiv is an HTMLDivElement" ); + } + t.ok( map.layers instanceof Array, "map.layers is an Array" ); + t.ok( map.controls instanceof Array, "map.controls is an Array" ); + t.eq( map.controls.length, 4, "Default map has 4 controls." ); + t.ok( map.events instanceof OpenLayers.Events, "map.events is an OpenLayers.Events" ); + t.ok( map.getMaxExtent() instanceof OpenLayers.Bounds, "map.maxExtent is an OpenLayers.Bounds" ); + t.ok( map.getNumZoomLevels() > 0, "map has a default numZoomLevels" ); + + map.destroy(); + } + + function test_Map_constructor_convenience(t) { + t.plan(13); + var map = new OpenLayers.Map({ + maxExtent: [-170, -80, 170, 80], + restrictedExtent: [-120, -65, 120, 65], + layers: [ + new OpenLayers.Layer(null, {isBaseLayer: true}) + ], + center: [-111, 45], + zoom: 3 + }); + + // maxExtent from array + t.ok(map.maxExtent instanceof OpenLayers.Bounds, "maxExtent bounds"); + t.eq(map.maxExtent.left, -170, "maxExtent left"); + t.eq(map.maxExtent.bottom, -80, "maxExtent bottom"); + t.eq(map.maxExtent.right, 170, "maxExtent right"); + t.eq(map.maxExtent.top, 80, "maxExtent top"); + + // restrictedExtent from array + t.ok(map.restrictedExtent instanceof OpenLayers.Bounds, "restrictedExtent bounds"); + t.eq(map.restrictedExtent.left, -120, "restrictedExtent left"); + t.eq(map.restrictedExtent.bottom, -65, "restrictedExtent bottom"); + t.eq(map.restrictedExtent.right, 120, "restrictedExtent right"); + t.eq(map.restrictedExtent.top, 65, "restrictedExtent top"); + + var center = map.getCenter(); + t.eq(center.lon, -111, "center lon"); + t.eq(center.lat, 45, "center lat"); + + t.eq(map.getZoom(), 3, "zoom"); + + map.destroy(); + } + + function test_Map_constructor_late_rendering(t) { + t.plan( 4 ); + + map = new OpenLayers.Map(); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + + t.ok(map.div != null, "Map has a div even though none was specified."); + t.ok(map.viewPortDiv.parentNode == map.div, "Map is attached to a temporary div that holds the viewPortDiv."); + + var mapDiv = document.getElementById("map"); + // clean up the effects of other tests + while(OpenLayers.Element.hasClass(mapDiv, "olMap")) { + OpenLayers.Element.removeClass(mapDiv, "olMap"); + } + map.render(mapDiv); // Can also take a string. + + t.ok(map.div == mapDiv, "Map is now rendered to the 'map' div.") + t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class"); + + map.destroy(); + + } + + function test_Map_constructor_renderTo(t) { + t.plan( 1 ); + + map = new OpenLayers.Map({ + div: "map" + }); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + + var mapDiv = document.getElementById("map"); + t.ok(map.div == mapDiv, "Map is rendered to the 'map' div.") + + map.destroy(); + } + + function test_Map_setOptions(t) { + t.plan(2); + map = new OpenLayers.Map('map', {maxExtent: new OpenLayers.Bounds(100, 200, 300, 400)}); + map.setOptions({theme: 'foo'}); + + t.eq(map.theme, 'foo', "theme is correctly set by setOptions"); + t.ok(map.maxExtent.equals(new OpenLayers.Bounds(100, 200, 300, 400)), + "maxExtent is correct after calling setOptions"); + + map.destroy(); + } + + function test_Map_add_layers(t) { + t.plan(8); + map = new OpenLayers.Map('map'); + var layer1 = new OpenLayers.Layer.WMS("Layer 1", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + var layer2 = new OpenLayers.Layer.WMS("Layer 2", + "http://wms.jpl.nasa.gov/wms.cgi", {layers: "modis,global_mosaic"}); + // this uses map.addLayer internally + map.addLayers([layer1, layer2]) + t.eq( map.layers.length, 2, "map has exactly two layers" ); + t.ok( map.layers[0] === layer1, "1st layer is layer1" ); + t.ok( map.layers[1] === layer2, "2nd layer is layer2" ); + t.ok( layer1.map === map, "layer.map is map" ); + t.eq( parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'], + "layer1 zIndex is set" ); + t.eq( parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5, + "layer2 zIndex is set" ); + + map.events.register('preaddlayer', this, function(evt) { + return !(evt.layer.name === 'donotadd'); + }); + var layer3 = new OpenLayers.Layer.WMS("donotadd", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayers([layer3]); + t.eq(map.layers.length, 2, "layer is not added since preaddlayer returns false"); + layer3.name = 'pleaseadd'; + map.addLayers([layer3]); + t.eq(map.layers.length, 3, "layer is added since preaddlayer returns true"); + + map.destroy(); + } + + function test_Map_options(t) { + t.plan(3); + map = new OpenLayers.Map('map', {numZoomLevels: 6, maxResolution: 3.14159, theme: 'foo'}); + t.eq( map.numZoomLevels, 6, "map.numZoomLevels set correctly via options hashtable" ); + t.eq( map.maxResolution, 3.14159, "map.maxResolution set correctly via options hashtable" ); + t.eq( map.theme, 'foo', "map theme set correctly." ); + + map.destroy(); + } + + function test_eventListeners(t) { + t.plan(1); + + var method = OpenLayers.Events.prototype.on; + // test that events.on is called at map construction + var options = { + eventListeners: {foo: "bar"}, + tileManager: null, + controls: [] + }; + OpenLayers.Events.prototype.on = function(obj) { + t.eq(obj, options.eventListeners, "events.on called with eventListeners"); + } + var map = new OpenLayers.Map('map', options); + OpenLayers.Events.prototype.on = method; + map.destroy(); + + // if events.on is called again, this will fail due to an extra test + // test map without eventListeners + OpenLayers.Events.prototype.on = function(obj) { + t.fail("events.on called without eventListeners"); + } + var map2 = new OpenLayers.Map("map", {tileManager: null, controls: []}); + OpenLayers.Events.prototype.on = method; + map2.destroy(); + } + + function test_Map_center(t) { + t.plan(14); + var log = []; + map = new OpenLayers.Map('map', { + zoomMethod: null, + eventListeners: { + "movestart": function() {log.push("movestart");}, + "move": function() {log.push("move");}, + "moveend": function() {log.push("moveend");} + } + }); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"} ); + map.addLayer(baseLayer); + var ll = new OpenLayers.LonLat(2,1); + map.setCenter(ll, 0); + t.ok( map.getCenter() instanceof OpenLayers.LonLat, "map.getCenter returns a LonLat"); + t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter"); + t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter"); + map.zoomIn(); + t.eq( map.getZoom(), 1, "map.zoom is correct after calling setCenter,zoom in"); + t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter, zoom in"); + map.zoomOut(); + t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter,zoom in, zoom out"); + + log = []; + map.zoomTo(5); + t.eq(log[0], "movestart", "zoomTo fires movestart event"); + t.eq(log[1], "move", "zoomTo fires move event"); + t.eq(log[2], "moveend", "zoomTo fires moveend event"); + t.eq( map.getZoom(), 5, "map.zoom is correct after calling zoomTo" ); + + /** + map.zoomToMaxExtent(); + t.eq( map.getZoom(), 2, "map.zoom is correct after calling zoomToMaxExtent" ); + var lonlat = map.getCenter(); + var zero = new OpenLayers.LonLat(0, 0); + t.ok( lonlat.equals(zero), "map center is correct after calling zoomToFullExtent" ); + */ + + map.getCenter().lon = 10; + t.ok( map.getCenter().equals(ll), "map.getCenter returns a clone of map.center"); + + // allow calling setCenter with an array + map.setCenter([4, 2]); + var center = map.getCenter(); + t.ok(center instanceof OpenLayers.LonLat, "(array) center is lonlat"); + t.eq(center.lon, 4, "(array) center lon"); + t.eq(center.lat, 2, "(array) center lat"); + + map.destroy(); + } + + function test_Map_zoomend_event (t) { + t.plan(2); + + map = new OpenLayers.Map('map', {zoomMethod: null}); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + map.events.register("zoomend", {count: 0}, function() { + this.count++; + t.ok(true, "zoomend event was triggered " + this.count + " times"); + }); + map.setCenter(new OpenLayers.LonLat(2, 1), 0); + map.zoomIn(); + map.zoomOut(); + + map.destroy(); + } + + function test_Map_add_remove_popup (t) { + t.plan(4); + + map = new OpenLayers.Map('map'); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + + var popup = new OpenLayers.Popup("chicken", + new OpenLayers.LonLat(0,0), + new OpenLayers.Size(200,200)); + map.setCenter(new OpenLayers.LonLat(0, 0), 0); + + map.addPopup(popup); + var pIndex = OpenLayers.Util.indexOf(map.popups, popup); + t.eq(pIndex, 0, "popup successfully added to Map's internal popups array"); + + var nodes = map.layerContainerDiv.childNodes; + + var found = false; + for (var i=0; i < nodes.length; i++) { + if (nodes.item(i) == popup.div) { + found = true; + break; + } + } + t.ok(found, "popup.div successfully added to the map's viewPort"); + + + map.removePopup(popup); + var pIndex = OpenLayers.Util.indexOf(map.popups, popup); + t.eq(pIndex, -1, "popup successfully removed from Map's internal popups array"); + + var found = false; + for (var i=0; i < nodes.length; i++) { + if (nodes.item(i) == popup.div) { + found = true; + break; + } + } + t.ok(!found, "popup.div successfully removed from the map's viewPort"); + + map.destroy(); + } + + function test_Map_add_popup_exclusive(t) { + t.plan(2); + + map = new OpenLayers.Map('map'); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + + map.setCenter(new OpenLayers.LonLat(0, 0), 0); + + for (var i = 0; i < 10; i++) { + var popup = new OpenLayers.Popup("chicken", + new OpenLayers.LonLat(0,0), + new OpenLayers.Size(200,200)); + map.addPopup(popup); + } + t.eq(map.popups.length, 10, "addPopup non exclusive mode works"); + + var popup = new OpenLayers.Popup("chicken", + new OpenLayers.LonLat(0,0), + new OpenLayers.Size(200,200)); + map.addPopup(popup, true); + t.eq(map.popups.length, 1, "addPopup exclusive mode works"); + + map.destroy(); + } + + +/*** THIS IS A GOOD TEST, BUT IT SHOULD BE MOVED TO WMS. + * Also, it won't work until we figure out the viewSize bug + + function 08_Map_px_lonlat_translation (t) { + t.plan( 6 ); + map = new OpenLayers.Map('map'); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}); + map.addLayer(baseLayer); + map.setCenter(new OpenLayers.LonLat(0, 0), 0); + + var pixel = new OpenLayers.Pixel(50,150); + var lonlat = map.getLonLatFromViewPortPx(pixel); + t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromViewPortPx returns valid OpenLayers.LonLat" ); + + var newPixel = map.getViewPortPxFromLonLat(lonlat); + t.ok( newPixel instanceof OpenLayers.Pixel, "getViewPortPxFromLonLat returns valid OpenLayers.Pixel" ); + + // WARNING!!! I'm faily sure that the following test's validity + // depends highly on rounding and the resolution. For now, + // in the default case, it seems to work. This may not + // always be so. + t.ok( newPixel.equals(pixel), "Translation to pixel and back to lonlat is consistent"); + + lonlat = map.getLonLatFromPixel(pixel); + t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromPixel returns valid OpenLayers.LonLat" ); + + newPixel = map.getPixelFromLonLat(lonlat); + t.ok( newPixel instanceof OpenLayers.Pixel, "getPixelFromLonLat returns valid OpenLayers.Pixel" ); + + t.ok( newPixel.equals(pixel), "2nd translation to pixel and back to lonlat is consistent"); + } + */ + + function test_Map_isValidZoomLevel(t) { + t.plan(5); + var map = new OpenLayers.Map("map"); + map.addLayer(new OpenLayers.Layer(null, { + isBaseLayer: true, wrapDateLine: true, numZoomLevels: 19 + })); + map.zoomToMaxExtent(); + + var valid; + + valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [-1]); + t.eq(valid, false, "-1 is not a valid zoomLevel"); + + valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [0]); + t.eq(valid, true, "0 is a valid zoomLevel"); + + valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [18]); + t.eq(valid, true, "18 is a valid zoomLevel"); + + valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [19]); + t.eq(valid, false, "19 is not a valid zoomLevel"); + + map.moveTo([16, 48], 0); + t.eq(map.getCenter().toShortString(), "0, 0", "no panning when moveTo is called with invalid zoom"); + + map.destroy(); + } + + function test_Map_isValidLonLat(t) { + t.plan( 3 ); + + 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'}, + {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } ); + map.addLayer(layer); + + t.ok( !map.isValidLonLat(null), "null lonlat is not valid" ); + t.ok( map.isValidLonLat(new OpenLayers.LonLat(33862, 717606)), "lonlat outside max extent is valid" ); + t.ok( !map.isValidLonLat(new OpenLayers.LonLat(10, 10)), "lonlat outside max extent is not valid" ); + + map.destroy(); + } + + function test_Map_getLayer(t) { + var numLayers = 3; + t.plan( numLayers + 1 ); + + var m = { + layers: [] + }; + + for(var i = 0; i < numLayers; i++) { + m.layers.push( { 'id': i } ); + } + + for(var i = 0; i < numLayers; i++) { + var layer = OpenLayers.Map.prototype.getLayer.apply(m, [i]); + t.ok( layer == m.layers[i], "getLayer correctly returns layer " + i); + } + + var gotLayer = OpenLayers.Map.prototype.getLayer.apply(m, ["chicken"]); + t.ok( gotLayer == null, "getLayer correctly returns null when layer not found"); + + map.destroy(); + } + + function test_Map_getLayersBy(t) { + + var map = { + getBy: OpenLayers.Map.prototype.getBy, + getLayersBy: OpenLayers.Map.prototype.getLayersBy, + layers: [ + {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: map.getLayersBy("foo", "foo"), + expected: [map.layers[0], map.layers[4]], + message: "(string literal) got two layers matching foo" + }, { + got: map.getLayersBy("foo", "bar"), + expected: [map.layers[1]], + message: "(string literal) got one layer matching foo" + }, { + got: map.getLayersBy("foo", "barfoo"), + expected: [], + message: "(string literal) got empty array for no foo match" + }, { + got: map.getLayersBy("foo", /foo/), + expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]], + message: "(regexp literal) got three layers containing string" + }, { + got: map.getLayersBy("foo", /foo$/), + expected: [map.layers[0], map.layers[4]], + message: "(regexp literal) got three layers ending with string" + }, { + got: map.getLayersBy("foo", /\s/), + expected: [map.layers[3]], + message: "(regexp literal) got layer containing space" + }, { + got: map.getLayersBy("foo", new RegExp("BAR", "i")), + expected: [map.layers[1], map.layers[2], map.layers[3]], + message: "(regexp object) got layers ignoring case" + }, { + got: map.getLayersBy("foo", {test: function(str) {return str.length > 3;}}), + expected: [map.layers[2], map.layers[3]], + message: "(custom object) got layers 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_Map_getLayersByName(t) { + + var map = { + getBy: OpenLayers.Map.prototype.getBy, + getLayersBy: OpenLayers.Map.prototype.getLayersBy, + getLayersByName: OpenLayers.Map.prototype.getLayersByName, + layers: [ + {name: "foo", id: Math.random()}, + {name: "bar", id: Math.random()}, + {name: "foobar", id: Math.random()}, + {name: "foo bar", id: Math.random()}, + {name: "foo", id: Math.random()} + ] + }; + + var cases = [ + { + got: map.getLayersByName("foo"), + expected: [map.layers[0], map.layers[4]], + message: "(string literal) got two layers matching name" + }, { + got: map.getLayersByName("bar"), + expected: [map.layers[1]], + message: "(string literal) got one layer matching name" + }, { + got: map.getLayersByName("barfoo"), + expected: [], + message: "(string literal) got empty array for no match" + }, { + got: map.getLayersByName(/foo/), + expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]], + message: "(regexp literal) got three layers containing string" + }, { + got: map.getLayersByName(/foo$/), + expected: [map.layers[0], map.layers[4]], + message: "(regexp literal) got three layers ending with string" + }, { + got: map.getLayersByName(/\s/), + expected: [map.layers[3]], + message: "(regexp literal) got layer containing space" + }, { + got: map.getLayersByName(new RegExp("BAR", "i")), + expected: [map.layers[1], map.layers[2], map.layers[3]], + message: "(regexp object) got layers ignoring case" + }, { + got: map.getLayersByName({test: function(str) {return str.length > 3;}}), + expected: [map.layers[2], map.layers[3]], + message: "(custom object) got layers with name 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_Map_getLayersByClass(t) { + + var map = { + getBy: OpenLayers.Map.prototype.getBy, + getLayersBy: OpenLayers.Map.prototype.getLayersBy, + getLayersByClass: OpenLayers.Map.prototype.getLayersByClass, + layers: [ + {CLASS_NAME: "foo", id: Math.random()}, + {CLASS_NAME: "bar", id: Math.random()}, + {CLASS_NAME: "foobar", id: Math.random()}, + {CLASS_NAME: "foo bar", id: Math.random()}, + {CLASS_NAME: "foo", id: Math.random()} + ] + }; + + var cases = [ + { + got: map.getLayersByClass("foo"), + expected: [map.layers[0], map.layers[4]], + message: "(string literal) got two layers matching type" + }, { + got: map.getLayersByClass("bar"), + expected: [map.layers[1]], + message: "(string literal) got one layer matching type" + }, { + got: map.getLayersByClass("barfoo"), + expected: [], + message: "(string literal) got empty array for no match" + }, { + got: map.getLayersByClass(/foo/), + expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]], + message: "(regexp literal) got three layers containing string" + }, { + got: map.getLayersByClass(/foo$/), + expected: [map.layers[0], map.layers[4]], + message: "(regexp literal) got three layers ending with string" + }, { + got: map.getLayersByClass(/\s/), + expected: [map.layers[3]], + message: "(regexp literal) got layer containing space" + }, { + got: map.getLayersByClass(new RegExp("BAR", "i")), + expected: [map.layers[1], map.layers[2], map.layers[3]], + message: "(regexp object) got layers ignoring case" + }, { + got: map.getLayersByClass({test: function(str) {return str.length > 3;}}), + expected: [map.layers[2], map.layers[3]], + message: "(custom object) got layers with type 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_Map_getControlsBy(t) { + + var map = { + getBy: OpenLayers.Map.prototype.getBy, + getControlsBy: OpenLayers.Map.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: map.getControlsBy("foo", "foo"), + expected: [map.controls[0], map.controls[4]], + message: "(string literal) got two controls matching foo" + }, { + got: map.getControlsBy("foo", "bar"), + expected: [map.controls[1]], + message: "(string literal) got one control matching foo" + }, { + got: map.getControlsBy("foo", "barfoo"), + expected: [], + message: "(string literal) got empty array for no foo match" + }, { + got: map.getControlsBy("foo", /foo/), + expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]], + message: "(regexp literal) got three controls containing string" + }, { + got: map.getControlsBy("foo", /foo$/), + expected: [map.controls[0], map.controls[4]], + message: "(regexp literal) got three controls ending with string" + }, { + got: map.getControlsBy("foo", /\s/), + expected: [map.controls[3]], + message: "(regexp literal) got control containing space" + }, { + got: map.getControlsBy("foo", new RegExp("BAR", "i")), + expected: [map.controls[1], map.controls[2], map.controls[3]], + message: "(regexp object) got layers ignoring case" + }, { + got: map.getControlsBy("foo", {test: function(str) {return str.length > 3;}}), + expected: [map.controls[2], map.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_Map_getControlsByClass(t) { + + var map = { + getBy: OpenLayers.Map.prototype.getBy, + getControlsBy: OpenLayers.Map.prototype.getControlsBy, + getControlsByClass: OpenLayers.Map.prototype.getControlsByClass, + controls: [ + {CLASS_NAME: "foo", id: Math.random()}, + {CLASS_NAME: "bar", id: Math.random()}, + {CLASS_NAME: "foobar", id: Math.random()}, + {CLASS_NAME: "foo bar", id: Math.random()}, + {CLASS_NAME: "foo", id: Math.random()} + ] + }; + + var cases = [ + { + got: map.getControlsByClass("foo"), + expected: [map.controls[0], map.controls[4]], + message: "(string literal) got two controls matching type" + }, { + got: map.getControlsByClass("bar"), + expected: [map.controls[1]], + message: "(string literal) got one control matching type" + }, { + got: map.getControlsByClass("barfoo"), + expected: [], + message: "(string literal) got empty array for no match" + }, { + got: map.getControlsByClass(/foo/), + expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]], + message: "(regexp literal) got three controls containing string" + }, { + got: map.getControlsByClass(/foo$/), + expected: [map.controls[0], map.controls[4]], + message: "(regexp literal) got three controls ending with string" + }, { + got: map.getControlsByClass(/\s/), + expected: [map.controls[3]], + message: "(regexp literal) got control containing space" + }, { + got: map.getControlsByClass(new RegExp("BAR", "i")), + expected: [map.controls[1], map.controls[2], map.controls[3]], + message: "(regexp object) got controls ignoring case" + }, { + got: map.getControlsByClass({test: function(str) {return str.length > 3;}}), + expected: [map.controls[2], map.controls[3]], + message: "(custom object) got controls with type 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_Map_double_addLayer(t) { + t.plan(2); + + 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'} + ); + + var added = map.addLayer(layer); + t.ok(added === true, "Map.addLayer returns true if the layer is added to the map."); + var added = map.addLayer(layer); + t.ok(added === false, "Map.addLayer returns false if the layer is already present."); + + map.destroy(); + } + + function test_Map_setBaseLayer(t) { + t.plan( 6 ); + + map = new OpenLayers.Map('map'); + + var wmslayer = new OpenLayers.Layer.WMS('Test Layer', + "http://octo.metacarta.com/cgi-bin/mapserv", + {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, + {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } ); + + var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2', + "http://octo.metacarta.com/cgi-bin/mapserv", + {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, + {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } ); + + map.addLayers([wmslayer, wmslayer2]); + + t.ok(map.baseLayer == wmslayer, "default base layer is first one added"); + + map.setBaseLayer(null); + t.ok(map.baseLayer == wmslayer, "setBaseLayer on null object does nothing (and does not break)"); + + map.setBaseLayer("chicken"); + t.ok(map.baseLayer == wmslayer, "setBaseLayer on non-layer object does nothing (and does not break)"); + + map.setBaseLayer(wmslayer2); + t.ok(map.baseLayer == wmslayer2, "setbaselayer correctly sets 'baseLayer' property"); + + map.destroy(); + + var l1 = new OpenLayers.Layer(), + l2 = new OpenLayers.Layer(null, {maxResolution: 1.4}); + map = new OpenLayers.Map({ + div: 'map', + allOverlays: true, + layers: [l1, l2], + zoom: 0, + center: [0, 0] + }); + t.eq(l2.div.style.display, "none", "Layer invisible because not in range"); + map.raiseLayer(l1, 1); + t.eq(l2.div.style.display, "block", "Layer visible after base layer change because in range now"); + map.destroy(); + } + + function test_Map_removeLayer(t) { + t.plan(1); + var f = function() {}; + var events = {triggerEvent: f}; + var layers = [ + {name: "fee", removeMap: f, events: events}, + {name: "fi", removeMap: f, events: events}, + {name: "fo", removeMap: f, events: events}, + {name: "fum", removeMap: f, events: events} + ]; + var map = { + layers: layers, + baseLayer: layers[0], + layerContainerDiv: {removeChild: f}, + events: {triggerEvent: f}, + resetLayersZIndex: function() {} + }; + OpenLayers.Map.prototype.removeLayer.apply(map, [map.baseLayer, false]); + t.eq(map.baseLayer, null, + "removing the baselayer sets baseLayer to null"); + } + + function test_Map_removeLayer_res(t) { + t.plan(2); + + map = new OpenLayers.Map('map'); + + var layer0 = new OpenLayers.Layer.WMS( + 'Test Layer 0', + "http://octo.metacarta.com/cgi-bin/mapserv", + {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, + {resolutions: [4, 2, 1]} + ); + + var layer1 = new OpenLayers.Layer.WMS( + 'Test Layer 1', + "http://octo.metacarta.com/cgi-bin/mapserv", + {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, + {resolutions: [4, 2]} + ); + + map.addLayers([layer0, layer1]); + map.zoomToMaxExtent(); + map.zoomTo(2); + t.eq(map.getResolution(), layer0.resolutions[2], + "correct resolution before removal"); + map.removeLayer(layer0); + t.eq(map.getResolution(), layer0.resolutions[1], + "correct resolution after removal"); + + map.destroy(); + } + + function test_Map_removeLayer_zindex(t) { + t.plan(2); + + map = new OpenLayers.Map('map'); + + var layer0 = new OpenLayers.Layer('Test Layer 0', {isBaseLayer:true}); + var layer1 = new OpenLayers.Layer('Test Layer 1', {isBaseLayer:true}); + var layer2 = new OpenLayers.Layer('Test Layer 2', {isBaseLayer:false}); + + map.addLayers([layer0, layer1, layer2]); + map.removeLayer(layer0); + + t.eq(parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'], + "correct z-index after removeLayer"); + t.eq(parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['Overlay'] + 5, + "correct z-index after removeLayer"); + + map.destroy(); + } + + function test_Map_removeLayer_preremovelayer(t) { + t.plan(4); + map = new OpenLayers.Map('map'); + + map.addLayer(new OpenLayers.Layer()); + map.removeLayer(map.layers[0]); + + // one test: standard behaviour without listener + t.eq(map.layers.length, 0, "without registered preremovelayer-listener layers can be removed as usual"); + + var callCnt = 0; + + map.events.register('preremovelayer', this, function(evt) { + callCnt++; + return !(evt.layer.name === 'donotremove'); + }); + var layer1 = new OpenLayers.Layer('donotremove'); + var layer2 = new OpenLayers.Layer('doremove'); + + map.addLayers([layer1,layer2]); + + // two tests: remove action can be canceled + map.removeLayer(layer1); + t.eq(map.layers.length, 2, "layer is not removed since preremovelayer returns false"); + map.removeLayer(layer2); + t.eq(map.layers.length, 1, "layer is removed since preremovelayer returns true"); + + // one test: listener was called twice + t.eq(callCnt, 2, "preremovelayer-listener was called exactly twice"); + + map.destroy(); + } + + function test_Map_setBaseLayer_after_pan (t) { + t.plan(1); + + map = new OpenLayers.Map('map'); + var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS", + "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} ); + var tmsLayer = new OpenLayers.Layer.TMS("TMS", + "http://labs.metacarta.com/wms-c/Basic.py/", + {'layername':'basic', 'type':'png'}); + map.addLayers([wmsLayer,tmsLayer]); + map.setBaseLayer(wmsLayer); + map.zoomToMaxExtent(); + map.setBaseLayer(tmsLayer); + map.zoomIn(); + map.pan(0, -200, {animate:false}); + var log = []; + map.applyTransform = function(x, y, scale) { + log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]); + OpenLayers.Map.prototype.applyTransform.apply(this, arguments); + }; + map.setBaseLayer(wmsLayer); + t.eq(log[0][0], 0, "layerContainer is recentered after setBaseLayer"); + + map.destroy(); + } + + function test_Map_moveLayer (t) { + t.plan(10); + + var ct = 0; + map = new OpenLayers.Map('map'); + var wmslayer = new OpenLayers.Layer.WMS('Test Layer', + "http://octo.metacarta.com/cgi-bin/mapserv", + {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, + {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } ); + + var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2', + "http://octo.metacarta.com/cgi-bin/mapserv", + {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, + {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } ); + + var wmslayer3 = new OpenLayers.Layer.WMS('Test Layer2', + "http://octo.metacarta.com/cgi-bin/mapserv", + {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, + {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } ); + + map.addLayers([wmslayer, wmslayer2, wmslayer3]); + map.events.register("changelayer", map, function (e) { ct++; }); + t.eq( map.getNumLayers(), 3, "getNumLayers returns the number of layers" ); + t.eq( map.getLayerIndex(wmslayer3), 2, "getLayerIndex returns the right index" ); + map.raiseLayer(wmslayer3, 1); + t.eq( map.getLayerIndex(wmslayer3), 2, "can't moveLayer up past the top of the stack" ); + map.raiseLayer(wmslayer, -1); + t.eq( map.getLayerIndex(wmslayer), 0, "can't moveLayer down past the bottom of the stack" ); + map.raiseLayer(wmslayer3, -1); + t.eq( map.getLayerIndex(wmslayer3), 1, "can moveLayer down from the top" ); + t.eq( parseInt(wmslayer3.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5, + "layer div has the right zIndex after moving down" ); + map.raiseLayer(wmslayer, 2); + t.eq( map.getLayerIndex(wmslayer), 2, "can moveLayer up from the bottom" ); + t.eq( parseInt(wmslayer.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 2 * 5, + "layer div has the right zIndex after moving up" ); + t.eq( map.getLayerIndex(wmslayer3), 0, "top layer is now on the bottom" ); + t.eq( ct, 3, "raiseLayer triggered changelayer the right # of times" ); + + map.destroy(); + } + + function test_Map_moveTo(t) { + t.plan(2); + + map = new OpenLayers.Map('map'); + var baseLayer = new OpenLayers.Layer.WMS("Test Layer", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"}, + {maxResolution: 'auto', maxExtent: new OpenLayers.Bounds(-10,-10,10,10)}); + baseLayer.events.on({ + move: function() { + t.ok(true, "move listener called"); + }, + movestart: function(e) { + t.eq(e.zoomChanged, true, "movestart listener called with expected value"); + } + }); + baseLayer.events.on({ + moveend: function(e) { + t.eq(e.zoomChanged, true, "moveend listener called with expected value"); + } + }); + map.addLayer(baseLayer); + var ll = new OpenLayers.LonLat(-100,-150); + map.moveTo(ll, 2); + t.ok(map.getCenter().equals(new OpenLayers.LonLat(0,0)), "safely sets out-of-bounds lonlat"); + + map.destroy(); + } + + function test_Map_defaultTheme(t) { + t.plan(5); + + var links = document.getElementsByTagName('link'); + map = new OpenLayers.Map('map'); + var gotNodes = 0; + var themeNode = null; + for(var i=0; i<links.length; ++i) { + if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) { + gotNodes += 1; + themeNode = links.item(i); + } + } + t.eq(gotNodes, 1, "by default, a single link node is added to document"); + t.ok(themeNode != null, "a link node with the theme href was added"); + t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet"); + t.eq(themeNode.type, "text/css", "node added has type set to text/css"); + + // reconstruct the map to prove that another link is not added + map = new OpenLayers.Map('map'); + t.eq(links.length, document.getElementsByTagName('link').length, + "calling the map constructor twice with the same theme doesn't add duplicate link nodes"); + + map.destroy(); + } + + function test_Map_customTheme(t) { + t.plan(5); + + var customTheme = 'foo'; + var options = {theme: customTheme}; + map = new OpenLayers.Map('map', options); + + var links = document.getElementsByTagName('link'); + var gotNodes = 0; + var themeNode = null; + for(var i=0; i<links.length; ++i) { + if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) { + gotNodes += 1; + themeNode = links.item(i); + } + } + + t.eq(map.theme, customTheme, "map theme is properly set"); + t.eq(gotNodes, 1, "with custom theme, a single link node is added to document"); + t.ok(themeNode != null, "a link node with the theme href was added"); + t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet"); + t.eq(themeNode.type, "text/css", "node added has type set to text/css"); + + map.destroy(); + } + + function test_Map_noTheme(t) { + t.plan(1); + + var head = document.getElementsByTagName('head')[0]; + var nodeCount = head.childNodes.length; + + var options = {theme: null}; + map = new OpenLayers.Map('map', options); + + t.eq(nodeCount, head.childNodes.length, "with no theme, a node is not added to document head" ); + + map.destroy(); + } + + function test_Map_addControls(t) { + t.plan(5); + var map = new OpenLayers.Map('map', { + controls: [] + }); + var controls = [ + new OpenLayers.Control({id:'firstctrl'}), + new OpenLayers.Control({id:'secondctrl'}) + ]; + map.addControls(controls); + t.eq(map.controls.length, 2, "two controls were added by map.addControls without a px-array"); + t.eq(map.controls[0].id, 'firstctrl', "control with index 0 has id 'firstctrl'"); + t.eq(map.controls[1].id, 'secondctrl', "control with index 1 has id 'secondctrl'"); + + var controls2 = [ + new OpenLayers.Control({id:'thirdctrl'}), + new OpenLayers.Control({id:'fourthctrl'}), + new OpenLayers.Control({id:'fifthctrl'}) + ]; + // this array is intentionally one element shorter than the above + var pixels2 = [ + null, + new OpenLayers.Pixel(27,11) + ]; + map.addControls(controls2, pixels2); + t.eq(map.controls.length, 5, "three additional controls were added by map.addControls with a px-array"); + t.eq(map.controls[3].position.toString(), pixels2[1].toString(), "control 'fourthctrl' has position set to given px"); + + map.destroy(); + } + + function test_Map_getControl(t) { + t.plan(2); + + var map1 = new OpenLayers.Map('map'); + + var control = new OpenLayers.Control(); + map1.addControl(control); + + var gotControl = map1.getControl(control.id); + t.ok(gotControl == control, "got right control"); + + gotControl = map1.getControl("bogus id"); + t.ok(gotControl == null, "getControl() for bad id returns null"); + + map1.destroy(); + } + + function test_Map_removeControl(t) { + t.plan(6); + + var oldNumControls, newNumControls; + + var map1 = new OpenLayers.Map('map'); + oldNumControls = map1.controls.length; + + var control = new OpenLayers.Control(); + map1.addControl(control); + + //add control + newNumControls = map1.controls.length; + t.ok( newNumControls = oldNumControls + 1, "adding a control increases control count") + + var foundDiv = false; + for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) { + var childNode = map1.viewPortDiv.childNodes[i]; + if (childNode == control.div) { + foundDiv = true; + } + } + t.ok(foundDiv, "new control's div correctly added to viewPort"); + + //remove control + map1.removeControl(control) + newNumControls = map1.controls.length; + t.ok( newNumControls == oldNumControls, "removing the control decreases control count") + + var gotControl = map1.getControl(control.id); + t.ok( gotControl == null, "control no longer in map's controls array"); + + var foundDiv = false; + for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) { + var childNode = map1.viewPortDiv.childNodes[i]; + if (childNode == control.div) { + foundDiv = true; + } + } + t.ok(!foundDiv, "control no longer child of viewPort"); + + //remove bogus + control = { id: "bogus id" }; + map1.removeControl(control); + newNumControls = map1.controls.length; + t.ok( newNumControls == oldNumControls, "removing bad controlid doesnt crash or decrease control count") + + map1.destroy(); + + } + + function test_Map_restrictedExtent(t) { + t.plan(25); + var extent = new OpenLayers.Bounds(-180, -90, 180, 90); + var options = { + maxResolution: "auto" + }; + var map = new OpenLayers.Map("map", options); + var layer = new OpenLayers.Layer.WMS( + "test", + "http://octo.metacarta.com/cgi-bin/mapserv?", + {map: "/mapdata/vmap_wms.map", layers: "basic"} + ); + map.addLayer(layer); + map.zoomToMaxExtent(); + var nw = new OpenLayers.LonLat(extent.left, extent.top); + var ne = new OpenLayers.LonLat(extent.right, extent.top); + var sw = new OpenLayers.LonLat(extent.left, extent.bottom); + var se = new OpenLayers.LonLat(extent.right, extent.bottom); + + // try panning to northwest corner + map.setOptions({restrictedExtent: extent}); + map.setCenter(nw, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + extent.getCenterLonLat().toString(), + "map extent properly restricted to northwest at zoom 0"); + t.eq(map.zoom, 0, "zoom not restricted for nw, 0"); + map.setCenter(nw, 5); + t.eq(map.getExtent().top, extent.top, + "map extent top properly restricted to northwest at zoom 5"); + t.eq(map.getExtent().left, extent.left, + "map extent left properly restricted to northwest at zoom 5"); + t.eq(map.zoom, 5, "zoom not restricted for nw, 5"); + map.setOptions({restrictedExtent: null}); + map.setCenter(nw, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + nw.toString(), + "map extent not restricted with null restrictedExtent for nw"); + + // try panning to northeast corner + map.setOptions({restrictedExtent: extent}); + map.setCenter(ne, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + extent.getCenterLonLat().toString(), + "map extent properly restricted to northeast at zoom 0"); + t.eq(map.zoom, 0, "zoom not restricted for ne, 0"); + map.setCenter(ne, 5); + t.eq(map.getExtent().top, extent.top, + "map extent top properly restricted to northeast at zoom 5"); + t.eq(map.getExtent().right, extent.right, + "map extent right properly restricted to northeast at zoom 5"); + t.eq(map.zoom, 5, "zoom not restricted for ne, 5"); + map.setOptions({restrictedExtent: null}); + map.setCenter(ne, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + ne.toString(), + "map extent not restricted with null restrictedExtent for ne"); + + // try panning to southwest corner + map.setOptions({restrictedExtent: extent}); + map.setCenter(sw, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + extent.getCenterLonLat().toString(), + "map extent properly restricted to southwest at zoom 0"); + t.eq(map.zoom, 0, "zoom not restricted for sw, 0"); + map.setCenter(sw, 5); + t.eq(map.getExtent().bottom, extent.bottom, + "map extent bottom properly restricted to southwest at zoom 5"); + t.eq(map.getExtent().left, extent.left, + "map extent left properly restricted to southwest at zoom 5"); + t.eq(map.zoom, 5, "zoom not restricted for sw, 5"); + map.setOptions({restrictedExtent: null}); + map.setCenter(sw, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + sw.toString(), + "map extent not restricted with null restrictedExtent for sw"); + + // try panning to southeast corner + map.setOptions({restrictedExtent: extent}); + map.setCenter(se, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + extent.getCenterLonLat().toString(), + "map extent properly restricted to southeast at zoom 0"); + t.eq(map.zoom, 0, "zoom not restricted for se, 0"); + map.setCenter(se, 5); + t.eq(map.getExtent().bottom, extent.bottom, + "map extent bottom properly restricted to southeast at zoom 5"); + t.eq(map.getExtent().right, extent.right, + "map extent right properly restricted to southeast at zoom 5"); + t.eq(map.zoom, 5, "zoom not restricted for se, 5"); + map.setOptions({restrictedExtent: null}); + map.setCenter(se, 0); + t.eq(map.getExtent().getCenterLonLat().toString(), + se.toString(), + "map extent not restricted with null restrictedExtent for se"); + + map.destroy(); + + extent = new OpenLayers.Bounds(8, 44.5, 19, 50); + var options = { + restrictedExtent: extent, + zoomMethod: null + }; + map = new OpenLayers.Map('map', options); + + var wms = new OpenLayers.Layer.WMS( + "OpenLayers WMS", + "http://vmap0.tiles.osgeo.org/wms/vmap0?", + {layers: 'basic'} + ); + + map.addLayers([wms]); + map.zoomToExtent(extent); + map.zoomIn(); + map.setOptions({restrictedExtent: null}); + map.pan(-250, -250); + t.ok((map.getExtent().bottom == 48.3486328125 && map.getExtent().left == 7.45751953125), "Expected extent when toggling restrictedExtent"); + map.destroy(); + } + + function test_Map_getResolutionForZoom(t) { + t.plan(2); + var map = new OpenLayers.Map("map"); + var res = map.getResolutionForZoom(); + t.eq(res, null, "getResolutionForZoom returns null for no base layer"); + map.fractionalZoom = true; + var layer = new OpenLayers.Layer("test", {isBaseLayer: true}); + map.addLayer(layer); + layer.getResolutionForZoom = function() { + t.ok(true, "getResolutionForZoom calls base layer getResolutionForZoom"); + } + var res = map.getResolutionForZoom(); + layer.destroy(); + map.destroy(); + } + + function test_zoomTo(t) { + t.plan(8); + + var map = new OpenLayers.Map("map", {zoomMethod: null}); + map.addLayer(new OpenLayers.Layer(null, { + isBaseLayer: true + })); + + map.zoomToMaxExtent(); + + map.zoomTo(2); + t.eq(map.getZoom(), 2, 'zoomTo(2)'); + + map.zoomTo(3.6); + t.eq(map.getZoom(), 4, 'zoomTo(3.6)'); + + map.zoomTo("4.6"); + t.eq(map.getZoom(), 5, 'zoomTo("4.6")'); + + map.zoomTo("1.2"); + t.eq(map.getZoom(), 1, 'zoomTo("1.2")'); + + // now allow fractional zoom + map.fractionalZoom = true; + + map.zoomTo(2); + t.eq(map.getZoom(), 2, '[fractionalZoom] zoomTo(2)'); + + map.zoomTo(3.6); + t.eq(map.getZoom(), 3.6, '[fractionalZoom] zoomTo(3.6)'); + + map.zoomTo("4.6"); + t.eq(map.getZoom(), 4.6, '[fractionalZoom] zoomTo("4.6")'); + + map.zoomTo("1.2"); + t.eq(map.getZoom(), 1.2, '[fractionalZoom] zoomTo("1.2")'); + + map.destroy(); + } + + function test_zoomTo_animated(t) { + t.plan(2); + + var map = new OpenLayers.Map("map"); + map.addLayer(new OpenLayers.Layer(null, { + isBaseLayer: true + })); + + map.zoomToMaxExtent(); + + map.zoomTo(2); + map.zoomIn(); + map.zoomOut(); + map.zoomIn(); + t.delay_call(2, function() { + t.eq(map.getZoom(), 3, '[fractionalZoom: false] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()'); + + // now allow fractional zoom + map.fractionalZoom = true; + + map.zoomTo(2.6); + map.zoomIn(); + map.zoomOut(); + map.zoomIn(); + }); + t.delay_call(4, function() { + t.eq(map.getZoom(), 3.6, '[fractionalZoom: true] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()'); + map.destroy(); + }); + + } + + function test_Map_getUnits(t) { + t.plan(2); + var map = new OpenLayers.Map("map"); + var units = map.getUnits(); + t.eq(units, null, "getUnits returns null for no base layer"); + + var layer = new OpenLayers.Layer("test", { + isBaseLayer: true, + units: 'foo' + }); + map.addLayer(layer); + var units = map.getUnits(); + t.eq(units, 'foo', "getUnits returns the base layer units property"); + layer.destroy(); + map.destroy(); + } + + function test_Map_destroy (t) { + t.plan( 3 ); + map = new OpenLayers.Map('map'); + map.destroy(); + t.eq( map.layers, null, "map.layers is null after destroy" ); + t.eq( map.controls, null, "map.controls is null after destroy" ); + t.eq( map.viewPortDiv, null, "map's viewportDiv nullified"); + } + + function test_Map_getMaxExtent(t){ + t.plan(5); + + var options = null; + var map = {}; + + //null options, no baseLayer + var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]); + t.eq(maxExtent, null, "null options, no baseLayer returns null"); + + //null options.restricted, no baseLayer + maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]); + t.eq(maxExtent, null, "null options.restricted, no baseLayer returns null"); + + //true options.restricted, null map.restrictedExtent no baseLayer + maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]); + t.eq(maxExtent, null, "true options.restricted, null map.restrictedExtent no baseLayer returns null"); + + //true options.restricted, valid map.restrictedExtent no baseLayer + options = { + 'restricted': true + }; + map.restrictedExtent = {}; + maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]); + t.ok(maxExtent == map.restrictedExtent, "true options.restricted, valid map.restrictedExtent no baseLayer returns map.restrictedExtent"); + + //null options, valid baseLayer + options = null; + map.baseLayer = { + 'maxExtent': {} + }; + var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]); + t.ok(maxExtent == map.baseLayer.maxExtent, "null options, valid baseLayer returns map.baseLayer.maxExtent"); + } + + function test_Map_zoomToMaxExtent(t){ + t.plan(4) + + gMaxExtent = {}; + + var map = { + 'getMaxExtent': function(options) { + gRestricted = options.restricted; + return gMaxExtent; + }, + 'zoomToExtent': function(extent) { + t.ok(extent == gMaxExtent, "zoomToExtent() always called on return from map.getMaxExtent()"); + } + }; + + //options is null + var options = null; + gRestricted = null; + OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]); + t.eq(gRestricted, true, "default 'restricted' passed to map.getMaxExtent() is true"); + + //valid options + options = { + 'restricted': {} + }; + gRestricted = null; + OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]); + t.ok(gRestricted == options.restricted, "when valid options argument, 'options.restricted' passed to map.getMaxExtent()"); + } + + function test_Map_zoomToScale(t) { + t.plan(4); + + var m = { + 'baseLayer': { 'units': {} }, + 'size': {'w': 10, 'h': 15}, + 'getSize': function() { return {'w': 10, 'h': 15}; }, + 'getCachedCenter': function() { return {'lon': -5, 'lat': -25}; }, + 'zoomToExtent': function(extent, closest) { + t.ok(extent.equals(g_ExpectedExtent), "extent correctly calculated for zoomToExtent()"); + t.ok(closest == g_Closest, "closest correctly passed on to zoomToExtent()"); + } + } + + var temp = OpenLayers.Util.getResolutionFromScale; + OpenLayers.Util.getResolutionFromScale = function(scale, units) { + t.ok(scale == g_Scale, "scale parameter correctly passed to getResolutionFromScale"); + t.ok(units == m.baseLayer.units, "map's baselayer's units parameter correctly passed to getResolutionFromScale"); + return 1000; + }; + + g_ExpectedExtent = new OpenLayers.Bounds(-5005,-7525,4995,7475); + g_Scale = {}; + g_Closest = {}; + var args = [g_Scale, g_Closest]; + OpenLayers.Map.prototype.zoomToScale.apply(m, args); + + OpenLayers.Util.getResolutionFromScale = temp; + } + + function test_Map_zoomToExtent(t) { + t.plan(12); + + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer(null, {isBaseLayer: true}); + map.addLayer(layer); + + var bounds = new OpenLayers.Bounds(-160, 15, -50, 69); + var center; + + // default for closest + map.zoomToExtent(bounds); + center = map.getCenter(); + t.eq(center.lon, -105, "a) correct x"); + t.eq(center.lat, 42, "a) correct y"); + t.eq(map.getZoom(), 2, "a) correct zoom"); + + // false for closest + map.zoomToExtent(bounds, false); + center = map.getCenter(); + t.eq(center.lon, -105, "b) correct x"); + t.eq(center.lat, 42, "b) correct y"); + t.eq(map.getZoom(), 2, "b) correct zoom"); + + // true for closest + map.zoomToExtent(bounds, true); + center = map.getCenter(); + t.eq(center.lon, -105, "c) correct x"); + t.eq(center.lat, 42, "c) correct y"); + t.eq(map.getZoom(), 3, "c) correct zoom"); + + // accept array + map.zoomToExtent([-160, 15, -50, 69]); + center = map.getCenter(); + t.eq(center.lon, -105, "(array) correct x"); + t.eq(center.lat, 42, "(array) correct y"); + t.eq(map.getZoom(), 2, "(array) correct zoom"); + + map.destroy(); + } + + function test_Map_zoomToExtent_wrapped(t) { + t.plan(9); + + var map = new OpenLayers.Map("map"); + var layer = new OpenLayers.Layer(null, {isBaseLayer: true, wrapDateLine: true}); + map.addLayer(layer); + + var bounds, center; + + var cases = [{ + // real world + bbox: [120, -20, 140, 0], + center: [130, -10] + }, { + // one world to the right + bbox: [220, -45, 240, 45], + center: [-130, 0] + }, { + // two worlds to the right + bbox: [550, -15, 560, 5], + center: [-165, -5] + }, { + // one world to the left + bbox: [-240, -15, -220, 5], + center: [130, -5] + }, { + // two worlds to the left + bbox: [-600, -15, -580, 5], + center: [130, -5] + }]; + + var num = cases.length; + t.plan(num * 2); + + var c, bounds, center; + for (var i=0; i<num; ++i) { + c = cases[i]; + bounds = OpenLayers.Bounds.fromArray(c.bbox); + map.zoomToExtent(bounds); + center = map.getCenter(); + t.eq(center.lon, c.center[0], "y: " + bounds); + t.eq(center.lat, c.center[1], "x: " + bounds); + } + + map.destroy(); + } + + + function test_allOverlays(t) { + + t.plan(18); + + var map = new OpenLayers.Map({ + div: "map", allOverlays: true + }); + + var a = new OpenLayers.Layer.Vector("a", {visibility: true}); + + var b = new OpenLayers.Layer.Image( + "b", + "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif", + new OpenLayers.Bounds(-180, -88.759, 180, 88.759), + new OpenLayers.Size(580, 288) + ); + + var c = new OpenLayers.Layer.WMS( + "c", + "http://labs.metacarta.com/wms/vmap0", + {layers: 'basic'} + ); + + var d = new OpenLayers.Layer.Vector("d"); + + map.addLayers([a, b, c, d]); + + var moveCount = 0; + a.moveTo = function() { + moveCount++; + OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments); + }; + + map.zoomToMaxExtent(); + t.eq(moveCount, 1, "map.moveTo moves the base layer only once"); + t.eq(map.getCenter().toString(), "lon=0,lat=0", "a map with all overlays can have a center"); + + a.setVisibility(false); + var moveend = 0; + a.events.on({"moveend": function() { moveend++; }}); + map.zoomToMaxExtent(); + t.eq(moveCount, 1, "map.moveTo does not move the base layer if it is invisible"); + t.eq(moveend, 0, "map.moveTo does not trigger \"moveend\" in the layer if the layer is invisible"); + a.setVisibility(true); + + // a, b, c, d + t.eq(map.baseLayer.name, "a", "base layer set to first layer added"); + + map.removeLayer(a); + // b, c, d + t.eq(map.baseLayer.name, "b", "if base layer is removed, lowest layer becomes base"); + + map.addLayer(a); + // b, c, d, a + t.eq(map.baseLayer.name, "b", "adding a new layer doesn't change base layer"); + + map.setLayerIndex(c, 1); + // b, d, c, a + t.eq(map.baseLayer.name, "b", "changing layer order above base doesn't mess with base"); + + map.setLayerIndex(d, 0); + // d, b, c, a + t.eq(map.baseLayer.name, "d", "changing layer order to 0 sets base layer"); + + map.raiseLayer(d, 1); + // b, d, c, a + t.eq(map.baseLayer.name, "b", "raising the base layer sets a new base layer"); + + map.raiseLayer(d, -1); + // d, b, c, a + t.eq(map.baseLayer.name, "d", "lowering a layer to lowest index sets as base"); + + // all this switching of base layer didn't muck with layer visibility + t.eq(a.visibility, true, "a is visible"); + t.eq(b.visibility, true, "b is visible"); + t.eq(c.visibility, true, "c is visible"); + t.eq(d.visibility, true, "d is visible"); + + // test that map can have an invisible base layer + b.setVisibility(false); + map.setLayerIndex(b, 0); + t.eq(b.visibility, false, "changing layer order doesn't change visibility"); + + + map.destroy(); + + // make sure setVisibility is called when adding a single layer to the map + map = new OpenLayers.Map({ + div: "map", allOverlays: true + }); + var count = 0; + var layer = new OpenLayers.Layer(null, { + visibility: true, + maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90), + setVisibility: function() { + ++count; + OpenLayers.Layer.prototype.setVisibility.apply(this, arguments); + } + }); + map.addLayer(layer); + map.zoomToMaxExtent(); + + t.eq(count, 1, "setVisibility called when visibility is true in layer config"); + t.eq(layer.div.style.display, "", "layer is visible."); + + map.destroy(); + + } + + function test_panTo(t) { + + t.plan(6); + + var log = []; + var map = new OpenLayers.Map("map", { + eventListeners: { + "movestart": function() {log.push("movestart");}, + "move": function() {log.push("move");}, + "moveend": function() {log.push("moveend");} + } + }); + map.addLayer( + new OpenLayers.Layer(null, {isBaseLayer: true}) + ); + map.setCenter(new OpenLayers.LonLat(0, 0), 0); + t.eq(log[log.length-1], "moveend", "moveend fired when map center is set"); + log = []; + + map.panTo(new OpenLayers.LonLat(1, 0)); + t.eq(map.panTween.playing, true, "the map pan tween is playing before destroy"); + + t.delay_call(2, function() { + t.eq(log[0], "movestart", "panTo starts with movestart event"); + t.eq(log[1], "move", "move events fired while panning"); + t.eq(log[log.length-1], "moveend", "panTo finishes with moveend event"); + map.destroy(); + t.ok(!map.panTween || !map.panTween.playing, "the map pan tween is not playing after destroy"); + }); + } + + function test_pan(t) { + t.plan(4); + + var map = new OpenLayers.Map("map"); + map.addLayer( + new OpenLayers.Layer(null, {isBaseLayer: true}) + ); + map.setCenter(new OpenLayers.LonLat(0, 0), 5); + var log = []; + map.events.on({ + "movestart": function() {log.push("movestart");}, + "move": function() {log.push("move");}, + "moveend": function() {log.push("moveend");} + }); + + // simulate the drag sequence of the DragPan control; + map.pan(5,5, {animate: false, dragging: true}); + map.pan(1,1, {animate: false, dragging: false}); + + t.eq(log[0], "movestart", "pan sequence starts with movestart"); + t.eq(log[1], "move", "followed by move,"); + t.eq(log[log.length-2], "move", "move again before we stop panning,"); + t.eq(log[log.length-1], "moveend", "and moveend when we're done."); + } + + function test_pan_no_anim_event_sequence(t) { + t.plan(4); + + var log = []; + var map = new OpenLayers.Map("map"); + map.addLayer( + new OpenLayers.Layer(null, {isBaseLayer: true}) + ); + map.setCenter(new OpenLayers.LonLat(0, 0), 5); + map.events.on({ + "movestart": function() { + log.push("movestart"); + }, + "move": function() { + log.push("move"); + }, + "moveend": function() { + log.push("moveend"); + } + }); + + map.pan(5,5, {animate: false}); + t.eq(log.length, 3, "no more than 3 events happen."); + t.eq(log[0], "movestart", "pan sequence starts with movestart"); + t.eq(log[1], "move", "followed by move,"); + t.eq(log[2], "moveend", "and moveend when we're done."); + + map.destroy(); + } + + // test if we can call updateSize before document.body is ready. updateOk + // is tested in the test_updateSize function below + var earlyMap = new OpenLayers.Map(); + var updateOk; + try { + earlyMap.updateSize(); + updateOk = true; + } catch(e) {} + earlyMap.destroy(); + function test_updateSize(t) { + t.plan(3); + + // checking updateSize from outside this test function (see above) + t.ok(updateOk, "updateSize works before document.body is ready"); + + var map, moveToCnt, size; + + map = new OpenLayers.Map({div: "map"}); + map.addLayer(new OpenLayers.Layer("layer", {isBaseLayer: true})); + + map.moveTo = function() { + moveToCnt++; + OpenLayers.Map.prototype.moveTo.apply(this, arguments); + }; + + map.getCurrentSize = function() { + return size; + }; + + // map has no center + // 1 test + moveToCnt = 0; + size = new OpenLayers.Size(650, 350); + map.updateSize(); + t.eq(moveToCnt, 0, "updateSize doesn't move the map if it doesn't have a center"); + + // map has a center + // 1 test + map.zoomToMaxExtent(); + moveToCnt = 0; + size = new OpenLayers.Size(600, 300); + map.updateSize(); + t.eq(moveToCnt, 1, "updateSize move the map if it has a center"); + + map.destroy(); + } + + function test_invisible_map(t) { + /** + * This test confirms that initializing a map using an element that is + * not currently displayed doesn't cause any trouble. + */ + t.plan(1); + + var map, msg = "initializing a map on an undisplayed element"; + try { + map = new OpenLayers.Map("invisimap"); + } catch (err) { + msg += ": " + err; + } + t.ok(!!map, msg); + + if (map) { + map.destroy(); + } + } + + function test_layers_option(t) { + + t.plan(3); + + var map = new OpenLayers.Map({ + div: "map", + layers: [ + new OpenLayers.Layer() + ] + }); + + t.eq(map.layers.length, 1, "single layer from options added"); + + map.destroy(); + + map = new OpenLayers.Map({ + div: "map", + layers: [ + new OpenLayers.Layer(null, {isBaseLayer: true}), + new OpenLayers.Layer(null, {isBaseLayer: false}) + ] + }); + + t.eq(map.layers.length, 2, "multiple layers added from options"); + t.ok(map.baseLayer, "map has a base layer"); + + map.destroy(); + + } + + function test_center_option(t) { + t.plan(7); + + var map, msg; + + + // try setting center without layers, this has no effect + var failed = false; + try { + map = new OpenLayers.Map({ + div: "map", + center: new OpenLayers.LonLat(1, 2) + }); + msg = "center option without layers has no effect"; + } catch (err) { + failed = true; + msg = "center option without layers throws error"; + } + t.ok(!failed, msg); + + if (map) { + map.destroy(); + } + + var log = []; + var meth = OpenLayers.Layer.prototype.moveTo; + OpenLayers.Layer.prototype.moveTo = function() { + log.push(arguments); + meth.apply(this, arguments); + }; + + // set center without zoom + var center = new OpenLayers.LonLat(1, 2); + map = new OpenLayers.Map({ + div: "map", + layers: [new OpenLayers.Layer(null, {isBaseLayer: true})], + center: center + }); + + t.ok(center.equals(map.getCenter()), "map center set without zoom"); + t.eq(log.length, 1, "moveTo called once"); + + map.destroy(); + OpenLayers.Layer.prototype.moveTo = meth; + + // set center and zoom + var zoom = 3; + map = new OpenLayers.Map({ + div: "map", + layers: [new OpenLayers.Layer(null, {isBaseLayer: true})], + center: center, + zoom: zoom + }); + + t.ok(center.equals(map.getCenter()), "map center set with center and zoom"); + t.eq(zoom, map.getZoom(), "map zoom set with center and zoom"); + + map.destroy(); + + // set center and zoom with all overlays + map = new OpenLayers.Map({ + div: "map", + allOverlays: true, + layers: [new OpenLayers.Layer()], + center: center, + zoom: zoom + }); + + t.ok(center.equals(map.getCenter()), "map center set with all overlays"); + t.eq(zoom, map.getZoom(), "map zoom set with all overlays"); + + map.destroy(); + + } + function test_pixel_lonlat(t) { + + t.plan(4); + + var map = new OpenLayers.Map({ + div: "map", + layers: [ + new OpenLayers.Layer("name", {isBaseLayer:true}) + ] + }); + map.zoomToMaxExtent(); + var px = map.getPixelFromLonLat(map.getLonLatFromPixel(new OpenLayers.Pixel(100, 100))); + t.eq(px.x, 100, "x is the same in and ot"); + t.eq(px.y, 100, "y is the same in and out"); + var ll = map.getLonLatFromPixel(map.getPixelFromLonLat(new OpenLayers.LonLat(100, 100))); + t.ok((ll.lon > (100 -map.getResolution()) && (ll.lon < (100 + map.getResolution()))), "lon is the same in and ot"); + t.ok((ll.lat > (100 -map.getResolution()) && (ll.lat < (100 + map.getResolution()))), "lat is the same in and ot"); + map.destroy(); + } + + function test_moveByPx(t) { + t.plan(14); + + var moved; + var Layer = OpenLayers.Class(OpenLayers.Layer, { + moveByPx: function(dx, dy) { + moved[this.name] = true; + } + }); + + var map = new OpenLayers.Map({ + div: 'map', + maxExtent: new OpenLayers.Bounds(-50, -50, 50, 50), + restrictedExtent: new OpenLayers.Bounds(-10, -10, 10, 10), + layers: [ + new Layer('base', + {isBaseLayer: true}), + new Layer('outofrange', + {isBaseLayer: false, minResolution:2}) + ] + }); + var log = []; + map.applyTransform = function(x, y, scale) { + log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]); + OpenLayers.Map.prototype.applyTransform.apply(this, arguments); + }; + + moved = {}; + map.zoomToExtent(new OpenLayers.Bounds(-1, -1, 1, 1)); + + // check initial state + t.eq(log[0][0], 0, + '[initial state] layer container left correct'); + t.eq(log[0][1], 0, + '[initial state] layer container top correct'); + t.eq(moved['base'], undefined, + '[initial state] base layer not moved'); + t.eq(moved['outofrange'], undefined, + '[initial state] out-of-range layer not moved'); + + // move to a valid position + moved = {}; + map.moveByPx(-455, 455); + t.eq(log[1][0], 455, + '[valid position] layer container left correct'); + t.eq(log[1][1], -455, + '[valid position] layer container top correct'); + t.eq(moved['base'], true, + '[valid position] base layer moved'); + t.eq(moved['outofrange'], undefined, + '[valid position] out-of-range layer not moved'); + + // move outside the max extent + moved = {}; + map.moveByPx(-4500, 4500); + t.eq(log.length, 2, + '[outside max extent] layer container offset unchanged'); + t.eq(moved['base'], undefined, + '[outside max extent] base layer not moved'); + t.eq(moved['outofrange'], undefined, + '[outside max extent] out-of-range layer not moved'); + + // move outside the restricted extent + moved = {}; + map.moveByPx(-500, 500); + t.eq(log.length, 2, + '[outside restricted extent] layer container offset unchanged'); + t.eq(moved['base'], undefined, + '[outside restricted extent] base layer not moved'); + t.eq(moved['outofrange'], undefined, + '[outside restricted extent] out-of-range layer not moved'); + + + map.destroy(); + } + + // test for http://trac.osgeo.org/openlayers/ticket/3388 + function test_moveByPx_restrictedExtent(t) { + t.plan(2); + + var map = new OpenLayers.Map({ + div: 'map', + restrictedExtent: new OpenLayers.Bounds(-22.5,-11.25,22.5,11.25), + layers: [ + new OpenLayers.Layer('name', {isBaseLayer: true}) + ] + }); + + map.zoomToExtent(new OpenLayers.Bounds(-11.25, 0, 11.25, 11.25)); + + var log = []; + map.applyTransform = function(x, y, scale) { + log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]); + OpenLayers.Map.prototype.applyTransform.apply(this, arguments); + }; + + map.moveByPx(-10, -10); + t.eq(log[0][0], 10, 'layer container left correct'); + t.eq(log[0][1], 0, 'layer container top correct'); + } + + function test_applyTransform(t) { + t.plan(10); + var origStylePrefix = OpenLayers.Util.vendorPrefix.style; + OpenLayers.Util.vendorPrefix.style = + OpenLayers.Util.vendorPrefix.css = + function(key) { return 'transform'; }; + + var map = new OpenLayers.Map('map'); + map.layerContainerDiv = {style: {}}; + delete map.applyTransform.transform; + delete map.applyTransform.template; + var origGetStyle = OpenLayers.Element.getStyle; + OpenLayers.Element.getStyle = function() { return 'foo'; } + map.applyTransform(1, 2, 3); + OpenLayers.Element.getStyle = origGetStyle; + t.eq(map.layerContainerDiv.style.transform, 'translate3d(1px,2px,0) scale3d(3,3,1)', '3d transform and scale used when available'); + + delete map.applyTransform.transform; + delete map.applyTransform.template; + var origIndexOf = String.prototype.indexOf; + String.prototype.indexOf = function() { return -1; }; + map.layerContainerOriginPx = {x: -3, y: 2}; + map.applyTransform(1, 2, 3); + String.prototype.indexOf = origIndexOf; + t.eq(map.layerContainerDiv.style.transform, 'translate(4px,0px) scale(3,3)', '2d translate and scale correct'); + t.eq(map.layerContainerDiv.style.left, '-3px', 'container origin x set as style.left'); + t.eq(map.layerContainerDiv.style.top, '2px', 'container origin y set as style.top'); + map.applyTransform(1, 2); + t.ok(!map.layerContainerDiv.style.transform, 'no transform set when no transform needed'); + t.eq(map.layerContainerDiv.style.left, '1px', 'style.left correct when no transform needed'); + t.eq(map.layerContainerDiv.style.top, '2px', 'style.top correct when no transform needed'); + + map.applyTransform.transform = null; + map.applyTransform(4, 5, 6); + t.eq(map.layerContainerDiv.style.left, '4px', 'style.left set when transform not available') + t.eq(map.layerContainerDiv.style.top, '5px', 'style.top set when transform not available') + t.ok(!map.layerContainerDiv.style.transform, 'no transform set, because not supported'); + + map.destroy(); + delete map.applyTransform.transform; + delete map.applyTransform.template; + OpenLayers.Util.vendorPrefix.style = origStylePrefix; + } + + function test_options(t) { + t.plan(2); + + var map = new OpenLayers.Map('map'); + t.eq(map.options, {}, 'map.options is empty with no options'); + map.destroy(); + + var options = { + resolutions: [1,2,3,5], + projection: "EPSG:4326", + units: 'm' + }; + var map = new OpenLayers.Map('map', options); + t.eq(map.options, options, 'map.options is a copy of the constructor option'); + map.destroy(); + } + + function test_adjustZoom(t) { + t.plan(5); + var map = new OpenLayers.Map({ + div: 'map', + layers: [ + new OpenLayers.Layer('name', { + isBaseLayer: true, + wrapDateLine: true + }) + ] + }); + map.zoomToMaxExtent(); + t.ok(map.getResolution() <= map.getMaxExtent().getWidth() / map.getSize().w, "wrapDateLine map not wider than world"); + + t.eq(map.adjustZoom(9), 9, "valid zoom maintained"); + t.eq(map.adjustZoom(1), 2, "zoom adjusted to not exceed world width"); + + map.fractionalZoom = true; + t.eq(map.adjustZoom(1).toPrecision(3), "1.29", "zoom adjusted to match world width"); + + map.moveTo([16, 48], 0); + t.eq(map.getCenter().toShortString(), "0, 0", "no panning when moveTo is called with invalid zoom"); + } + + function test_correctCenterAtZoomLevel0(t) { + t.plan(1); + var map = new OpenLayers.Map({ + div: 'map', + maxExtent: new OpenLayers.Bounds(-30, 48.00, 3.50, 64.00), + restrictedExtent: new OpenLayers.Bounds(-30, 48.00, 3.50, 64.00), + projection: "EPSG:4258", + units: "degrees", + layers: [ + new OpenLayers.Layer('name', { + isBaseLayer: true + }) + ] + }); + map.setCenter(new OpenLayers.LonLat(-1.3, 50.8), 4); + map.moveTo(null, 0); + var center = map.getCenter(); + t.ok(center.equals(new OpenLayers.LonLat(-13.25, 56)), "Center is correct and not equal to maxExtent's center"); + } + + function test_getZoomTargetCenter(t) { + t.plan(1); + var map = new OpenLayers.Map({ + div: 'map', + layers: [ + new OpenLayers.Layer('', {isBaseLayer: true}) + ], + center: [0, 0], + zoom: 1 + }); + + var ll = map.getZoomTargetCenter({x: 44, y: 22}, map.getMaxResolution()); + + t.eq(ll.toShortString(), "180, -90", "getZoomTargetCenter works."); + + map.destroy(); + } + + function test_autoUpdateSize(t) { + t.plan(1); + OpenLayers.Event.unloadCache(); + var resizeListener = false; + var map = new OpenLayers.Map({ + autoUpdateSize: false, + div: 'map', + layers: [ + new OpenLayers.Layer('name', { + isBaseLayer: true, + wrapDateLine: true + }) + ] + }); + map.setCenter(new OpenLayers.LonLat(-1.3, 50.8), 4); + for (var key in OpenLayers.Event.observers) { + var obj = OpenLayers.Event.observers[key]; + for (var i=0, ii=obj.length; i<ii; ++i) { + var listener = obj[i]; + if (listener.name === 'resize' && listener.element === window) { + resizeListener = true; + } + } + } + t.eq(resizeListener, map.autoUpdateSize, "resize listener not registered when autoUpdateSize is false"); + map.destroy(); + } + + function test_tileManager(t) { + t.plan(3); + var map = new OpenLayers.Map('map'); + t.ok(map.tileManager instanceof OpenLayers.TileManager, "Default tileManager created"); + map.destroy(); + map = new OpenLayers.Map('map', {tileManager: null}); + t.ok(map.tileManager === null, "No tileManager created"); + map.destroy(); + var options = {cacheSize: 512}; + map = new OpenLayers.Map('map', {tileManager: options}); + t.eq(map.tileManager.cacheSize, 512, "cacheSize taken from options"); + map.destroy(); + } + + </script> +</head> +<body> + <div id="map" style="width: 600px; height: 300px;"/> + <div style="display: none;"><div id="invisimap"></div></div> +</body> +</html> |