mirror of
https://github.com/TheGreyDiamond/elevatormapRewritten.git
synced 2025-12-19 00:10:46 +01:00
Started user control
This commit is contained in:
2
static/leafletCluster/spec/after.js
Normal file
2
static/leafletCluster/spec/after.js
Normal file
@@ -0,0 +1,2 @@
|
||||
// put after Leaflet files as imagePath can't be detected in a PhantomJS env
|
||||
L.Icon.Default.imagePath = "../dist/images";
|
||||
1253
static/leafletCluster/spec/expect.js
Normal file
1253
static/leafletCluster/spec/expect.js
Normal file
File diff suppressed because it is too large
Load Diff
93
static/leafletCluster/spec/happen.js
Normal file
93
static/leafletCluster/spec/happen.js
Normal file
@@ -0,0 +1,93 @@
|
||||
// https://github.com/tmcw/happen
|
||||
|
||||
!(function(context) {
|
||||
var h = {};
|
||||
|
||||
// Make inheritance bearable: clone one level of properties
|
||||
function extend(child, parent) {
|
||||
for (var property in parent) {
|
||||
if (typeof child[property] == 'undefined') {
|
||||
child[property] = parent[property];
|
||||
}
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
h.once = function(x, o) {
|
||||
var evt;
|
||||
|
||||
if (o.type.slice(0, 3) === 'key') {
|
||||
if (typeof Event === 'function') {
|
||||
evt = new Event(o.type);
|
||||
evt.keyCode = o.keyCode || 0;
|
||||
evt.charCode = o.charCode || 0;
|
||||
evt.shift = o.shift || false;
|
||||
evt.meta = o.meta || false;
|
||||
evt.ctrl = o.ctrl || false;
|
||||
evt.alt = o.alt || false;
|
||||
} else {
|
||||
evt = document.createEvent('KeyboardEvent');
|
||||
// https://developer.mozilla.org/en/DOM/event.initKeyEvent
|
||||
// https://developer.mozilla.org/en/DOM/KeyboardEvent
|
||||
evt[(evt.initKeyEvent) ? 'initKeyEvent'
|
||||
: 'initKeyboardEvent'](
|
||||
o.type, // in DOMString typeArg,
|
||||
true, // in boolean canBubbleArg,
|
||||
true, // in boolean cancelableArg,
|
||||
null, // in nsIDOMAbstractView viewArg, Specifies UIEvent.view. This value may be null.
|
||||
o.ctrl || false, // in boolean ctrlKeyArg,
|
||||
o.alt || false, // in boolean altKeyArg,
|
||||
o.shift || false, // in boolean shiftKeyArg,
|
||||
o.meta || false, // in boolean metaKeyArg,
|
||||
o.keyCode || 0, // in unsigned long keyCodeArg,
|
||||
o.charCode || 0 // in unsigned long charCodeArg);
|
||||
);
|
||||
}
|
||||
} else {
|
||||
evt = document.createEvent('MouseEvents');
|
||||
// https://developer.mozilla.org/en/DOM/event.initMouseEvent
|
||||
evt.initMouseEvent(o.type,
|
||||
true, // canBubble
|
||||
true, // cancelable
|
||||
window, // 'AbstractView'
|
||||
o.clicks || 0, // click count
|
||||
o.screenX || 0, // screenX
|
||||
o.screenY || 0, // screenY
|
||||
o.clientX || 0, // clientX
|
||||
o.clientY || 0, // clientY
|
||||
o.ctrl || 0, // ctrl
|
||||
o.alt || false, // alt
|
||||
o.shift || false, // shift
|
||||
o.meta || false, // meta
|
||||
o.button || false, // mouse button
|
||||
null // relatedTarget
|
||||
);
|
||||
}
|
||||
|
||||
x.dispatchEvent(evt);
|
||||
};
|
||||
|
||||
var shortcuts = ['click', 'mousedown', 'mouseup', 'mousemove', 'keydown', 'keyup', 'keypress'],
|
||||
s, i = 0;
|
||||
|
||||
while (s = shortcuts[i++]) {
|
||||
h[s] = (function(s) {
|
||||
return function(x, o) {
|
||||
h.once(x, extend(o || {}, { type: s }));
|
||||
};
|
||||
})(s);
|
||||
}
|
||||
|
||||
h.dblclick = function(x, o) {
|
||||
h.once(x, extend(o || {}, {
|
||||
type: 'dblclick',
|
||||
clicks: 2
|
||||
}));
|
||||
};
|
||||
|
||||
this.happen = h;
|
||||
|
||||
if (typeof module !== 'undefined') {
|
||||
module.exports = this.happen;
|
||||
}
|
||||
})(this);
|
||||
79
static/leafletCluster/spec/index.html
Normal file
79
static/leafletCluster/spec/index.html
Normal file
@@ -0,0 +1,79 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Spec Runner</title>
|
||||
<link rel="stylesheet" type="text/css" href="../node_modules/mocha/mocha.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="mocha"></div>
|
||||
<script src="expect.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/mocha/mocha.js"></script>
|
||||
<script type="text/javascript" src="happen.js"></script>
|
||||
<script type="text/javascript" src="sinon.js"></script>
|
||||
<script type="text/javascript" src="../node_modules/leaflet/dist/leaflet-src.js"></script>
|
||||
|
||||
<!-- source files -->
|
||||
<script type="text/javascript" src="../src/DistanceGrid.js"></script>
|
||||
<script type="text/javascript" src="../src/MarkerCluster.js"></script>
|
||||
<script type="text/javascript" src="../src/MarkerClusterGroup.js"></script>
|
||||
<script type="text/javascript" src="../src/MarkerCluster.QuickHull.js"></script>
|
||||
<script type="text/javascript" src="../src/MarkerCluster.Spiderfier.js"></script>
|
||||
<script type="text/javascript" src="../src/MarkerOpacity.js"></script>
|
||||
<script type="text/javascript" src="../src/MarkerClusterGroup.Refresh.js"></script>
|
||||
|
||||
<script>
|
||||
mocha.setup('bdd');
|
||||
mocha.ignoreLeaks();
|
||||
</script>
|
||||
|
||||
<!-- spec files -->
|
||||
|
||||
<script type="text/javascript" src="suites/SpecHelper.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/LeafletSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/DistanceGridSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/QuickHullSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/AddLayer.MultipleSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/AddLayer.SingleSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/AddLayersSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/animateOptionSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/singleMarkerModeSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/ChildChangingIconSupportSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/markerMoveSupportSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/CircleMarkerSupportSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/CircleSupportSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/onAddSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/onRemoveSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/clearLayersSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/eachLayerSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/eventsSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/getBoundsSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/getLayersSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/getVisibleParentSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/NonPointSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/RemoveLayerSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/removeLayersSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/spiderfySpec.js"></script>
|
||||
<script type="text/javascript" src="suites/unspiderfySpec.js"></script>
|
||||
<script type="text/javascript" src="suites/zoomAnimationSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/RememberOpacity.js"></script>
|
||||
<script type="text/javascript" src="suites/supportNegativeZoomSpec.js"></script>
|
||||
|
||||
<script type="text/javascript" src="suites/RefreshSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/removeOutsideVisibleBoundsSpec.js"></script>
|
||||
<script type="text/javascript" src="suites/nonIntegerZoomSpec.js"></script>
|
||||
|
||||
<script>
|
||||
(window.mochaPhantomJS || window.mocha).run();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
67
static/leafletCluster/spec/karma.conf.js
Normal file
67
static/leafletCluster/spec/karma.conf.js
Normal file
@@ -0,0 +1,67 @@
|
||||
// Karma configuration
|
||||
var libSources = require(__dirname+'/../build/build.js').getFiles();
|
||||
var leafletSources = require(__dirname+'/../node_modules/leaflet/build/build.js').getFiles(); // Caution Leaflet 1.0.0-beta.2 build needs magic-string
|
||||
|
||||
// base path, that will be used to resolve files and exclude
|
||||
basePath = '';
|
||||
|
||||
for (var i=0; i < libSources.length; i++) {
|
||||
libSources[i] = "../" + libSources[i];
|
||||
}
|
||||
for (var i=0; i < leafletSources.length; i++) {
|
||||
leafletSources[i] = "../node_modules/leaflet/" + leafletSources[i];
|
||||
}
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files = [].concat([
|
||||
"../node_modules/mocha/mocha.js",
|
||||
MOCHA_ADAPTER,
|
||||
"sinon.js",
|
||||
"expect.js"
|
||||
], leafletSources, libSources, [
|
||||
"after.js",
|
||||
"happen.js",
|
||||
"suites/SpecHelper.js",
|
||||
"suites/**/*.js"
|
||||
]);
|
||||
|
||||
// list of files to exclude
|
||||
exclude = [
|
||||
];
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress', 'junit'
|
||||
reporters = ['dots'];
|
||||
|
||||
// web server port
|
||||
port = 8080;
|
||||
|
||||
// cli runner port
|
||||
runnerPort = 9100;
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors = true;
|
||||
|
||||
// level of logging
|
||||
// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
|
||||
logLevel = LOG_WARN;
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch = false;
|
||||
|
||||
// Start these browsers, currently available:
|
||||
// - Chrome
|
||||
// - ChromeCanary
|
||||
// - Firefox
|
||||
// - Opera
|
||||
// - Safari (only Mac)
|
||||
// - PhantomJS
|
||||
// - IE (only Windows)
|
||||
browsers = ['PhantomJS'];
|
||||
|
||||
// If browser does not capture in given timeout [ms], kill it
|
||||
captureTimeout = 5000;
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, it capture browsers, run tests and exit
|
||||
singleRun = true;
|
||||
4223
static/leafletCluster/spec/sinon.js
Normal file
4223
static/leafletCluster/spec/sinon.js
Normal file
File diff suppressed because it is too large
Load Diff
114
static/leafletCluster/spec/suites/AddLayer.MultipleSpec.js
Normal file
114
static/leafletCluster/spec/suites/AddLayer.MultipleSpec.js
Normal file
@@ -0,0 +1,114 @@
|
||||
describe('addLayer adding multiple markers', function () {
|
||||
var map, div, clock;
|
||||
beforeEach(function () {
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
clock.restore();
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._icon).to.be(null); //Null as was added and then removed
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
it('creates a cluster with an animation when 2 overlapping markers are added after the group is added to the map', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup({ animateAddingMarkers: true });
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Then markers should be removed from map
|
||||
expect(marker._icon).to.be(null);
|
||||
expect(marker2._icon).to.be(null);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
|
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added before the group is added to the map', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([3.0, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2);
|
||||
});
|
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added after the group is added to the map', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([3.0, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
|
||||
expect(marker._icon).to.be(null); //Null as was added and then removed
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2);
|
||||
});
|
||||
});
|
||||
154
static/leafletCluster/spec/suites/AddLayer.SingleSpec.js
Normal file
154
static/leafletCluster/spec/suites/AddLayer.SingleSpec.js
Normal file
@@ -0,0 +1,154 @@
|
||||
describe('addLayer adding a single marker', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Nothing for this test suite.
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('appears when added to the group before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('appears when added to the group after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('appears (using animations) when added after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true });
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('does not appear when too far away when added before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([3.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
});
|
||||
|
||||
it('does not appear when too far away when added after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([3.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
});
|
||||
|
||||
it('passes control to addLayers when marker is a Layer Group', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var layerGroup = new L.LayerGroup([marker1, marker2]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(layerGroup);
|
||||
|
||||
expect(group._topClusterLevel.getChildCount()).to.equal(2);
|
||||
|
||||
expect(marker1._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
159
static/leafletCluster/spec/suites/AddLayersSpec.js
Normal file
159
static/leafletCluster/spec/suites/AddLayersSpec.js
Normal file
@@ -0,0 +1,159 @@
|
||||
describe('addLayers adding multiple markers', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Nothing for this test suite.
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayers([marker, marker2]);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
|
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([3.0, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2, marker3]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2);
|
||||
});
|
||||
|
||||
it('creates a cluster and marker when 2 overlapping markers and one non-overlapping are added after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([3.0, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayers([marker, marker2, marker3]);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2);
|
||||
});
|
||||
|
||||
it('handles nested Layer Groups', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([3.0, 1.5]);
|
||||
var layerGroup = new L.LayerGroup([marker1, new L.LayerGroup([marker2])]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayers([layerGroup, marker3]);
|
||||
|
||||
expect(marker1._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2);
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
describe('support child markers changing icon', function () {
|
||||
var map, div, clock;
|
||||
beforeEach(function () {
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
clock.restore();
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('child markers end up with the right icon after becoming unclustered', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5], { icon: new L.DivIcon({html: 'Inner1Text' }) });
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker._icon.innerHTML).to.contain('Inner1Text');
|
||||
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._icon).to.be(null); //Have been removed from the map
|
||||
|
||||
marker.setIcon(new L.DivIcon({ html: 'Inner2Text' })); //Change the icon
|
||||
|
||||
group.removeLayer(marker2); //Remove the other marker, so we'll become unclustered
|
||||
|
||||
expect(marker._icon.innerHTML).to.contain('Inner2Text');
|
||||
});
|
||||
});
|
||||
184
static/leafletCluster/spec/suites/CircleMarkerSupportSpec.js
Normal file
184
static/leafletCluster/spec/suites/CircleMarkerSupportSpec.js
Normal file
@@ -0,0 +1,184 @@
|
||||
describe('support for CircleMarker elements', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('appears when added to the group before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// marker > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(marker._path.parentNode.parentNode).to.not.be(undefined);
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('appears when added to the group after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._path.parentNode.parentNode).to.not.be(undefined);
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('appears animated when added to the group after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true });
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
var marker2 = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(marker._path.parentNode).to.be(null);
|
||||
expect(marker2._path.parentNode).to.be(null);
|
||||
});
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
var marker2 = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._path).to.be(undefined);
|
||||
expect(marker2._path).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
var marker2 = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._path.parentNode).to.be(null); //Removed then re-added, so null
|
||||
expect(marker2._path).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('disappears when removed from the group', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._path.parentNode).to.not.be(undefined);
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(marker._path.parentNode).to.be(null);
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
181
static/leafletCluster/spec/suites/CircleSupportSpec.js
Normal file
181
static/leafletCluster/spec/suites/CircleSupportSpec.js
Normal file
@@ -0,0 +1,181 @@
|
||||
describe('support for Circle elements', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('appears when added to the group before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// marker > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(marker._path.parentNode).to.not.be(undefined);
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('appears when added to the group after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._path.parentNode).to.not.be(undefined);
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('appears animated when added to the group after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true });
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200);
|
||||
var marker2 = new L.Circle([1.5, 1.5], 200);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200);
|
||||
var marker2 = new L.Circle([1.5, 1.5], 200);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._path).to.be(undefined);
|
||||
expect(marker2._path).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200);
|
||||
var marker2 = new L.Circle([1.5, 1.5], 200);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._path.parentNode).to.be(null); //Removed then re-added, so null
|
||||
expect(marker2._path).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
it('disappears when removed from the group', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 200);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._path.parentNode).to.not.be(undefined);
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(marker._path.parentNode).to.be(null);
|
||||
|
||||
clock.tick(1000);
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
21
static/leafletCluster/spec/suites/DistanceGridSpec.js
Normal file
21
static/leafletCluster/spec/suites/DistanceGridSpec.js
Normal file
@@ -0,0 +1,21 @@
|
||||
describe('distance grid', function () {
|
||||
it('addObject', function () {
|
||||
var grid = new L.DistanceGrid(100),
|
||||
obj = {};
|
||||
|
||||
expect(grid.addObject(obj, { x: 0, y: 0 })).to.eql(undefined);
|
||||
expect(grid.removeObject(obj, { x: 0, y: 0 })).to.eql(true);
|
||||
});
|
||||
|
||||
it('eachObject', function (done) {
|
||||
var grid = new L.DistanceGrid(100),
|
||||
obj = {};
|
||||
|
||||
expect(grid.addObject(obj, { x: 0, y: 0 })).to.eql(undefined);
|
||||
|
||||
grid.eachObject(function(o) {
|
||||
expect(o).to.eql(obj);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
6
static/leafletCluster/spec/suites/LeafletSpec.js
Normal file
6
static/leafletCluster/spec/suites/LeafletSpec.js
Normal file
@@ -0,0 +1,6 @@
|
||||
describe('L#noConflict', function() {
|
||||
it('restores the previous L value and returns Leaflet namespace', function(){
|
||||
|
||||
expect(L.version).to.be.ok();
|
||||
});
|
||||
});
|
||||
276
static/leafletCluster/spec/suites/NonPointSpec.js
Normal file
276
static/leafletCluster/spec/suites/NonPointSpec.js
Normal file
@@ -0,0 +1,276 @@
|
||||
describe('adding non point data works', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Nothing for this test suite.
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('Allows adding a polygon before via addLayer', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0,2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// polygon > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(polygon._path).to.not.be(undefined);
|
||||
expect(polygon._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
|
||||
expect(group.hasLayer(polygon));
|
||||
});
|
||||
|
||||
it('Allows adding a polygon before via addLayers([])', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayers([polygon]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(polygon._path).to.not.be(undefined);
|
||||
expect(polygon._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
});
|
||||
|
||||
it('Removes polygons from map when removed', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
map.removeLayer(group);
|
||||
|
||||
expect(polygon._path.parentNode).to.be(null);
|
||||
});
|
||||
|
||||
describe('hasLayer', function () {
|
||||
|
||||
it('returns false when not added', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
|
||||
map.addLayer(polygon);
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
it('returns true before adding to map', function() {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayers([polygon]);
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true after adding to map after adding polygon', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
});
|
||||
|
||||
it('returns true after adding to map before adding polygon', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(polygon);
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('removeLayer', function() {
|
||||
|
||||
it('removes before adding to map', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
it('removes before adding to map', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayers([polygon]);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
it('removes after adding to map after adding polygon', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
it('removes after adding to map before adding polygon', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('removeLayers', function () {
|
||||
|
||||
it('removes before adding to map', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayers([polygon]);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
it('removes before adding to map', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayers([polygon]);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayers([polygon]);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
it('removes after adding to map after adding polygon', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayers([polygon]);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
it('removes after adding to map before adding polygon', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(polygon);
|
||||
expect(group.hasLayer(polygon)).to.be(true);
|
||||
|
||||
group.removeLayers([polygon]);
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
97
static/leafletCluster/spec/suites/PaneSpec.js
Normal file
97
static/leafletCluster/spec/suites/PaneSpec.js
Normal file
@@ -0,0 +1,97 @@
|
||||
describe('Map pane selection', function() {
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Nothing for this test suite.
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Create map pane
|
||||
map.createPane('testPane');
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('recognizes and applies option', function() {
|
||||
group = new L.MarkerClusterGroup({clusterPane: 'testPane'});
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(map._panes.testPane.childNodes.length).to.be(1);
|
||||
});
|
||||
|
||||
it('defaults to default marker pane', function() {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(map._panes[L.Marker.prototype.options.pane].childNodes.length).to.be(1);
|
||||
});
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
52
static/leafletCluster/spec/suites/QuickHullSpec.js
Normal file
52
static/leafletCluster/spec/suites/QuickHullSpec.js
Normal file
@@ -0,0 +1,52 @@
|
||||
describe('quickhull', function () {
|
||||
describe('getDistant', function () {
|
||||
it('zero distance', function () {
|
||||
var bl = [
|
||||
{ lat: 0, lng: 0 },
|
||||
{ lat: 0, lng: 10 }
|
||||
];
|
||||
expect(L.QuickHull.getDistant({ lat: 0, lng: 0 }, bl)).to.eql(0);
|
||||
});
|
||||
it('non-zero distance', function () {
|
||||
var bl = [
|
||||
{ lat: 0, lng: 0 },
|
||||
{ lat: 0, lng: 10 }
|
||||
];
|
||||
expect(L.QuickHull.getDistant({ lat: 5, lng: 5 }, bl)).to.eql(-50);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getConvexHull', function () {
|
||||
it('creates a hull', function () {
|
||||
expect(L.QuickHull.getConvexHull([ { lat: 0, lng: 0 },
|
||||
{ lat: 10, lng: 0 },
|
||||
{ lat: 10, lng: 10 },
|
||||
{ lat: 0, lng: 10 },
|
||||
{ lat: 5, lng: 5 }
|
||||
])).to.eql([
|
||||
{ lat: 0, lng: 10 },
|
||||
{ lat: 10, lng: 10 },
|
||||
{ lat: 10, lng: 0 },
|
||||
{ lat: 0, lng: 0 }
|
||||
]);
|
||||
});
|
||||
it('creates a hull for vertically-aligned objects', function () {
|
||||
expect(L.QuickHull.getConvexHull([ { lat: 0, lng: 0 },
|
||||
{ lat: 5, lng: 0 },
|
||||
{ lat: 10, lng: 0 }
|
||||
])).to.eql([
|
||||
{ lat: 0, lng: 0 },
|
||||
{ lat: 10, lng: 0 }
|
||||
]);
|
||||
});
|
||||
it('creates a hull for horizontally-aligned objects', function () {
|
||||
expect(L.QuickHull.getConvexHull([ { lat: 0, lng: 0 },
|
||||
{ lat: 0, lng: 5 },
|
||||
{ lat: 0, lng: 10 }
|
||||
])).to.eql([
|
||||
{ lat: 0, lng: 0 },
|
||||
{ lat: 0, lng: 10 }
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
481
static/leafletCluster/spec/suites/RefreshSpec.js
Normal file
481
static/leafletCluster/spec/suites/RefreshSpec.js
Normal file
@@ -0,0 +1,481 @@
|
||||
describe('refreshClusters', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
// Look away to avoid refreshing the display while adding markers.
|
||||
// By adding markers one by one (instead of using addLayers) we make
|
||||
// sure we never start an async process.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[-11, -11],
|
||||
[-10, -10]
|
||||
]))
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
function getClusterAtZoom(marker, zoom) {
|
||||
var parent = marker.__parent;
|
||||
|
||||
while (parent && parent._zoom !== zoom) {
|
||||
parent = parent.__parent;
|
||||
}
|
||||
|
||||
return parent;
|
||||
}
|
||||
|
||||
function setMapView() {
|
||||
// Now look at the markers to force cluster icons drawing.
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('flags all non-visible parent clusters of a given marker', function () {
|
||||
|
||||
group = L.markerClusterGroup().addTo(map);
|
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group),
|
||||
marker2 = L.marker([1.5, 1.5]).addTo(group); // Needed to force a cluster.
|
||||
|
||||
setMapView();
|
||||
|
||||
var marker1cluster10 = getClusterAtZoom(marker1, 10),
|
||||
marker1cluster2 = getClusterAtZoom(marker1, 2),
|
||||
marker1cluster5 = getClusterAtZoom(marker1, 5);
|
||||
|
||||
// First go to some zoom levels so that Leaflet initializes clusters icons.
|
||||
expect(marker1cluster10._iconNeedsUpdate).to.be.ok();
|
||||
map.setZoom(10, {animate: false});
|
||||
expect(marker1cluster10._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
expect(marker1cluster2._iconNeedsUpdate).to.be.ok();
|
||||
map.setZoom(2, {animate: false});
|
||||
expect(marker1cluster2._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
// Finish on an intermediate zoom level.
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.be.ok();
|
||||
map.setZoom(5, {animate: false});
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
// Run any animation.
|
||||
clock.tick(1000);
|
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the marker.
|
||||
group.refreshClusters(marker1);
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster10._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker1cluster2._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
// Also check that visible clusters are "un-flagged" since they should be re-drawn.
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
});
|
||||
|
||||
it('re-draws visible clusters', function () {
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
iconCreateFunction: function (cluster) {
|
||||
var markers = cluster.getAllChildMarkers();
|
||||
|
||||
for(var i in markers) {
|
||||
if (markers[i].changed) {
|
||||
return new L.DivIcon({
|
||||
className: "changed"
|
||||
});
|
||||
}
|
||||
}
|
||||
return new L.DivIcon({
|
||||
className: "original"
|
||||
});
|
||||
}
|
||||
}).addTo(map);
|
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group),
|
||||
marker2 = L.marker([1.5, 1.5]).addTo(group); // Needed to force a cluster.
|
||||
|
||||
setMapView();
|
||||
|
||||
var marker1cluster9 = getClusterAtZoom(marker1, 9);
|
||||
|
||||
// First go to some zoom levels so that Leaflet initializes clusters icons.
|
||||
expect(marker1cluster9._iconNeedsUpdate).to.be.ok();
|
||||
map.setZoom(9, {animate: false});
|
||||
expect(marker1cluster9._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
expect(marker1cluster9._icon.className).to.contain("original");
|
||||
expect(marker1cluster9._icon.className).to.not.contain("changed");
|
||||
|
||||
// Run any animation.
|
||||
clock.tick(1000);
|
||||
|
||||
// Alter the marker.
|
||||
marker1.changed = true;
|
||||
|
||||
// Then request clusters refresh.
|
||||
group.refreshClusters(marker1);
|
||||
|
||||
// Now check that visible clusters icon is re-drawn.
|
||||
expect(marker1cluster9._icon.className).to.contain("changed");
|
||||
expect(marker1cluster9._icon.className).to.not.contain("original");
|
||||
|
||||
});
|
||||
|
||||
// Shared code for the 2 below tests
|
||||
function iconCreateFunction(cluster) {
|
||||
var markers = cluster.getAllChildMarkers();
|
||||
|
||||
for(var i in markers) {
|
||||
if (markers[i].changed) {
|
||||
return new L.DivIcon({
|
||||
className: "changed"
|
||||
});
|
||||
}
|
||||
}
|
||||
return new L.DivIcon({
|
||||
className: "original"
|
||||
});
|
||||
}
|
||||
|
||||
it('re-draws markers in singleMarkerMode', function () {
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
singleMarkerMode: true,
|
||||
iconCreateFunction: iconCreateFunction
|
||||
}).addTo(map);
|
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group);
|
||||
|
||||
setMapView();
|
||||
|
||||
expect(marker1._icon.className).to.contain("original");
|
||||
|
||||
// Alter the marker.
|
||||
marker1.changed = true;
|
||||
|
||||
// Then request clusters refresh.
|
||||
group.refreshClusters(marker1);
|
||||
|
||||
expect(marker1._icon.className).to.contain("changed");
|
||||
expect(marker1._icon.className).to.not.contain("original");
|
||||
|
||||
});
|
||||
|
||||
it('does not modify markers that do not belong to the current group (in singleMarkerMode)', function () {
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
singleMarkerMode: true,
|
||||
iconCreateFunction: iconCreateFunction
|
||||
}).addTo(map);
|
||||
|
||||
var marker1 = L.marker([1.5, 1.5]).addTo(group),
|
||||
marker2 = L.marker([1.5, 1.5], {
|
||||
icon: iconCreateFunction({
|
||||
getAllChildMarkers: function () {
|
||||
return marker2;
|
||||
}
|
||||
})
|
||||
}).addTo(map);
|
||||
|
||||
setMapView();
|
||||
|
||||
expect(marker1._icon.className).to.contain("original");
|
||||
expect(marker2._icon.className).to.contain("original");
|
||||
|
||||
// Alter the markers.
|
||||
marker1.changed = true;
|
||||
marker2.changed = true;
|
||||
|
||||
// Then request clusters refresh.
|
||||
group.refreshClusters([marker1, marker2]);
|
||||
|
||||
expect(marker1._icon.className).to.contain("changed");
|
||||
expect(marker1._icon.className).to.not.contain("original");
|
||||
|
||||
expect(marker2._icon.className).to.contain("original");
|
||||
expect(marker2._icon.className).to.not.contain("changed");
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Shared code for below tests.
|
||||
var marker1 = L.marker([1.5, 1.5]),
|
||||
marker2 = L.marker([1.5, 1.5]), // Needed to force a cluster.
|
||||
marker3 = L.marker([1.1, 1.1]),
|
||||
marker4 = L.marker([1.1, 1.1]), // Needed to force a cluster.
|
||||
marker5 = L.marker([1.9, 1.9]),
|
||||
marker6 = L.marker([1.9, 1.9]), // Needed to force a cluster.
|
||||
marker1cluster8,
|
||||
marker1cluster3,
|
||||
marker1cluster5,
|
||||
marker3cluster8,
|
||||
marker3cluster3,
|
||||
marker3cluster5,
|
||||
marker5cluster8,
|
||||
marker5cluster3,
|
||||
marker5cluster5;
|
||||
|
||||
function init3clusterBranches() {
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
maxClusterRadius: 2 // Make sure we keep distinct clusters.
|
||||
}).addTo(map);
|
||||
|
||||
// Populate Marker Cluster Group.
|
||||
marker1.addTo(group);
|
||||
marker2.addTo(group);
|
||||
marker3.addTo(group);
|
||||
marker4.addTo(group);
|
||||
marker5.addTo(group);
|
||||
marker6.addTo(group);
|
||||
|
||||
setMapView();
|
||||
|
||||
marker1cluster8 = getClusterAtZoom(marker1, 8);
|
||||
marker1cluster3 = getClusterAtZoom(marker1, 3);
|
||||
marker1cluster5 = getClusterAtZoom(marker1, 5);
|
||||
marker3cluster8 = getClusterAtZoom(marker3, 8);
|
||||
marker3cluster3 = getClusterAtZoom(marker3, 3);
|
||||
marker3cluster5 = getClusterAtZoom(marker3, 5);
|
||||
marker5cluster8 = getClusterAtZoom(marker5, 8);
|
||||
marker5cluster3 = getClusterAtZoom(marker5, 3);
|
||||
marker5cluster5 = getClusterAtZoom(marker5, 5);
|
||||
|
||||
// Make sure we have 3 distinct clusters up to zoom level Z (let's choose Z = 3)
|
||||
expect(marker1cluster3._childCount).to.equal(2);
|
||||
expect(marker3cluster3._childCount).to.equal(2);
|
||||
expect(marker5cluster3._childCount).to.equal(2);
|
||||
|
||||
// First go to some zoom levels so that Leaflet initializes clusters icons.
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok();
|
||||
map.setZoom(3, {animate: false});
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
// Finish on an intermediate zoom level.
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker3cluster5._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker5cluster5._iconNeedsUpdate).to.be.ok();
|
||||
map.setZoom(5, {animate: false});
|
||||
expect(marker1cluster5._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster5._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker5cluster5._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
// Run any animation.
|
||||
clock.tick(1000);
|
||||
|
||||
// Ready to refresh clusters with method of choice and assess result.
|
||||
}
|
||||
|
||||
it('does not flag clusters of other markers', function () {
|
||||
|
||||
init3clusterBranches();
|
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the marker.
|
||||
group.refreshClusters(marker1);
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
// Finally check that non-involved clusters are not "dirty".
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
});
|
||||
|
||||
it('processes itself when no argument is passed', function () {
|
||||
|
||||
init3clusterBranches();
|
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the marker.
|
||||
group.refreshClusters();
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
});
|
||||
|
||||
it('accepts an array of markers', function () {
|
||||
|
||||
init3clusterBranches();
|
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
group.refreshClusters([marker1, marker5]);
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
});
|
||||
|
||||
it('accepts a mapping of markers', function () {
|
||||
|
||||
init3clusterBranches();
|
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
group.refreshClusters({
|
||||
id1: marker1,
|
||||
id2: marker5
|
||||
}); // Clusters of marker3 and 4 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
});
|
||||
|
||||
it('accepts an L.LayerGroup', function () {
|
||||
|
||||
init3clusterBranches();
|
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
var layerGroup = new L.LayerGroup([marker1, marker5]);
|
||||
group.refreshClusters(layerGroup);
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
});
|
||||
|
||||
it('accepts an L.MarkerCluster', function () {
|
||||
|
||||
init3clusterBranches();
|
||||
|
||||
// Then request clusters refresh.
|
||||
// No need to actually modify the markers.
|
||||
group.refreshClusters(marker1cluster8);
|
||||
// Clusters of marker3, 4, 5 and 6 shall not be flagged.
|
||||
|
||||
// Now check that non-visible clusters are flagged as "dirty".
|
||||
expect(marker1cluster8._iconNeedsUpdate).to.be.ok();
|
||||
expect(marker1cluster3._iconNeedsUpdate).to.be.ok();
|
||||
|
||||
// Clusters of marker3 and 4 shall not be flagged.
|
||||
expect(marker3cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker3cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
expect(marker5cluster8._iconNeedsUpdate).to.not.be.ok();
|
||||
expect(marker5cluster3._iconNeedsUpdate).to.not.be.ok();
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
151
static/leafletCluster/spec/suites/RememberOpacity.js
Normal file
151
static/leafletCluster/spec/suites/RememberOpacity.js
Normal file
@@ -0,0 +1,151 @@
|
||||
describe('Remember opacity', function () {
|
||||
var map, div, clock, markers;
|
||||
|
||||
var markerDefs = [
|
||||
{latLng: [ 0, 0], opts: {opacity: 0.9}},
|
||||
{latLng: [ 0, 1], opts: {opacity: 0.5}},
|
||||
{latLng: [ 0,-1], opts: {opacity: 0.5}},
|
||||
{latLng: [ 1, 0], opts: {opacity: 0.5}},
|
||||
{latLng: [-1, 0], opts: {opacity: 0.5}},
|
||||
{latLng: [ 1, 1], opts: {opacity: 0.2}},
|
||||
{latLng: [ 1,-1], opts: {opacity: 0.2}},
|
||||
{latLng: [-1, 1], opts: {opacity: 0.2}},
|
||||
{latLng: [-1,-1], opts: {opacity: 0.2}}
|
||||
];
|
||||
|
||||
var bounds = L.latLngBounds( L.latLng( -1.1, -1.1),
|
||||
L.latLng( 1.1, 1.1) );
|
||||
|
||||
beforeEach(function () {
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
markers = [];
|
||||
for (var i = 0; i < markerDefs.length; i++) {
|
||||
markers.push( L.marker(markerDefs[i].latLng, markerDefs[i].opts ) );
|
||||
}
|
||||
});
|
||||
afterEach(function () {
|
||||
clock.restore();
|
||||
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('clusters semitransparent markers into an opaque one', function () {
|
||||
map.setView(new L.LatLng(0,0), 1);
|
||||
|
||||
var clusterLayer = new L.MarkerClusterGroup({
|
||||
maxClusterRadius: 20
|
||||
});
|
||||
clusterLayer.addLayers(markers);
|
||||
map.addLayer(clusterLayer);
|
||||
|
||||
var visibleClusters = clusterLayer._featureGroup.getLayers();
|
||||
expect(visibleClusters.length).to.be(1);
|
||||
expect(visibleClusters[0].options.opacity).to.be(1);
|
||||
});
|
||||
|
||||
|
||||
it('unclusters an opaque marker into semitransparent ones', function () {
|
||||
map.setView(new L.LatLng(0,0), 1);
|
||||
var visibleClusters;
|
||||
|
||||
var clusterLayer = new L.MarkerClusterGroup({
|
||||
maxClusterRadius: 20
|
||||
});
|
||||
clusterLayer.addLayers(markers);
|
||||
map.addLayer(clusterLayer);
|
||||
|
||||
map.fitBounds(bounds);
|
||||
clock.tick(1000);
|
||||
|
||||
visibleClusters = clusterLayer._featureGroup.getLayers();
|
||||
expect(visibleClusters.length).to.be(9);
|
||||
for (var i=0; i<9; i++) {
|
||||
expect(visibleClusters[i].options.opacity).to.be.within(0.2,0.9);
|
||||
}
|
||||
|
||||
// It shall also work after zooming in/out a second time.
|
||||
map.setView(new L.LatLng(0,0), 1);
|
||||
clock.tick(1000);
|
||||
|
||||
map.fitBounds(bounds);
|
||||
clock.tick(1000);
|
||||
|
||||
visibleClusters = clusterLayer._featureGroup.getLayers();
|
||||
expect(visibleClusters.length).to.be(9);
|
||||
for (var i=0; i<9; i++) {
|
||||
expect(visibleClusters[i].options.opacity).to.be.within(0.2,0.9);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('has no problems zooming in and out several times', function () {
|
||||
var visibleClusters;
|
||||
|
||||
var clusterLayer = new L.MarkerClusterGroup({
|
||||
maxClusterRadius: 20
|
||||
});
|
||||
clusterLayer.addLayers(markers);
|
||||
map.addLayer(clusterLayer);
|
||||
|
||||
// Zoom in and out a couple times
|
||||
for (var i=0; i<10; i++) {
|
||||
map.fitBounds(bounds);
|
||||
clock.tick(1000);
|
||||
|
||||
visibleClusters = clusterLayer._featureGroup.getLayers();
|
||||
expect(visibleClusters.length).to.be(9);
|
||||
for (var i=0; i<9; i++) {
|
||||
expect(visibleClusters[i].options.opacity).to.be.within(0.2,0.9);
|
||||
}
|
||||
|
||||
map.setView(new L.LatLng(0,0), 1);
|
||||
clock.tick(1000);
|
||||
|
||||
visibleClusters = clusterLayer._featureGroup.getLayers();
|
||||
expect(visibleClusters.length).to.be(1);
|
||||
expect(visibleClusters[0].options.opacity).to.be(1);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
it('retains the opacity of each individual marker', function () {
|
||||
map.setView(new L.LatLng(0,0), 1);
|
||||
|
||||
var visibleClusters;
|
||||
var clusterLayer = new L.MarkerClusterGroup({
|
||||
maxClusterRadius: 20
|
||||
});
|
||||
clusterLayer.addLayers(markers);
|
||||
map.addLayer(clusterLayer);
|
||||
|
||||
|
||||
// Zoom in and out a couple times
|
||||
for (var i=0; i<5; i++) {
|
||||
map.fitBounds(bounds);
|
||||
clock.tick(1000);
|
||||
|
||||
map.setView(new L.LatLng(0,0), 1);
|
||||
clock.tick(1000);
|
||||
}
|
||||
|
||||
for (var i=0; i<markerDefs.length; i++) {
|
||||
|
||||
// console.log(markerDefs[i].latLng, markerDefs[i].opts.opacity);
|
||||
|
||||
map.setView(L.latLng(markerDefs[i].latLng), 18);
|
||||
clock.tick(1000);
|
||||
visibleClusters = clusterLayer._featureGroup.getLayers();
|
||||
expect(visibleClusters.length).to.be(1);
|
||||
expect(visibleClusters[0].options.opacity).to.be(markerDefs[i].opts.opacity);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
239
static/leafletCluster/spec/suites/RemoveLayerSpec.js
Normal file
239
static/leafletCluster/spec/suites/RemoveLayerSpec.js
Normal file
@@ -0,0 +1,239 @@
|
||||
describe('removeLayer', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('removes a layer that was added to it', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(marker._icon).to.be(null);
|
||||
});
|
||||
|
||||
it('doesnt remove a layer not added to it', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
map.addLayer(marker);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('removes a layer that was added to it (before being on the map) that is shown in a cluster', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('removes a layer that was added to it (after being on the map) that is shown in a cluster', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(marker._icon).to.be(null);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('removes a layer that was added to it (before being on the map) that is individually', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1, 1.5]);
|
||||
var marker2 = new L.Marker([3, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(marker._icon).to.be(null);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('removes a layer (with animation) that was added to it (after being on the map) that is shown in a cluster', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup({ animateAddingMarkers: true });
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
expect(marker._icon).to.be(null);
|
||||
expect(marker2._icon).to.be(null);
|
||||
|
||||
group.removeLayer(marker);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
expect(marker._icon).to.be(null);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('removes the layers that are in the given LayerGroup', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayers([marker, marker2]);
|
||||
|
||||
var layer = L.layerGroup();
|
||||
layer.addLayer(marker2);
|
||||
group.removeLayer(layer);
|
||||
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
});
|
||||
|
||||
it('removes the layers that are in the given LayerGroup when not on the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
|
||||
var layer = L.layerGroup();
|
||||
layer.addLayer(marker2);
|
||||
group.removeLayer(layer);
|
||||
|
||||
expect(group.hasLayer(marker)).to.be(true);
|
||||
expect(group.hasLayer(marker2)).to.be(false);
|
||||
});
|
||||
|
||||
it('passes control to removeLayers when marker is a Layer Group', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker1, marker2]);
|
||||
|
||||
var layer = L.layerGroup();
|
||||
layer.addLayer(marker2);
|
||||
group.removeLayer(new L.LayerGroup([layer]));
|
||||
|
||||
expect(group.hasLayer(marker1)).to.be(true);
|
||||
expect(group.hasLayer(marker2)).to.be(false);
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
26
static/leafletCluster/spec/suites/SpecHelper.js
Normal file
26
static/leafletCluster/spec/suites/SpecHelper.js
Normal file
@@ -0,0 +1,26 @@
|
||||
function noSpecs() {
|
||||
xit('has no specs');
|
||||
}
|
||||
|
||||
if (!Array.prototype.map) {
|
||||
Array.prototype.map = function(fun /*, thisp */) {
|
||||
"use strict";
|
||||
|
||||
if (this === void 0 || this === null)
|
||||
throw new TypeError();
|
||||
|
||||
var t = Object(this);
|
||||
var len = t.length >>> 0;
|
||||
if (typeof fun !== "function")
|
||||
throw new TypeError();
|
||||
|
||||
var res = new Array(len);
|
||||
var thisp = arguments[1];
|
||||
for (var i = 0; i < len; i++) {
|
||||
if (i in t)
|
||||
res[i] = fun.call(thisp, t[i], i, t);
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
}
|
||||
147
static/leafletCluster/spec/suites/animateOptionSpec.js
Normal file
147
static/leafletCluster/spec/suites/animateOptionSpec.js
Normal file
@@ -0,0 +1,147 @@
|
||||
describe('animate option', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
previousTransitionSetting = L.DomUtil.TRANSITION;
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
// Restore previous setting so that next tests are unaffected.
|
||||
L.DomUtil.TRANSITION = previousTransitionSetting;
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, previousTransitionSetting;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('hooks animated methods version by default', function () {
|
||||
|
||||
// Need to add to map so that we have the top cluster level created.
|
||||
group = L.markerClusterGroup().addTo(map);
|
||||
|
||||
var withAnimation = L.MarkerClusterGroup.prototype._withAnimation;
|
||||
|
||||
// MCG animated methods.
|
||||
expect(group._animationStart).to.be(withAnimation._animationStart);
|
||||
expect(group._animationZoomIn).to.be(withAnimation._animationZoomIn);
|
||||
expect(group._animationZoomOut).to.be(withAnimation._animationZoomOut);
|
||||
expect(group._animationAddLayer).to.be(withAnimation._animationAddLayer);
|
||||
|
||||
// MarkerCluster spiderfy animated methods
|
||||
var cluster = group._topClusterLevel;
|
||||
|
||||
withAnimation = L.MarkerCluster.prototype;
|
||||
|
||||
expect(cluster._animationSpiderfy).to.be(withAnimation._animationSpiderfy);
|
||||
expect(cluster._animationUnspiderfy).to.be(withAnimation._animationUnspiderfy);
|
||||
|
||||
});
|
||||
|
||||
it('hooks non-animated methods version when set to false', function () {
|
||||
|
||||
// Need to add to map so that we have the top cluster level created.
|
||||
group = L.markerClusterGroup({animate: false}).addTo(map);
|
||||
|
||||
var noAnimation = L.MarkerClusterGroup.prototype._noAnimation;
|
||||
|
||||
// MCG non-animated methods.
|
||||
expect(group._animationStart).to.be(noAnimation._animationStart);
|
||||
expect(group._animationZoomIn).to.be(noAnimation._animationZoomIn);
|
||||
expect(group._animationZoomOut).to.be(noAnimation._animationZoomOut);
|
||||
expect(group._animationAddLayer).to.be(noAnimation._animationAddLayer);
|
||||
|
||||
// MarkerCluster spiderfy non-animated methods
|
||||
var cluster = group._topClusterLevel;
|
||||
|
||||
noAnimation = L.MarkerClusterNonAnimated.prototype;
|
||||
|
||||
expect(cluster._animationSpiderfy).to.be(noAnimation._animationSpiderfy);
|
||||
expect(cluster._animationUnspiderfy).to.be(noAnimation._animationUnspiderfy);
|
||||
|
||||
});
|
||||
|
||||
it('always hooks non-animated methods version when L.DomUtil.TRANSITION is false', function () {
|
||||
|
||||
// Fool Leaflet, make it think the browser does not support transitions.
|
||||
L.DomUtil.TRANSITION = false;
|
||||
|
||||
// Need to add to map so that we have the top cluster level created.
|
||||
group = L.markerClusterGroup({animate: true}).addTo(map);
|
||||
|
||||
var noAnimation = L.MarkerClusterGroup.prototype._noAnimation;
|
||||
|
||||
// MCG non-animated methods.
|
||||
expect(group._animationStart).to.be(noAnimation._animationStart);
|
||||
expect(group._animationZoomIn).to.be(noAnimation._animationZoomIn);
|
||||
expect(group._animationZoomOut).to.be(noAnimation._animationZoomOut);
|
||||
expect(group._animationAddLayer).to.be(noAnimation._animationAddLayer);
|
||||
|
||||
// MarkerCluster spiderfy non-animated methods
|
||||
var cluster = group._topClusterLevel;
|
||||
|
||||
noAnimation = L.MarkerClusterNonAnimated.prototype;
|
||||
|
||||
expect(cluster._animationSpiderfy).to.be(noAnimation._animationSpiderfy);
|
||||
expect(cluster._animationUnspiderfy).to.be(noAnimation._animationUnspiderfy);
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
44
static/leafletCluster/spec/suites/clearLayersSpec.js
Normal file
44
static/leafletCluster/spec/suites/clearLayersSpec.js
Normal file
@@ -0,0 +1,44 @@
|
||||
describe('clearLayer', function () {
|
||||
var map, div;
|
||||
beforeEach(function () {
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('clears everything before adding to map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([polygon, marker]);
|
||||
group.clearLayers();
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
expect(group.hasLayer(marker)).to.be(false);
|
||||
});
|
||||
|
||||
it('hits polygons and markers after adding to map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([polygon, marker]);
|
||||
map.addLayer(group);
|
||||
group.clearLayers();
|
||||
|
||||
expect(group.hasLayer(polygon)).to.be(false);
|
||||
expect(group.hasLayer(marker)).to.be(false);
|
||||
});
|
||||
});
|
||||
103
static/leafletCluster/spec/suites/disableClusteringAtZoomSpec.js
Normal file
103
static/leafletCluster/spec/suites/disableClusteringAtZoomSpec.js
Normal file
@@ -0,0 +1,103 @@
|
||||
describe('disableClusteringAtZoom option', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('unclusters at zoom level equal or higher', function () {
|
||||
|
||||
var maxZoom = 15;
|
||||
|
||||
group = new L.MarkerClusterGroup({
|
||||
disableClusteringAtZoom: maxZoom
|
||||
});
|
||||
|
||||
group.addLayers([
|
||||
new L.Marker([1.5, 1.5]),
|
||||
new L.Marker([1.5, 1.5])
|
||||
]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group._maxZoom).to.equal(maxZoom - 1);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.equal(1); // 1 cluster.
|
||||
|
||||
map.setZoom(14);
|
||||
clock.tick(1000);
|
||||
expect(map._panes.markerPane.childNodes.length).to.equal(1); // 1 cluster.
|
||||
|
||||
map.setZoom(15);
|
||||
clock.tick(1000);
|
||||
expect(map._panes.markerPane.childNodes.length).to.equal(2); // 2 markers.
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
54
static/leafletCluster/spec/suites/eachLayerSpec.js
Normal file
54
static/leafletCluster/spec/suites/eachLayerSpec.js
Normal file
@@ -0,0 +1,54 @@
|
||||
describe('eachLayer', function () {
|
||||
var map, div;
|
||||
beforeEach(function () {
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('hits polygons and markers before adding to map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([polygon, marker]);
|
||||
|
||||
var layers = [];
|
||||
group.eachLayer(function (l) {
|
||||
layers.push(l);
|
||||
});
|
||||
|
||||
expect(layers.length).to.be(2);
|
||||
expect(layers).to.contain(marker);
|
||||
expect(layers).to.contain(polygon);
|
||||
});
|
||||
|
||||
it('hits polygons and markers after adding to map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([polygon, marker]);
|
||||
map.addLayer(group);
|
||||
|
||||
var layers = [];
|
||||
group.eachLayer(function (l) {
|
||||
layers.push(l);
|
||||
});
|
||||
|
||||
expect(layers.length).to.be(2);
|
||||
expect(layers).to.contain(marker);
|
||||
expect(layers).to.contain(polygon);
|
||||
});
|
||||
});
|
||||
409
static/leafletCluster/spec/suites/eventsSpec.js
Normal file
409
static/leafletCluster/spec/suites/eventsSpec.js
Normal file
@@ -0,0 +1,409 @@
|
||||
describe('events', function() {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
//
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('is fired for a single child marker', function () {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.on('click', callback);
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
// In Leaflet 1.0.0, event propagation must be explicitly set by 3rd argument.
|
||||
marker.fire('click', null, true);
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
|
||||
it('is fired for a child polygon', function () {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.on('click', callback);
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
|
||||
polygon.fire('click', null, true);
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
|
||||
it('is fired for a cluster click', function () {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.on('clusterclick', callback);
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
var cluster = group.getVisibleParent(marker);
|
||||
expect(cluster instanceof L.MarkerCluster).to.be(true);
|
||||
|
||||
cluster.fire('click', null, true);
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
|
||||
describe('after being added, removed, re-added from the map', function() {
|
||||
|
||||
it('still fires events for nonpoint data', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.on('click', callback);
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
map.removeLayer(group);
|
||||
map.addLayer(group);
|
||||
|
||||
polygon.fire('click', null, true);
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
|
||||
it('still fires events for point data', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.on('click', callback);
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
map.removeLayer(group);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.fire('click', null, true);
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
|
||||
it('still fires cluster events', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.on('clusterclick', callback);
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
map.removeLayer(group);
|
||||
map.addLayer(group);
|
||||
|
||||
var cluster = group.getVisibleParent(marker);
|
||||
expect(cluster instanceof L.MarkerCluster).to.be(true);
|
||||
|
||||
cluster.fire('click', null, true);
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
|
||||
it('does not break map events', function () {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
map.on('zoomend', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
map.removeLayer(group);
|
||||
map.addLayer(group);
|
||||
|
||||
map.fire('zoomend');
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
|
||||
//layeradd
|
||||
it('fires layeradd when markers are added while not on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layeradd', callback);
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layeradd when vectors are added while not on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layeradd', callback);
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
group.addLayer(polygon);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layeradd when markers are added while on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layeradd', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layeradd when vectors are added while on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layeradd', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
group.addLayer(polygon);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layeradd when markers are added using addLayers while on the map with chunked loading', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true });
|
||||
group.on('layeradd', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
group.addLayers([marker]);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layeradd when vectors are added using addLayers while on the map with chunked loading', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true });
|
||||
group.on('layeradd', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
group.addLayers([polygon]);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
//layerremove
|
||||
it('fires layerremove when a marker is removed while not on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layerremove', callback);
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
group.addLayer(marker);
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layerremove when a vector is removed while not on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layerremove', callback);
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
group.addLayer(polygon);
|
||||
group.removeLayer(polygon);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layerremove when a marker is removed while on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layerremove', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
group.addLayer(marker);
|
||||
group.removeLayer(marker);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layerremove when a vector is removed while on the map', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
group.on('layerremove', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
group.addLayer(polygon);
|
||||
group.removeLayer(polygon);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layerremove when a marker is removed using removeLayers while on the map with chunked loading', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true });
|
||||
group.on('layerremove', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
group.addLayers([marker]);
|
||||
group.removeLayers([marker]);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layerremove when a vector is removed using removeLayers while on the map with chunked loading', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true });
|
||||
group.on('layerremove', callback);
|
||||
map.addLayer(group);
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
group.addLayers([polygon]);
|
||||
group.removeLayers([polygon]);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layerremove when a marker is removed using removeLayers while not on the map with chunked loading', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true });
|
||||
group.on('layerremove', callback);
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
group.addLayers([marker]);
|
||||
group.removeLayers([marker]);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
|
||||
it('fires layerremove when a vector is removed using removeLayers while not on the map with chunked loading', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup({ chunkedLoading: true });
|
||||
group.on('layerremove', callback);
|
||||
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
group.addLayers([polygon]);
|
||||
group.removeLayers([polygon]);
|
||||
|
||||
expect(callback.callCount).to.be(1);
|
||||
});
|
||||
});
|
||||
|
||||
/*
|
||||
//No normal events can be fired by a clustered marker, so probably don't need this.
|
||||
it('is fired for a clustered child marker', function() {
|
||||
var callback = sinon.spy();
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.on('click', callback);
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.fire('click');
|
||||
|
||||
expect(callback.called).to.be(true);
|
||||
});
|
||||
*/
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
118
static/leafletCluster/spec/suites/getBoundsSpec.js
Normal file
118
static/leafletCluster/spec/suites/getBoundsSpec.js
Normal file
@@ -0,0 +1,118 @@
|
||||
describe('getBounds', function() {
|
||||
var map, div;
|
||||
beforeEach(function() {
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function() {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
describe('polygon layer', function() {
|
||||
it('returns the correct bounds before adding to the map', function() {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
|
||||
expect(group.getBounds().equals(polygon.getBounds())).to.be(true);
|
||||
});
|
||||
|
||||
it('returns the correct bounds after adding to the map after adding polygon', function() {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayer(polygon);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group.getBounds().equals(polygon.getBounds())).to.be(true);
|
||||
});
|
||||
|
||||
it('returns the correct bounds after adding to the map before adding polygon', function() {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(polygon);
|
||||
|
||||
expect(group.getBounds().equals(polygon.getBounds())).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('marker layers', function () {
|
||||
it('returns the correct bounds before adding to the map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.0, 5.0]);
|
||||
var marker3 = new L.Marker([6.0, 2.0]);
|
||||
|
||||
group.addLayers([marker, marker2, marker3]);
|
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.0, 5.0], [6.0, 1.5]))).to.be(true);
|
||||
});
|
||||
|
||||
it('returns the correct bounds after adding to the map after adding markers', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.0, 5.0]);
|
||||
var marker3 = new L.Marker([6.0, 2.0]);
|
||||
|
||||
group.addLayers([marker, marker2, marker3]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.0, 5.0], [6.0, 1.5]))).to.be(true);
|
||||
});
|
||||
|
||||
it('returns the correct bounds after adding to the map before adding markers', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.0, 5.0]);
|
||||
var marker3 = new L.Marker([6.0, 2.0]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayers([marker, marker2, marker3]);
|
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.0, 5.0], [6.0, 1.5]))).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('marker and polygon layers', function() {
|
||||
it('returns the correct bounds before adding to the map', function() {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([6.0, 3.0]);
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
group.addLayers([marker, polygon]);
|
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.5, 1.5], [6.0, 3.0]))).to.be(true);
|
||||
});
|
||||
|
||||
it('returns the correct bounds after adding to the map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([6.0, 3.0]);
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayers([marker, polygon]);
|
||||
|
||||
expect(group.getBounds().equals(L.latLngBounds([1.5, 1.5], [6.0, 3.0]))).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('blank layer', function () {
|
||||
it('returns a blank bounds', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
|
||||
expect(group.getBounds().isValid()).to.be(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
65
static/leafletCluster/spec/suites/getLayersSpec.js
Normal file
65
static/leafletCluster/spec/suites/getLayersSpec.js
Normal file
@@ -0,0 +1,65 @@
|
||||
describe('getLayers', function () {
|
||||
var map, div;
|
||||
beforeEach(function () {
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('hits polygons and markers before adding to map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([polygon, marker]);
|
||||
|
||||
var layers = group.getLayers();
|
||||
|
||||
expect(layers.length).to.be(2);
|
||||
expect(layers).to.contain(marker);
|
||||
expect(layers).to.contain(polygon);
|
||||
});
|
||||
|
||||
it('hits polygons and markers after adding to map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([polygon, marker]);
|
||||
map.addLayer(group);
|
||||
|
||||
var layers = group.getLayers();
|
||||
|
||||
expect(layers.length).to.be(2);
|
||||
expect(layers).to.contain(marker);
|
||||
expect(layers).to.contain(polygon);
|
||||
});
|
||||
|
||||
it('skips markers and polygons removed while not on the map', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var polygon = new L.Polygon([[1.5, 1.5], [2.0, 1.5], [2.0, 2.0], [1.5, 2.0]]);
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([polygon, marker]);
|
||||
|
||||
map.addLayer(group);
|
||||
map.removeLayer(group);
|
||||
|
||||
group.removeLayers([polygon, marker]);
|
||||
|
||||
var layers = group.getLayers();
|
||||
|
||||
expect(layers.length).to.be(0);
|
||||
});
|
||||
});
|
||||
59
static/leafletCluster/spec/suites/getVisibleParentSpec.js
Normal file
59
static/leafletCluster/spec/suites/getVisibleParentSpec.js
Normal file
@@ -0,0 +1,59 @@
|
||||
describe('getVisibleParent', function () {
|
||||
var map, div;
|
||||
beforeEach(function () {
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('gets the marker if the marker is visible', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
var vp = group.getVisibleParent(marker);
|
||||
|
||||
expect(vp).to.be(marker);
|
||||
});
|
||||
|
||||
it('gets the visible cluster if it is clustered', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
var vp = group.getVisibleParent(marker);
|
||||
|
||||
expect(vp).to.be.a(L.MarkerCluster);
|
||||
expect(vp._icon).to.not.be(null);
|
||||
expect(vp._icon).to.not.be(undefined);
|
||||
});
|
||||
|
||||
it('returns null if the marker and parents are all not visible', function () {
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([5.5, 1.5]);
|
||||
var marker2 = new L.Marker([5.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
var vp = group.getVisibleParent(marker);
|
||||
|
||||
expect(vp).to.be(null);
|
||||
});
|
||||
});
|
||||
111
static/leafletCluster/spec/suites/markerMoveSupportSpec.js
Normal file
111
static/leafletCluster/spec/suites/markerMoveSupportSpec.js
Normal file
@@ -0,0 +1,111 @@
|
||||
describe('moving markers', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('moves a marker that was moved while off the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([10, 10]);
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
|
||||
map.removeLayer(group);
|
||||
marker.setLatLng([1.5, 1.5]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group.getLayers().length).to.be(1);
|
||||
});
|
||||
|
||||
it('moves multiple markers that were moved while off the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
map.addLayer(group);
|
||||
|
||||
var markers = [];
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var marker = new L.Marker([10, 10]);
|
||||
group.addLayer(marker);
|
||||
markers.push(marker);
|
||||
}
|
||||
|
||||
map.removeLayer(group);
|
||||
for (var i = 0; i < 10; i++) {
|
||||
var marker = markers[i];
|
||||
marker.setLatLng([1.5, 1.5]);
|
||||
}
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group.getLayers().length).to.be(10);
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
44
static/leafletCluster/spec/suites/nonIntegerZoomSpec.js
Normal file
44
static/leafletCluster/spec/suites/nonIntegerZoomSpec.js
Normal file
@@ -0,0 +1,44 @@
|
||||
describe('non-integer min/max zoom', function () {
|
||||
var map, div, clock;
|
||||
beforeEach(function () {
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { minZoom: 0.5, maxZoom: 18.5 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
clock.restore();
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
it('dont break adding and removing markers', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
group.addLayer(marker3);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
expect(marker3._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
|
||||
group.removeLayer(marker2);
|
||||
});
|
||||
});
|
||||
55
static/leafletCluster/spec/suites/onAddSpec.js
Normal file
55
static/leafletCluster/spec/suites/onAddSpec.js
Normal file
@@ -0,0 +1,55 @@
|
||||
describe('onAdd', function () {
|
||||
var map, div;
|
||||
beforeEach(function () {
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div);
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
|
||||
it('throws an error if maxZoom is not specified', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
|
||||
var ex = null;
|
||||
try {
|
||||
map.addLayer(group);
|
||||
} catch (e) {
|
||||
ex = e;
|
||||
}
|
||||
|
||||
expect(ex).to.not.be(null);
|
||||
});
|
||||
|
||||
it('successfully handles removing and re-adding a layer while not on the map', function () {
|
||||
map.options.maxZoom = 18;
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
|
||||
map.removeLayer(group);
|
||||
group.removeLayer(marker);
|
||||
group.addLayer(marker);
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
expect(map.hasLayer(group)).to.be(true);
|
||||
expect(group.hasLayer(marker)).to.be(true);
|
||||
});
|
||||
});
|
||||
42
static/leafletCluster/spec/suites/onRemoveSpec.js
Normal file
42
static/leafletCluster/spec/suites/onRemoveSpec.js
Normal file
@@ -0,0 +1,42 @@
|
||||
describe('onRemove', function () {
|
||||
var map, div;
|
||||
beforeEach(function () {
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
});
|
||||
afterEach(function () {
|
||||
document.body.removeChild(div);
|
||||
});
|
||||
|
||||
|
||||
it('removes the shown coverage polygon', function () {
|
||||
|
||||
var group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
group._showCoverage({ layer: group._topClusterLevel });
|
||||
|
||||
expect(group._shownPolygon).to.not.be(null);
|
||||
|
||||
map.removeLayer(group);
|
||||
|
||||
expect(group._shownPolygon).to.be(null);
|
||||
});
|
||||
});
|
||||
209
static/leafletCluster/spec/suites/removeLayersSpec.js
Normal file
209
static/leafletCluster/spec/suites/removeLayersSpec.js
Normal file
@@ -0,0 +1,209 @@
|
||||
describe('removeLayers', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('removes all the layer given to it', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var markers = [
|
||||
new L.Marker([1.5, 1.5]),
|
||||
new L.Marker([1.5, 1.5]),
|
||||
new L.Marker([1.5, 1.5])
|
||||
];
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
group.addLayers(markers);
|
||||
|
||||
group.removeLayers(markers);
|
||||
|
||||
expect(group.hasLayer(markers[0])).to.be(false);
|
||||
expect(group.hasLayer(markers[1])).to.be(false);
|
||||
expect(group.hasLayer(markers[2])).to.be(false);
|
||||
|
||||
expect(group.getLayers().length).to.be(0);
|
||||
});
|
||||
|
||||
it('removes all the layer given to it even though they move', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var markers = [
|
||||
new L.Marker([10, 10]),
|
||||
new L.Marker([20, 20]),
|
||||
new L.Marker([30, 30])
|
||||
];
|
||||
var len = markers.length;
|
||||
map.addLayer(group);
|
||||
|
||||
group.addLayers(markers);
|
||||
|
||||
markers.forEach(function (marker) {
|
||||
marker.setLatLng([1.5, 1.5]);
|
||||
group.removeLayer(marker);
|
||||
expect(group.getLayers().length).to.be(len - 1);
|
||||
group.addLayer(marker);
|
||||
expect(group.getLayers().length).to.be(len);
|
||||
});
|
||||
|
||||
expect(group.getLayers().length).to.be(len);
|
||||
});
|
||||
|
||||
it('removes all the layer given to it even if the group is not on the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var markers = [
|
||||
new L.Marker([1.5, 1.5]),
|
||||
new L.Marker([1.5, 1.5]),
|
||||
new L.Marker([1.5, 1.5])
|
||||
];
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayers(markers);
|
||||
map.removeLayer(group);
|
||||
group.removeLayers(markers);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(group.hasLayer(markers[0])).to.be(false);
|
||||
expect(group.hasLayer(markers[1])).to.be(false);
|
||||
expect(group.hasLayer(markers[2])).to.be(false);
|
||||
|
||||
expect(group.getLayers().length).to.be(0);
|
||||
});
|
||||
|
||||
it('doesnt break if we are spiderfied', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var markers = [
|
||||
new L.Marker([1.5, 1.5]),
|
||||
new L.Marker([1.5, 1.5]),
|
||||
new L.Marker([1.5, 1.5])
|
||||
];
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
group.addLayers(markers);
|
||||
|
||||
markers[0].__parent.spiderfy();
|
||||
|
||||
// We must wait for the spiderfy animation to timeout
|
||||
clock.tick(200);
|
||||
|
||||
group.removeLayers(markers);
|
||||
|
||||
expect(group.hasLayer(markers[0])).to.be(false);
|
||||
expect(group.hasLayer(markers[1])).to.be(false);
|
||||
expect(group.hasLayer(markers[2])).to.be(false);
|
||||
|
||||
expect(group.getLayers().length).to.be(0);
|
||||
|
||||
group.on('spiderfied', function() {
|
||||
expect(group._spiderfied).to.be(null);
|
||||
});
|
||||
});
|
||||
|
||||
it('handles nested Layer Groups', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
var marker3 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
|
||||
group.addLayers([marker1, marker2, marker3]);
|
||||
|
||||
expect(group.hasLayer(marker1)).to.be(true);
|
||||
expect(group.hasLayer(marker2)).to.be(true);
|
||||
expect(group.hasLayer(marker3)).to.be(true);
|
||||
|
||||
group.removeLayers([
|
||||
marker1,
|
||||
new L.LayerGroup([
|
||||
marker2, new L.LayerGroup([
|
||||
marker3
|
||||
])
|
||||
])
|
||||
]);
|
||||
|
||||
expect(group.hasLayer(marker1)).to.be(false);
|
||||
expect(group.hasLayer(marker2)).to.be(false);
|
||||
expect(group.hasLayer(marker3)).to.be(false);
|
||||
|
||||
expect(group.getLayers().length).to.be(0);
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,278 @@
|
||||
describe('Option removeOutsideVisibleBounds', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Nothing for this test suite.
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
// Restore the previous setting, so that even in case of test failure, next tests are not affected.
|
||||
L.Browser.mobile = previousMobileSetting;
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
//group.removeLayers(group.getLayers());
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var marker1 = L.marker([1.5, -0.4]), // 2 screens width away.
|
||||
marker2 = L.marker([1.5, 0.6]), // 1 screen width away.
|
||||
marker3 = L.marker([1.5, 1.5]), // In view port.
|
||||
marker4 = L.marker([1.5, 2.4]), // 1 screen width away.
|
||||
marker5 = L.marker([1.5, 3.4]), // 2 screens width away.
|
||||
markers = [marker1, marker2, marker3, marker4, marker5],
|
||||
previousMobileSetting = L.Browser.mobile,
|
||||
div, map, group, i, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
// Add all markers once to map then remove them immediately so that their icon is null (instead of undefined).
|
||||
for (i = 0; i < markers.length; i++) {
|
||||
map.removeLayer(markers[i].addTo(map));
|
||||
}
|
||||
|
||||
|
||||
function prepareGroup() {
|
||||
|
||||
// "group" should be assigned with a Marker Cluster Group before calling this function.
|
||||
group.addTo(map);
|
||||
|
||||
group.addLayers(markers);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('removes objects more than 1 screen away from view port by default', function () {
|
||||
|
||||
group = L.markerClusterGroup();
|
||||
|
||||
prepareGroup();
|
||||
|
||||
expect(marker1._icon).to.be(null);
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // markers 2, 3 and 4.
|
||||
expect(marker5._icon).to.be(null);
|
||||
|
||||
});
|
||||
|
||||
it('removes objects out of view port by default for mobile device', function () {
|
||||
|
||||
// Fool Leaflet, make it thinks it runs on a mobile device.
|
||||
L.Browser.mobile = true;
|
||||
|
||||
group = L.markerClusterGroup();
|
||||
|
||||
prepareGroup();
|
||||
|
||||
expect(marker1._icon).to.be(null);
|
||||
expect(marker2._icon).to.be(null);
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1); // marker 3 only.
|
||||
expect(marker4._icon).to.be(null);
|
||||
expect(marker5._icon).to.be(null);
|
||||
|
||||
});
|
||||
|
||||
it('leaves all objects on map when set to false', function () {
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
removeOutsideVisibleBounds: false
|
||||
});
|
||||
|
||||
prepareGroup();
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(5); // All 5 markers.
|
||||
|
||||
});
|
||||
|
||||
|
||||
// Following tests need markers at very high latitude.
|
||||
// They test the _checkBoundsMaxLat method against the default Web/Spherical Mercator projection maximum latitude (85.0511287798).
|
||||
// The actual map view should be '-1.0986328125,84.92929204957956,1.0986328125,85.11983467698401'
|
||||
// The expanded bounds without correction should be '-3.2958984375,84.7387494221751,3.2958984375,85.31037730438847'
|
||||
var latLngsMaxLatDefault = [
|
||||
[100, 3], // Impossible in real world, but nothing prevents the user from entering such latitude, and Web/Spherical Mercator projection will still display it at 85.0511287798
|
||||
[85.2, 1.5], // 1 "screen" heights away.
|
||||
[85, 0], // In center of view.
|
||||
[84.8, -1.5], // 1 "screen" height away.
|
||||
[84.6, -3] // 2 "screens" height away.
|
||||
];
|
||||
|
||||
function moveMarkersAndMapToMaxLat(latLngs, isSouth) {
|
||||
for (i = 0; i < markers.length; i++) {
|
||||
if (isSouth) {
|
||||
markers[i].setLatLng([-latLngs[i][0], latLngs[i][1]]);
|
||||
} else {
|
||||
markers[i].setLatLng(latLngs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
map.fitBounds([
|
||||
[isSouth ? -86 : 85, -1],
|
||||
[isSouth ? -85 : 86, 1] // The actual map view longitude span will be wider. '-1.0986328125,84.92929204957956,1.0986328125,85.11983467698401'
|
||||
]);
|
||||
}
|
||||
|
||||
function checkProjection(latLngs) {
|
||||
expect(map.options.crs).to.equal(L.CRS.EPSG3857);
|
||||
expect(L.CRS.EPSG3857.projection).to.equal(L.Projection.SphericalMercator);
|
||||
expect(L.Projection.SphericalMercator.MAX_LATITUDE).to.be.a('number');
|
||||
|
||||
var mapZoom = map.getZoom();
|
||||
|
||||
for (i = 0; i < markers.length; i++) {
|
||||
try {
|
||||
expect(markers[i].__parent._zoom).to.be.below(mapZoom);
|
||||
} catch (e) {
|
||||
console.log("Failed marker: " + (i + 1));
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
it('includes objects above the Web Mercator projection maximum limit by default', function () {
|
||||
|
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatDefault);
|
||||
|
||||
group = L.markerClusterGroup();
|
||||
|
||||
prepareGroup();
|
||||
|
||||
checkProjection(latLngsMaxLatDefault);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(4); // Markers 1, 2, 3 and 4.
|
||||
expect(marker5._icon).to.be(null);
|
||||
|
||||
});
|
||||
|
||||
it('includes objects below the Web Mercator projection minimum limit by default', function () {
|
||||
|
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatDefault, true);
|
||||
|
||||
// Make sure we are really in Southern hemisphere.
|
||||
expect(map.getBounds().getNorth()).to.be.below(-80);
|
||||
|
||||
group = L.markerClusterGroup();
|
||||
|
||||
prepareGroup();
|
||||
|
||||
checkProjection(latLngsMaxLatDefault);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(4); // Markers 1, 2, 3 and 4.
|
||||
expect(marker5._icon).to.be(null);
|
||||
|
||||
});
|
||||
|
||||
|
||||
// The actual map view should be '-1.0986328125,84.92929204957956,1.0986328125,85.11983467698401'
|
||||
var latLngsMaxLatMobile = [
|
||||
[100, 1], // Impossible in real world, but nothing prevents the user from entering such latitude, and Web/Spherical Mercator projection will still display it at 85.0511287798
|
||||
[85.2, 0.5], // 1 "screen" heights away, but should be included by the correction.
|
||||
[85, 0], // In center of view.
|
||||
[84.9, -1], // 1 "screen" height away.
|
||||
[84.8, -1.5] // 2 "screens" height away.
|
||||
];
|
||||
|
||||
it('includes objects above the Web Mercator projection maximum limit for mobile device', function () {
|
||||
|
||||
// Fool Leaflet, make it thinks it runs on a mobile device.
|
||||
L.Browser.mobile = true;
|
||||
|
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatMobile);
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
maxClusterRadius: 10
|
||||
});
|
||||
|
||||
prepareGroup();
|
||||
|
||||
checkProjection(latLngsMaxLatMobile);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // Markers 1, 2 and 3.
|
||||
expect(marker4._icon).to.be(null);
|
||||
expect(marker5._icon).to.be(null);
|
||||
|
||||
});
|
||||
|
||||
it('includes objects below the Web Mercator projection minimum limit for mobile device', function () {
|
||||
|
||||
// Fool Leaflet, make it thinks it runs on a mobile device.
|
||||
L.Browser.mobile = true;
|
||||
|
||||
moveMarkersAndMapToMaxLat(latLngsMaxLatMobile, true);
|
||||
|
||||
// Make sure we are really in Southern hemisphere.
|
||||
expect(map.getBounds().getNorth()).to.be.below(-80);
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
maxClusterRadius: 10
|
||||
});
|
||||
|
||||
prepareGroup();
|
||||
|
||||
checkProjection(latLngsMaxLatMobile);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // Markers 1, 2 and 3.
|
||||
expect(marker4._icon).to.be(null);
|
||||
expect(marker5._icon).to.be(null);
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
110
static/leafletCluster/spec/suites/singleMarkerModeSpec.js
Normal file
110
static/leafletCluster/spec/suites/singleMarkerModeSpec.js
Normal file
@@ -0,0 +1,110 @@
|
||||
describe('singleMarkerMode option', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Reset the marker icon.
|
||||
marker.setIcon(defaultIcon);
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group;
|
||||
|
||||
var defaultIcon = new L.Icon.Default(),
|
||||
clusterIcon = new L.Icon.Default(),
|
||||
marker = L.marker([1.5, 1.5]);
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('overrides marker icons when set to true', function () {
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
singleMarkerMode: true,
|
||||
iconCreateFunction: function (layer) {
|
||||
return clusterIcon;
|
||||
}
|
||||
}).addTo(map);
|
||||
|
||||
expect(marker.options.icon).to.equal(defaultIcon);
|
||||
|
||||
marker.addTo(group);
|
||||
|
||||
expect(marker.options.icon).to.equal(clusterIcon);
|
||||
|
||||
});
|
||||
|
||||
it('does not modify marker icons by default (or set to false)', function () {
|
||||
|
||||
group = L.markerClusterGroup({
|
||||
iconCreateFunction: function (layer) {
|
||||
return clusterIcon;
|
||||
}
|
||||
}).addTo(map);
|
||||
|
||||
expect(marker.options.icon).to.equal(defaultIcon);
|
||||
|
||||
marker.addTo(group);
|
||||
|
||||
expect(marker.options.icon).to.equal(defaultIcon);
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
381
static/leafletCluster/spec/suites/spiderfySpec.js
Normal file
381
static/leafletCluster/spec/suites/spiderfySpec.js
Normal file
@@ -0,0 +1,381 @@
|
||||
describe('spiderfy', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('Spiderfies 2 Markers', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('Spiderfies 2 CircleMarkers', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
var marker2 = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
// Leaflet 1.0.0 now uses an intermediate L.Renderer.
|
||||
// marker > _path > _rootGroup (g) > _container (svg) > pane (div)
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
});
|
||||
|
||||
it('Spiderfies 2 Circles', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 10);
|
||||
var marker2 = new L.Circle([1.5, 1.5], 10);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
expect(marker._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
expect(marker2._path.parentNode.parentNode.parentNode).to.be(map.getPane('overlayPane'));
|
||||
});
|
||||
|
||||
it('Spiderfies at current zoom if all child markers are at the exact same position', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
// Get the appropriate cluster.
|
||||
var cluster = marker.__parent,
|
||||
zoom = map.getZoom();
|
||||
|
||||
while (cluster._zoom !== zoom) {
|
||||
cluster = cluster.__parent;
|
||||
}
|
||||
|
||||
expect(zoom).to.be.lessThan(10);
|
||||
|
||||
cluster.fireEvent('click', null, true);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map.getZoom()).to.equal(zoom);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
});
|
||||
|
||||
it('Spiderfies at current zoom if all child markers are still within a single cluster at map maxZoom', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.50001]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker.__parent._zoom).to.equal(18);
|
||||
|
||||
// Get the appropriate cluster.
|
||||
var cluster = marker.__parent,
|
||||
zoom = map.getZoom();
|
||||
|
||||
while (cluster._zoom !== zoom) {
|
||||
cluster = cluster.__parent;
|
||||
}
|
||||
|
||||
expect(zoom).to.be.lessThan(10);
|
||||
|
||||
cluster.fireEvent('click', null, true);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map.getZoom()).to.equal(zoom);
|
||||
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
});
|
||||
|
||||
it('removes all markers and spider legs when group is removed from map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3); // The 2 markers + semi-transparent cluster.
|
||||
expect(map.getPane('overlayPane').firstChild.firstChild.childNodes.length).to.be(2); // The 2 spider legs.
|
||||
|
||||
});
|
||||
|
||||
it('adds then removes class "leaflet-cluster-anim" from mapPane on spiderfy', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
expect(map._panes.mapPane.className).to.contain('leaflet-cluster-anim');
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim');
|
||||
|
||||
});
|
||||
|
||||
it('adds then removes class "leaflet-cluster-anim" from mapPane on unspiderfy', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
marker.__parent.unspiderfy();
|
||||
|
||||
expect(map._panes.mapPane.className).to.contain('leaflet-cluster-anim');
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim');
|
||||
|
||||
});
|
||||
|
||||
it('fires unspiderfied event on unspiderfy', function (done) {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
// Add event listener
|
||||
group.on('unspiderfied', function (event) {
|
||||
expect(event.target).to.be(group);
|
||||
expect(event.cluster).to.be.a(L.Marker);
|
||||
expect(event.markers[1]).to.be(marker);
|
||||
expect(event.markers[0]).to.be(marker2);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
marker.__parent.unspiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
});
|
||||
|
||||
it('does not leave class "leaflet-cluster-anim" on mapPane when group is removed while spiderfied', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
map.removeLayer(group);
|
||||
|
||||
expect(map._panes.mapPane.className).to.not.contain('leaflet-cluster-anim');
|
||||
|
||||
});
|
||||
|
||||
describe('zoomend event listener', function () {
|
||||
|
||||
it('unspiderfies correctly', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 10);
|
||||
var marker2 = new L.Circle([1.5, 1.5], 10);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
expect(group._spiderfied).to.not.be(null);
|
||||
|
||||
map.fire('zoomend');
|
||||
|
||||
//We should unspiderfy with no animation, so this should be null
|
||||
expect(group._spiderfied).to.be(null);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('spiderfied event listener', function () {
|
||||
it('Spiderfies 2 Markers', function (done) {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
// Add event listener
|
||||
group.on('spiderfied', function (event) {
|
||||
expect(event.target).to.be(group);
|
||||
expect(event.cluster).to.be.a(L.Marker);
|
||||
expect(event.markers[1]).to.be(marker);
|
||||
expect(event.markers[0]).to.be(marker2);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(200);
|
||||
});
|
||||
|
||||
it('Spiderfies 2 Circles', function (done) {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Circle([1.5, 1.5], 10);
|
||||
var marker2 = new L.Circle([1.5, 1.5], 10);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
// Add event listener
|
||||
group.on('spiderfied', function (event) {
|
||||
expect(event.target).to.be(group);
|
||||
expect(event.cluster).to.be.a(L.Marker);
|
||||
expect(event.markers[1]).to.be(marker);
|
||||
expect(event.markers[0]).to.be(marker2);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(200);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
124
static/leafletCluster/spec/suites/supportNegativeZoomSpec.js
Normal file
124
static/leafletCluster/spec/suites/supportNegativeZoomSpec.js
Normal file
@@ -0,0 +1,124 @@
|
||||
describe('things behave correctly with negative minZoom', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
// Nothing for this test suite.
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// Throw away group as it can be assigned with different configurations between tests.
|
||||
group = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { minZoom: -3, maxZoom: 18 });
|
||||
|
||||
map.setView(L.latLng(0, 0), -3);
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('shows a single marker added to the group before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('shows a single marker added to the group after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon.parentNode).to.be(map._panes.markerPane);
|
||||
});
|
||||
|
||||
it('creates a cluster when 2 overlapping markers are added before the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
expect(marker._icon).to.be(undefined);
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
it('creates a cluster when 2 overlapping markers are added after the group is added to the map', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
map.addLayer(group);
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
|
||||
expect(marker._icon).to.be(null); //Null as was added and then removed
|
||||
expect(marker2._icon).to.be(undefined);
|
||||
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(1);
|
||||
});
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
169
static/leafletCluster/spec/suites/unspiderfySpec.js
Normal file
169
static/leafletCluster/spec/suites/unspiderfySpec.js
Normal file
@@ -0,0 +1,169 @@
|
||||
describe('unspiderfy', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.removeLayers(group.getLayers());
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, {
|
||||
maxZoom: 18
|
||||
});
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('Unspiderfies 2 Markers', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
group.unspiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map.hasLayer(marker)).to.be(false);
|
||||
expect(map.hasLayer(marker2)).to.be(false);
|
||||
});
|
||||
|
||||
it('Unspiderfies 2 CircleMarkers', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.CircleMarker([1.5, 1.5]);
|
||||
var marker2 = new L.CircleMarker([1.5, 1.5]);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
group.unspiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map.hasLayer(marker)).to.be(false);
|
||||
expect(map.hasLayer(marker2)).to.be(false);
|
||||
});
|
||||
|
||||
it('Unspiderfies 2 Circles', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Circle([1.5, 1.5], 10);
|
||||
var marker2 = new L.Circle([1.5, 1.5], 10);
|
||||
|
||||
group.addLayer(marker);
|
||||
group.addLayer(marker2);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
group.unspiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map.hasLayer(marker)).to.be(false);
|
||||
expect(map.hasLayer(marker2)).to.be(false);
|
||||
});
|
||||
|
||||
it('fires unspiderfied event on unspiderfy', function (done) {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([1.5, 1.5]);
|
||||
var marker2 = new L.Marker([1.5, 1.5]);
|
||||
|
||||
group.addLayers([marker, marker2]);
|
||||
map.addLayer(group);
|
||||
|
||||
marker.__parent.spiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
// Add event listener
|
||||
group.on('unspiderfied', function (event) {
|
||||
expect(event.target).to.be(group);
|
||||
expect(event.cluster).to.be.a(L.Marker);
|
||||
expect(event.markers[1]).to.be(marker);
|
||||
expect(event.markers[0]).to.be(marker2);
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
group.unspiderfy();
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
410
static/leafletCluster/spec/suites/zoomAnimationSpec.js
Normal file
410
static/leafletCluster/spec/suites/zoomAnimationSpec.js
Normal file
@@ -0,0 +1,410 @@
|
||||
describe('zoomAnimation', function () {
|
||||
|
||||
/**
|
||||
* Avoid as much as possible creating and destroying objects for each test.
|
||||
* Instead, try re-using them, except for the ones under test of course.
|
||||
* PhantomJS does not perform garbage collection for the life of the page,
|
||||
* i.e. during the entire test process (Karma runs all tests in a single page).
|
||||
* http://stackoverflow.com/questions/27239708/how-to-get-around-memory-error-with-karma-phantomjs
|
||||
*
|
||||
* The `beforeEach` and `afterEach do not seem to cause much issue.
|
||||
* => they can still be used to initialize some setup between each test.
|
||||
* Using them keeps a readable spec/index.
|
||||
*
|
||||
* But refrain from re-creating div and map every time. Re-use those objects.
|
||||
*/
|
||||
|
||||
/////////////////////////////
|
||||
// SETUP FOR EACH TEST
|
||||
/////////////////////////////
|
||||
|
||||
beforeEach(function () {
|
||||
|
||||
clock = sinon.useFakeTimers();
|
||||
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
// Restore the previous setting, so that even in case of test failure, next tests are not affected.
|
||||
L.Browser.mobile = previousMobileSetting;
|
||||
|
||||
if (group instanceof L.MarkerClusterGroup) {
|
||||
group.clearLayers();
|
||||
map.removeLayer(group);
|
||||
}
|
||||
|
||||
// group must be thrown away since we are testing it with a potentially
|
||||
// different configuration at each test.
|
||||
group = null;
|
||||
|
||||
clock.restore();
|
||||
clock = null;
|
||||
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// PREPARATION CODE
|
||||
/////////////////////////////
|
||||
|
||||
var previousMobileSetting = L.Browser.mobile,
|
||||
div, map, group, clock;
|
||||
|
||||
div = document.createElement('div');
|
||||
div.style.width = '200px';
|
||||
div.style.height = '200px';
|
||||
document.body.appendChild(div);
|
||||
|
||||
map = L.map(div, { maxZoom: 18 });
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// TESTS
|
||||
/////////////////////////////
|
||||
|
||||
it('adds the visible marker to the map when zooming in', function () {
|
||||
map.setView(new L.LatLng(-37.36142550190516, 174.254150390625), 7);
|
||||
|
||||
group = new L.MarkerClusterGroup({
|
||||
showCoverageOnHover: true,
|
||||
maxClusterRadius: 20,
|
||||
disableClusteringAtZoom: 15
|
||||
});
|
||||
var marker = new L.Marker([-37.77852090603777, 175.3103667497635]);
|
||||
group.addLayer(marker); //The one we zoom in on
|
||||
group.addLayer(new L.Marker([-37.711800591811055, 174.50034790039062])); //Marker that we cluster with at the top zoom level, but not 1 level down
|
||||
map.addLayer(group);
|
||||
|
||||
clock.tick(1000);
|
||||
map.setView([-37.77852090603777, 175.3103667497635], 15);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon).to.not.be(null);
|
||||
});
|
||||
|
||||
it('adds the visible marker to the map when jumping around', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
var marker1 = new L.Marker([48.858280181884766, 2.2945759296417236]);
|
||||
var marker2 = new L.Marker([16.02359962463379, -61.70280075073242]);
|
||||
group.addLayer(marker1); //The one we zoom in on first
|
||||
group.addLayer(marker2); //Marker that we cluster with at the top zoom level, but not 1 level down
|
||||
map.addLayer(group);
|
||||
|
||||
//show the first
|
||||
map.fitBounds(new L.LatLngBounds(new L.LatLng(41.371582, -5.142222), new L.LatLng(51.092804, 9.561556)));
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
map.fitBounds(new L.LatLngBounds(new L.LatLng(15.830972671508789, -61.807167053222656), new L.LatLng(16.516849517822266, -61.0)));
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Now the second one should be visible on the map
|
||||
expect(marker2._icon).to.not.be(undefined);
|
||||
expect(marker2._icon).to.not.be(null);
|
||||
});
|
||||
|
||||
it('adds the visible markers to the map, but not parent clusters when jumping around', function () {
|
||||
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]),
|
||||
marker2 = new L.Marker([59.9516, 30.3308]),
|
||||
marker3 = new L.Marker([59.9513, 30.3312]);
|
||||
|
||||
group.addLayer(marker1);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
map.addLayer(group);
|
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
//Zoom so that all the markers will be visible (Same as zoomToShowLayer)
|
||||
map.setView(marker1.getLatLng(), 18);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Now the markers should all be visible, and there should be no visible clusters
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3);
|
||||
});
|
||||
|
||||
it('removes clicked clusters on the edge of a mobile screen', function () {
|
||||
|
||||
L.Browser.mobile = true;
|
||||
|
||||
// Corresponds to zoom level 8 for the above div dimensions.
|
||||
map.fitBounds(new L.LatLngBounds([
|
||||
[1, 1],
|
||||
[2, 2]
|
||||
]));
|
||||
|
||||
group = new L.MarkerClusterGroup({
|
||||
maxClusterRadius: 80
|
||||
}).addTo(map);
|
||||
|
||||
// Add a marker 1 pixel below the initial screen bottom edge.
|
||||
var bottomPoint = map.getPixelBounds().max.add([0, 1]),
|
||||
bottomLatLng = map.unproject(bottomPoint),
|
||||
centerLng = map.getCenter().lng,
|
||||
bottomPosition = new L.LatLng(
|
||||
bottomLatLng.lat,
|
||||
centerLng
|
||||
),
|
||||
bottomMarker = new L.Marker(bottomPosition).addTo(group),
|
||||
initialZoom = map.getZoom();
|
||||
|
||||
expect(bottomMarker._icon).to.be(undefined);
|
||||
|
||||
// Add many markers 79 pixels above the first one, so they cluster with it.
|
||||
var newPoint = bottomPoint.add([0, -79]),
|
||||
newLatLng = L.latLng(
|
||||
map.unproject(newPoint).lat,
|
||||
centerLng
|
||||
);
|
||||
|
||||
for (var i = 0; i < 10; i += 1) {
|
||||
group.addLayer(new L.Marker(newLatLng));
|
||||
}
|
||||
|
||||
var parentCluster = bottomMarker.__parent;
|
||||
|
||||
expect(parentCluster._icon.parentNode).to.be(map._panes.markerPane);
|
||||
|
||||
parentCluster.fireEvent('click', null, true);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
expect(map.getZoom()).to.equal(initialZoom + 1); // The fitBounds with 200px height should result in zooming 1 level in.
|
||||
|
||||
// Finally make sure that the cluster has been removed from map.
|
||||
expect(parentCluster._icon).to.be(null);
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(2); // The bottomMarker + cluster for the 10 above markers.
|
||||
|
||||
});
|
||||
|
||||
describe('zoomToShowLayer', function () {
|
||||
|
||||
it('zoom to single marker inside map view', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([59.9520, 30.3307]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
var zoomCallbackSpy = sinon.spy();
|
||||
|
||||
map.setView(marker.getLatLng(), 10);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
var initialCenter = map.getCenter();
|
||||
var initialZoom = map.getZoom();
|
||||
|
||||
group.zoomToShowLayer(marker, zoomCallbackSpy);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Marker should be visible, map center and zoom level should stay the same, callback called once
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon).to.not.be(null);
|
||||
expect(map.getBounds().contains(marker.getLatLng())).to.be.true;
|
||||
expect(map.getCenter()).to.eql(initialCenter);
|
||||
expect(map.getZoom()).to.equal(initialZoom);
|
||||
sinon.assert.calledOnce(zoomCallbackSpy);
|
||||
});
|
||||
|
||||
it('pan map to single marker outside map view', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker = new L.Marker([59.9520, 30.3307]);
|
||||
|
||||
group.addLayer(marker);
|
||||
map.addLayer(group);
|
||||
|
||||
var zoomCallbackSpy = sinon.spy();
|
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
var initialZoom = map.getZoom();
|
||||
|
||||
group.zoomToShowLayer(marker, zoomCallbackSpy);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Marker should be visible, map center should be equal to marker center,
|
||||
//zoom level should stay the same, callback called once
|
||||
expect(marker._icon).to.not.be(undefined);
|
||||
expect(marker._icon).to.not.be(null);
|
||||
expect(map.getBounds().contains(marker.getLatLng())).to.be.true;
|
||||
expect(map.getCenter()).to.eql(marker.getLatLng());
|
||||
expect(map.getZoom()).to.equal(initialZoom);
|
||||
sinon.assert.calledOnce(zoomCallbackSpy);
|
||||
});
|
||||
|
||||
it('change view and zoom to marker in cluster inside map view', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]);
|
||||
var marker2 = new L.Marker([59.9516, 30.3308]);
|
||||
var marker3 = new L.Marker([59.9513, 30.3312]);
|
||||
|
||||
group.addLayer(marker1);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
map.addLayer(group);
|
||||
|
||||
var zoomCallbackSpy = sinon.spy();
|
||||
|
||||
map.setView(marker1.getLatLng(), 16);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Now the markers should all be visible, there should be no visible clusters, and callback called once
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3);
|
||||
expect(map.getBounds().contains(marker1.getLatLng())).to.be.true;
|
||||
sinon.assert.calledOnce(zoomCallbackSpy);
|
||||
});
|
||||
|
||||
it('change view and zoom to marker in cluster outside map view', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]);
|
||||
var marker2 = new L.Marker([59.9516, 30.3308]);
|
||||
var marker3 = new L.Marker([59.9513, 30.3312]);
|
||||
|
||||
group.addLayer(marker1);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
map.addLayer(group);
|
||||
|
||||
var zoomCallbackSpy = sinon.spy();
|
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Now the markers should all be visible, there should be no visible clusters, and callback called once
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(3);
|
||||
expect(map.getBounds().contains(marker1.getLatLng())).to.be.true;
|
||||
sinon.assert.calledOnce(zoomCallbackSpy);
|
||||
});
|
||||
|
||||
it('spiderfy overlapping markers', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]);
|
||||
var marker2 = new L.Marker([59.9520, 30.3307]);
|
||||
var marker3 = new L.Marker([59.9520, 30.3307]);
|
||||
|
||||
group.addLayer(marker1);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
map.addLayer(group);
|
||||
|
||||
var zoomCallbackSpy = sinon.spy();
|
||||
|
||||
//Show none of them
|
||||
map.setView([53.0676, 170.6835], 16);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Now the markers should all be visible, parent cluster should be spiderfied, and callback called once
|
||||
expect(marker1._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker2._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(marker3._icon.parentNode).to.be(map._panes.markerPane);
|
||||
expect(map._panes.markerPane.childNodes.length).to.be(4);//3 markers + spiderfied parent cluster
|
||||
sinon.assert.calledOnce(zoomCallbackSpy);
|
||||
});
|
||||
|
||||
it('zoom or spiderfy markers if they visible on next level of zoom', function () {
|
||||
group = new L.MarkerClusterGroup();
|
||||
|
||||
var marker1 = new L.Marker([59.9520, 30.3307]);
|
||||
var marker2 = new L.Marker([59.9516, 30.3308]);
|
||||
var marker3 = new L.Marker([59.9513, 30.3312]);
|
||||
|
||||
group.addLayer(marker1);
|
||||
group.addLayer(marker2);
|
||||
group.addLayer(marker3);
|
||||
map.addLayer(group);
|
||||
|
||||
var zoomCallbackSpy = sinon.spy();
|
||||
|
||||
//Markers will be visible on zoom 18
|
||||
map.setView([59.9520, 30.3307], 17);
|
||||
|
||||
clock.tick(1000);
|
||||
|
||||
group.zoomToShowLayer(marker1, zoomCallbackSpy);
|
||||
|
||||
//Run the the animation
|
||||
clock.tick(1000);
|
||||
|
||||
//Now the markers should all be visible (zoomed or spiderfied), and callback called once
|
||||
expect(marker1._icon).to.not.be(undefined);
|
||||
expect(marker1._icon).to.not.be(null);
|
||||
expect(marker2._icon).to.not.be(undefined);
|
||||
expect(marker2._icon).to.not.be(null);
|
||||
expect(marker3._icon).to.not.be(undefined);
|
||||
expect(marker3._icon).to.not.be(null);
|
||||
sinon.assert.calledOnce(zoomCallbackSpy);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/////////////////////////////
|
||||
// CLEAN UP CODE
|
||||
/////////////////////////////
|
||||
|
||||
map.remove();
|
||||
document.body.removeChild(div);
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user