summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Strategy
diff options
context:
space:
mode:
authorChris Schlaeger <chris@linux.com>2014-08-12 21:56:44 +0200
committerChris Schlaeger <chris@linux.com>2014-08-12 21:56:44 +0200
commitea346a785dc1b3f7c156f6fc33da634e1f1a627b (patch)
treeaf67530553d20b6e82ad60fd79593e9c4abf5565 /misc/openlayers/tests/Strategy
parent59741cd535c47f25971bf8c32b25da25ceadc6d5 (diff)
downloadpostrunner-0.0.4.zip
Adding jquery, flot and openlayers to be included with the GEM.v0.0.4
Diffstat (limited to 'misc/openlayers/tests/Strategy')
-rw-r--r--misc/openlayers/tests/Strategy/BBOX.html361
-rw-r--r--misc/openlayers/tests/Strategy/Cluster.html148
-rw-r--r--misc/openlayers/tests/Strategy/Filter.html135
-rw-r--r--misc/openlayers/tests/Strategy/Fixed.html253
-rw-r--r--misc/openlayers/tests/Strategy/Paging.html113
-rw-r--r--misc/openlayers/tests/Strategy/Refresh.html177
-rw-r--r--misc/openlayers/tests/Strategy/Save.html127
7 files changed, 1314 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Strategy/BBOX.html b/misc/openlayers/tests/Strategy/BBOX.html
new file mode 100644
index 0000000..6e409e6
--- /dev/null
+++ b/misc/openlayers/tests/Strategy/BBOX.html
@@ -0,0 +1,361 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(1);
+
+ var ratio = 4;
+
+ var s = new OpenLayers.Strategy.BBOX({ratio: ratio});
+ t.eq(s.ratio, ratio, "ctor sets ratio");
+ }
+
+ function test_activate(t) {
+ t.plan(5);
+
+ var l = new OpenLayers.Layer.Vector();
+ var s = new OpenLayers.Strategy.BBOX();
+ s.setLayer(l);
+
+ t.eq(s.active, false, "not active after construction");
+
+ var activated = s.activate();
+ t.eq(activated, true, "activate returns true");
+ t.eq(s.active, true, "activated after activate");
+ t.ok(l.events.listeners["moveend"][0].obj == s &&
+ l.events.listeners["moveend"][0].func == s.update,
+ "activates registers moveend listener");
+ t.ok(l.events.listeners["refresh"][0].obj == s &&
+ l.events.listeners["refresh"][0].func == s.update,
+ "activates registers refresh listener");
+ }
+
+ function test_update(t) {
+ t.plan(7);
+
+ // Create a dummy layer that can act as the map base layer.
+ // This will be unnecessary if #1921 is addressed (allowing
+ // map to have different projection than base layer).
+ var dummy = new OpenLayers.Layer(null, {isBaseLayer: true});
+
+ var strategy = new OpenLayers.Strategy.BBOX({
+ ratio: 1 // makes for easier comparison to map bounds
+ });
+ var log = [];
+ var layer = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true,
+ protocol: new OpenLayers.Protocol({abort: function(response) { log.push(response); }}),
+ strategies: [strategy]
+ });
+
+ // create a map with the layers and a center
+ var map = new OpenLayers.Map("map", {zoomMethod: null});
+ map.addLayers([dummy, layer]);
+ map.zoomToMaxExtent();
+
+ /**
+ * The setCenter call above should set strategy bounds. I *think* this
+ * issue is captured in http://trac.openlayers.org/ticket/1835.
+ * For now, I'm going to force an update on the strategy. This line
+ * should be removed when the issue(s) described in #1835 are addressed.
+ */
+ strategy.update({force: true});
+ strategy.response = {};
+ strategy.update({force: true});
+ t.eq(log.length, 1, "Response aborted");
+ log = [];
+ strategy.update({force: true});
+ strategy.update({force: true, noAbort: true});
+ t.eq(log.length, 0, "Response not aborted when noAbort is true");
+
+ // test that the strategy bounds were set
+ t.ok(map.getExtent().equals(strategy.bounds), "[set center] bounds set to map extent");
+
+ // zoom and test that bounds are not reset
+ var old = strategy.bounds.clone();
+ map.zoomIn();
+ t.ok(strategy.bounds.equals(old), "[zoom in] bounds not reset");
+
+ // force update and check that bounds change
+ strategy.update({force: true});
+ t.ok(!strategy.bounds.equals(old), "[force update] bounds changed");
+ t.ok(strategy.bounds.equals(map.getExtent()), "[force update] bounds set to map extent");
+
+ // change the layer projection to confirm strategy uses same
+ layer.projection = new OpenLayers.Projection("EPSG:900913");
+ strategy.update({force: true});
+ var from = map.getProjectionObject();
+ var to = layer.projection;
+
+ var strategyBounds = strategy.bounds,
+ mapExtent = map.getExtent().transform(from, to),
+ // we don't use bounds::toString because we might run into
+ // precision issues
+ precision = 7,
+ strategyBoundsGot = [
+ strategyBounds.left.toFixed( precision ),
+ strategyBounds.bottom.toFixed( precision ),
+ strategyBounds.right.toFixed( precision ),
+ strategyBounds.top.toFixed( precision )
+ ].join(','),
+ mapExtentExpected = [
+ mapExtent.left.toFixed( precision ),
+ mapExtent.bottom.toFixed( precision ),
+ mapExtent.right.toFixed( precision ),
+ mapExtent.top.toFixed( precision )
+ ].join(',');
+ t.eq(strategyBoundsGot, mapExtentExpected,
+ "[force update different proj] bounds transformed");
+ }
+
+ function test_events(t) {
+
+ t.plan(7);
+
+ var log = [];
+
+ var response = new OpenLayers.Protocol.Response();
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector(null, {
+ strategies: [new OpenLayers.Strategy.BBOX()],
+ protocol: new OpenLayers.Protocol({
+ read: function(config) {
+ config.callback.call(config.scope, response);
+ }
+ }),
+ isBaseLayer: true,
+ eventListeners: {
+ loadstart: function(event) {
+ log.push(event);
+ },
+ loadend: function(event) {
+ log.push(event);
+ }
+ }
+ });
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ t.eq(log.length, 2, "2 events logged");
+ t.eq(log[0].type, "loadstart", "loadstart first");
+ t.ok(log[0].filter.type === OpenLayers.Filter.Spatial.BBOX, "loadstart includes filter used");
+ t.eq(log[1].type, "loadend", "loadend second");
+ t.ok(log[1].response == response, "loadend includes response");
+
+ var calls = [];
+ layer.protocol.read = function(obj) {
+ calls.push(obj);
+ }
+ layer.refresh({force: true, whee: 'chicken'});
+
+ t.eq(calls.length, 1, "1 call to read");
+ t.eq(calls[0].whee, "chicken", "properties passed to read");
+
+ map.destroy();
+
+ }
+
+ function test_triggerRead(t) {
+ t.plan(4);
+
+ var s = new OpenLayers.Strategy.BBOX();
+
+ var filter = {"fake": "filter"};
+
+ s.createFilter = function() {
+ return filter;
+ };
+ s.response = {"fake": "response"};
+
+ var log = {};
+
+ var protocol = new OpenLayers.Protocol({
+ read: function(options) {
+ log.options = options;
+ },
+ abort: function(response) {
+ log.abort = response.fake;
+ }
+ });
+
+ var layer = new OpenLayers.Layer.Vector(null, {
+ strategies: [s],
+ protocol: protocol,
+ isBaseLayer: true
+ });
+ var map = new OpenLayers.Map("map");
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ t.ok(log.options.filter == filter,
+ "protocol read called with correct filter");
+ t.ok(log.options.callback == s.merge,
+ "protocol read called with correct callback");
+ t.ok(log.options.scope == s,
+ "protocol read called with correct scope");
+ t.eq(log.abort, "response",
+ "protocol abort called with correct response");
+
+ map.destroy();
+
+ }
+
+ function test_resFactor(t) {
+ t.plan(2);
+
+ var map = new OpenLayers.Map("map", {zoomMethod: null});
+ var bbox = new OpenLayers.Strategy.BBOX();
+ var fakeProtocol = new OpenLayers.Protocol({
+ 'read': function() {
+ t.ok(true, "read called once without resfactor");
+ }
+ });
+ var layer = new OpenLayers.Layer.Vector("test", {
+ strategies: [bbox],
+ protocol: fakeProtocol,
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+ map.zoomIn();
+
+ fakeProtocol.read = function() {
+ t.ok("read called again on zooming with resFactor: 1");
+ }
+ bbox.resFactor = 1;
+ map.zoomIn();
+
+ }
+
+ function test_createFilter(t) {
+ t.plan(3);
+
+ var s = new OpenLayers.Strategy.BBOX();
+
+ var f;
+
+ // 2 test
+ s.setLayer({});
+ f = s.createFilter();
+ t.ok(f.CLASS_NAME.search(/^OpenLayers.Filter.Spatial/) != -1,
+ "createFilter returns a spatial filter object");
+ t.eq(f.type, OpenLayers.Filter.Spatial.BBOX,
+ "createFilter returns a BBOX-typed filter");
+
+ // 1 test
+ s.setLayer({filter: {fake: "filter"}});
+ f = s.createFilter();
+ t.ok(f.CLASS_NAME.search(/^OpenLayers.Filter.Logical/) != -1,
+ "createFilter returns a logical filter object");
+ }
+
+ function test_merge(t) {
+ t.plan(4);
+
+ var strategy = new OpenLayers.Strategy.BBOX();
+
+ // create map with default projection
+ var map = new OpenLayers.Map("map");
+
+ // create layer with custom projection
+ var layer = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true,
+ strategies: [strategy],
+ protocol: new OpenLayers.Protocol(),
+ projection: new OpenLayers.Projection("EPSG:900913")
+ });
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ // create some features
+ var geometries = [
+ new OpenLayers.Geometry.Point(100, 200),
+ new OpenLayers.Geometry.Point(1000, 2000)
+ ];
+ var features = [
+ new OpenLayers.Feature.Vector(geometries[0].clone()),
+ new OpenLayers.Feature.Vector(geometries[1].clone())
+ ];
+
+ // call merge with a mocked up response
+ strategy.merge({features: features, success: OpenLayers.Function.True});
+
+ // test that feature geometries have been transformed to map projection
+ var from = layer.projection;
+ var to = map.getProjectionObject();
+ t.geom_eq(layer.features[0].geometry, features[0].geometry.transform(from, to), "[different proj] feature 0 geometry transformed");
+ t.geom_eq(layer.features[1].geometry, features[1].geometry.transform(from, to), "[different proj] feature 1 geometry transformed");
+
+ // same as above but with same map/layer projection
+ layer.destroyFeatures();
+ layer.projection = map.getProjectionObject();
+
+ features = [
+ new OpenLayers.Feature.Vector(geometries[0].clone()),
+ new OpenLayers.Feature.Vector(geometries[1].clone())
+ ];
+
+ // call merge again with mocked up response
+ strategy.merge({features: features, success: OpenLayers.Function.True});
+
+ // test that feature geometries have not been transformed
+ t.geom_eq(layer.features[0].geometry, features[0].geometry, "[same proj] feature 0 geometry not transformed");
+ t.geom_eq(layer.features[1].geometry, features[1].geometry, "[same proj] feature 1 geometry not transformed");
+
+ }
+
+ // Test fix for Ticket #3142
+ function test_layerLoadedAfterBeingAdded(t) {
+ t.plan(3);
+
+ var dummy = new OpenLayers.Layer(null, {isBaseLayer: true});
+
+ var strategy = new OpenLayers.Strategy.BBOX({
+ ratio: 1 // makes for easier comparison to map bounds
+ });
+ var layer = new OpenLayers.Layer.Vector(null, {
+ protocol: new OpenLayers.Protocol(),
+ strategies: [strategy]
+ });
+
+ // Make sure to test the case of a vector layer needing to be
+ // reprojected while the map is not yet centered
+ var layerReproject = new OpenLayers.Layer.Vector(null, {
+ protocol: new OpenLayers.Protocol(),
+ strategies: [new OpenLayers.Strategy.BBOX()],
+ projection: 'EPSG:900913'
+ });
+
+ // Make sure that layers that are not in range don't request data
+ var layerOutOfRange = new OpenLayers.Layer.Vector(null, {
+ maxResolution: 1,
+ protocol: new OpenLayers.Protocol(),
+ strategies: [new OpenLayers.Strategy.BBOX()]
+ });
+
+ var map = new OpenLayers.Map("map");
+ map.addLayer(dummy);
+ map.addLayer(layerReproject);
+ map.setCenter(new OpenLayers.LonLat(0, 0));
+ map.addLayer(layer);
+ map.addLayer(layerOutOfRange);
+ // test that the strategy bounds were set
+ t.ok(map.getExtent().equals(strategy.bounds), "[set center] bounds set to map extent");
+ t.eq(layerOutOfRange.strategies[0].bounds, null, "Data not requested if layer is out of range");
+
+ layerOutOfRange.setVisibility(false);
+ layerOutOfRange.setVisibility(true);
+ t.eq(layerOutOfRange.strategies[0].bounds, null, "Data not requested if layer is out of range when switching visibility");
+
+ map.destroy();
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 200px" />
+</body>
+</html>
diff --git a/misc/openlayers/tests/Strategy/Cluster.html b/misc/openlayers/tests/Strategy/Cluster.html
new file mode 100644
index 0000000..3358ff9
--- /dev/null
+++ b/misc/openlayers/tests/Strategy/Cluster.html
@@ -0,0 +1,148 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_activate(t) {
+ t.plan(2);
+
+ var strategy = new OpenLayers.Strategy.Cluster();
+ t.eq(strategy.active, false, "not active after construction");
+
+ var layer = new OpenLayers.Layer.Vector("Vector Layer", {
+ strategies: [strategy]
+ });
+ var map = new OpenLayers.Map('map');
+ map.addLayer(layer);
+
+ t.eq(strategy.active, true, "active after adding to map");
+ }
+
+ function test_clusters(t) {
+ t.plan(22);
+
+ function featuresEq(got, exp) {
+ var eq = false;
+ if(got instanceof Array && exp instanceof Array) {
+ if(got.length === exp.length) {
+ for(var i=0; i<got.length; ++i) {
+ if(got[i] !== exp[i]) {
+ console.log(got[i], exp[i]);
+ break;
+ }
+ }
+ eq = (i == got.length);
+ }
+ }
+ return eq;
+ }
+
+ var strategy = new OpenLayers.Strategy.Cluster();
+ var layer = new OpenLayers.Layer.Vector("Vector Layer", {
+ strategies: [strategy],
+ isBaseLayer: true
+ });
+ var map = new OpenLayers.Map('map', {
+ resolutions: [4, 2, 1],
+ maxExtent: new OpenLayers.Bounds(-40, -40, 40, 40),
+ zoomMethod: null
+ });
+ map.addLayer(layer);
+
+ // create features in a line, 1 unit apart
+ var features = new Array(80);
+ for(var i=0; i<80; ++i) {
+ features[i] = new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(-40 + i, 0)
+ );
+ }
+
+ // add one additional feature, with no geometry - just to confirm it doesn't break things
+ features.push(new OpenLayers.Feature.Vector());
+
+ layer.addFeatures(features);
+ map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+
+ // resolution 4
+ // threshold: 4 * 20 = 80 units
+ // one cluster
+ t.eq(layer.features.length, 1, "[4] layer has one cluster");
+ t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 80)), "[4] cluster includes all features with geometries");
+
+ // resolution 2
+ // threshold: 2 * 20 = 40 units
+ // two clusters (41 and 39) - first cluster includes all features within 40 units of the first (0-40 or 41 features)
+ map.zoomIn();
+ t.eq(layer.features.length, 2, "[2] layer has two clusters");
+ t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 41)), "[2] first cluster includes first 41 features");
+ t.ok(featuresEq(layer.features[1].cluster, features.slice(41, 80)), "[2] second cluster includes last 39 features");
+
+ // resolution 1
+ // threshold: 1 * 20 = 20 units
+ // four clusters (21, 21, 21, and 17)
+ map.zoomIn();
+ t.eq(layer.features.length, 4, "[1] layer has four clusters");
+ t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 21)), "[1] first cluster includes first 21 features");
+ t.ok(featuresEq(layer.features[1].cluster, features.slice(21, 42)), "[1] second cluster includes second 21 features");
+ t.ok(featuresEq(layer.features[2].cluster, features.slice(42, 63)), "[1] third cluster includes third 21 features");
+ t.ok(featuresEq(layer.features[3].cluster, features.slice(63, 80)), "[1] fourth cluster includes last 17 features");
+
+ // zoom out and back in to test threshold property (21)
+ map.zoomOut();
+ strategy.threshold = 21;
+ map.zoomIn();
+ t.eq(layer.features.length, 20, "[1-threshold 21] layer has 20 clusters");
+ t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 21)), "[1-threshold 21] first cluster includes first 21 features");
+ t.ok(featuresEq(layer.features[1].cluster, features.slice(21, 42)), "[1-threshold 21] second cluster includes second 21 features");
+ t.ok(featuresEq(layer.features[2].cluster, features.slice(42, 63)), "[1-threshold 21] third cluster includes third 21 features");
+ t.ok(featuresEq(layer.features.slice(3, 20), features.slice(63, 80)), "[1-threshold 21] last 17 features are not clustered");
+
+ // zoom out and back in to test high threshold
+ map.zoomOut();
+ strategy.threshold = 100; // clusters must contain 100 features or more
+ map.zoomIn();
+ // the one feature with no geometry is not added to the layer
+ t.eq(layer.features.length, features.length-1, "[1-threshold 100] layer has " + (features.length-1) + " clusters");
+ t.ok(featuresEq(layer.features, features.slice(0, 80)), "[1-threshold 100] layer has all features with geometry");
+
+ // remove features and zoom
+ strategy.threshold = 1;
+ map.setCenter(new OpenLayers.LonLat(0, 0), 0);
+ t.eq(strategy.features.length, 81,
+ "[remove features] cluster has cache");
+ layer.removeAllFeatures();
+ t.eq(layer.features.length, 0,
+ "[remove features] layer has no features after remove");
+ t.ok(!strategy.features,
+ "[remove features] cluster has no cache after remove");
+ map.zoomIn();
+ t.eq(layer.features.length, 0,
+ "[remove features] layer has no features after zoom");
+ t.ok(!strategy.features,
+ "[remove features] cluster has no cache after zoom");
+
+ map.destroy();
+ }
+
+ function test_deactivate(t) {
+ t.plan(2);
+
+ var strategy = new OpenLayers.Strategy.Cluster();
+ var layer = new OpenLayers.Layer.Vector("Vector Layer", {
+ strategies: [strategy]
+ });
+ var map = new OpenLayers.Map('map');
+ map.addLayer(layer);
+
+ t.eq(strategy.active, true, "active after adding to map");
+
+ map.removeLayer(layer);
+ t.eq(strategy.active, false, "not active after removing from map");
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 200px" />
+</body>
+</html>
diff --git a/misc/openlayers/tests/Strategy/Filter.html b/misc/openlayers/tests/Strategy/Filter.html
new file mode 100644
index 0000000..7889d1e
--- /dev/null
+++ b/misc/openlayers/tests/Strategy/Filter.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../OLLoader.js"></script>
+<script>
+
+var features = [];
+for (var i=0; i<20; ++i) {
+ features.push(
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(0, 0), {index: i}
+ )
+ );
+}
+
+var filter = new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.LESS_THAN,
+ property: "index",
+ value: 10
+});
+
+function test_initialize(t) {
+
+ t.plan(4);
+
+ var strategy = new OpenLayers.Strategy.Filter({filter: filter});
+
+ t.ok(strategy instanceof OpenLayers.Strategy, "is strategy");
+ t.ok(strategy instanceof OpenLayers.Strategy.Filter, "is filter strategy");
+
+ t.ok(strategy.filter === filter, "has filter");
+
+ strategy.destroy();
+
+ try {
+ strategy = new OpenLayers.Strategy.Filter();
+ t.ok(true, "strategy without filter works");
+ } catch (err) {
+ t.fail("strategy without filter should not throw");
+ }
+
+
+}
+
+function test_autoActivate(t) {
+
+ t.plan(2);
+
+ var strategy = new OpenLayers.Strategy.Filter({filter: filter});
+
+ var layer = new OpenLayers.Layer.Vector(null, {
+ strategies: [strategy]
+ });
+
+ t.ok(!strategy.active, "strategy not active before adding to map");
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ allOverlays: true,
+ layers: [layer],
+ center: new OpenLayers.LonLat(0, 0),
+ zoom: 1
+ });
+
+ t.ok(strategy.active, "strategy active after adding to map");
+
+ map.destroy();
+
+}
+
+function test_setFilter(t) {
+
+ t.plan(13);
+
+ var strategy = new OpenLayers.Strategy.Filter({filter: filter});
+ var layer = new OpenLayers.Layer.Vector(null, {
+ strategies: [strategy]
+ });
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ allOverlays: true,
+ layers: [layer],
+ center: new OpenLayers.LonLat(0, 0),
+ zoom: 1
+ });
+
+ var log = [];
+ layer.events.on({
+ beforefeaturesadded: function(event) {
+ log.push(event.type);
+ },
+ beforefeaturesremoved: function(event) {
+ log.push(event.type);
+ }
+ })
+
+ // a) add all features
+ log = [];
+ layer.addFeatures(features);
+ t.eq(features.length, 20, "a) collection of 20 features")
+ t.eq(layer.features.length, 10, "a) layer got 10 with filter 'index < 10'");
+ t.eq(strategy.cache.length, 10, "a) strategy cached 10 with filter 'index < 10'");
+ t.eq(log.length, 1, "a) one event logged");
+ t.eq(log[0], "beforefeaturesadded", "a) beforefeaturesadded fired");
+
+ // b) update filter
+ log = [];
+ filter.value = 5;
+ strategy.setFilter(filter);
+ t.eq(layer.features.length, 5, "b) layer got 5 with filter 'index < 5'");
+ t.eq(strategy.cache.length, 15, "b) strategy cached 15 with filter 'index < 5'");
+ t.eq(log.length, 1, "b) one event logged");
+ t.eq(log[0], "beforefeaturesremoved", "b) beforefeaturesremoved fired");
+
+ // c) update filter
+ log = [];
+ filter.value = 15;
+ strategy.setFilter(filter);
+ t.eq(layer.features.length, 15, "c) layer got 15 with filter 'index < 15'");
+ t.eq(strategy.cache.length, 5, "c) strategy cached 5 with filter 'index < 15'");
+ t.eq(log.length, 1, "c) one event logged");
+ t.eq(log[0], "beforefeaturesadded", "c) beforefeaturesadded fired");
+
+ map.destroy();
+
+}
+
+
+
+</script></head>
+<body>
+ <div id="map" style="width: 512px; height: 256px" />
+</body>
+</html> \ No newline at end of file
diff --git a/misc/openlayers/tests/Strategy/Fixed.html b/misc/openlayers/tests/Strategy/Fixed.html
new file mode 100644
index 0000000..a9bf608
--- /dev/null
+++ b/misc/openlayers/tests/Strategy/Fixed.html
@@ -0,0 +1,253 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_activate(t) {
+ t.plan(5);
+
+ var featureList = ['foo', 'bar'];
+ // a fake protocol
+ var protocol = {
+ read: function(options) {
+ options.callback.call(options.scope, {
+ features: featureList,
+ success: OpenLayers.Function.True
+ });
+ }
+ };
+
+ // Create a dummy layer that can act as the map base layer.
+ // This will be unnecessary if #1920 is addressed or if base layer
+ // handling is changed.
+ var dummy = new OpenLayers.Layer(null, {isBaseLayer: true});
+
+ var layer = new OpenLayers.Layer.Vector("Vector Layer", {
+ strategies: [new OpenLayers.Strategy.Fixed()],
+ protocol: protocol,
+ addFeatures: function(features) {
+ t.eq(features, featureList, "Features added to the layer");
+ }
+ });
+
+ var layerp = new OpenLayers.Layer.Vector("Hidden preload Layer", {
+ strategies: [new OpenLayers.Strategy.Fixed({preload:true})],
+ protocol: protocol,
+ visibility: false,
+ addFeatures: function(features) {
+ t.ok(!this.visibility, "Features preloaded before visible");
+ }
+ });
+
+ var s = new OpenLayers.Strategy.Fixed();
+ var layer2 = new OpenLayers.Layer.Vector("Hidden lazyload Layer", {
+ strategies: [s],
+ protocol: protocol,
+ visibility: false,
+ addFeatures: function(features) {
+ t.ok(this.visibility, "Layer visible when features added");
+ }
+ });
+
+ var map = new OpenLayers.Map('map');
+ map.addLayers([dummy, layer, layerp, layer2]);
+
+ t.ok(layer2.events.listeners["visibilitychanged"][0].obj == s &&
+ layer2.events.listeners["visibilitychanged"][0].func == s.load,
+ "activate registers visibilitychanged listener if layer hidden"+
+ " and is lazyloading");
+
+ layer2.setVisibility(true);
+
+ t.ok(layer2.events.listeners["visibilitychanged"] == false,
+ "visibilitychanged listener unregistered");
+ }
+
+ function test_events(t) {
+
+ t.plan(7);
+
+ var log = [];
+
+ var response = new OpenLayers.Protocol.Response();
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector(null, {
+ filter: new OpenLayers.Filter.Comparison({
+ type: '==',
+ property: 'foo',
+ value: 'bar'
+ }),
+ strategies: [new OpenLayers.Strategy.Fixed()],
+ protocol: new OpenLayers.Protocol({
+ read: function(config) {
+ config.callback.call(config.scope, response);
+ }
+ }),
+ isBaseLayer: true,
+ eventListeners: {
+ loadstart: function(event) {
+ log.push(event);
+ },
+ loadend: function(event) {
+ log.push(event);
+ }
+ }
+ });
+
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ t.eq(log.length, 2, "2 events logged");
+ t.eq(log[0].type, "loadstart", "loadstart first");
+ t.eq(log[0].filter, layer.filter, "filter passed on as argument to loadstart");
+ t.eq(log[1].type, "loadend", "loadend second");
+ t.ok(log[1].response == response, "loadend includes response");
+
+ var calls = [];
+ layer.protocol.read = function(obj) {
+ calls.push(obj);
+ }
+ layer.refresh({whee: 'chicken'});
+
+ t.eq(calls.length, 1, "1 call to read");
+ t.eq(calls[0].whee, "chicken", "properties passed to read");
+
+ map.destroy();
+
+ }
+
+
+ function test_merge(t) {
+
+ t.plan(6);
+
+ var strategy = new OpenLayers.Strategy.Fixed();
+
+ // create map with default projection
+ var map = new OpenLayers.Map("map");
+
+ var log = {
+ loadend: 0
+ };
+
+ // create layer with custom projection
+ var layer = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true,
+ strategies: [strategy],
+ protocol: new OpenLayers.Protocol(),
+ projection: new OpenLayers.Projection("EPSG:900913"),
+ eventListeners: {
+ loadend: function() {
+ ++log.loadend;
+ }
+ }
+ });
+
+ // give the layer some existing features (one)
+ layer.addFeatures([
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(0, 0)
+ )
+ ]);
+
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ // create some features
+ var geometries = [
+ new OpenLayers.Geometry.Point(100, 200),
+ new OpenLayers.Geometry.Point(1000, 2000)
+ ];
+ var features = [
+ new OpenLayers.Feature.Vector(geometries[0].clone()),
+ new OpenLayers.Feature.Vector(geometries[1].clone())
+ ];
+
+ // call merge with a mocked up response
+ strategy.merge({features: features, success: OpenLayers.Function.True});
+
+ // confirm that the original features were destroyed
+ t.eq(layer.features.length, 2, "old features destroyed");
+
+ // confirm that loadend was called
+ t.eq(log.loadend, 1, "merge triggers loadend");
+
+ // test that feature geometries have been transformed to map projection
+ var from = layer.projection;
+ var to = map.getProjectionObject();
+ t.geom_eq(layer.features[0].geometry, features[0].geometry.transform(from, to), "[different proj] feature 0 geometry transformed");
+ t.geom_eq(layer.features[1].geometry, features[1].geometry.transform(from, to), "[different proj] feature 1 geometry transformed");
+
+ // same as above but with same map/layer projection
+ layer.destroyFeatures();
+ layer.projection = map.getProjectionObject();
+
+ features = [
+ new OpenLayers.Feature.Vector(geometries[0].clone()),
+ new OpenLayers.Feature.Vector(geometries[1].clone())
+ ];
+
+ // call merge again with mocked up response
+ strategy.merge({features: features, success: OpenLayers.Function.True});
+
+ // test that feature geometries have not been transformed
+ t.geom_eq(layer.features[0].geometry, features[0].geometry, "[same proj] feature 0 geometry not transformed");
+ t.geom_eq(layer.features[1].geometry, features[1].geometry, "[same proj] feature 1 geometry not transformed");
+
+ }
+
+ function test_load(t) {
+ t.plan(3);
+
+ // set up
+
+ var log;
+
+ var map = new OpenLayers.Map({
+ div: "map",
+ projection: new OpenLayers.Projection("EPSG:900913"),
+ layers: [new OpenLayers.Layer("", {isBaseLayer: true})]
+ });
+
+ var response = new OpenLayers.Protocol.Response();
+
+ var strategy = new OpenLayers.Strategy.Fixed({
+ merge: function(r) {
+ log = {scope: this, response: r};
+ }
+ });
+
+ var layer = new OpenLayers.Layer.Vector("vector", {
+ strategies: [strategy],
+ protocol: {
+ read: function(o) {
+ o.callback.call(o.scope, response);
+ }
+ }
+ });
+
+ map.addLayer(layer);
+
+ // test
+
+ strategy.load();
+
+ // verify that the callback is correctly bound
+ t.ok(log !== undefined,
+ "merge was called");
+ t.ok(log.scope == strategy,
+ "merge called with expected scope");
+ t.ok(log.response == response,
+ "merge called with response as the first arg");
+
+ // tear down
+
+ map.destroy();
+ }
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 200px" />
+</body>
+</html>
diff --git a/misc/openlayers/tests/Strategy/Paging.html b/misc/openlayers/tests/Strategy/Paging.html
new file mode 100644
index 0000000..a85167e
--- /dev/null
+++ b/misc/openlayers/tests/Strategy/Paging.html
@@ -0,0 +1,113 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_activate(t) {
+ t.plan(2);
+
+ var strategy = new OpenLayers.Strategy.Paging();
+ t.eq(strategy.active, false, "not active after construction");
+
+ var layer = new OpenLayers.Layer.Vector("Vector Layer", {
+ strategies: [strategy]
+ });
+ var map = new OpenLayers.Map('map');
+ map.addLayer(layer);
+
+ t.eq(strategy.active, true, "active after adding to map");
+ }
+
+ function test_paging(t) {
+ t.plan(18);
+
+ var strategy = new OpenLayers.Strategy.Paging();
+ var layer = new OpenLayers.Layer.Vector("Vector Layer", {
+ strategies: [strategy],
+ drawFeature: function() {}
+ });
+ var map = new OpenLayers.Map('map');
+ map.addLayer(layer);
+
+ var features = new Array(25);
+ for(var i=0; i<features.length; ++i) {
+ features[i] = {destroy: function() {}};
+ }
+
+ function featuresEq(got, exp) {
+ var eq = false;
+ if(got instanceof Array && exp instanceof Array) {
+ if(got.length === exp.length) {
+ for(var i=0; i<got.length; ++i) {
+ if(got[i] !== exp[i]) {
+ console.log(got[i], exp[i]);
+ break;
+ }
+ }
+ eq = (i == got.length);
+ }
+ }
+ return eq;
+ }
+
+ var len = strategy.pageLength();
+ t.eq(len, 10, "page length defaults to 10");
+
+ // add 25 features to the layer
+ layer.addFeatures(features);
+ t.eq(strategy.features.length, features.length, "strategy caches all features");
+ t.eq(layer.features.length, len, "layer gets one page of features");
+ t.ok(featuresEq(layer.features, features.slice(0, len)), "layer gets first page initially");
+ t.eq(strategy.pageNum(), 0, "strategy reports 0 based page number");
+ t.eq(strategy.pageCount(), Math.ceil(features.length / len), "strategy reports correct number of pages");
+
+ // load next page of features
+ var changed = strategy.pageNext();
+ t.eq(changed, true, "(1) strategy reports change");
+ t.eq(strategy.pageNum(), 1, "second page");
+ t.ok(featuresEq(layer.features, features.slice(len, 2*len)), "layer has second page of features");
+
+ // load next page of features (half page)
+ changed = strategy.pageNext();
+ t.eq(changed, true, "(2) strategy reports change");
+ t.eq(strategy.pageNum(), 2, "third page");
+
+ // try to change forward again
+ changed = strategy.pageNext();
+ t.eq(changed, false, "strategy reports no change");
+ t.eq(layer.features.length, features.length % len, "layer has partial page");
+ t.ok(featuresEq(layer.features, features.slice(2*len, 3*len)), "layer has third page of features");
+ t.eq(strategy.pageNum(), 2, "still on third page");
+
+ // change back a page
+ changed = strategy.pagePrevious();
+ t.eq(changed, true, "(3) strategy reports change");
+ t.eq(strategy.pageNum(), 1, "back on second page");
+ t.ok(featuresEq(layer.features, features.slice(len, 2*len)), "layer has second page of features again");
+
+ layer.destroy();
+
+ }
+
+ function test_deactivate(t) {
+ t.plan(2);
+
+ var strategy = new OpenLayers.Strategy.Paging();
+ var layer = new OpenLayers.Layer.Vector("Vector Layer", {
+ strategies: [strategy]
+ });
+ var map = new OpenLayers.Map('map');
+ map.addLayer(layer);
+
+ t.eq(strategy.active, true, "active after adding to map");
+
+ map.removeLayer(layer);
+ t.eq(strategy.active, false, "not active after removing from map");
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 200px" />
+</body>
+</html>
diff --git a/misc/openlayers/tests/Strategy/Refresh.html b/misc/openlayers/tests/Strategy/Refresh.html
new file mode 100644
index 0000000..054f028
--- /dev/null
+++ b/misc/openlayers/tests/Strategy/Refresh.html
@@ -0,0 +1,177 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var interval = 5000;
+
+ function test_initialize(t) {
+ t.plan(2);
+
+ var s = new OpenLayers.Strategy.Refresh({interval: interval});
+ t.ok(typeof s.interval === "number", "interval must be a number");
+ t.eq(s.interval, interval, "ctor sets interval");
+ }
+
+ function test_activate(t) {
+ t.plan(4);
+
+ var l = new OpenLayers.Layer.Vector();
+ l.setVisibility(false);
+ var s = new OpenLayers.Strategy.Refresh();
+ s.setLayer(l);
+
+ t.eq(s.active, false, "not active after construction");
+
+ var activated = s.activate();
+ t.eq(activated, true, "activate returns true");
+ t.eq(s.active, true, "activated after activate");
+ t.ok(l.events.listeners.visibilitychanged[0].obj == s &&
+ l.events.listeners.visibilitychanged[0].func == s.reset,
+ "activates registers visibilitychanged listener");
+ }
+
+ function test_deactivate(t) {
+ t.plan(3);
+
+ var l = new OpenLayers.Layer.Vector();
+ l.setVisibility(false);
+ var s = new OpenLayers.Strategy.Refresh();
+ s.setLayer(l);
+ s.activate();
+ var deactivated = s.deactivate();
+ t.eq(deactivated, true, "deactivate returns true");
+ t.eq(s.active, false, "deactivated after activate");
+ t.ok(l.events.listeners.visibilitychanged.length == 0,
+ "deactivate unregisters visibilitychanged listener");
+ }
+
+ function test_activateWithVisibleLayer(t) {
+ t.plan(5);
+
+ var l = new OpenLayers.Layer.Vector();
+ l.setVisibility(true);
+ var s = new OpenLayers.Strategy.Refresh({interval: interval});
+ s.setLayer(l);
+
+ t.eq(s.active, false, "not active after construction");
+
+ var activated = s.activate();
+ t.eq(activated, true, "activate returns true");
+ t.eq(s.active, true, "activated after activate");
+ t.ok(l.events.listeners.visibilitychanged[0].obj == s &&
+ l.events.listeners.visibilitychanged[0].func == s.reset,
+ "activates registers visibilitychanged listener");
+ t.ok(s.timer !== null, "timer should be set on activate if layer is visible");
+
+ // reset the timer!!
+ s.stop();
+ }
+
+ function test_events(t) {
+
+ t.plan(1);
+ var log = {
+ visibilitychanged: 0
+ };
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector(null, {
+ strategies: [new OpenLayers.Strategy.Refresh({interval: interval})],
+ protocol: new OpenLayers.Protocol({
+ read: function(config) {
+ config.callback.call(config.scope, {});
+ }
+ }),
+ isBaseLayer: true,
+ eventListeners: {
+ visibilitychanged: function() {
+ ++log.visibilitychanged;
+ }
+ }
+ });
+ map.addLayer(layer);
+
+ layer.setVisibility(false);
+ t.eq(log.visibilitychanged, 1, "visibilitychanged triggered");
+
+ map.destroy();
+
+ }
+
+ function test_refreshWithNormalProgress(t) {
+
+ t.plan(1);
+ var log = {
+ refreshcalled: 0
+ };
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector(null, {
+ strategies: [new OpenLayers.Strategy.Refresh({
+ interval: interval,
+ refresh: function() {
+ if (this.layer && this.layer.refresh) {
+ ++log.refreshcalled;
+ }
+ }
+ })],
+ protocol: new OpenLayers.Protocol({
+ read: function(config) {
+ config.callback.call(config.scope, {});
+ }
+ }),
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+
+ t.delay_call((5 * (interval / 1000)) + 0.5, function() {
+ t.eq(log.refreshcalled, 5, "number of refreshes");
+ map.destroy();
+ });
+
+ }
+
+ function test_refreshWithSwitchingVisibility(t) {
+
+ t.plan(1);
+ var log = {
+ refreshcalled: 0
+ };
+
+ var map = new OpenLayers.Map("map");
+ var layer = new OpenLayers.Layer.Vector(null, {
+ strategies: [new OpenLayers.Strategy.Refresh({
+ interval: interval,
+ refresh: function() {
+ if (this.layer && this.layer.refresh) {
+ ++log.refreshcalled;
+ }
+ }
+ })],
+ protocol: new OpenLayers.Protocol({
+ read: function(config) {
+ config.callback.call(config.scope, {});
+ }
+ }),
+ isBaseLayer: true
+ });
+ map.addLayer(layer);
+
+ window.setTimeout(function() {
+ layer.setVisibility(false);
+ }, 2.5 * interval);
+
+ t.delay_call((5 * (interval / 1000)) + 0.5, function() {
+ t.eq(log.refreshcalled, 2, "number of refreshes");
+ map.destroy();
+ });
+
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 200px;"></div>
+</body>
+</html>
diff --git a/misc/openlayers/tests/Strategy/Save.html b/misc/openlayers/tests/Strategy/Save.html
new file mode 100644
index 0000000..1290485
--- /dev/null
+++ b/misc/openlayers/tests/Strategy/Save.html
@@ -0,0 +1,127 @@
+<html>
+<head>
+ <script src="../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ function test_initialize(t) {
+ t.plan(1);
+ var strategy = new OpenLayers.Strategy.Save();
+ t.eq(strategy.auto, false, "auto is false by default");
+ }
+
+ function test_activate(t) {
+
+ t.plan(3);
+
+ var strategy = new OpenLayers.Strategy.Save();
+ var layer = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true,
+ protocol: new OpenLayers.Protocol(),
+ strategies: [strategy]
+ });
+ var map = new OpenLayers.Map("map");
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ // check that auto true registers listeners
+ strategy.deactivate();
+ strategy.auto = true;
+ strategy.activate();
+ t.ok(layer.events.listeners["featureadded"][0].func === strategy.triggerSave,
+ "[auto true] triggerSave registered as listener for featureadded");
+ t.ok(layer.events.listeners["afterfeaturemodified"][0].func === strategy.triggerSave,
+ "[auto true] triggerSave registered as listener for afterfeaturemodified");
+
+ // check that auto can be set to interval
+ strategy.deactivate();
+ strategy.auto = 1;
+ strategy.activate();
+ t.ok(strategy.timer != null, "[auto number] timer set")
+
+ map.destroy();
+
+ }
+
+ function test_save(t) {
+ t.plan(9);
+
+ var strategy = new OpenLayers.Strategy.Save();
+
+ // mock up a protocol for synchronous and successful commits
+ var protocol = new OpenLayers.Protocol({
+ commit: function(features, options) {
+ var response = new OpenLayers.Protocol.Response();
+ response.reqFeatures = features;
+ response.insertIds = [];
+ for(var i=0; i<features.length; ++i) {
+ // test feature.url first
+ t.eq(features[i].url, "url" + i,
+ "feature.url correctly set (url" + i + ")");
+ if(features[i].state == OpenLayers.State.INSERT) {
+ response.insertIds.push("new_" + i);
+ }
+ }
+ response.code = OpenLayers.Protocol.Response.SUCCESS;
+ options.callback.call(options.scope, response);
+ }
+ });
+
+ var layer = new OpenLayers.Layer.Vector(null, {
+ isBaseLayer: true,
+ protocol: protocol,
+ strategies: [strategy],
+ projection: "EPSG:4326"
+ });
+ var map = new OpenLayers.Map("map", {
+ getProjectionObject: function() {
+ return new OpenLayers.Projection("EPSG:900913");
+ }
+ })
+ map.addLayer(layer);
+ map.zoomToMaxExtent();
+
+ // give the layer some features
+ var features = [
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(5, 45)
+ ), // insert
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(6, 46)
+ ), // delete
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(7, 47)
+ ), // update
+ new OpenLayers.Feature.Vector(
+ new OpenLayers.Geometry.Point(8, 48)
+ ) // nothing
+ ];
+ features[0].state = OpenLayers.State.INSERT;
+ features[0].url = "url0";
+ features[1].state = OpenLayers.State.DELETE;
+ features[1].url = "url1";
+ features[2].state = OpenLayers.State.UPDATE;
+ features[2].url = "url2";
+ features[3].url = "url3";
+ layer.addFeatures(features);
+
+ // save feature modifications
+ strategy.save(features);
+
+ // confirm that newly created feature has an id and no longer has insert state
+ t.eq(features[0].fid, "new_0", "newly created feature gets fid");
+ t.ok(features[0].state == null, "newly created feature no longer insert state");
+
+ // confirm that deleted features are not on layer
+ t.eq(layer.features.length, 3, "layer only has three features");
+ t.ok(features[1].layer == null, "deleted feature has no layer");
+
+ // confirm that updated feature no longer has update state
+ t.ok(features[2].state == null, "updated feature no longer update state");
+ }
+
+ </script>
+</head>
+<body>
+ <div id="map" style="width: 400px; height: 200px" />
+</body>
+</html>