From 0e60831f46b863b3c5d7f5c0446f92f0bef232c3 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Mon, 14 Jul 2014 08:59:28 -0700 Subject: [PATCH] Remove `sliceBuffer`, add typed array tests, and ensure typed array clones have the correct `byteOffset` and `length`. --- lodash.js | 62 ++++++++++++++++++---------------------------------- test/test.js | 47 +++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 62 deletions(-) diff --git a/lodash.js b/lodash.js index d484660ed..8004334a5 100644 --- a/lodash.js +++ b/lodash.js @@ -1427,8 +1427,7 @@ if (Ctor instanceof Ctor) { Ctor = ctorByClass[className]; } - - return new Ctor(sliceBuffer(value.buffer, value.byteOffset, value.length * Ctor.BYTES_PER_ELEMENT)); + return new Ctor(cloneBuffer(value.buffer), value.byteOffset, value.length); case numberClass: case stringClass: @@ -2904,7 +2903,26 @@ * @returns {ArrayBuffer} Returns the cloned array buffer. */ function cloneBuffer(buffer) { - return sliceBuffer(buffer, 0); + return bufferSlice.call(buffer, 0); + } + if (!bufferSlice) { + // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array` + cloneBuffer = !(ArrayBuffer && Uint8Array) ? identity : function(buffer) { + var byteLength = buffer.byteLength, + floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, + offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, + result = new ArrayBuffer(byteLength); + + if (floatLength) { + var view = new Float64Array(result, 0, floatLength); + view.set(new Float64Array(buffer, 0, floatLength)); + } + if (byteLength != offset) { + view = new Uint8Array(result, offset); + view.set(new Uint8Array(buffer, offset)); + } + return result; + }; } /** @@ -2993,44 +3011,6 @@ return result; } - /** - * Slices the given array buffer from the `start` index up to, but not including, the `end` index. - * - * @private - * @param {ArrayBuffer} buffer The array buffer to slice. - * @param {number} [start=0] The start index. - * @param {number} [end=buffer.byteLength] The end index. - * @returns {ArrayBuffer} Returns the slice of `buffer`. - */ - function sliceBuffer(buffer, start, end) { - typeof start == 'number' || (start = 0); - typeof end == 'number' || (end = buffer.byteLength); - return bufferSlice.call(buffer, start, end); - } - if (!bufferSlice) { - // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array` - sliceBuffer = !(ArrayBuffer && Uint8Array) ? identity : function(buffer, start, end) { - typeof start == 'number' || (start = 0); - typeof end == 'number' || (end = buffer.byteLength); - - var byteLength = end - start, - floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, - offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, - result = new ArrayBuffer(byteLength); - - if (floatLength) { - var view = new Float64Array(result, 0, floatLength); - view.set(new Float64Array(buffer, start, floatLength)); - } - if (byteLength != offset) { - offset += start; - view = new Uint8Array(result, offset); - view.set(new Uint8Array(buffer, offset)); - } - return result; - }; - } - /** * An implementation of `_.uniq` optimized for sorted arrays without support * for callback shorthands and `this` binding. diff --git a/test/test.js b/test/test.js index 88ba459f2..9dde72d15 100644 --- a/test/test.js +++ b/test/test.js @@ -1460,23 +1460,6 @@ }); }); - _.each(typedArrays, function(type) { - test('`_.' + methodName + '` should clone ' + type + ' arrays', 3, function() { - var Ctor = root[type]; - if (Ctor) { - var array = new Ctor(new ArrayBuffer(8)), - actual = func(array); - - deepEqual(actual, array); - notStrictEqual(actual, array); - notStrictEqual(actual.buffer, array.buffer); - } - else { - skipTest(3); - } - }); - }); - test('`_.' + methodName + '` should clone array buffers', 2, function() { var buffer = ArrayBuffer && new ArrayBuffer(8); if (buffer) { @@ -1489,6 +1472,28 @@ } }); + _.each(typedArrays, function(type) { + test('`_.' + methodName + '` should clone ' + type + ' arrays', 10, function() { + var Ctor = root[type]; + if (Ctor) { + var array = new Ctor(new ArrayBuffer(24)); + + _.times(2, function(index) { + var actual = index ? func(array, 8, 1) : func(array); + + deepEqual(actual, array); + notStrictEqual(actual, array); + notStrictEqual(actual.buffer, array.buffer); + strictEqual(actual.byteOffset, array.byteOffset); + strictEqual(actual.length, array.length); + }); + } + else { + skipTest(10); + } + }); + }); + test('`_.' + methodName + '` should clone problem JScript properties (test in IE < 9)', 2, function() { var actual = func(shadowedObject); deepEqual(actual, shadowedObject); @@ -7454,8 +7459,8 @@ }, 32); } else { - skipTest(); - QUnit.start(); + skipTest(); + QUnit.start(); } }); }()); @@ -9788,8 +9793,8 @@ test('should work with templates containing newlines and comments', 1, function() { var compiled = _.template('<%\n\ - // comment\n\ - if (value) { value += 3; }\n\ + // comment\n\ + if (value) { value += 3; }\n\ %>

<%= value %>

' );