Merge pull request #20 from mgmeyers/Array.prototype.find

* mgmeyers/Array.prototype.find:
  Adds tests for Array.prototype.find
This commit is contained in:
Brian Terlson 2014-07-17 11:28:15 -07:00
commit 0efbedeaa1
14 changed files with 304 additions and 0 deletions

View File

@ -0,0 +1,30 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Array.prototype.find shouldn't throw a TypeError if IsCallable(predicate) is true
*/
var callableValues = [
function () {},
Array.prototype.forEach,
Proxy,
new Proxy(function () {}, function () {}),
x => x
];
function testcase() {
for (var i = 0, len = callableValues.length; i < len; i++) {
try {
[].find(callableValues[i]);
} catch (e) {
if (e instanceof TypeError) {
return false;
}
}
}
return true;
}
runTestCase(testcase);

View File

@ -0,0 +1,15 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Find on empty array should return undefined
*/
var a = [].find(function () {
return true;
});
if (a !== undefined) {
$ERROR('#1: a !== undefined. Actual: ' + typeof a);
}

View File

@ -0,0 +1,11 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description The length property of the find method is 1
*/
if ([].find.length !== 1) {
$ERROR('1: [].find.length !== 1. Actual: ' + [].find.length);
}

View File

@ -0,0 +1,28 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Array may be mutated by calls to the predicate
*/
[1, 2, 3].find(function (v, i, arr) {
arr[i + 1] = arr[i + 1] + 1;
switch (i) {
case 0:
if (arr[i] !== 1) {
$ERROR('#1: arr[0] !== 1. Actual: ' + arr[i]);
}
break;
case 1:
if (arr[i] !== 3) {
$ERROR('#2: arr[1] !== 3. Actual: ' + arr[i]);
}
break;
case 2:
if (arr[i] !== 4) {
$ERROR('#3: arr[1] !== 4. Actual: ' + arr[i]);
}
break;
}
});

View File

@ -0,0 +1,13 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Find with a predicate with no return value should return undefined
*/
var a = [1, 2, 3].find(function () {});
if (a !== undefined) {
$ERROR('#1: a !== undefined. Actual: ' + typeof a);
}

View File

@ -0,0 +1,33 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Array.prototype.find should throw a TypeError if IsCallable(predicate) is false
*/
var uncallableValues = [
undefined,
null,
true,
this,
{},
'string',
0
];
function testcase() {
for (var i = 0, len = uncallableValues.length; i < len; i++) {
try {
[].find(uncallableValues[i]);
return false;
} catch (e) {
if (!(e instanceof TypeError)) {
return false;
}
}
}
return true;
}
runTestCase(testcase);

View File

@ -0,0 +1,24 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description predicate is called with three arguments: the value of the element, the index of the element, and the object being traversed.
*/
var a = [1];
var b = a.find(function (v, i, arr) {
if (arguments.length !== 3) {
$ERROR('#1: arguments.length !== 3. Actual: ' + arguments.length);
}
if (v !== 1) {
$ERROR('#2: element value !== 1. Actual: ' + v);
}
if (i !== 0) {
$ERROR('#3: index !== 0. Actual: ' + i);
}
if (arr !== a) {
$ERROR('#4: object being traversed !== a');
}
});

View File

@ -0,0 +1,14 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Elements added to array after find has been called should not be visited
*/
[1].find(function (v, i, arr) {
arr.push('string');
if (v === 'string') {
$ERROR('#' + i + ': \'string\' should not be visited');
}
});

View File

@ -0,0 +1,29 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Elements removed from array after find has been called should not be visited
*/
[1, 'string', 2].find(function (v, i, arr) {
var stringIndex = arr.indexOf('string');
if (stringIndex !== -1) delete arr[stringIndex];
if (v === 'string') {
$ERROR('#1: \'string\' should not exist, it has been deleted');
}
if (v === undefined) {
$ERROR('#2: deleted element should not be visited');
}
});
[1, 'string', 2].find(function (v, i, arr) {
var stringIndex = arr.indexOf('string');
if (stringIndex !== -1) arr.splice(stringIndex, 1);
if (v === 'string') {
$ERROR('#3: \'string\' should not exist, it has been deleted');
}
if (v === undefined) {
$ERROR('#4: deleted element should not be visited');
}
});

View File

@ -0,0 +1,29 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Find should return value if predicate returns true
*/
var testVals = [
undefined,
null,
0,
'string',
String,
this,
true,
[1,2,3]
];
var a;
for (var i = 0, len = testVals.length; i < len; i++) {
a = testVals.find(function (v) {
return v === testVals[i];
});
if (a !== testVals[i]) {
$ERROR('#' + (i + 1) + ': a !== testVals[' + i + ']. Actual: ' + a);
}
}

View File

@ -0,0 +1,20 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description predicate is called only for elements of the array which actually exist; it is not called for missing elements of the array
*/
var a = [];
a[10] = 1;
a[11] = 2;
var b = a.find(function (v) {
return v !== 1;
});
if (b !== 2) {
$ERROR('#1: b !== 2. Actual: ' + b);
}

View File

@ -0,0 +1,18 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description thisArg should be bound to this if provided
*/
var globalThis = this;
[1].find(function () {
if (this !== Array) {
$ERROR('#1: this !== Array');
}
if (this === globalThis) {
$ERROR('#2: this === globalThis. Should be Array');
}
}, Array);

View File

@ -0,0 +1,25 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description Array.prototype.find should convert thisArg into an object
*/
var dataTypes = [
undefined,
null,
true,
this,
{},
'string',
0,
function () {}
]
for (var i = 0, len = dataTypes.length; i < len; i++) {
[1].find(function () {
if (!(this instanceof Object)) {
$ERROR('#' + i + ': !(this instanceof Object). Actual: ' + typeof this);
}
}, dataTypes[i])
}

View File

@ -0,0 +1,15 @@
// Copyright (c) 2014 Matthew Meyers. All rights reserved.
// This code is governed by the BSD license found in the LICENSE file.
/**
* @path
* @description thisArg should be undefined if not provided
*/
var globalThis = this;
[1].find(function () {
if (this !== globalThis) {
$ERROR('#1: this !== globalThis');
}
});