]> dev.renevier.net Git - syp.git/blob - openlayers/tests/Map.html
initial commit
[syp.git] / openlayers / tests / Map.html
1 <html>
2 <head>
3   <script src="../lib/OpenLayers.js"></script>
4   <script type="text/javascript">
5
6     var isMozilla = (navigator.userAgent.indexOf("compatible") == -1);
7     var map;
8
9     function test_Map_constructor (t) {
10         t.plan( 11 );
11         
12         map = new OpenLayers.Map('map'); 
13         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
14             "http://octo.metacarta.com/cgi-bin/mapserv?",
15             {map: "/mapdata/vmap_wms.map", layers: "basic"});
16         map.addLayer(baseLayer);
17
18         t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class");
19
20         t.ok( map instanceof OpenLayers.Map, "new OpenLayers.Map returns object" );
21         if (!isMozilla) {
22             t.ok( true, "skipping element test outside of Mozilla");
23             t.ok( true, "skipping element test outside of Mozilla");
24             t.ok( true, "skipping element test outside of Mozilla");
25         } else {
26             t.ok( map.div instanceof HTMLDivElement, "map.div is an HTMLDivElement" );
27             t.ok( map.viewPortDiv instanceof HTMLDivElement, "map.viewPortDiv is an HTMLDivElement" );
28             t.ok( map.layerContainerDiv instanceof HTMLDivElement, "map.layerContainerDiv is an HTMLDivElement" );
29         }
30         t.ok( map.layers instanceof Array, "map.layers is an Array" );
31         t.ok( map.controls instanceof Array, "map.controls is an Array" );
32         t.eq( map.controls.length, 4, "Default map has 4 controls." );
33         t.ok( map.events instanceof OpenLayers.Events, "map.events is an OpenLayers.Events" );
34         t.ok( map.getMaxExtent() instanceof OpenLayers.Bounds, "map.maxExtent is an OpenLayers.Bounds" );
35         t.ok( map.getNumZoomLevels() > 0, "map has a default numZoomLevels" );
36     }
37     
38     function test_Map_constructor_late_rendering(t) {
39         t.plan( 4 );
40         
41         map = new OpenLayers.Map(); 
42         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
43             "http://octo.metacarta.com/cgi-bin/mapserv?",
44             {map: "/mapdata/vmap_wms.map", layers: "basic"});
45         map.addLayer(baseLayer);
46         
47         t.ok(map.div != null, "Map has a div even though none was specified.");
48         t.ok(map.viewPortDiv.parentNode == map.div, "Map is attached to a temporary div that holds the viewPortDiv.");
49         
50         var mapDiv = document.getElementById("map");
51         // clean up the effects of other tests
52         while(OpenLayers.Element.hasClass(mapDiv, "olMap")) {
53             OpenLayers.Element.removeClass(mapDiv, "olMap");
54         }
55         map.render(mapDiv); // Can also take a string.
56         
57         t.ok(map.div == mapDiv, "Map is now rendered to the 'map' div.")
58         t.ok( OpenLayers.Element.hasClass(map.div, "olMap"), "Map div has olMap class");
59     }
60     
61     function test_Map_constructor_renderTo(t) {
62         t.plan( 1 );
63         
64         map = new OpenLayers.Map({
65             div: "map"
66         }); 
67         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
68             "http://octo.metacarta.com/cgi-bin/mapserv?",
69             {map: "/mapdata/vmap_wms.map", layers: "basic"});
70         map.addLayer(baseLayer);
71         
72         var mapDiv = document.getElementById("map");
73         t.ok(map.div == mapDiv, "Map is rendered to the 'map' div.")
74     }
75
76     function test_Map_setOptions(t) {
77         t.plan(2);
78         map = new OpenLayers.Map('map', {maxExtent: new OpenLayers.Bounds(100, 200, 300, 400)});
79         map.setOptions({theme: 'foo'});
80         
81         t.eq(map.theme, 'foo', "theme is correctly set by setOptions");
82         t.ok(map.maxExtent.equals(new OpenLayers.Bounds(100, 200, 300, 400)), 
83              "maxExtent is correct after calling setOptions");
84     }
85
86     function test_Map_add_layers(t) {
87         t.plan(6);
88         map = new OpenLayers.Map('map');
89         var layer1 = new OpenLayers.Layer.WMS("Layer 1", 
90             "http://octo.metacarta.com/cgi-bin/mapserv?",
91             {map: "/mapdata/vmap_wms.map", layers: "basic"});
92         var layer2 = new OpenLayers.Layer.WMS("Layer 2",
93             "http://wms.jpl.nasa.gov/wms.cgi", {layers: "modis,global_mosaic"});
94         // this uses map.addLayer internally
95         map.addLayers([layer1, layer2])
96         t.eq( map.layers.length, 2, "map has exactly two layers" );
97         t.ok( map.layers[0] === layer1, "1st layer is layer1" );
98         t.ok( map.layers[1] === layer2, "2nd layer is layer2" );
99         t.ok( layer1.map === map, "layer.map is map" ); 
100         t.eq( parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'], 
101                 "layer1 zIndex is set" );
102         t.eq( parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5, 
103                 "layer2 zIndex is set" );
104     }
105
106     function test_Map_options(t) {
107         t.plan(3);
108         map = new OpenLayers.Map('map', {numZoomLevels: 6, maxResolution: 3.14159, theme: 'foo'});
109         t.eq( map.numZoomLevels, 6, "map.numZoomLevels set correctly via options hashtable" );
110         t.eq( map.maxResolution, 3.14159, "map.maxResolution set correctly via options hashtable" );
111         t.eq( map.theme, 'foo', "map theme set correctly." );
112     }
113     
114     function test_eventListeners(t) {
115         t.plan(1);
116         
117         var method = OpenLayers.Events.prototype.on;
118         // test that events.on is called at map construction
119         var options = {
120             eventListeners: {foo: "bar"},
121             controls: []
122         };
123         OpenLayers.Events.prototype.on = function(obj) {
124             t.eq(obj, options.eventListeners, "events.on called with eventListeners");
125         }
126         var map = new OpenLayers.Map('map', options);
127         OpenLayers.Events.prototype.on = method;
128         map.destroy();
129
130         // if events.on is called again, this will fail due to an extra test
131         // test map without eventListeners
132         OpenLayers.Events.prototype.on = function(obj) {
133             t.fail("events.on called without eventListeners");
134         }
135         var map2 = new OpenLayers.Map("map", {controls: []});
136         OpenLayers.Events.prototype.on = method;
137         map2.destroy();
138     }
139
140     function test_Map_center(t) {
141         t.plan(8);
142         map = new OpenLayers.Map('map');
143         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
144             "http://octo.metacarta.com/cgi-bin/mapserv?",
145             {map: "/mapdata/vmap_wms.map", layers: "basic"} );
146         map.addLayer(baseLayer);
147         var ll = new OpenLayers.LonLat(2,1);
148         map.setCenter(ll, 0);
149         t.ok( map.getCenter() instanceof OpenLayers.LonLat, "map.getCenter returns a LonLat");
150         t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter");
151         t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter");
152         map.zoomIn();
153         t.eq( map.getZoom(), 1, "map.zoom is correct after calling setCenter,zoom in");
154         t.ok( map.getCenter().equals(ll), "map center is correct after calling setCenter, zoom in");
155         map.zoomOut();
156         t.eq( map.getZoom(), 0, "map.zoom is correct after calling setCenter,zoom in, zoom out");
157
158         map.zoomTo(5);
159         t.eq( map.getZoom(), 5, "map.zoom is correct after calling zoomTo" );
160
161     /**
162         map.zoomToMaxExtent();
163         t.eq( map.getZoom(), 2, "map.zoom is correct after calling zoomToMaxExtent" );
164         var lonlat = map.getCenter();
165         var zero = new OpenLayers.LonLat(0, 0);
166         t.ok( lonlat.equals(zero), "map center is correct after calling zoomToFullExtent" );
167     */
168
169         map.getCenter().lon = 10;
170         t.ok( map.getCenter().equals(ll), "map.getCenter returns a clone of map.center");
171     }
172
173     function test_Map_zoomend_event (t) {
174         t.plan(2);
175
176         map = new OpenLayers.Map('map');
177         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
178             "http://octo.metacarta.com/cgi-bin/mapserv?",
179             {map: "/mapdata/vmap_wms.map", layers: "basic"});
180         map.addLayer(baseLayer);
181         map.events.register("zoomend", {count: 0}, function() { 
182             this.count++; 
183             t.ok(true, "zoomend event was triggered " + this.count + " times");
184             });
185         map.setCenter(new OpenLayers.LonLat(2, 1), 0);
186         map.zoomIn();
187         map.zoomOut();
188     }
189
190     function test_Map_add_remove_popup (t) {
191         t.plan(4);
192
193         map = new OpenLayers.Map('map');
194         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
195             "http://octo.metacarta.com/cgi-bin/mapserv?",
196             {map: "/mapdata/vmap_wms.map", layers: "basic"});
197         map.addLayer(baseLayer);
198         
199         var popup = new OpenLayers.Popup("chicken", 
200                                          new OpenLayers.LonLat(0,0),
201                                          new OpenLayers.Size(200,200));
202         map.setCenter(new OpenLayers.LonLat(0, 0), 0);
203
204         map.addPopup(popup);
205         var pIndex = OpenLayers.Util.indexOf(map.popups, popup);
206         t.eq(pIndex, 0, "popup successfully added to Map's internal popups array");
207
208         var nodes = map.layerContainerDiv.childNodes;
209         
210         var found = false;
211         for (var i=0; i < nodes.length; i++) {
212             if (nodes.item(i) == popup.div) {
213                 found = true;
214                 break;
215             }
216         }
217         t.ok(found, "popup.div successfully added to the map's viewPort");
218
219         
220         map.removePopup(popup);
221         var pIndex = OpenLayers.Util.indexOf(map.popups, popup);
222         t.eq(pIndex, -1, "popup successfully removed from Map's internal popups array");
223
224         var found = false;
225         for (var i=0; i < nodes.length; i++) {
226             if (nodes.item(i) == popup.div) {
227                 found = true;
228                 break;
229             }
230         }
231         t.ok(!found, "popup.div successfully removed from the map's viewPort");
232     }
233
234     function test_Map_add_popup_exclusive(t) {
235         t.plan(2);
236
237         map = new OpenLayers.Map('map');
238         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
239             "http://octo.metacarta.com/cgi-bin/mapserv?",
240             {map: "/mapdata/vmap_wms.map", layers: "basic"});
241         map.addLayer(baseLayer);
242         
243         map.setCenter(new OpenLayers.LonLat(0, 0), 0);
244
245         for (var i = 0; i < 10; i++) {
246             var popup = new OpenLayers.Popup("chicken", 
247                                              new OpenLayers.LonLat(0,0),
248                                              new OpenLayers.Size(200,200));
249             map.addPopup(popup);
250         }
251         t.eq(map.popups.length, 10, "addPopup non exclusive mode works");
252
253         var popup = new OpenLayers.Popup("chicken", 
254                                          new OpenLayers.LonLat(0,0),
255                                          new OpenLayers.Size(200,200));
256         map.addPopup(popup, true);
257         t.eq(map.popups.length, 1, "addPopup exclusive mode works");
258     }   
259     
260
261 /***  THIS IS A GOOD TEST, BUT IT SHOULD BE MOVED TO WMS. 
262  *     Also, it won't work until we figure out the viewSize bug
263
264     function 08_Map_px_lonlat_translation (t) {
265         t.plan( 6 );    
266         map = new OpenLayers.Map('map');
267         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
268             "http://octo.metacarta.com/cgi-bin/mapserv?",
269             {map: "/mapdata/vmap_wms.map", layers: "basic"});
270         map.addLayer(baseLayer);
271         map.setCenter(new OpenLayers.LonLat(0, 0), 0);
272  
273         var pixel = new OpenLayers.Pixel(50,150);
274         var lonlat = map.getLonLatFromViewPortPx(pixel);
275         t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromViewPortPx returns valid OpenLayers.LonLat" );
276
277         var newPixel = map.getViewPortPxFromLonLat(lonlat);
278         t.ok( newPixel instanceof OpenLayers.Pixel, "getViewPortPxFromLonLat returns valid OpenLayers.Pixel" );
279
280         // WARNING!!!  I'm faily sure that the following test's validity 
281         //             depends highly on rounding and the resolution. For now,
282         //             in the default case, it seems to work. This may not 
283         //             always be so.
284         t.ok( newPixel.equals(pixel), "Translation to pixel and back to lonlat is consistent");
285
286         lonlat = map.getLonLatFromPixel(pixel);
287         t.ok( lonlat instanceof OpenLayers.LonLat, "getLonLatFromPixel returns valid OpenLayers.LonLat" );
288
289         newPixel = map.getPixelFromLonLat(lonlat);
290         t.ok( newPixel instanceof OpenLayers.Pixel, "getPixelFromLonLat returns valid OpenLayers.Pixel" );
291
292         t.ok( newPixel.equals(pixel), "2nd translation to pixel and back to lonlat is consistent");
293     }
294  */
295
296     function test_Map_isValidLonLat(t) {
297         t.plan( 3 );    
298
299         map = new OpenLayers.Map('map');
300         layer = new OpenLayers.Layer.WMS('Test Layer', 
301                     "http://octo.metacarta.com/cgi-bin/mapserv", 
302                     {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
303                     {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
304         map.addLayer(layer);
305         
306         t.ok( !map.isValidLonLat(null), "null lonlat is not valid" );
307         t.ok( map.isValidLonLat(new OpenLayers.LonLat(33862, 717606)), "lonlat outside max extent is valid" );
308         t.ok( !map.isValidLonLat(new OpenLayers.LonLat(10, 10)), "lonlat outside max extent is not valid" );
309     }
310
311     function test_Map_getLayer(t) {
312         var numLayers = 3;
313         t.plan( numLayers + 1 );    
314
315         var m = {
316             layers: []
317         };
318         
319         for(var i = 0; i < numLayers; i++) {
320             m.layers.push( { 'id': i } );
321         }
322
323         for(var i = 0; i < numLayers; i++) {
324             var layer = OpenLayers.Map.prototype.getLayer.apply(m, [i]);
325             t.ok( layer == m.layers[i], "getLayer correctly returns layer " + i);
326         }
327
328         var gotLayer = OpenLayers.Map.prototype.getLayer.apply(m, ["chicken"]);
329         t.ok( gotLayer == null, "getLayer correctly returns null when layer not found");
330     }
331
332     function test_Map_getLayersBy(t) {
333         
334         var map = {
335             getBy: OpenLayers.Map.prototype.getBy,
336             getLayersBy: OpenLayers.Map.prototype.getLayersBy,
337             layers: [
338                 {foo: "foo", id: Math.random()},
339                 {foo: "bar", id: Math.random()},
340                 {foo: "foobar", id: Math.random()},
341                 {foo: "foo bar", id: Math.random()},
342                 {foo: "foo", id: Math.random()}
343             ]
344         };
345
346         var cases = [
347             {
348                 got: map.getLayersBy("foo", "foo"),
349                 expected: [map.layers[0], map.layers[4]],
350                 message: "(string literal) got two layers matching foo"
351             }, {
352                 got: map.getLayersBy("foo", "bar"),
353                 expected: [map.layers[1]],
354                 message: "(string literal) got one layer matching foo"
355             }, {
356                 got: map.getLayersBy("foo", "barfoo"),
357                 expected: [],
358                 message: "(string literal) got empty array for no foo match"
359             }, {
360                 got: map.getLayersBy("foo", /foo/),
361                 expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
362                 message: "(regexp literal) got three layers containing string"
363             }, {
364                 got: map.getLayersBy("foo", /foo$/),
365                 expected: [map.layers[0], map.layers[4]],
366                 message: "(regexp literal) got three layers ending with string"
367             }, {
368                 got: map.getLayersBy("foo", /\s/),
369                 expected: [map.layers[3]],
370                 message: "(regexp literal) got layer containing space"
371             }, {
372                 got: map.getLayersBy("foo", new RegExp("BAR", "i")),
373                 expected: [map.layers[1], map.layers[2], map.layers[3]],
374                 message: "(regexp object) got layers ignoring case"
375             }, {
376                 got: map.getLayersBy("foo", {test: function(str) {return str.length > 3;}}),
377                 expected: [map.layers[2], map.layers[3]],
378                 message: "(custom object) got layers with foo length greater than 3"
379             }
380         ];
381         t.plan(cases.length);
382         for(var i=0; i<cases.length; ++i) {
383             t.eq(cases[i].got, cases[i].expected, cases[i].message);
384         }
385         
386     }
387
388     function test_Map_getLayersByName(t) {
389         
390         var map = {
391             getBy: OpenLayers.Map.prototype.getBy,
392             getLayersBy: OpenLayers.Map.prototype.getLayersBy,
393             getLayersByName: OpenLayers.Map.prototype.getLayersByName,
394             layers: [
395                 {name: "foo", id: Math.random()},
396                 {name: "bar", id: Math.random()},
397                 {name: "foobar", id: Math.random()},
398                 {name: "foo bar", id: Math.random()},
399                 {name: "foo", id: Math.random()}
400             ]
401         };
402
403         var cases = [
404             {
405                 got: map.getLayersByName("foo"),
406                 expected: [map.layers[0], map.layers[4]],
407                 message: "(string literal) got two layers matching name"
408             }, {
409                 got: map.getLayersByName("bar"),
410                 expected: [map.layers[1]],
411                 message: "(string literal) got one layer matching name"
412             }, {
413                 got: map.getLayersByName("barfoo"),
414                 expected: [],
415                 message: "(string literal) got empty array for no match"
416             }, {
417                 got: map.getLayersByName(/foo/),
418                 expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
419                 message: "(regexp literal) got three layers containing string"
420             }, {
421                 got: map.getLayersByName(/foo$/),
422                 expected: [map.layers[0], map.layers[4]],
423                 message: "(regexp literal) got three layers ending with string"
424             }, {
425                 got: map.getLayersByName(/\s/),
426                 expected: [map.layers[3]],
427                 message: "(regexp literal) got layer containing space"
428             }, {
429                 got: map.getLayersByName(new RegExp("BAR", "i")),
430                 expected: [map.layers[1], map.layers[2], map.layers[3]],
431                 message: "(regexp object) got layers ignoring case"
432             }, {
433                 got: map.getLayersByName({test: function(str) {return str.length > 3;}}),
434                 expected: [map.layers[2], map.layers[3]],
435                 message: "(custom object) got layers with name length greater than 3"
436             }
437         ];
438         t.plan(cases.length);
439         for(var i=0; i<cases.length; ++i) {
440             t.eq(cases[i].got, cases[i].expected, cases[i].message);
441         }
442         
443     }
444
445     function test_Map_getLayersByClass(t) {
446         
447         var map = {
448             getBy: OpenLayers.Map.prototype.getBy,
449             getLayersBy: OpenLayers.Map.prototype.getLayersBy,
450             getLayersByClass: OpenLayers.Map.prototype.getLayersByClass,
451             layers: [
452                 {CLASS_NAME: "foo", id: Math.random()},
453                 {CLASS_NAME: "bar", id: Math.random()},
454                 {CLASS_NAME: "foobar", id: Math.random()},
455                 {CLASS_NAME: "foo bar", id: Math.random()},
456                 {CLASS_NAME: "foo", id: Math.random()}
457             ]
458         };
459
460         var cases = [
461             {
462                 got: map.getLayersByClass("foo"),
463                 expected: [map.layers[0], map.layers[4]],
464                 message: "(string literal) got two layers matching type"
465             }, {
466                 got: map.getLayersByClass("bar"),
467                 expected: [map.layers[1]],
468                 message: "(string literal) got one layer matching type"
469             }, {
470                 got: map.getLayersByClass("barfoo"),
471                 expected: [],
472                 message: "(string literal) got empty array for no match"
473             }, {
474                 got: map.getLayersByClass(/foo/),
475                 expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],
476                 message: "(regexp literal) got three layers containing string"
477             }, {
478                 got: map.getLayersByClass(/foo$/),
479                 expected: [map.layers[0], map.layers[4]],
480                 message: "(regexp literal) got three layers ending with string"
481             }, {
482                 got: map.getLayersByClass(/\s/),
483                 expected: [map.layers[3]],
484                 message: "(regexp literal) got layer containing space"
485             }, {
486                 got: map.getLayersByClass(new RegExp("BAR", "i")),
487                 expected: [map.layers[1], map.layers[2], map.layers[3]],
488                 message: "(regexp object) got layers ignoring case"
489             }, {
490                 got: map.getLayersByClass({test: function(str) {return str.length > 3;}}),
491                 expected: [map.layers[2], map.layers[3]],
492                 message: "(custom object) got layers with type length greater than 3"
493             }
494         ];
495         t.plan(cases.length);
496         for(var i=0; i<cases.length; ++i) {
497             t.eq(cases[i].got, cases[i].expected, cases[i].message);
498         }
499         
500     }
501
502     function test_Map_getControlsBy(t) {
503         
504         var map = {
505             getBy: OpenLayers.Map.prototype.getBy,
506             getControlsBy: OpenLayers.Map.prototype.getControlsBy,
507             controls: [
508                 {foo: "foo", id: Math.random()},
509                 {foo: "bar", id: Math.random()},
510                 {foo: "foobar", id: Math.random()},
511                 {foo: "foo bar", id: Math.random()},
512                 {foo: "foo", id: Math.random()}
513             ]
514         };
515
516         var cases = [
517             {
518                 got: map.getControlsBy("foo", "foo"),
519                 expected: [map.controls[0], map.controls[4]],
520                 message: "(string literal) got two controls matching foo"
521             }, {
522                 got: map.getControlsBy("foo", "bar"),
523                 expected: [map.controls[1]],
524                 message: "(string literal) got one control matching foo"
525             }, {
526                 got: map.getControlsBy("foo", "barfoo"),
527                 expected: [],
528                 message: "(string literal) got empty array for no foo match"
529             }, {
530                 got: map.getControlsBy("foo", /foo/),
531                 expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],
532                 message: "(regexp literal) got three controls containing string"
533             }, {
534                 got: map.getControlsBy("foo", /foo$/),
535                 expected: [map.controls[0], map.controls[4]],
536                 message: "(regexp literal) got three controls ending with string"
537             }, {
538                 got: map.getControlsBy("foo", /\s/),
539                 expected: [map.controls[3]],
540                 message: "(regexp literal) got control containing space"
541             }, {
542                 got: map.getControlsBy("foo", new RegExp("BAR", "i")),
543                 expected: [map.controls[1], map.controls[2], map.controls[3]],
544                 message: "(regexp object) got layers ignoring case"
545             }, {
546                 got: map.getControlsBy("foo", {test: function(str) {return str.length > 3;}}),
547                 expected: [map.controls[2], map.controls[3]],
548                 message: "(custom object) got controls with foo length greater than 3"
549             }
550         ];
551         t.plan(cases.length);
552         for(var i=0; i<cases.length; ++i) {
553             t.eq(cases[i].got, cases[i].expected, cases[i].message);
554         }
555         
556     }
557
558     function test_Map_getControlsByClass(t) {
559         
560         var map = {
561             getBy: OpenLayers.Map.prototype.getBy,
562             getControlsBy: OpenLayers.Map.prototype.getControlsBy,
563             getControlsByClass: OpenLayers.Map.prototype.getControlsByClass,
564             controls: [
565                 {CLASS_NAME: "foo", id: Math.random()},
566                 {CLASS_NAME: "bar", id: Math.random()},
567                 {CLASS_NAME: "foobar", id: Math.random()},
568                 {CLASS_NAME: "foo bar", id: Math.random()},
569                 {CLASS_NAME: "foo", id: Math.random()}
570             ]
571         };
572
573         var cases = [
574             {
575                 got: map.getControlsByClass("foo"),
576                 expected: [map.controls[0], map.controls[4]],
577                 message: "(string literal) got two controls matching type"
578             }, {
579                 got: map.getControlsByClass("bar"),
580                 expected: [map.controls[1]],
581                 message: "(string literal) got one control matching type"
582             }, {
583                 got: map.getControlsByClass("barfoo"),
584                 expected: [],
585                 message: "(string literal) got empty array for no match"
586             }, {
587                 got: map.getControlsByClass(/foo/),
588                 expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],
589                 message: "(regexp literal) got three controls containing string"
590             }, {
591                 got: map.getControlsByClass(/foo$/),
592                 expected: [map.controls[0], map.controls[4]],
593                 message: "(regexp literal) got three controls ending with string"
594             }, {
595                 got: map.getControlsByClass(/\s/),
596                 expected: [map.controls[3]],
597                 message: "(regexp literal) got control containing space"
598             }, {
599                 got: map.getControlsByClass(new RegExp("BAR", "i")),
600                 expected: [map.controls[1], map.controls[2], map.controls[3]],
601                 message: "(regexp object) got controls ignoring case"
602             }, {
603                 got: map.getControlsByClass({test: function(str) {return str.length > 3;}}),
604                 expected: [map.controls[2], map.controls[3]],
605                 message: "(custom object) got controls with type length greater than 3"
606             }
607         ];
608         t.plan(cases.length);
609         for(var i=0; i<cases.length; ++i) {
610             t.eq(cases[i].got, cases[i].expected, cases[i].message);
611         }
612         
613     }
614
615     function test_Map_double_addLayer(t) {
616         t.plan( 1 );    
617
618         map = new OpenLayers.Map($('map'));
619         layer = new OpenLayers.Layer.WMS('Test Layer', 
620                     "http://octo.metacarta.com/cgi-bin/mapserv", 
621                     {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'} 
622                     );
623
624         map.addLayers([layer,layer]);
625         
626         t.eq( map.layers.length, 1, "Map does not allow double adding of layers." );
627     
628     }
629
630     function test_Map_setBaseLayer(t) {
631         t.plan( 4 );
632         
633         map = new OpenLayers.Map('map');
634
635         var wmslayer = new OpenLayers.Layer.WMS('Test Layer', 
636                     "http://octo.metacarta.com/cgi-bin/mapserv", 
637                     {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
638                     {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
639
640         var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2', 
641                     "http://octo.metacarta.com/cgi-bin/mapserv", 
642                     {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
643                     {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
644
645         map.addLayers([wmslayer, wmslayer2]);
646
647         t.ok(map.baseLayer == wmslayer, "default base layer is first one added");
648         
649         map.setBaseLayer(null);
650         t.ok(map.baseLayer == wmslayer, "setBaseLayer on null object does nothing (and does not break)");
651         
652         map.setBaseLayer("chicken");
653         t.ok(map.baseLayer == wmslayer, "setBaseLayer on non-layer object does nothing (and does not break)");
654         
655         map.setBaseLayer(wmslayer2);
656         t.ok(map.baseLayer == wmslayer2, "setbaselayer correctly sets 'baseLayer' property");
657     }
658     
659     function test_Map_removeLayer(t) {
660         t.plan(1);
661         var f = function() {};
662         var layers = [
663             {name: "fee", removeMap: f},
664             {name: "fi", removeMap: f},
665             {name: "fo", removeMap: f},
666             {name: "fum", removeMap: f}
667         ];
668         var map = {
669             layers: layers,
670             baseLayer: layers[0],
671             layerContainerDiv: {removeChild: f},
672             events: {triggerEvent: f},
673             resetLayersZIndex: function() {}
674         };
675         OpenLayers.Map.prototype.removeLayer.apply(map, [map.baseLayer, false]);
676         t.eq(map.baseLayer, null,
677              "removing the baselayer sets baseLayer to null");        
678     }
679
680     function test_Map_removeLayer_res(t) {
681         t.plan(2);
682         
683         map = new OpenLayers.Map('map');
684
685         var layer0 = new OpenLayers.Layer.WMS(
686             'Test Layer 0', 
687             "http://octo.metacarta.com/cgi-bin/mapserv", 
688             {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
689             {resolutions: [4, 2, 1]}
690         );
691
692         var layer1 = new OpenLayers.Layer.WMS(
693             'Test Layer 1', 
694             "http://octo.metacarta.com/cgi-bin/mapserv", 
695             {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
696             {resolutions: [4, 2]}
697         );
698
699         map.addLayers([layer0, layer1]);
700         map.zoomToMaxExtent();
701         map.zoomTo(2);
702         t.eq(map.getResolution(), layer0.resolutions[2],
703              "correct resolution before removal");
704         map.removeLayer(layer0);
705         t.eq(map.getResolution(), layer0.resolutions[1],
706              "correct resolution after removal");
707     }
708
709     function test_Map_removeLayer_zindex(t) {
710         t.plan(2);
711         
712         map = new OpenLayers.Map('map');
713
714         var layer0 = new OpenLayers.Layer('Test Layer 0', {isBaseLayer:true});
715         var layer1 = new OpenLayers.Layer('Test Layer 1', {isBaseLayer:true});
716         var layer2 = new OpenLayers.Layer('Test Layer 2', {isBaseLayer:false});
717
718         map.addLayers([layer0, layer1, layer2]);
719         map.removeLayer(layer0);
720
721         t.eq(parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'],
722              "correct z-index after removeLayer");
723         t.eq(parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['Overlay'] + 5,
724              "correct z-index after removeLayer");
725     }
726
727     function test_Map_setBaseLayer_after_pan (t) {
728         t.plan(1);
729
730         map = new OpenLayers.Map('map');
731         var wmsLayer = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
732             "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
733         var tmsLayer = new OpenLayers.Layer.TMS("TMS",
734                                     "http://labs.metacarta.com/wms-c/Basic.py/",
735                                     {'layername':'basic', 'type':'png'});
736         map.addLayers([wmsLayer,tmsLayer]);
737         map.setBaseLayer(wmsLayer);
738         map.zoomToMaxExtent();
739         map.setBaseLayer(tmsLayer);
740         map.zoomIn();
741         map.pan(0, -200, {animate:false});
742         map.setBaseLayer(wmsLayer);
743         t.eq(map.layerContainerDiv.style.top, "0px", "layerContainer is recentered after setBaseLayer");
744     }
745
746     function test_Map_moveLayer (t) {
747         t.plan(10);
748
749         var ct  = 0;
750         map = new OpenLayers.Map('map');
751         var wmslayer = new OpenLayers.Layer.WMS('Test Layer', 
752                     "http://octo.metacarta.com/cgi-bin/mapserv", 
753                     {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
754                     {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
755
756         var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2', 
757                     "http://octo.metacarta.com/cgi-bin/mapserv", 
758                     {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
759                     {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
760
761         var wmslayer3 = new OpenLayers.Layer.WMS('Test Layer2', 
762                     "http://octo.metacarta.com/cgi-bin/mapserv", 
763                     {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, 
764                     {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:"EPSG:2805" } );
765
766         map.addLayers([wmslayer, wmslayer2, wmslayer3]);
767         map.events.register("changelayer", map, function (e) { ct++; });
768         t.eq( map.getNumLayers(), 3, "getNumLayers returns the number of layers" );
769         t.eq( map.getLayerIndex(wmslayer3), 2, "getLayerIndex returns the right index" );
770         map.raiseLayer(wmslayer3, 1);
771         t.eq( map.getLayerIndex(wmslayer3), 2, "can't moveLayer up past the top of the stack" );
772         map.raiseLayer(wmslayer, -1);
773         t.eq( map.getLayerIndex(wmslayer), 0, "can't moveLayer down past the bottom of the stack" );
774         map.raiseLayer(wmslayer3, -1);
775         t.eq( map.getLayerIndex(wmslayer3), 1, "can moveLayer down from the top" );
776         t.eq( parseInt(wmslayer3.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5,
777             "layer div has the right zIndex after moving down" );
778         map.raiseLayer(wmslayer, 2);
779         t.eq( map.getLayerIndex(wmslayer), 2, "can moveLayer up from the bottom" );
780         t.eq( parseInt(wmslayer.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 2 * 5,
781             "layer div has the right zIndex after moving up" );
782         t.eq( map.getLayerIndex(wmslayer3), 0, "top layer is now on the bottom" );
783         t.eq( ct, 3, "raiseLayer triggered changelayer the right # of times" );
784     }
785
786     function test_Map_moveTo(t) {
787         t.plan(2);
788
789         map = new OpenLayers.Map('map');
790         var baseLayer = new OpenLayers.Layer.WMS("Test Layer", 
791             "http://octo.metacarta.com/cgi-bin/mapserv?",
792             {map: "/mapdata/vmap_wms.map", layers: "basic"},
793             {maxResolution: 'auto', maxExtent: new OpenLayers.Bounds(-10,-10,10,10)});
794         baseLayer.events.on({
795             move: function() {
796                 t.ok(true, "move listener called");
797             },
798             moveend: function(e) {
799                 t.eq(e.zoomChanged, true, "moveend listener called with expected value");
800             }
801         });
802         map.addLayer(baseLayer);
803         var ll = new OpenLayers.LonLat(-100,-150);
804         map.moveTo(ll, 2);
805         t.ok(map.getCenter().equals(new OpenLayers.LonLat(0,0)), "safely sets out-of-bounds lonlat");
806     }
807
808     function test_Map_defaultTheme(t) {
809         t.plan(5);
810         
811         var links = document.getElementsByTagName('link');
812         map = new OpenLayers.Map('map');
813         var gotNodes = 0;
814         var themeNode = null;
815         for(var i=0; i<links.length; ++i) {
816             if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {
817                 gotNodes += 1;
818                 themeNode = links.item(i);
819             }
820         }
821         t.eq(gotNodes, 1, "by default, a single link node is added to document");
822         t.ok(themeNode != null, "a link node with the theme href was added");
823         t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet");
824         t.eq(themeNode.type, "text/css", "node added has type set to text/css");
825         
826         // reconstruct the map to prove that another link is not added
827         map = new OpenLayers.Map('map');
828         t.eq(links.length, document.getElementsByTagName('link').length,
829              "calling the map constructor twice with the same theme doesn't add duplicate link nodes");
830     }
831
832     function test_Map_customTheme(t) {
833         t.plan(5);
834         
835         var customTheme = 'foo';
836         var options = {theme: customTheme};
837         map = new OpenLayers.Map('map', options);
838
839         var links = document.getElementsByTagName('link');
840         var gotNodes = 0;
841         var themeNode = null;
842         for(var i=0; i<links.length; ++i) {
843             if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {
844                 gotNodes += 1;
845                 themeNode = links.item(i);
846             }
847         }
848         
849         t.eq(map.theme, customTheme, "map theme is properly set");
850         t.eq(gotNodes, 1, "with custom theme, a single link node is added to document");
851         t.ok(themeNode != null, "a link node with the theme href was added");
852         t.eq(themeNode.rel, "stylesheet", "node added has rel set to stylesheet");
853         t.eq(themeNode.type, "text/css", "node added has type set to text/css");
854     }
855
856     function test_Map_noTheme(t) {
857         t.plan(1);
858         
859         var head = document.getElementsByTagName('head')[0];
860         var nodeCount = head.childNodes.length;
861         
862         var options = {theme: null};
863         map = new OpenLayers.Map('map', options);
864
865         t.eq(nodeCount, head.childNodes.length, "with no theme, a node is not added to document head" );
866     }
867
868     function test_Map_getControl(t) {
869         t.plan(2);
870         
871         var map1 = new OpenLayers.Map('map');
872         
873         var control = new OpenLayers.Control();
874         map1.addControl(control);
875
876         var gotControl = map1.getControl(control.id);
877         t.ok(gotControl == control, "got right control");
878         
879         gotControl = map1.getControl("bogus id");
880         t.ok(gotControl == null, "getControl() for bad id returns null");
881     }
882
883     function test_Map_removeControl(t) {
884         t.plan(6);
885         
886         var oldNumControls, newNumControls;
887         
888         var map1 = new OpenLayers.Map('map');
889         oldNumControls = map1.controls.length;
890         
891         var control = new OpenLayers.Control();
892         map1.addControl(control);
893
894     //add control        
895         newNumControls = map1.controls.length;
896         t.ok( newNumControls = oldNumControls + 1, "adding a control increases control count")
897
898         var foundDiv = false;
899         for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {
900             var childNode = map1.viewPortDiv.childNodes[i];
901             if (childNode == control.div) {
902                 foundDiv = true;
903             }
904         }
905         t.ok(foundDiv, "new control's div correctly added to viewPort");
906
907     //remove control        
908         map1.removeControl(control)
909         newNumControls = map1.controls.length;
910         t.ok( newNumControls == oldNumControls, "removing the control decreases control count")
911
912         var gotControl = map1.getControl(control.id);
913         t.ok( gotControl == null, "control no longer in map's controls array");
914
915         var foundDiv = false;
916         for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {
917             var childNode = map1.viewPortDiv.childNodes[i];
918             if (childNode == control.div) {
919                 foundDiv = true;
920             }
921         }
922         t.ok(!foundDiv, "control no longer child of viewPort");
923
924     //remove bogus
925         control = { id: "bogus id" };
926         map1.removeControl(control);
927         newNumControls = map1.controls.length;
928         t.ok( newNumControls == oldNumControls, "removing bad controlid doesnt crash or decrease control count")
929     }
930
931     function test_Map_restrictedExtent(t) {
932         t.plan(24);
933         var extent = new OpenLayers.Bounds(-180, -90, 180, 90);
934         var options = {
935             maxResolution: "auto"
936         };
937         var map = new OpenLayers.Map("map", options);
938         var layer = new OpenLayers.Layer.WMS(
939             "test", 
940             "http://octo.metacarta.com/cgi-bin/mapserv?",
941             {map: "/mapdata/vmap_wms.map", layers: "basic"}
942         );
943         map.addLayer(layer);
944         map.zoomToMaxExtent();
945         var nw = new OpenLayers.LonLat(extent.left, extent.top);
946         var ne = new OpenLayers.LonLat(extent.right, extent.top);
947         var sw = new OpenLayers.LonLat(extent.left, extent.bottom);
948         var se = new OpenLayers.LonLat(extent.right, extent.bottom);
949         
950         // try panning to northwest corner
951         map.setOptions({restrictedExtent: extent});
952         map.setCenter(nw, 0);
953         t.eq(map.getExtent().getCenterLonLat().toString(),
954              extent.getCenterLonLat().toString(),
955              "map extent properly restricted to northwest at zoom 0");
956         t.eq(map.zoom, 0, "zoom not restricted for nw, 0");
957         map.setCenter(nw, 5);
958         t.eq(map.getExtent().top, extent.top,
959              "map extent top properly restricted to northwest at zoom 5");
960         t.eq(map.getExtent().left, extent.left,
961              "map extent left properly restricted to northwest at zoom 5");
962         t.eq(map.zoom, 5, "zoom not restricted for nw, 5");
963         map.setOptions({restrictedExtent: null});
964         map.setCenter(nw, 0);
965         t.eq(map.getExtent().getCenterLonLat().toString(),
966              nw.toString(),
967              "map extent not restricted with null restrictedExtent for nw");
968
969         // try panning to northeast corner
970         map.setOptions({restrictedExtent: extent});
971         map.setCenter(ne, 0);
972         t.eq(map.getExtent().getCenterLonLat().toString(),
973              extent.getCenterLonLat().toString(),
974              "map extent properly restricted to northeast at zoom 0");
975         t.eq(map.zoom, 0, "zoom not restricted for ne, 0");
976         map.setCenter(ne, 5);
977         t.eq(map.getExtent().top, extent.top,
978              "map extent top properly restricted to northeast at zoom 5");
979         t.eq(map.getExtent().right, extent.right,
980              "map extent right properly restricted to northeast at zoom 5");
981         t.eq(map.zoom, 5, "zoom not restricted for ne, 5");
982         map.setOptions({restrictedExtent: null});
983         map.setCenter(ne, 0);
984         t.eq(map.getExtent().getCenterLonLat().toString(),
985              ne.toString(),
986              "map extent not restricted with null restrictedExtent for ne");
987         
988         // try panning to southwest corner
989         map.setOptions({restrictedExtent: extent});
990         map.setCenter(sw, 0);
991         t.eq(map.getExtent().getCenterLonLat().toString(),
992              extent.getCenterLonLat().toString(),
993              "map extent properly restricted to southwest at zoom 0");
994         t.eq(map.zoom, 0, "zoom not restricted for sw, 0");
995         map.setCenter(sw, 5);
996         t.eq(map.getExtent().bottom, extent.bottom,
997              "map extent bottom properly restricted to southwest at zoom 5");
998         t.eq(map.getExtent().left, extent.left,
999              "map extent left properly restricted to southwest at zoom 5");
1000         t.eq(map.zoom, 5, "zoom not restricted for sw, 5");
1001         map.setOptions({restrictedExtent: null});
1002         map.setCenter(sw, 0);
1003         t.eq(map.getExtent().getCenterLonLat().toString(),
1004              sw.toString(),
1005              "map extent not restricted with null restrictedExtent for sw");
1006
1007         // try panning to southeast corner
1008         map.setOptions({restrictedExtent: extent});
1009         map.setCenter(se, 0);
1010         t.eq(map.getExtent().getCenterLonLat().toString(),
1011              extent.getCenterLonLat().toString(),
1012              "map extent properly restricted to southeast at zoom 0");
1013         t.eq(map.zoom, 0, "zoom not restricted for se, 0");
1014         map.setCenter(se, 5);
1015         t.eq(map.getExtent().bottom, extent.bottom,
1016              "map extent bottom properly restricted to southeast at zoom 5");
1017         t.eq(map.getExtent().right, extent.right,
1018              "map extent right properly restricted to southeast at zoom 5");
1019         t.eq(map.zoom, 5, "zoom not restricted for se, 5");
1020         map.setOptions({restrictedExtent: null});
1021         map.setCenter(se, 0);
1022         t.eq(map.getExtent().getCenterLonLat().toString(),
1023              se.toString(),
1024              "map extent not restricted with null restrictedExtent for se");
1025     }
1026     
1027     function test_Map_getResolutionForZoom(t) {
1028         t.plan(2);
1029         var map = new OpenLayers.Map("map");
1030         var res = map.getResolutionForZoom();
1031         t.eq(res, null, "getResolutionForZoom returns null for no base layer");
1032         map.fractionalZoom = true;
1033         var layer = new OpenLayers.Layer("test", {isBaseLayer: true});
1034         layer.getResolutionForZoom = function() {
1035             t.ok(true, "getResolutionForZoom calls base layer getResolutionForZoom");
1036         }
1037         map.addLayer(layer);
1038         var res = map.getResolutionForZoom();
1039         layer.destroy();
1040         map.destroy();
1041     }
1042     
1043     function test_Map_getUnits(t) {
1044         t.plan(2);
1045         var map = new OpenLayers.Map("map");
1046         var units = map.getUnits();
1047         t.eq(units, null, "getUnits returns null for no base layer");
1048         
1049         var layer = new OpenLayers.Layer("test", {
1050             isBaseLayer: true,
1051             units: 'foo'
1052         });
1053         map.addLayer(layer);
1054         var units = map.getUnits();
1055         t.eq(units, 'foo', "getUnits returns the base layer units property");
1056         layer.destroy();
1057         map.destroy();
1058     }
1059
1060     function test_Map_destroy (t) {
1061         t.plan( 3 );    
1062         map = new OpenLayers.Map('map');
1063         map.destroy();
1064         t.eq( map.layers, null, "map.layers is null after destroy" );
1065         t.eq( map.controls, null, "map.controls is null after destroy" );
1066         t.eq( map.viewPortDiv, null, "map's viewportDiv nullified");
1067     }
1068
1069     function test_Map_getMaxExtent(t){
1070         t.plan(5);
1071
1072         var options = null;
1073         var map = {};
1074
1075       //null options, no baseLayer
1076         var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1077         t.eq(maxExtent, null, "null options, no baseLayer returns null");     
1078
1079       //null options.restricted, no baseLayer
1080         maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1081         t.eq(maxExtent, null, "null options.restricted, no baseLayer returns null");     
1082
1083       //true options.restricted, null map.restrictedExtent no baseLayer
1084         maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1085         t.eq(maxExtent, null, "true options.restricted, null map.restrictedExtent no baseLayer returns null");     
1086
1087       //true options.restricted, valid map.restrictedExtent no baseLayer
1088         options = {
1089             'restricted': true
1090         };
1091         map.restrictedExtent = {};
1092         maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1093         t.ok(maxExtent == map.restrictedExtent, "true options.restricted, valid map.restrictedExtent no baseLayer returns map.restrictedExtent");     
1094
1095       //null options, valid baseLayer
1096         options = null;
1097         map.baseLayer = {
1098             'maxExtent': {}
1099         };
1100         var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);
1101         t.ok(maxExtent == map.baseLayer.maxExtent, "null options, valid baseLayer returns map.baseLayer.maxExtent");     
1102     }
1103
1104     function test_Map_zoomToMaxExtent(t){
1105         t.plan(4)
1106
1107         gMaxExtent = {};
1108
1109         var map = {
1110             'getMaxExtent': function(options) {
1111                 gRestricted = options.restricted; 
1112                 return gMaxExtent;
1113             }, 
1114             'zoomToExtent': function(extent) {
1115                 t.ok(extent == gMaxExtent, "zoomToExtent() always called on return from map.getMaxExtent()");
1116             } 
1117         };
1118
1119       //options is null
1120         var options = null;
1121         gRestricted = null;
1122         OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);
1123         t.eq(gRestricted, true, "default 'restricted' passed to map.getMaxExtent() is true");
1124         
1125       //valid options
1126         options = {
1127             'restricted': {}
1128         };
1129         gRestricted = null;
1130         OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);
1131         t.ok(gRestricted == options.restricted, "when valid options argument, 'options.restricted' passed to map.getMaxExtent()");
1132     }
1133
1134     function test_Map_zoomToScale(t) {
1135         t.plan(4);
1136         
1137         var m = {
1138             'baseLayer': { 'units': {} },
1139             'getSize': function() { return {'w': 10, 'h': 15}; },
1140             'getCenter': function() { return {'lon': -5, 'lat': -25}; },
1141             'zoomToExtent': function(extent, closest) {
1142                 t.ok(extent.equals(g_ExpectedExtent), "extent correctly calculated for zoomToExtent()");
1143                 t.ok(closest == g_Closest, "closest correctly passed on to zoomToExtent()");
1144             }            
1145         }
1146
1147         var temp = OpenLayers.Util.getResolutionFromScale;
1148         OpenLayers.Util.getResolutionFromScale = function(scale, units) {
1149             t.ok(scale == g_Scale, "scale parameter correctly passed to getResolutionFromScale");
1150             t.ok(units == m.baseLayer.units, "map's baselayer's units parameter correctly passed to getResolutionFromScale");
1151             return 1000;
1152         };
1153  
1154         g_ExpectedExtent = new OpenLayers.Bounds(-5005,-7525,4995,7475);
1155         g_Scale = {};
1156         g_Closest = {};
1157         var args = [g_Scale, g_Closest];
1158         OpenLayers.Map.prototype.zoomToScale.apply(m, args);    
1159
1160         OpenLayers.Util.getResolutionFromScale = temp;
1161     }
1162     
1163     function test_Map_zoomToExtent(t) {
1164         t.plan(8);
1165
1166         
1167         var m = {
1168             'baseLayer': {
1169                 'wrapDateLine': false      
1170             },
1171             'setCenter': function(center, zoomLevel) {
1172                 g_Center = center;
1173                 g_ZoomLevel = zoomLevel;
1174             },
1175             'getZoomForExtent': function(bounds, closest) {
1176                 t.ok(bounds.equals(g_ToCenterBounds), "bounds correctly passed into getZoomForExtent()");
1177                 t.ok(closest == g_Closest, "closest correctly passed along to getZoomForExtent()");
1178                 return g_ZoomLevelReturn;
1179             }
1180         };
1181
1182     //no wrapDateLine        
1183         g_ZoomLevelReturn = {};
1184         g_Bounds = new OpenLayers.Bounds(-20,-15,0,5);
1185         g_ExpectedCenter = new OpenLayers.LonLat(-10,-5);
1186         g_Closest = {};
1187         g_ToCenterBounds = g_Bounds;
1188         var args = [g_Bounds, g_Closest];
1189         OpenLayers.Map.prototype.zoomToExtent.apply(m, args);
1190         
1191         t.ok(g_Center.equals(g_ExpectedCenter), "setCenter called on correct center");
1192         t.ok(g_ZoomLevel == g_ZoomLevelReturn, "correctly passes along zoom level as returned from getZoomForExtent()");
1193
1194
1195     //wrapDateLine
1196         m.baseLayer.wrapDateLine = true;
1197         m.getMaxExtent = function() { return new OpenLayers.Bounds(-200,-200,200,200); };
1198
1199         g_ZoomLevelReturn = {};
1200         g_BoundsCenter = {};
1201         g_Bounds = new OpenLayers.Bounds(160,-60,-60,60);
1202         g_ExpectedCenter = new OpenLayers.LonLat(-150,0);
1203         g_Closest = {};
1204         g_ToCenterBounds = new OpenLayers.Bounds(160,-60,340,60);
1205         var args = [g_Bounds, g_Closest];
1206         OpenLayers.Map.prototype.zoomToExtent.apply(m, args);
1207         t.ok(g_Center.equals(g_ExpectedCenter), "setCenter called on correct center");
1208         t.ok(g_ZoomLevel == g_ZoomLevelReturn, "correctly passes along zoom level as returned from getZoomForExtent()");
1209
1210         
1211     }
1212     
1213     function test_allOverlays(t) {
1214         
1215         t.plan(16);
1216
1217         var map = new OpenLayers.Map({
1218             div: "map", allOverlays: true
1219         });
1220         
1221         var a = new OpenLayers.Layer.Vector("a", {visibility: true});
1222
1223         var b = new OpenLayers.Layer.Image(
1224             "b",
1225             "http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif",
1226             new OpenLayers.Bounds(-180, -88.759, 180, 88.759),
1227             new OpenLayers.Size(580, 288)
1228         );
1229
1230         var c = new OpenLayers.Layer.WMS(
1231             "c",
1232             "http://labs.metacarta.com/wms/vmap0",
1233             {layers: 'basic'}
1234         );
1235
1236         var d = new OpenLayers.Layer.Vector("d");
1237         
1238         map.addLayers([a, b, c, d]);
1239
1240         var moveCount = 0;
1241         a.moveTo = function() {
1242             moveCount++;
1243             OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);
1244         };
1245
1246         map.zoomToMaxExtent();
1247         t.eq(moveCount, 1, "map.moveTo moves the base layer only once");
1248         t.eq(map.getCenter().toString(), "lon=0,lat=0", "a map with all overlays can have a center");
1249
1250         a.setVisibility(false);
1251         var moveend = 0;
1252         a.events.on({"moveend": function() { moveend++; }}); 
1253         map.zoomToMaxExtent();
1254         t.eq(moveCount, 1, "map.moveTo does not move the base layer if it is invisible");
1255         t.eq(moveend, 0, "map.moveTo does not trigger \"moveend\" in the layer if the layer is invisible");
1256         a.setVisibility(true);
1257         
1258         // a, b, c, d
1259         t.eq(map.baseLayer.name, "a", "base layer set to first layer added");
1260         
1261         map.removeLayer(a);
1262         // b, c, d
1263         t.eq(map.baseLayer.name, "b", "if base layer is removed, lowest layer becomes base");
1264         
1265         map.addLayer(a);
1266         // b, c, d, a
1267         t.eq(map.baseLayer.name, "b", "adding a new layer doesn't change base layer");
1268         
1269         map.setLayerIndex(c, 1);
1270         // b, d, c, a
1271         t.eq(map.baseLayer.name, "b", "changing layer order above base doesn't mess with base");
1272         
1273         map.setLayerIndex(d, 0);
1274         // d, b, c, a
1275         t.eq(map.baseLayer.name, "d", "changing layer order to 0 sets base layer");
1276         
1277         map.raiseLayer(d, 1);
1278         // b, d, c, a
1279         t.eq(map.baseLayer.name, "b", "raising the base layer sets a new base layer");
1280         
1281         map.raiseLayer(d, -1);
1282         // d, b, c, a
1283         t.eq(map.baseLayer.name, "d", "lowering a layer to lowest index sets as base");
1284         
1285         // all this switching of base layer didn't muck with layer visibility
1286         t.eq(a.visibility, true, "a is visible");
1287         t.eq(b.visibility, true, "b is visible");
1288         t.eq(c.visibility, true, "c is visible");
1289         t.eq(d.visibility, true, "d is visible");
1290         
1291         // test that map can have an invisible base layer
1292         b.setVisibility(false);
1293         map.setLayerIndex(b, 0);
1294         t.eq(b.visibility, false, "changing layer order doesn't change visibility");
1295
1296        
1297         map.destroy();
1298         
1299     }
1300
1301   </script>
1302 </head>
1303 <body>
1304     <div id="map" style="width: 600px; height: 300px;"/>
1305 </body>
1306 </html>