/* global describe, chai, it */

function isEmpty (obj) {
	for (var prop in obj) {
		if (obj.hasOwnProperty(prop)) {
			return false;
		}
	}

	return true;
}

// List of valid L.TileLayer options to check options against
var TileLayerValidOptions = [
    'minZoom', 'maxZoom', 'maxNativeZoom', 'tileSize', 'subdomains', 'errorTileUrl',
    'attribution', 'tms', 'continuousWorld', 'noWrap', 'zoomOffset', 'zoomReverse',
    'opacity', 'zIndex', 'unloadInvisibleTiles', 'updateWhenIdle', 'detectRetina',
    'reuseTiles', 'bounds'
]

// monkey-patch getTileUrl with fake values.
L.TileLayer.prototype.getTileUrl = function (coords) {
	return L.Util.template(this._url, L.extend({
		r: '',
		s: this._getSubdomain(coords),
		x: coords.x,
		y: coords.y,
		z: 15
	}, this.options));
};

describe('leaflet-providers', function () {
	chai.should();
	var providers = L.TileLayer.Provider.providers;

	describe('variant definition structure', function () {
		it('each provider has keys url, options, variants', function () {
			for (var name in providers) {
				providers[name].should.contain.any.keys('url', 'options', 'variants');
			}
		});
		it('each variant should be an object or a string', function () {
			for (var name in providers) {
				var variants = providers[name].variants;

				for (var v in variants) {
					if (typeof variants[v] === 'string' || isEmpty(variants[v])) {
						// string or empty object, which is fine.
						continue;
					} else {
						variants[v].should.be.an.instanceof(Object);
						variants[v].should.contain.any.keys('url', 'options');

						// verify that keys in the options map are valid L.TileLayer options or
						// exist in the tile url.
						var url = variants[v].url || providers[name].url;
						for (var key in variants[v].options) {
							if (TileLayerValidOptions.indexOf(key) != -1) {
								continue;
							}
							var placeholder = '{' + key + '}';
							url.should.contain(placeholder);
						}
					}
				}
			}
		});
	});

	L.tileLayer.provider.eachLayer(function (name) {
		describe(name, function () {
			var layer = L.tileLayer.provider(name);

			it('should be a L.TileLayer', function () {
				layer.should.be.an.instanceof(L.TileLayer);
			});

			it('should not throw while requesting a tile url', function () {
				layer.getTileUrl({x: 16369, y: 10896});
			});
		});
	});
});

/* global describe, chai, it */

function isEmpty (obj) {
	for (var prop in obj) {
		if (obj.hasOwnProperty(prop)) {
			return false;
		}
	}

	return true;
}

// List of valid L.TileLayer options to check options against
var validTileLayerOptions = [
	'minZoom', 'maxZoom', 'maxNativeZoom', 'tileSize', 'subdomains', 'errorTileUrl',
	'attribution', 'tms', 'continuousWorld', 'noWrap', 'zoomOffset', 'zoomReverse',
	'opacity', 'zIndex', 'unloadInvisibleTiles', 'updateWhenIdle', 'detectRetina',
	'reuseTiles', 'bounds'
];

// monkey-patch getTileUrl with fake values.
L.TileLayer.prototype.getTileUrl = function (coords) {
	return L.Util.template(this._url, L.extend({
		r: '',
		s: this._getSubdomain(coords),
		x: coords.x,
		y: coords.y,
		z: 15
	}, this.options));
};

describe('leaflet-providers', function () {
	chai.should();
	var providers = L.TileLayer.Provider.providers;

	describe('variant definition structure', function () {
		it('each provider has keys url, options, variants', function () {
			for (var name in providers) {
				providers[name].should.contain.any.keys('url', 'options', 'variants');
			}
		});
		it('each variant should be an object or a string', function () {
			for (var name in providers) {
				var variants = providers[name].variants;

				for (var v in variants) {
					if (typeof variants[v] === 'string' || isEmpty(variants[v])) {
						// string or empty object, which is fine.
						continue;
					} else {
						variants[v].should.be.an.instanceof(Object);
						variants[v].should.contain.any.keys('url', 'options');
					}
				}
			}
		});
	});

	describe('Each layer', function () {
		L.tileLayer.provider.eachLayer(function (name, variant) {
			describe(name, function () {
				var layer = L.tileLayer.provider(name);

				it('should be a L.TileLayer', function () {
					layer.should.be.an.instanceof(L.TileLayer);
				});

				it('should not throw while requesting a tile url', function () {
					layer.getTileUrl({x: 16369, y: 10896});
				});

				it('should have valid options', function () {
					for (var key in layer.options) {
						if (validTileLayerOptions.indexOf(key) != -1) {
							continue;
						}
						var placeholder = '{' + key + '}';
						layer._url.should.contain(placeholder);
					}
				})
			});
		});
	})
});

Move the valid options check to the checks done for each layer