Commit 3624982c authored by oliver@apple.com's avatar oliver@apple.com

Bug 25229: Need support for Array.prototype.reduceRight

<https://bugs.webkit.org/show_bug.cgi?id=25229>

Reviewed by Gavin Barraclough.

Implement Array.reduceRight


git-svn-id: svn://svn.chromium.org/blink/trunk@42570 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 7d56968b
2009-04-15 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough.
Bug 25229: Need support for Array.prototype.reduceRight
<https://bugs.webkit.org/show_bug.cgi?id=25229>
Implement Array.reduceRight
* runtime/ArrayPrototype.cpp:
(JSC::arrayProtoFuncReduceRight):
2009-04-15 Oliver Hunt <oliver@apple.com> 2009-04-15 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough. Reviewed by Gavin Barraclough.
...@@ -58,6 +58,7 @@ static JSValuePtr arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const ...@@ -58,6 +58,7 @@ static JSValuePtr arrayProtoFuncIndexOf(ExecState*, JSObject*, JSValuePtr, const
static JSValuePtr arrayProtoFuncFilter(ExecState*, JSObject*, JSValuePtr, const ArgList&); static JSValuePtr arrayProtoFuncFilter(ExecState*, JSObject*, JSValuePtr, const ArgList&);
static JSValuePtr arrayProtoFuncMap(ExecState*, JSObject*, JSValuePtr, const ArgList&); static JSValuePtr arrayProtoFuncMap(ExecState*, JSObject*, JSValuePtr, const ArgList&);
static JSValuePtr arrayProtoFuncReduce(ExecState*, JSObject*, JSValuePtr, const ArgList&); static JSValuePtr arrayProtoFuncReduce(ExecState*, JSObject*, JSValuePtr, const ArgList&);
static JSValuePtr arrayProtoFuncReduceRight(ExecState*, JSObject*, JSValuePtr, const ArgList&);
static JSValuePtr arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&); static JSValuePtr arrayProtoFuncLastIndexOf(ExecState*, JSObject*, JSValuePtr, const ArgList&);
} }
...@@ -107,6 +108,7 @@ const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::a ...@@ -107,6 +108,7 @@ const ClassInfo ArrayPrototype::info = {"Array", &JSArray::info, 0, ExecState::a
lastIndexOf arrayProtoFuncLastIndexOf DontEnum|Function 1 lastIndexOf arrayProtoFuncLastIndexOf DontEnum|Function 1
filter arrayProtoFuncFilter DontEnum|Function 1 filter arrayProtoFuncFilter DontEnum|Function 1
reduce arrayProtoFuncReduce DontEnum|Function 1 reduce arrayProtoFuncReduce DontEnum|Function 1
reduceRight arrayProtoFuncReduceRight DontEnum|Function 1
map arrayProtoFuncMap DontEnum|Function 1 map arrayProtoFuncMap DontEnum|Function 1
@end @end
*/ */
...@@ -843,6 +845,75 @@ JSValuePtr arrayProtoFuncReduce(ExecState* exec, JSObject*, JSValuePtr thisValue ...@@ -843,6 +845,75 @@ JSValuePtr arrayProtoFuncReduce(ExecState* exec, JSObject*, JSValuePtr thisValue
return rv; return rv;
} }
JSValuePtr arrayProtoFuncReduceRight(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{
JSObject* thisObj = thisValue.toThisObject(exec);
JSValuePtr function = args.at(exec, 0);
CallData callData;
CallType callType = function.getCallData(callData);
if (callType == CallTypeNone)
return throwError(exec, TypeError);
unsigned i = 0;
JSValuePtr rv;
unsigned length = thisObj->get(exec, exec->propertyNames().length).toUInt32(exec);
if (!length && args.size() == 1)
return throwError(exec, TypeError);
JSArray* array = 0;
if (isJSArray(&exec->globalData(), thisObj))
array = asArray(thisObj);
if (args.size() >= 2)
rv = args.at(exec, 1);
else if (array && array->canGetIndex(length - 1)){
rv = array->getIndex(length - 1);
i = 1;
} else {
for (i = 0; i < length; i++) {
rv = getProperty(exec, thisObj, length - i - 1);
if (rv)
break;
}
if (!rv)
return throwError(exec, TypeError);
i++;
}
if (callType == CallTypeJS && array) {
CachedCall cachedCall(exec, asFunction(function), 4, exec->exceptionSlot());
for (; i < length && !exec->hadException(); ++i) {
unsigned idx = length - i - 1;
cachedCall.setThis(jsNull());
cachedCall.setArgument(0, rv);
if (UNLIKELY(!array->canGetIndex(idx)))
break; // length has been made unsafe while we enumerate fallback to slow path
cachedCall.setArgument(1, array->getIndex(idx));
cachedCall.setArgument(2, jsNumber(exec, idx));
cachedCall.setArgument(3, array);
rv = cachedCall.call();
}
if (i == length) // only return if we reached the end of the array
return rv;
}
for (; i < length && !exec->hadException(); ++i) {
unsigned idx = length - i - 1;
JSValuePtr prop = getProperty(exec, thisObj, idx);
if (!prop)
continue;
ArgList eachArguments;
eachArguments.append(rv);
eachArguments.append(prop);
eachArguments.append(jsNumber(exec, idx));
eachArguments.append(thisObj);
rv = call(exec, function, callType, callData, jsNull(), eachArguments);
}
return rv;
}
JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args) JSValuePtr arrayProtoFuncIndexOf(ExecState* exec, JSObject*, JSValuePtr thisValue, const ArgList& args)
{ {
// JavaScript 1.5 Extension by Mozilla // JavaScript 1.5 Extension by Mozilla
......
2009-04-15 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough.
Bug 25229: Need support for Array.prototype.reduceRight
<https://bugs.webkit.org/show_bug.cgi?id=25229>
Add test coverage for Array.reduceRight
* fast/js/array-enumerators-functions-expected.txt:
* fast/js/array-reduceRight-expected.txt: Added.
* fast/js/array-reduceRight.html: Added.
* fast/js/resources/array-enumerators-functions.js:
* fast/js/resources/array-reduceRight.js: Added.
2009-04-15 Oliver Hunt <oliver@apple.com> 2009-04-15 Oliver Hunt <oliver@apple.com>
Reviewed by Gavin Barraclough. Reviewed by Gavin Barraclough.
......
This test checks the behavior of the reduceRight() method on a number of objects.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS [0,1,2,3].reduceRight(function(a,b){ return a + b; }) is 6
PASS [1,2,3].reduceRight(function(a,b){ return a + b; }) is 6
PASS [0,1,2,3].reduceRight(function(a,b){ return a + b; }, 4) is 10
PASS [1,2,3].reduceRight(function(a,b){ return a + b; }, 4) is 10
PASS toObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; }) is 6
PASS toObject([1,2,3]).reduceRight(function(a,b){ return a + b; }) is 6
PASS toObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; }, 4) is 10
PASS toObject([1,2,3]).reduceRight(function(a,b){ return a + b; }, 4) is 10
PASS toUnorderedObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; }) is 6
PASS toUnorderedObject([1,2,3]).reduceRight(function(a,b){ return a + b; }) is 6
PASS toUnorderedObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; }, 4) is 10
PASS toUnorderedObject([1,2,3]).reduceRight(function(a,b){ return a + b; }, 4) is 10
PASS sparseArray.reduceRight(function(a,b){ return a + b; }, 0) is 10
PASS toObject(sparseArray).reduceRight(function(a,b){ return a + b; }, 0) is 10
PASS sparseArray.reduceRight(function(a,b){ callCount++; }); callCount is 0
PASS toObject(sparseArray).reduceRight(function(a,b){ callCount++; }); callCount is 0
PASS sparseArray.reduceRight(function(a,b){ callCount++; }, 0); callCount is 1
PASS toObject(sparseArray).reduceRight(function(a,b){ callCount++; }, 0); callCount is 1
PASS [0,1,2,3,4].reduceRight(function(a,b){ callCount++; }, 0); callCount is 5
PASS [0,1,2,3,4].reduceRight(function(a,b){ callCount++; }); callCount is 4
PASS [1, 2, 3, 4].reduceRight(function(a,b, i, thisObj){ thisObj.length--; callCount++; return a + b; }, 0); callCount is 4
PASS [1, 2, 3, 4].reduceRight(function(a,b, i, thisObj){ thisObj.length = 1; callCount++; return a + b; }, 0); callCount is 2
PASS [1, 2, 3, 4].reduceRight(function(a,b, i, thisObj){ thisObj.length++; callCount++; return a + b; }, 0); callCount is 4
PASS toObject([1, 2, 3, 4]).reduceRight(function(a,b, i, thisObj){ thisObj.length--; callCount++; return a + b; }, 0); callCount is 4
PASS toObject([1, 2, 3, 4]).reduceRight(function(a,b, i, thisObj){ thisObj.length++; callCount++; return a + b; }, 0); callCount is 4
PASS [[0,1], [2,3], [4,5]].reduceRight(function(a,b) {return a.concat(b);}, []) is [4,5,2,3,0,1]
PASS toObject([[0,1], [2,3], [4,5]]).reduceRight(function(a,b) {return a.concat(b);}, []) is [4,5,2,3,0,1]
PASS toObject([0,1,2,3,4,5]).reduceRight(function(a,b,i) {return a.concat([i,b]);}, []) is [5,5,4,4,3,3,2,2,1,1,0,0]
PASS toUnorderedObject([[0,1], [2,3], [4,5]]).reduceRight(function(a,b) {return a.concat(b);}, []) is [4,5,2,3,0,1]
PASS toUnorderedObject([0,1,2,3,4,5]).reduceRight(function(a,b,i) {return a.concat([i,b]);}, []) is [5,5,4,4,3,3,2,2,1,1,0,0]
PASS [0,1,2,3,4,5].reduceRight(function(a,b,i) {return a.concat([i,b]);}, []) is [5,5,4,4,3,3,2,2,1,1,0,0]
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<link rel="stylesheet" href="resources/js-test-style.css">
<script src="resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<div id="console"></div>
<script src="resources/array-reduceRight.js"></script>
<script src="resources/js-test-post.js"></script>
</body>
</html>
...@@ -2,14 +2,15 @@ description( ...@@ -2,14 +2,15 @@ description(
"This test checks the behavior of the various array enumeration functions in certain edge case scenarios" "This test checks the behavior of the various array enumeration functions in certain edge case scenarios"
); );
var functions = ["every", "forEach", "some", "filter", "reduce", "map"]; var functions = ["every", "forEach", "some", "filter", "reduce", "map", "reduceRight"];
var forwarders = [ var forwarders = [
function(elem, index, array) { return currentFunc.call(this, elem, index, array); }, function(elem, index, array) { return currentFunc.call(this, elem, index, array); },
function(elem, index, array) { return currentFunc.call(this, elem, index, array); }, function(elem, index, array) { return currentFunc.call(this, elem, index, array); },
function(elem, index, array) { return currentFunc.call(this, elem, index, array); }, function(elem, index, array) { return currentFunc.call(this, elem, index, array); },
function(elem, index, array) { return currentFunc.call(this, elem, index, array); }, function(elem, index, array) { return currentFunc.call(this, elem, index, array); },
function(prev, elem, index, array) { return currentFunc.call(this, elem, index, array); }, function(prev, elem, index, array) { return currentFunc.call(this, elem, index, array); },
function(elem, index, array) { return currentFunc.call(this, elem, index, array); } function(elem, index, array) { return currentFunc.call(this, elem, index, array); },
function(prev, elem, index, array) { return currentFunc.call(this, elem, index, array); }
]; ];
function toObject(array) { function toObject(array) {
...@@ -35,8 +36,9 @@ function returnElem(elem) { count++; return elem; } ...@@ -35,8 +36,9 @@ function returnElem(elem) { count++; return elem; }
function returnIndex(a, index) { if (lastIndex >= index) throw "Unordered traversal"; lastIndex = index; count++; return index; } function returnIndex(a, index) { if (lastIndex >= index) throw "Unordered traversal"; lastIndex = index; count++; return index; }
function increaseLength(a, b, array) { count++; array.length++; } function increaseLength(a, b, array) { count++; array.length++; }
function decreaseLength(a, b, array) { count++; array.length--; } function decreaseLength(a, b, array) { count++; array.length--; }
function halveLength(a, b, array) { count++; if (!array.halved) array.length = (array.length / 2) | 0; array.halved = true; }
var testFunctions = ["returnFalse", "returnTrue", "returnElem", "returnIndex", "increaseLength", "decreaseLength"]; var testFunctions = ["returnFalse", "returnTrue", "returnElem", "returnIndex", "increaseLength", "decreaseLength", "halveLength"];
var simpleArray = [0,1,2,3,4,5]; var simpleArray = [0,1,2,3,4,5];
var emptyArray = []; var emptyArray = [];
...@@ -60,6 +62,8 @@ for (var f = 0; f < functions.length; f++) { ...@@ -60,6 +62,8 @@ for (var f = 0; f < functions.length; f++) {
currentFunc = this[testFunctions[t]]; currentFunc = this[testFunctions[t]];
if (arrays[a] === "largeEmptyArray" && functionName === "map") if (arrays[a] === "largeEmptyArray" && functionName === "map")
continue; continue;
if (currentFunc === returnIndex && functionName === "reduceRight")
continue;
shouldBe("count=0;lastIndex=-1;copyArray("+arrays[a]+")."+functionName+"(forwarders[f], "+testFunctions[t]+", 0)", shouldBe("count=0;lastIndex=-1;copyArray("+arrays[a]+")."+functionName+"(forwarders[f], "+testFunctions[t]+", 0)",
"count=0;lastIndex=-1;Array.prototype."+functionName+".call(toObject("+arrays[a]+"), forwarders[f], "+testFunctions[t]+", 0)"); "count=0;lastIndex=-1;Array.prototype."+functionName+".call(toObject("+arrays[a]+"), forwarders[f], "+testFunctions[t]+", 0)");
} }
...@@ -74,6 +78,8 @@ for (var f = 0; f < functions.length; f++) { ...@@ -74,6 +78,8 @@ for (var f = 0; f < functions.length; f++) {
currentFunc = this[testFunctions[t]]; currentFunc = this[testFunctions[t]];
if (arrays[a] === "largeEmptyArray" && functionName === "map") if (arrays[a] === "largeEmptyArray" && functionName === "map")
continue; continue;
if (currentFunc === returnIndex && functionName === "reduceRight")
continue;
shouldBe("count=0;lastIndex=-1;copyArray("+arrays[a]+")."+functionName+"(forwarders[f], "+testFunctions[t]+", 0)", shouldBe("count=0;lastIndex=-1;copyArray("+arrays[a]+")."+functionName+"(forwarders[f], "+testFunctions[t]+", 0)",
"count=0;lastIndex=-1;Array.prototype."+functionName+".call(toUnorderedObject("+arrays[a]+"), forwarders[f], "+testFunctions[t]+", 0)"); "count=0;lastIndex=-1;Array.prototype."+functionName+".call(toUnorderedObject("+arrays[a]+"), forwarders[f], "+testFunctions[t]+", 0)");
} }
...@@ -82,26 +88,30 @@ for (var f = 0; f < functions.length; f++) { ...@@ -82,26 +88,30 @@ for (var f = 0; f < functions.length; f++) {
// Test number of function calls // Test number of function calls
var callCounts = [ var callCounts = [
[[1,0,0,1],[6,0,0,7],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,0,0,1]], [[1,0,0,1],[6,0,0,7],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,0,0,1]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6]], [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6],[3,0,0,6]],
[[6,0,0,7],[1,0,0,1],[2,0,0,2],[2,0,0,2],[6,0,0,7],[3,0,0,6]], [[6,0,0,7],[1,0,0,1],[2,0,0,2],[2,0,0,2],[6,0,0,7],[3,0,0,6],[3,0,0,6]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6]], [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6],[3,0,0,6]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6]], [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6],[3,0,0,6]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6]] [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[3,0,0,6],[3,0,0,6]],
]; [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[4,0,0,7]]
var objCallCounts = [ ];
[[1,0,0,1],[6,0,0,7],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,0,0,1]], var objCallCounts = [
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]], [[1,0,0,1],[6,0,0,7],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,0,0,1],[1,0,0,1]],
[[6,0,0,7],[1,0,0,1],[2,0,0,2],[2,0,0,2],[6,0,0,7],[6,0,0,7]], [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]], [[6,0,0,7],[1,0,0,1],[2,0,0,2],[2,0,0,2],[6,0,0,7],[6,0,0,7],[6,0,0,7]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]], [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]] [[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]],
[[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7],[6,0,0,7]]
]; ];
for (var f = 0; f < functions.length; f++) { for (var f = 0; f < functions.length; f++) {
for (var t = 0; t < testFunctions.length; t++) { for (var t = 0; t < testFunctions.length; t++) {
for (var a = 0; a < arrays.length; a++) { for (var a = 0; a < arrays.length; a++) {
var functionName = functions[f]; var functionName = functions[f];
currentFunc = this[testFunctions[t]]; currentFunc = this[testFunctions[t]];
if (currentFunc === returnIndex && functionName === "reduceRight")
continue;
var expectedCnt = "" + callCounts[f][t][a]; var expectedCnt = "" + callCounts[f][t][a];
shouldBe("count=0;lastIndex=-1;copyArray("+arrays[a]+")."+functionName+"(forwarders[f], "+testFunctions[t]+", 0); count", expectedCnt); shouldBe("count=0;lastIndex=-1;copyArray("+arrays[a]+")."+functionName+"(forwarders[f], "+testFunctions[t]+", 0); count", expectedCnt);
var expectedCnt = "" + objCallCounts[f][t][a]; var expectedCnt = "" + objCallCounts[f][t][a];
......
description(
"This test checks the behavior of the reduceRight() method on a number of objects."
);
function toObject(array) {
var o = {};
for (var i in array)
o[i] = array[i];
o.length = array.length;
o.reduceRight = Array.prototype.reduceRight;
return o;
}
function toUnorderedObject(array) {
var o = {};
var props = [];
for (var i in array)
props.push(i);
for (var i = props.length - 1; i >= 0; i--)
o[props[i]] = array[props[i]];
o.length = array.length;
o.reduceRight = Array.prototype.reduceRight;
return o;
}
shouldBe("[0,1,2,3].reduceRight(function(a,b){ return a + b; })", "6");
shouldBe("[1,2,3].reduceRight(function(a,b){ return a + b; })", "6");
shouldBe("[0,1,2,3].reduceRight(function(a,b){ return a + b; }, 4)", "10");
shouldBe("[1,2,3].reduceRight(function(a,b){ return a + b; }, 4)", "10");
shouldBe("toObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; })", "6");
shouldBe("toObject([1,2,3]).reduceRight(function(a,b){ return a + b; })", "6");
shouldBe("toObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; }, 4)", "10");
shouldBe("toObject([1,2,3]).reduceRight(function(a,b){ return a + b; }, 4)", "10");
shouldBe("toUnorderedObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; })", "6");
shouldBe("toUnorderedObject([1,2,3]).reduceRight(function(a,b){ return a + b; })", "6");
shouldBe("toUnorderedObject([0,1,2,3]).reduceRight(function(a,b){ return a + b; }, 4)", "10");
shouldBe("toUnorderedObject([1,2,3]).reduceRight(function(a,b){ return a + b; }, 4)", "10");
sparseArray = [];
sparseArray[10] = 10;
shouldBe("sparseArray.reduceRight(function(a,b){ return a + b; }, 0)", "10");
shouldBe("toObject(sparseArray).reduceRight(function(a,b){ return a + b; }, 0)", "10");
var callCount = 0;
shouldBe("sparseArray.reduceRight(function(a,b){ callCount++; }); callCount", "0");
callCount = 0;
shouldBe("toObject(sparseArray).reduceRight(function(a,b){ callCount++; }); callCount", "0");
var callCount = 0;
shouldBe("sparseArray.reduceRight(function(a,b){ callCount++; }, 0); callCount", "1");
callCount = 0;
shouldBe("toObject(sparseArray).reduceRight(function(a,b){ callCount++; }, 0); callCount", "1");
callCount = 0;
shouldBe("[0,1,2,3,4].reduceRight(function(a,b){ callCount++; }, 0); callCount", "5");
callCount = 0;
shouldBe("[0,1,2,3,4].reduceRight(function(a,b){ callCount++; }); callCount", "4");
callCount = 0;
shouldBe("[1, 2, 3, 4].reduceRight(function(a,b, i, thisObj){ thisObj.length--; callCount++; return a + b; }, 0); callCount", "4");
callCount = 0;
shouldBe("[1, 2, 3, 4].reduceRight(function(a,b, i, thisObj){ thisObj.length = 1; callCount++; return a + b; }, 0); callCount", "2");
callCount = 0;
shouldBe("[1, 2, 3, 4].reduceRight(function(a,b, i, thisObj){ thisObj.length++; callCount++; return a + b; }, 0); callCount", "4");
callCount = 0;
shouldBe("toObject([1, 2, 3, 4]).reduceRight(function(a,b, i, thisObj){ thisObj.length--; callCount++; return a + b; }, 0); callCount", "4");
callCount = 0;
shouldBe("toObject([1, 2, 3, 4]).reduceRight(function(a,b, i, thisObj){ thisObj.length++; callCount++; return a + b; }, 0); callCount", "4");
shouldBe("[[0,1], [2,3], [4,5]].reduceRight(function(a,b) {return a.concat(b);}, [])", "[4,5,2,3,0,1]");
shouldBe("toObject([[0,1], [2,3], [4,5]]).reduceRight(function(a,b) {return a.concat(b);}, [])", "[4,5,2,3,0,1]");
shouldBe("toObject([0,1,2,3,4,5]).reduceRight(function(a,b,i) {return a.concat([i,b]);}, [])", "[5,5,4,4,3,3,2,2,1,1,0,0]");
shouldBe("toUnorderedObject([[0,1], [2,3], [4,5]]).reduceRight(function(a,b) {return a.concat(b);}, [])", "[4,5,2,3,0,1]");
shouldBe("toUnorderedObject([0,1,2,3,4,5]).reduceRight(function(a,b,i) {return a.concat([i,b]);}, [])", "[5,5,4,4,3,3,2,2,1,1,0,0]");
shouldBe("[0,1,2,3,4,5].reduceRight(function(a,b,i) {return a.concat([i,b]);}, [])", "[5,5,4,4,3,3,2,2,1,1,0,0]");
successfullyParsed = true;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment