Adding mapbox-gl branch
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for working with ES6 iterables.
|
||||
* Note that this file is written ES5-only.
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/The_Iterator_protocol
|
||||
*/
|
||||
|
||||
goog.module('goog.labs.iterable');
|
||||
|
||||
|
||||
/**
|
||||
* Get the iterator for an iterable.
|
||||
* @param {!Iterable<VALUE>} iterable
|
||||
* @return {!Iterator<VALUE>}
|
||||
* @template VALUE
|
||||
*/
|
||||
exports.getIterator = function(iterable) {
|
||||
return iterable[goog.global.Symbol.iterator]();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Call a function with every value of an iterable.
|
||||
*
|
||||
* Warning: this function will never halt if given an iterable that
|
||||
* is never exhausted.
|
||||
*
|
||||
* @param {!function(VALUE): void} f
|
||||
* @param {!Iterable<VALUE>} iterable
|
||||
* @template VALUE
|
||||
*/
|
||||
exports.forEach = function(f, iterable) {
|
||||
var iterator = exports.getIterator(iterable);
|
||||
while (true) {
|
||||
var next = iterator.next();
|
||||
if (next.done) {
|
||||
return;
|
||||
}
|
||||
f(next.value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Maps the values of one iterable to create another iterable.
|
||||
*
|
||||
* When next() is called on the returned iterable, it will call the given
|
||||
* function {@code f} with the next value of the given iterable
|
||||
* {@code iterable} until the given iterable is exhausted.
|
||||
*
|
||||
* @param {!function(this: THIS, VALUE): RESULT} f
|
||||
* @param {!Iterable<VALUE>} iterable
|
||||
* @return {!Iterable<RESULT>} The created iterable that gives the mapped
|
||||
* values.
|
||||
* @template THIS, VALUE, RESULT
|
||||
*/
|
||||
exports.map = function(f, iterable) {
|
||||
return new FactoryIterable(function() {
|
||||
var iterator = exports.getIterator(iterable);
|
||||
return new MapIterator(f, iterator);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper class for {@code map}.
|
||||
* @param {!function(VALUE): RESULT} f
|
||||
* @param {!Iterator<VALUE>} iterator
|
||||
* @constructor
|
||||
* @implements {Iterator<RESULT>}
|
||||
* @template VALUE, RESULT
|
||||
*/
|
||||
var MapIterator = function(f, iterator) {
|
||||
/** @private */
|
||||
this.func_ = f;
|
||||
/** @private */
|
||||
this.iterator_ = iterator;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
MapIterator.prototype.next = function() {
|
||||
var nextObj = this.iterator_.next();
|
||||
|
||||
if (nextObj.done) {
|
||||
return {done: true, value: undefined};
|
||||
}
|
||||
|
||||
var mappedValue = this.func_(nextObj.value);
|
||||
return {
|
||||
done: false,
|
||||
value: mappedValue
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Helper class to create an iterable with a given iterator factory.
|
||||
* @param {function():!Iterator<VALUE>} iteratorFactory
|
||||
* @constructor
|
||||
* @implements {Iterable<VALUE>}
|
||||
* @template VALUE
|
||||
*/
|
||||
var FactoryIterable = function(iteratorFactory) {
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
this.iteratorFactory_ = iteratorFactory;
|
||||
};
|
||||
|
||||
|
||||
// TODO(nnaze): For now, this section is not run if Symbol is not defined,
|
||||
// since goog.global.Symbol.iterator will not be defined below.
|
||||
// Determine best course of action if "Symbol" is not available.
|
||||
if (goog.global.Symbol) {
|
||||
/**
|
||||
* @return {!Iterator<VALUE>}
|
||||
*/
|
||||
FactoryIterable.prototype[goog.global.Symbol.iterator] = function() {
|
||||
return this.iteratorFactory_();
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
// Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Tests for goog.labs.iterable
|
||||
*/
|
||||
|
||||
goog.module('goog.labs.iterableTest');
|
||||
|
||||
goog.module.declareTestMethods();
|
||||
goog.setTestOnly();
|
||||
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
var iterable = goog.require('goog.labs.iterable');
|
||||
var recordFunction = goog.require('goog.testing.recordFunction');
|
||||
|
||||
|
||||
/**
|
||||
* Create an iterator starting at "start" and increments up to
|
||||
* (but not including) "stop".
|
||||
*/
|
||||
function createRangeIterator(start, stop) {
|
||||
var value = start;
|
||||
var next = function() {
|
||||
if (value < stop) {
|
||||
return {
|
||||
value: value++,
|
||||
done: false
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
value: undefined,
|
||||
done: true
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
next: next
|
||||
};
|
||||
}
|
||||
|
||||
function createRangeIterable(start, stop) {
|
||||
var obj = {};
|
||||
|
||||
// Refer to goog.global['Symbol'] because otherwise this
|
||||
// is a parse error in earlier IEs.
|
||||
obj[goog.global['Symbol'].iterator] = function() {
|
||||
return createRangeIterator(start, stop);
|
||||
};
|
||||
return obj;
|
||||
}
|
||||
|
||||
function isSymbolDefined() {
|
||||
return !!goog.global['Symbol'];
|
||||
}
|
||||
|
||||
exports.testCreateRangeIterable = function() {
|
||||
// Do not run if Symbol does not exist in this browser.
|
||||
if (!isSymbolDefined()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var rangeIterator = createRangeIterator(0, 3);
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
assertObjectEquals({
|
||||
value: i,
|
||||
done: false
|
||||
}, rangeIterator.next());
|
||||
}
|
||||
|
||||
for (var i = 0; i < 3; i++) {
|
||||
assertObjectEquals({
|
||||
value: undefined,
|
||||
done: true
|
||||
}, rangeIterator.next());
|
||||
}
|
||||
};
|
||||
|
||||
exports.testForEach = function() {
|
||||
// Do not run if Symbol does not exist in this browser.
|
||||
if (!isSymbolDefined()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var range = createRangeIterable(0, 3);
|
||||
|
||||
var callback = recordFunction();
|
||||
iterable.forEach(callback, range, self);
|
||||
|
||||
callback.assertCallCount(3);
|
||||
|
||||
var calls = callback.getCalls();
|
||||
for (var i = 0; i < calls.length; i++) {
|
||||
var call = calls[i];
|
||||
assertArrayEquals([i], call.getArguments());
|
||||
}
|
||||
};
|
||||
|
||||
exports.testMap = function() {
|
||||
// Do not run if Symbol does not exist in this browser.
|
||||
if (!isSymbolDefined()) {
|
||||
return;
|
||||
}
|
||||
|
||||
var range = createRangeIterable(0, 3);
|
||||
|
||||
function addTwo(i) {
|
||||
return i + 2;
|
||||
}
|
||||
|
||||
var newIterable = iterable.map(addTwo, range);
|
||||
var newIterator = iterable.getIterator(newIterable);
|
||||
|
||||
var nextObj = newIterator.next();
|
||||
assertEquals(2, nextObj.value);
|
||||
assertFalse(nextObj.done);
|
||||
|
||||
nextObj = newIterator.next();
|
||||
assertEquals(3, nextObj.value);
|
||||
assertFalse(nextObj.done);
|
||||
|
||||
nextObj = newIterator.next();
|
||||
assertEquals(4, nextObj.value);
|
||||
assertFalse(nextObj.done);
|
||||
|
||||
// Check that the iterator repeatedly signals done.
|
||||
for (var i = 0; i < 3; i++) {
|
||||
nextObj = newIterator.next();
|
||||
assertUndefined(nextObj.value);
|
||||
assertTrue(nextObj.done);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user