From ac9b0bfc1bcc76e4fc09d92173b39c8039ec4d6f Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 30 Jan 2016 00:52:08 -0800 Subject: [PATCH 01/31] Increment package version to enable ci tests. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bb4464c037..3dda1d6ea8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lodash", - "version": "4.1.0", + "version": "4.1.1-pre", "main": "lodash.js", "private": true, "devDependencies": { From 13659e87cb232d57ac89f52bc8f9076a33261ac0 Mon Sep 17 00:00:00 2001 From: Ivan Tanev Date: Sat, 30 Jan 2016 02:52:36 +0200 Subject: [PATCH 02/31] Ensure `_.attempt` preserves custom errors. --- lodash.js | 2 +- test/test.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lodash.js b/lodash.js index f0b0b6bbea..fdc5d7ab78 100644 --- a/lodash.js +++ b/lodash.js @@ -12926,7 +12926,7 @@ try { return apply(func, undefined, args); } catch (e) { - return isError(e) ? e : new Error(e); + return isObject(e) ? e : new Error(e); } }); diff --git a/test/test.js b/test/test.js index 78dcdaa228..9672c9647c 100644 --- a/test/test.js +++ b/test/test.js @@ -1482,6 +1482,20 @@ assert.ok(lodashStable.isEqual(actual, Error('x'))); }); + QUnit.test('should preserve custom errors', function(assert) { + assert.expect(1); + + function CustomError(message) { + this.name = 'CustomError'; + this.message = message; + } + + CustomError.prototype = lodashStable.create(Error.prototype); + + var actual = _.attempt(function() { throw new CustomError('x'); }); + assert.ok(actual instanceof CustomError); + }); + QUnit.test('should work with an error object from another realm', function(assert) { assert.expect(1); From 1f160b31ff009baffd44dba90c22888c149bcfca Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Fri, 29 Jan 2016 22:41:02 -0800 Subject: [PATCH 03/31] Make doc code sample comments match source comment style. [ci skip] --- lodash.js | 189 +++++++++++++++++++++++++++--------------------------- 1 file changed, 94 insertions(+), 95 deletions(-) diff --git a/lodash.js b/lodash.js index fdc5d7ab78..93cffa5450 100644 --- a/lodash.js +++ b/lodash.js @@ -1254,14 +1254,14 @@ * lodash.isFunction(lodash.bar); * // => true * - * // using `context` to mock `Date#getTime` use in `_.now` + * // Use `context` to mock `Date#getTime` use in `_.now`. * var mock = _.runInContext({ * 'Date': function() { * return { 'getTime': getTimeMock }; * } * }); * - * // or creating a suped-up `defer` in Node.js + * // Create a suped-up `defer` in Node.js. * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; */ function runInContext(context) { @@ -1451,11 +1451,11 @@ * * var wrapped = _([1, 2, 3]); * - * // returns an unwrapped value + * // Returns an unwrapped value. * wrapped.reduce(_.add); * // => 6 * - * // returns a wrapped value + * // Returns a wrapped value. * var squares = wrapped.map(square); * * _.isArray(squares); @@ -5471,7 +5471,7 @@ * _.differenceBy([3.1, 2.2, 1.3], [4.4, 2.5], Math.floor); * // => [3.1, 1.3] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); * // => [{ 'x': 2 }] */ @@ -5603,15 +5603,15 @@ * _.dropRightWhile(users, function(o) { return !o.active; }); * // => objects for ['barney'] * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); * // => objects for ['barney', 'fred'] * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.dropRightWhile(users, ['active', false]); * // => objects for ['barney'] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.dropRightWhile(users, 'active'); * // => objects for ['barney', 'fred', 'pebbles'] */ @@ -5643,15 +5643,15 @@ * _.dropWhile(users, function(o) { return !o.active; }); * // => objects for ['pebbles'] * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.dropWhile(users, { 'user': 'barney', 'active': false }); * // => objects for ['fred', 'pebbles'] * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.dropWhile(users, ['active', false]); * // => objects for ['pebbles'] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.dropWhile(users, 'active'); * // => objects for ['barney', 'fred', 'pebbles'] */ @@ -5722,15 +5722,15 @@ * _.findIndex(users, function(o) { return o.user == 'barney'; }); * // => 0 * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.findIndex(users, { 'user': 'fred', 'active': false }); * // => 1 * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.findIndex(users, ['active', false]); * // => 0 * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.findIndex(users, 'active'); * // => 2 */ @@ -5761,15 +5761,15 @@ * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); * // => 2 * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.findLastIndex(users, { 'user': 'barney', 'active': true }); * // => 0 * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.findLastIndex(users, ['active', false]); * // => 2 * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.findLastIndex(users, 'active'); * // => 0 */ @@ -5906,7 +5906,7 @@ * _.indexOf([1, 2, 1, 2], 2); * // => 1 * - * // using `fromIndex` + * // Search from the `fromIndex`. * _.indexOf([1, 2, 1, 2], 2, 2); * // => 3 */ @@ -5977,7 +5977,7 @@ * _.intersectionBy([2.1, 1.2], [4.3, 2.4], Math.floor); * // => [2.1] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }] */ @@ -6080,7 +6080,7 @@ * _.lastIndexOf([1, 2, 1, 2], 2); * // => 3 * - * // using `fromIndex` + * // Search from the `fromIndex`. * _.lastIndexOf([1, 2, 1, 2], 2, 2); * // => 1 */ @@ -6356,7 +6356,7 @@ * _.sortedIndexBy(['thirty', 'fifty'], 'forty', _.propertyOf(dict)); * // => 1 * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.sortedIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); * // => 0 */ @@ -6424,7 +6424,7 @@ * @returns {number} Returns the index at which `value` should be inserted into `array`. * @example * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.sortedLastIndexBy([{ 'x': 4 }, { 'x': 5 }], { 'x': 4 }, 'x'); * // => 1 */ @@ -6604,15 +6604,15 @@ * _.takeRightWhile(users, function(o) { return !o.active; }); * // => objects for ['fred', 'pebbles'] * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); * // => objects for ['pebbles'] * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.takeRightWhile(users, ['active', false]); * // => objects for ['fred', 'pebbles'] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.takeRightWhile(users, 'active'); * // => [] */ @@ -6644,15 +6644,15 @@ * _.takeWhile(users, function(o) { return !o.active; }); * // => objects for ['barney', 'fred'] * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.takeWhile(users, { 'user': 'barney', 'active': false }); * // => objects for ['barney'] * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.takeWhile(users, ['active', false]); * // => objects for ['barney', 'fred'] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.takeWhile(users, 'active'); * // => [] */ @@ -6697,7 +6697,7 @@ * _.unionBy([2.1, 1.2], [4.3, 2.4], Math.floor); * // => [2.1, 1.2, 4.3] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ @@ -6774,7 +6774,7 @@ * _.uniqBy([2.1, 1.2, 2.3], Math.floor); * // => [2.1, 1.2] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 1 }, { 'x': 2 }] */ @@ -6930,7 +6930,7 @@ * _.xorBy([2.1, 1.2], [4.3, 2.4], Math.floor); * // => [1.2, 4.3] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); * // => [{ 'x': 2 }] */ @@ -7188,11 +7188,11 @@ * { 'user': 'fred', 'age': 40 } * ]; * - * // without explicit chaining + * // A sequence without explicit chaining. * _(users).head(); * // => { 'user': 'barney', 'age': 36 } * - * // with explicit chaining + * // A sequence with explicit chaining. * _(users) * .chain() * .head() @@ -7447,15 +7447,15 @@ * { 'user': 'fred', 'active': false } * ]; * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.every(users, { 'user': 'barney', 'active': false }); * // => false * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.every(users, ['active', false]); * // => true * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.every(users, 'active'); * // => false */ @@ -7488,15 +7488,15 @@ * _.filter(users, function(o) { return !o.active; }); * // => objects for ['fred'] * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.filter(users, { 'age': 36, 'active': true }); * // => objects for ['barney'] * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.filter(users, ['active', false]); * // => objects for ['fred'] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.filter(users, 'active'); * // => objects for ['barney'] */ @@ -7527,15 +7527,15 @@ * _.find(users, function(o) { return o.age < 40; }); * // => object for 'barney' * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.find(users, { 'age': 1, 'active': true }); * // => object for 'pebbles' * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.find(users, ['active', false]); * // => object for 'fred' * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.find(users, 'active'); * // => object for 'barney' */ @@ -7649,7 +7649,7 @@ * _.groupBy([6.1, 4.2, 6.3], Math.floor); * // => { '4': [4.2], '6': [6.1, 6.3] } * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.groupBy(['one', 'two', 'three'], 'length'); * // => { '3': ['one', 'two'], '5': ['three'] } */ @@ -7805,7 +7805,7 @@ * { 'user': 'fred' } * ]; * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.map(users, 'user'); * // => ['barney', 'fred'] */ @@ -7837,7 +7837,7 @@ * { 'user': 'barney', 'age': 36 } * ]; * - * // sort by `user` in ascending order and by `age` in descending order + * // Sort by `user` in ascending order and by `age` in descending order. * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ @@ -7878,15 +7878,15 @@ * _.partition(users, function(o) { return o.active; }); * // => objects for [['fred'], ['barney', 'pebbles']] * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.partition(users, { 'age': 1, 'active': false }); * // => objects for [['pebbles'], ['barney', 'fred']] * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.partition(users, ['active', false]); * // => objects for [['barney', 'pebbles'], ['fred']] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.partition(users, 'active'); * // => objects for [['fred'], ['barney', 'pebbles']] */ @@ -7983,15 +7983,15 @@ * _.reject(users, function(o) { return !o.active; }); * // => objects for ['fred'] * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.reject(users, { 'age': 40, 'active': true }); * // => objects for ['barney'] * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.reject(users, ['active', false]); * // => objects for ['fred'] * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.reject(users, 'active'); * // => objects for ['barney'] */ @@ -8130,15 +8130,15 @@ * { 'user': 'fred', 'active': false } * ]; * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.some(users, { 'user': 'barney', 'active': false }); * // => false * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.some(users, ['active', false]); * // => true * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.some(users, 'active'); * // => true */ @@ -8338,7 +8338,7 @@ * bound('!'); * // => 'hi fred!' * - * // using placeholders + * // Bound with placeholders. * var bound = _.bind(greet, object, _, '!'); * bound('hi'); * // => 'hi fred!' @@ -8391,7 +8391,7 @@ * bound('!'); * // => 'hiya fred!' * - * // using placeholders + * // Bound with placeholders. * var bound = _.bindKey(object, 'greet', _, '!'); * bound('hi'); * // => 'hiya fred!' @@ -8441,7 +8441,7 @@ * curried(1, 2, 3); * // => [1, 2, 3] * - * // using placeholders + * // Curried with placeholders. * curried(1)(_, 3)(2); * // => [1, 2, 3] */ @@ -8485,7 +8485,7 @@ * curried(1, 2, 3); * // => [1, 2, 3] * - * // using placeholders + * // Curried with placeholders. * curried(3)(1, _)(2); * // => [1, 2, 3] */ @@ -8528,21 +8528,21 @@ * @returns {Function} Returns the new debounced function. * @example * - * // avoid costly calculations while the window size is in flux + * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * - * // invoke `sendMail` when clicked, debouncing subsequent calls + * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * - * // ensure `batchLog` is invoked once after 1 second of debounced calls + * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * - * // cancel a trailing debounced invocation + * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { @@ -8675,7 +8675,7 @@ * _.defer(function(text) { * console.log(text); * }, 'deferred'); - * // logs 'deferred' after one or more milliseconds + * // => logs 'deferred' after one or more milliseconds */ var defer = rest(function(func, args) { return baseDelay(func, 1, args); @@ -8758,12 +8758,12 @@ * values(object); * // => [1, 2] * - * // modifying the result cache + * // Modify the result cache. * values.cache.set(object, ['a', 'b']); * values(object); * // => ['a', 'b'] * - * // replacing `_.memoize.Cache` + * // Replace `_.memoize.Cache`. * _.memoize.Cache = WeakMap; */ function memoize(func, resolver) { @@ -8908,7 +8908,7 @@ * sayHelloTo('fred'); * // => 'hello fred' * - * // using placeholders + * // Partially applied with placeholders. * var greetFred = _.partial(greet, _, 'fred'); * greetFred('hi'); * // => 'hi fred' @@ -8944,7 +8944,7 @@ * greetFred('hi'); * // => 'hi fred' * - * // using placeholders + * // Partially applied with placeholders. * var sayHelloTo = _.partialRight(greet, 'hello', _); * sayHelloTo('fred'); * // => 'hello fred' @@ -9051,7 +9051,6 @@ * say(['fred', 'hello']); * // => 'fred says hello' * - * // with a Promise * var numbers = Promise.all([ * Promise.resolve(40), * Promise.resolve(36) @@ -9101,14 +9100,14 @@ * @returns {Function} Returns the new throttled function. * @example * - * // avoid excessively updating the position while scrolling + * // Avoid excessively updating the position while scrolling. * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); * - * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes + * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); * jQuery(element).on('click', throttled); * - * // cancel a trailing throttled invocation + * // Cancel the trailing throttled invocation. * jQuery(window).on('popstate', throttled.cancel); */ function throttle(func, wait, options) { @@ -10727,15 +10726,15 @@ * _.findKey(users, function(o) { return o.age < 40; }); * // => 'barney' (iteration order is not guaranteed) * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.findKey(users, { 'age': 1, 'active': true }); * // => 'pebbles' * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.findKey(users, ['active', false]); * // => 'fred' * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.findKey(users, 'active'); * // => 'barney' */ @@ -10764,15 +10763,15 @@ * _.findLastKey(users, function(o) { return o.age < 40; }); * // => returns 'pebbles' assuming `_.findKey` returns 'barney' * - * // using the `_.matches` iteratee shorthand + * // The `_.matches` iteratee shorthand. * _.findLastKey(users, { 'age': 36, 'active': true }); * // => 'barney' * - * // using the `_.matchesProperty` iteratee shorthand + * // The `_.matchesProperty` iteratee shorthand. * _.findLastKey(users, ['active', false]); * // => 'fred' * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.findLastKey(users, 'active'); * // => 'pebbles' */ @@ -11245,7 +11244,7 @@ * _.mapValues(users, function(o) { return o.age; }); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) * - * // using the `_.property` iteratee shorthand + * // The `_.property` iteratee shorthand. * _.mapValues(users, 'age'); * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ @@ -12409,54 +12408,54 @@ * @returns {Function} Returns the compiled template function. * @example * - * // using the "interpolate" delimiter to create a compiled template + * // Use the "interpolate" delimiter to create a compiled template. * var compiled = _.template('hello <%= user %>!'); * compiled({ 'user': 'fred' }); * // => 'hello fred!' * - * // using the HTML "escape" delimiter to escape data property values + * // Use the HTML "escape" delimiter to escape data property values. * var compiled = _.template('<%- value %>'); * compiled({ 'value': ' - + +