Initial commit

This commit is contained in:
zhongjin
2020-06-13 18:34:34 +08:00
commit 52aaa9f15d
655 changed files with 96796 additions and 0 deletions
@@ -0,0 +1,50 @@
/* global L */
var cartoLayerGroupViewTests = require('../shared-tests-for-carto-layer-group');
var LeafletCartoDBLayerGroupView = require('../../../../src/geo/leaflet/leaflet-cartodb-layer-group-view');
describe('leaflet-cartodb-layer-group-view', function () {
/**
* Helper function used to get a map in the shared tests.
*/
function createNativeMap (container) {
// Create a leaflet map inside a container
container.setAttribute('id', 'map');
container.style.height = '200px';
document.body.appendChild(container);
return L.map('map').setView([47.84808037632246, 14.2822265625], 4);
}
/**
* Helper function used to get the tiles in the shared tests
*/
function getTileUrl (layerGroupView) {
return layerGroupView.leafletLayer._url.replace('{s}', '0');
}
/**
* Gmaps events and Leaflet events are different.
*/
var event = {
containerPoint: { x: 264, y: 309 },
data: {
name: 'fakeCityName',
cartodb_id: 123
},
e: {
clientX: 696,
clientY: 325,
type: 'mousemove'
},
latlng: {
lat: 42.293564192170095,
lng: -8.173828125000002
},
layer: 0,
layerPoint: { x: 264, y: 309 },
originalEvent: {},
target: {},
type: 'mouseMove'
};
cartoLayerGroupViewTests(createNativeMap, LeafletCartoDBLayerGroupView, getTileUrl, event);
});
@@ -0,0 +1,54 @@
var Backbone = require('backbone');
var LeafletLayerView = require('../../../../src/geo/leaflet/leaflet-layer-view');
LeafletLayerView.prototype._createLeafletLayer = function () {
return jasmine.createSpyObj('leafletLayer', ['redraw', 'on']);
};
describe('leaflet-layer-view', function () {
beforeEach(function () {
this.layerModel = new Backbone.Model();
spyOn(this.layerModel, 'bind');
spyOn(this.layerModel, 'unbind');
this.leafletMap = jasmine.createSpyObj('leafletMap', ['removeLayer']);
this.layerView = new LeafletLayerView(this.layerModel, {
nativeMap: this.leafletMap
});
this.leafletLayer = this.layerView.leafletLayer;
});
it('should have a model change binding', function () {
expect(this.layerModel.bind).toHaveBeenCalledWith('change', this.layerView._modelUpdated, this.layerView);
});
describe('.remove', function () {
beforeEach(function () {
spyOn(this.layerView, 'trigger');
spyOn(this.layerView, 'unbind');
this.layerView.remove();
});
it('should remove layer from leaflet map', function () {
expect(this.leafletMap.removeLayer).toHaveBeenCalledWith(this.leafletLayer);
});
it('should trigger remove event', function () {
expect(this.layerView.trigger).toHaveBeenCalledWith('remove', this.layerView);
});
it('should unbind', function () {
expect(this.layerModel.unbind).toHaveBeenCalledWith(null, null, this.layerView);
expect(this.layerView.unbind).toHaveBeenCalled();
});
});
describe('.reload', function () {
beforeEach(function () {
this.layerView.reload();
});
it('should redraw map', function () {
expect(this.leafletLayer.redraw).toHaveBeenCalled();
});
});
});
@@ -0,0 +1,253 @@
var $ = require('jquery');
var _ = require('underscore');
var Backbone = require('backbone');
var Map = require('../../../../src/geo/map');
var TileLayer = require('../../../../src/geo/map/tile-layer');
var CartoDBLayer = require('../../../../src/geo/map/cartodb-layer');
var PlainLayer = require('../../../../src/geo/map/plain-layer');
var LayersCollection = require('../../../../src/geo/map/layers');
var CartoDBLayerGroup = require('../../../../src/geo/cartodb-layer-group');
var LeafletMapView = require('../../../../src/geo/leaflet/leaflet-map-view');
var LeafletTiledLayerView = require('../../../../src/geo/leaflet/leaflet-tiled-layer-view');
var LeafletPlainLayerView = require('../../../../src/geo/leaflet/leaflet-plain-layer-view');
var createEngine = require('../../fixtures/engine.fixture.js');
describe('geo/leaflet/leaflet-map-view', function () {
var mapView;
var map;
var spy;
var container;
var layer;
var engineMock;
beforeEach(function () {
container = $('<div>').css({
'height': '200px',
'width': '200px'
});
map = new Map(null, {
layersFactory: {},
attribution: [ '© CARTO' ]
});
spyOn(map, 'setMapViewSize').and.callThrough();
spyOn(map, 'setPixelToLatLngConverter').and.callThrough();
spyOn(map, 'setLatLngToPixelConverter').and.callThrough();
this.layerGroupModel = new CartoDBLayerGroup({}, { layersCollection: new LayersCollection() });
spyOn(this.layerGroupModel, 'hasTileURLTemplates').and.returnValue(true);
spyOn(this.layerGroupModel, 'getTileURLTemplate').and.returnValue('http://documentation.cartodb.com/api/v1/map/90e64f1b9145961af7ba36d71b887dd2:0/0/{z}/{x}/{y}.png');
mapView = new LeafletMapView({
el: container,
mapModel: map,
engine: new Backbone.Model(),
layerGroupModel: this.layerGroupModel
});
mapView.render();
var layerURL = 'http://{s}.tiles.mapbox.com/v3/cartodb.map-1nh578vv/{z}/{x}/{y}.png';
layer = new TileLayer({ urlTemplate: layerURL }, { engine: {} });
spy = jasmine.createSpyObj('spy', ['zoomChanged', 'centerChanged', 'keyboardChanged', 'changed']);
map.bind('change:zoom', spy.zoomChanged);
map.bind('change:keyboard', spy.keyboardChanged);
map.bind('change:center', spy.centerChanged);
map.bind('change', spy.changed);
engineMock = createEngine();
});
it('should change bounds when center is set', function () {
var spy = jasmine.createSpy('change:view_bounds_ne');
spyOn(map, 'getViewBounds');
map.bind('change:view_bounds_ne', spy);
map.set('center', [10, 10]);
expect(spy).toHaveBeenCalled();
expect(map.getViewBounds).not.toHaveBeenCalled();
});
it('should allow adding a layer', function () {
map.addLayer(layer);
expect(map.layers.length).toEqual(1);
});
it('should add layers on reset', function () {
map.layers.reset([
layer
]);
expect(map.layers.length).toEqual(1);
});
it('should allow removing a layer', function () {
map.addLayer(layer);
map.removeLayer(layer);
expect(map.layers.length).toEqual(0);
expect(_.size(mapView._layerViews)).toEqual(0);
});
it('should allow removing a layer by index', function () {
map.addLayer(layer);
map.removeLayerAt(0);
expect(map.layers.length).toEqual(0);
});
it('should allow removing a layer by Cid', function () {
var cid = map.addLayer(layer);
map.removeLayerByCid(cid);
expect(map.layers.length).toEqual(0);
});
it('should create a TiledLayerView when the layer is Tiled', function () {
var lyr = map.addLayer(layer);
var layerView = mapView.getLayerViewByLayerCid(lyr);
expect(LeafletTiledLayerView.prototype.isPrototypeOf(layerView)).isPrototypeOf();
});
it('should create a PlainLayer when the layer is cartodb', function () {
layer = new PlainLayer(null, { engine: {} });
var lyr = map.addLayer(layer);
var layerView = mapView.getLayerViewByLayerCid(lyr);
expect(layerView.setQuery).not.toEqual(LeafletPlainLayerView);
});
it('should insert layers in specified order', function () {
var tileLayer = new TileLayer({ urlTemplate: 'http://tilelayer1.com' }, { engine: {} });
map.addLayer(tileLayer);
var tileLayer2 = new TileLayer({ urlTemplate: 'http://tilelayer2.com' }, { engine: {} });
map.addLayer(tileLayer2, { at: 0 });
expect(mapView.getLayerViewByLayerCid(tileLayer.cid).leafletLayer.options.zIndex).toEqual(1);
expect(mapView.getLayerViewByLayerCid(tileLayer2.cid).leafletLayer.options.zIndex).toEqual(0);
});
it('should remove all layers when map view is cleaned', function () {
var cartoDBLayer1 = new CartoDBLayer({ meta: { cartocss: '#layer {}' } }, { engine: engineMock });
var cartoDBLayer2 = new CartoDBLayer({ meta: { cartocss: '#layer {}' } }, { engine: engineMock });
var tileLayer = new TileLayer({ urlTemplate: 'test' }, { engine: {} });
map.addLayer(cartoDBLayer1);
map.addLayer(cartoDBLayer2);
map.addLayer(tileLayer);
expect(_.size(mapView._layerViews)).toEqual(3);
var layerGroupView = mapView.getLayerViewByLayerCid(cartoDBLayer1.cid);
spyOn(layerGroupView, 'remove');
var tileLayerView = mapView.getLayerViewByLayerCid(tileLayer.cid);
spyOn(tileLayerView, 'remove');
mapView.clean();
expect(_.size(mapView._layerViews)).toEqual(0);
expect(layerGroupView.remove).toHaveBeenCalled();
expect(tileLayerView.remove).toHaveBeenCalled();
expect(mapView.layerGroupModel).not.toBeDefined();
});
it("should not add a layer view when it can't be created", function () {
var layer = new TileLayer({type: 'cartojs-test'}, { engine: {} });
map.addLayer(layer);
expect(_.size(mapView._layerViews)).toEqual(0);
});
describe('attributions', function () {
it('should not render Leaflet attributions', function () {
var attributions = mapView.$el.find('.leaflet-control-attribution');
expect(attributions.text()).toEqual('');
});
});
it('should disable leaflet dragging and double click zooming when the map has drag disabled', function () {
var container = $('<div>').css({
'height': '200px',
'width': '200px'
});
var map = new Map({
drag: false
}, {
layersFactory: {}
});
var mapView = new LeafletMapView({
el: container,
mapModel: map,
engine: new Backbone.Model(),
layerGroupModel: new Backbone.Model()
});
mapView.render();
expect(mapView._leafletMap.dragging.enabled()).toBeFalsy();
expect(mapView._leafletMap.doubleClickZoom.enabled()).toBeFalsy();
});
it('should "forward" a dragend event to the map model', function () {
var container = $('<div>').css({
'height': '200px',
'width': '200px'
});
var map = new Map({
drag: false
}, {
layersFactory: {}
});
var mapView = new LeafletMapView({
el: container,
mapModel: map,
engine: new Backbone.Model(),
layerGroupModel: new Backbone.Model()
});
mapView.render();
spyOn(map, 'trigger');
mapView._leafletMap.fire('moveend');
expect(map.trigger).toHaveBeenCalledWith('moveend', jasmine.any(Object));
});
it('should update mapView size on resize', function () {
mapView._leafletMap.fire('resize');
expect(map.setMapViewSize).toHaveBeenCalled();
});
describe('converters', function () {
it('should set converters', function () {
expect(map.setPixelToLatLngConverter).toHaveBeenCalled();
expect(map.setLatLngToPixelConverter).toHaveBeenCalled();
expect(map._pixelToLatLngConverter).toBeDefined();
expect(map._latLngToPixelConverter).toBeDefined();
});
it('should call native methods', function () {
spyOn(mapView._leafletMap, 'latLngToContainerPoint').and.callThrough();
spyOn(mapView._leafletMap, 'containerPointToLatLng').and.callThrough();
var pixelToLatLng = map.pixelToLatLng();
pixelToLatLng({x: 0, y: 0});
expect(mapView._leafletMap.containerPointToLatLng).toHaveBeenCalled();
var latLngToPixel = map.latLngToPixel();
latLngToPixel([0, 0]);
expect(mapView._leafletMap.latLngToContainerPoint).toHaveBeenCalled();
});
});
describe('.invalidateSize', function () {
it('should invalidate size in Leaflet and "re-center"', function () {
spyOn(mapView._leafletMap, 'invalidateSize');
spyOn(mapView._leafletMap, 'setView');
var center = mapView.map.get('center');
var zoom = mapView.map.get('zoom');
mapView.invalidateSize();
expect(mapView._leafletMap.setView).toHaveBeenCalledWith(center, zoom, jasmine.any(Object));
expect(mapView._leafletMap.invalidateSize).toHaveBeenCalled();
});
});
});
@@ -0,0 +1,132 @@
var Backbone = require('backbone');
var LeafletTiledLayerView = require('../../../../src/geo/leaflet/leaflet-tiled-layer-view');
describe('leaflet-tiled-layer-view', function () {
describe('when does not support high resolution screens', function () {
beforeEach(function () {
this.layerModel = new Backbone.Model({
urlTemplate: 'http://whatever.com',
subdomains: 'a',
opacity: 1,
attribution: 'CARTO',
errorTileUrl: 'http://matall.in',
maxZoom: 10,
minZoom: 0,
tms: false
});
this.leafletMap = jasmine.createSpy('leafletMap');
this.layerView = new LeafletTiledLayerView(this.layerModel, {
nativeMap: this.leafletMap
});
});
it('should have options set correctly', function () {
expect(this.layerView.leafletLayer.options.subdomains).toEqual(['a']);
expect(this.layerView.leafletLayer._url).toBe('http://whatever.com');
expect(this.layerView.leafletLayer.options.attribution).toBe('CARTO');
expect(this.layerView.leafletLayer.options.errorTileUrl).toBe('http://matall.in');
expect(this.layerView.leafletLayer.options.maxZoom).toBe(10);
expect(this.layerView.leafletLayer.options.minZoom).toBe(0);
expect(this.layerView.leafletLayer.options.opacity).toBe(1);
expect(this.layerView.leafletLayer.options.tms).toBeFalsy();
});
describe('._modelUpdated', function () {
beforeEach(function () {
this.layerModel.set({
subdomains: ['b'],
urlTemplate: 'http://hello.com',
attribution: 'carto',
maxZoom: 12,
minZoom: 1,
tms: true
});
});
it('should update several attributes', function () {
expect(this.layerView.leafletLayer.options.subdomains).toEqual(['b']);
expect(this.layerView.leafletLayer.options.attribution).toBe('carto');
expect(this.layerView.leafletLayer.options.errorTileUrl).toBe('http://matall.in');
expect(this.layerView.leafletLayer.options.maxZoom).toBe(12);
expect(this.layerView.leafletLayer.options.minZoom).toBe(1);
expect(this.layerView.leafletLayer.options.opacity).toBe(1);
expect(this.layerView.leafletLayer.options.tms).toBeTruthy();
});
it('should update url', function () {
expect(this.layerView.leafletLayer._url).toBe('http://hello.com');
});
});
it('should trigger load and loading events', function () {
var loadCallback = jasmine.createSpy('loadCallback');
this.layerView.bind('load', loadCallback);
this.layerView.leafletLayer.fire('load');
expect(loadCallback).toHaveBeenCalled();
var loadingCallback = jasmine.createSpy('loadingCallback');
this.layerView.bind('loading', loadingCallback);
this.layerView.leafletLayer.fire('loading');
expect(loadingCallback).toHaveBeenCalled();
});
});
describe('when supports high resolution screens', function () {
beforeEach(function () {
this.layerModel = new Backbone.Model({
urlTemplate: 'http://whatever.com',
urlTemplate2x: 'http://whatever.com2x',
subdomains: 'a',
opacity: 1,
attribution: 'CARTO',
errorTileUrl: 'http://matall.in',
maxZoom: 10,
minZoom: 0,
tms: false
});
this.leafletMap = jasmine.createSpy('leafletMap');
this.layerView = new LeafletTiledLayerView(this.layerModel, {
nativeMap: this.leafletMap
});
});
describe('when is high resolution screen', function () {
beforeEach(function () {
spyOn(this.layerView, '_isHdpi').and.returnValue(true);
});
it('should update the model correctly if high resolution template is enabled', function () {
this.layerModel.set({
urlTemplate: 'http://hello.com',
urlTemplate2x: 'http://hello.com2x'
});
expect(this.layerView.leafletLayer._url).toBe('http://hello.com2x');
});
it('should update the model correctly if high resolution template is not enabled', function () {
this.layerModel.set({
urlTemplate: 'http://hello.com'
});
expect(this.layerView.leafletLayer._url).toBe('http://hello.com');
});
});
describe('when it is not a high resolution screen', function () {
beforeEach(function () {
spyOn(this.layerView, '_isHdpi').and.returnValue(false);
});
it('should update the model correctly if high resolution template is enabled', function () {
this.layerModel.set({
urlTemplate: 'http://hello.com',
urlTemplate2x: 'http://hello.com2x'
});
expect(this.layerView.leafletLayer._url).toBe('http://hello.com');
});
});
});
});
@@ -0,0 +1,101 @@
/* global L */
var $ = require('jquery');
var Backbone = require('backbone');
var Map = require('../../../../src/geo/map');
var LeafletMapView = require('../../../../src/geo/leaflet/leaflet-map-view');
var LeafletLayerViewFactory = require('../../../../src/geo/leaflet/leaflet-layer-view-factory');
var TorqueLayer = require('../../../../src/geo/map/torque-layer');
var MockFactory = require('../../../helpers/mockFactory');
var createEngine = require('../../fixtures/engine.fixture.js');
var SharedTestsForTorqueLayer = require('../shared-tests-for-torque-layer');
describe('geo/leaflet/leaflet-torque-layer-view', function () {
var engineMock;
beforeEach(function () {
var container = $('<div>').css({
'height': '200px',
'width': '200px'
});
engineMock = createEngine();
this.map = new Map(null, {
layersFactory: {}
});
spyOn(this.map, 'trigger');
this.mapView = new LeafletMapView({
el: container,
mapModel: this.map,
engine: new Backbone.Model(),
layerViewFactory: new LeafletLayerViewFactory(),
layerGroupModel: new Backbone.Model(),
showLimitErrors: false
});
this.mapView.render();
spyOn(L.TorqueLayer.prototype, 'initialize').and.callThrough();
this.model = new TorqueLayer({
source: MockFactory.createAnalysisModel({ id: 'a0' }),
cartocss: 'Map {}',
dynamic_cdn: 'dynamic-cdn-value'
}, { engine: engineMock });
this.map.addLayer(this.model);
this.view = this.mapView._layerViews[this.model.cid];
});
SharedTestsForTorqueLayer.call(this);
it('should reuse layer view', function () {
this.view.check = 'testing';
var newLayer = new TorqueLayer({
source: MockFactory.createAnalysisModel({ id: 'a0' }),
cartocss: 'Map {}',
dynamic_cdn: 'dynamic-cdn-value'
}, {
engine: engineMock
});
this.map.layers.reset([ newLayer ]);
expect(this.mapView._layerViews[newLayer.cid].model).toEqual(newLayer);
expect(this.mapView._layerViews[newLayer.cid].check).toEqual('testing');
});
it('should apply Leaflet TorqueLayer initialize method on the extended view with a bunch of attrs', function () {
expect(L.TorqueLayer.prototype.initialize).toHaveBeenCalled();
var attrs = L.TorqueLayer.prototype.initialize.calls.argsFor(0)[0];
expect(attrs.cartocss).toEqual(jasmine.any(String));
expect(attrs.dynamic_cdn).toEqual('dynamic-cdn-value');
expect(attrs.instanciateCallback).toEqual(jasmine.any(Function));
});
it("should update providers's templateURL when urls change", function () {
this.model.set('tileURLTemplates', [
'http://pepe.carto.com/{z}/{x}/{y}.torque',
'http://juan.carto.com/{z}/{x}/{y}.torque'
]);
expect(this.view.leafletLayer.provider.templateUrl).toEqual('http://pepe.carto.com/{z}/{x}/{y}.torque');
});
describe('when LeafletTorqueLayer triggers tileError', function () {
it('should trigger error:limit in mapModel if showLimitErrors is true', function () {
this.view.showLimitErrors = true;
this.view.nativeTorqueLayer.fire('tileError');
var calls = this.map.trigger.calls.all();
var types = calls.map(function (call) {
return call.args[0];
});
expect(types).toContain('error:limit');
});
it('should not trigger error:limit in mapModel if showLimitErrors is false', function () {
this.view.nativeTorqueLayer.fire('tileError');
var calls = this.map.trigger.calls.all();
var types = calls.map(function (call) {
return call.args[0];
});
expect(types).not.toContain('error:limit');
});
});
});