sugar
Version:
A Javascript library for working with native objects.
877 lines (682 loc) • 154 kB
JavaScript
test('Array', function () {
var arr, expected, expectedIndexes, count, f1 = function(){}, f2 = function(){};
var sparseArraySupport = 0 in [undefined];
// Using [] or the constructor "new Array" will cause this test to fail in IE7/8. Evidently passing undefined to the
// constructor will not push undefined as expected, however the length property will still appear as if it was pushed.
// arr = [undefined, undefined, undefined];
//
// However we can do it this way, which is a much more likely user scenario in any case:
var arrayOfUndefined = [];
arrayOfUndefined.push(undefined);
arrayOfUndefined.push(undefined);
arrayOfUndefined.push(undefined);
arr = [1,2,3];
count = 0;
for(var key in arr){
count++;
}
equalWithWarning(count, 3, 'for..in loops will break on arrays.');
equal(['a','b','c'].indexOf('b'), 1, 'Array#indexOf | b in a,b,c');
equal(['a','b','c'].indexOf('b', 0), 1, 'Array#indexOf | b in a,b,c from 0');
equal(['a','b','c'].indexOf('a'), 0, 'Array#indexOf | a in a,b,c');
equal(['a','b','c'].indexOf('f'), -1, 'Array#indexOf | f in a,b,c');
equal(['a','b','c','b'].indexOf('b'), 1, 'Array#indexOf | finds first instance');
equal(['a','b','c','b'].indexOf('b', 2), 3, 'Array#indexOf | finds first instance from index');
equal([5,2,4].indexOf(5), 0, 'Array#indexOf | 5 in 5,2,4');
equal([5,2,4].indexOf(2), 1, 'Array#indexOf | 2 in 5,2,4');
equal([5,2,4].indexOf(4), 2, 'Array#indexOf | 4 in 5,2,4');
equal([5,2,4,4].indexOf(4, 3), 3, 'Array#indexOf | 4 in 5,2,4,4 from index 3');
equal([5,2,4,4].indexOf(4, 10), -1, 'Array#indexOf | 4 in 5,2,4,4 from index 10');
equal([5,2,4,4].indexOf(4, -10), 2, 'Array#indexOf | 4 in 5,2,4,4 from index -10');
equal([5,2,4,4].indexOf(4, -1), 3, 'Array#indexOf | 4 in 5,2,4,4 from index -1');
equal([{ foo: 'bar' }].indexOf({ foo: 'bar' }), -1, 'Array#indexOf | will not find deep objects (use findIndex)');
equal([{ foo: 'bar' }].indexOf(function(a) { return a.foo === 'bar'; }), -1, 'Array#indexOf | will not run against a function (use findIndex)');
equal(['a','b','c','d','a','b'].lastIndexOf('b'), 5, 'Array#lastIndexOf | b');
equal(['a','b','c','d','a','b'].lastIndexOf('b', 4), 1, 'Array#lastIndexOf | b from index 4');
equal(['a','b','c','d','a','b'].lastIndexOf('z'), -1, 'Array#lastIndexOf | z');
equal([1,5,6,8,8,2,5,3].lastIndexOf(3), 7, 'Array#lastIndexOf | 1,5,6,8,8,2,5,3 | 3');
equal([1,5,6,8,8,2,5,3].lastIndexOf(3, 0), -1, 'Array#lastIndexOf | 1,5,6,8,8,2,5,3 | 3 from index 0');
equal([1,5,6,8,8,2,5,3].lastIndexOf(8), 4, 'Array#lastIndexOf | 1,5,6,8,8,2,5,3 | 8');
equal([1,5,6,8,8,2,5,3].lastIndexOf(8, 3), 3, 'Array#lastIndexOf | 1,5,6,8,8,2,5,3 | 8 from index 3');
equal([1,5,6,8,8,2,5,3].lastIndexOf(1), 0, 'Array#lastIndexOf | 1,5,6,8,8,2,5,3 | 1');
equal([1,5,6,8,8,2,5,3].lastIndexOf(42), -1, 'Array#lastIndexOf | 1,5,6,8,8,2,5,3 | 42');
equal([2,5,9,2].lastIndexOf(2), 3, 'Array#lastIndexOf | 2,5,9,2 | 2');
equal([2,5,9,2].lastIndexOf(7), -1, 'Array#lastIndexOf | 2,5,9,2 | 7');
equal([2,5,9,2].lastIndexOf(2, 3), 3, 'Array#lastIndexOf | 2,5,9,2 | 2 from index 3');
equal([2,5,9,2].lastIndexOf(2, 2), 0, 'Array#lastIndexOf | 2,5,9,2 | 2 from index 2');
equal([2,5,9,2].lastIndexOf(2, -2), 0, 'Array#lastIndexOf | 2,5,9,2 | 2 from index -2');
equal([2,5,9,2].lastIndexOf(2, -1), 3, 'Array#lastIndexOf | 2,5,9,2 | 2 from index -1');
equal([2,5,9,2].lastIndexOf(2, -10), -1, 'Array#lastIndexOf | 2,5,9,2 | 2 from index -10');
// Prototype's "lastIndexOf" apparently doesn't pass this particular test.
//equal([2,5,9,2].lastIndexOf(2, 10), 3, 'Array#lastIndexOf | 2,5,9,2 | 2 from index 10', { prototype: (jQuery.browser.msie ? 10 : 3) });
equal([{ foo: 'bar' }].lastIndexOf({ foo: 'bar' }), -1, 'Array#lastIndexOf | will not find deep objects (use findIndex)');
equal([{ foo: 'bar' }].lastIndexOf(function(a) { return a.foo === 'bar'; }), -1, 'Array#lastIndexOf | will not run against a function (use findIndex)');
equal([1,1,1].every(1), true, 'Array#every | accepts a number shortcut match');
equal([1,1,2].every(1), false, 'Array#every | accepts a number shortcut no match');
equal(['a','a','a'].every('a'), true, 'Array#every | accepts a string shortcut match');
equal(['a','b','a'].every('a'), false, 'Array#every | accepts a string shortcut no match');
equal(['a','b','c'].every(/[a-f]/), true, 'Array#every | accepts a regex shortcut match');
equal(['a','b','c'].every(/[m-z]/), false, 'Array#every | accepts a regex shortcut no match');
equal([{a:1},{a:1}].every({a:1}), true, 'Array#every | checks objects match');
equal([{a:1},{a:2}].every({a:1}), false, 'Array#every | checks object no match');
equal([12,5,8,130,44].every(function(el, i, a) { return el >= 10; }), false, 'Array#every | not every element is greater than 10');
equal([12,54,18,130,44].every(function(el, i, a) { return el >= 10; }), true, 'Array#every | every element is greater than 10');
equal(arrayOfUndefined.every(undefined), true, 'Array#every | all undefined');
equal(arrayOfUndefined.clone().add('a').every(undefined), false, 'Array#every | every undefined');
equal(['a', 'b'].every(undefined), false, 'Array#every | none undefined');
['a'].every(function(el, i, a) {
equal(el, 'a', 'Array#every | First parameter is the element');
equal(i, 0, 'Array#every | Second parameter is the index');
equal(a, ['a'], 'Array#every | Third parameter is the array', { prototype: undefined });
equal(this.toString(), 'this', 'Array#every | Scope is passed properly');
}, 'this');
equal([{name:'john',age:25}].all({name:'john',age:25}), true, 'Array#all | handles complex objects', { prototype: false });
equal([{name:'john',age:25},{name:'fred',age:85}].all('age'), false, 'Array#all | simple string mistakenly passed for complex objects');
equal([{name:'john',age:25},{name:'fred',age:85}].all({name:'john',age:25}), false, "Array#all | john isn't all");
equal([1,2,3].some(1), true, 'Array#some | accepts a number shortcut match');
equal([2,3,4].some(1), false, 'Array#some | accepts a number shortcut no match');
equal(['a','b','c'].some('a'), true, 'Array#some | accepts a string shortcut match');
equal(['b','c','d'].some('a'), false, 'Array#some | accepts a string shortcut no match');
equal(['a','b','c'].some(/[a-f]/), true, 'Array#some | accepts a regex shortcut match');
equal(['a','b','c'].some(/[m-z]/), false, 'Array#some | accepts a regex shortcut no match');
equal([{a:1},{a:2}].some({a:1}), true, 'Array#some | checks objects match');
equal([{a:2},{a:3}].some({a:1}), false, 'Array#some | checks object no match');
equal([12,5,8,130,44].some(function(el, i, a) { return el > 10 }), true, 'Array#some | some elements are greater than 10');
equal([12,5,8,130,44].some(function(el, i, a) { return el < 10 }), true, 'Array#some | some elements are less than 10');
equal([12,54,18,130,44].some(function(el, i, a) { return el >= 10 }), true, 'Array#some | all elements are greater than 10');
equal([12,5,8,130,44].some(function(el, i, a) { return el < 4 }), false, 'Array#some | no elements are less than 4');
equal(arrayOfUndefined.some(undefined), true, 'Array#some | all undefined');
equal(arrayOfUndefined.clone().add('a').some(undefined), true, 'Array#some | some undefined');
equal(['a', 'b'].some(undefined), false, 'Array#some | none undefined');
equal([].some(function(el, i, a) { return el > 10 }), false, 'Array#some | no elements are greater than 10 in an empty array');
['a'].some(function(el, i, a) {
equal(el, 'a', 'Array#some | first parameter is the element');
equal(i, 0, 'Array#some | second parameter is the index');
equal(a, ['a'], 'Array#some | third parameter is the array', { prototype: undefined });
equal(this.toString(), 'this', 'Array#some | scope is passed properly');
}, 'this');
equal([{name:'john',age:25}].some({name:'john',age:25}), true, 'Array#every | handles complex objects');
equal([{name:'john',age:25},{name:'fred',age:85}].some('age'), false, 'Array#some | simple string mistakenly passed for complex objects');
equal([{name:'john',age:25},{name:'fred',age:85}].some({name:'john',age:25}), true, 'Array#some | john can be found ');
equal([1,2,3].filter(1), [1], 'Array#filter | accepts a number shortcut match');
equal([2,3,4].filter(1), [], 'Array#filter | accepts a number shortcut no match');
equal(['a','b','c'].filter('a'), ['a'], 'Array#filter | accepts a string shortcut match');
equal(['b','c','d'].filter('a'), [], 'Array#filter | accepts a string shortcut no match');
equal(['a','b','c'].filter(/[a-f]/), ['a','b','c'], 'Array#filter | accepts a regex shortcut match');
equal(['a','b','c'].filter(/[m-z]/), [], 'Array#filter | accepts a regex shortcut no match');
equal([{a:1},{a:2}].filter({a:1}), [{a:1}], 'Array#filter | checks objects match');
equal([{a:2},{a:3}].filter({a:1}), [], 'Array#filter | checks object no match');
equal([12,4,8,130,44].filter(function(el, i, a) { return el > 10 }), [12,130,44], 'Array#filter | numbers above 10');
equal([12,4,8,130,44].filter(function(el, i, a) { return el < 10 }), [4,8], 'Array#filter | numbers below 10');
['a'].filter(function(el, i, a) {
equal(el, 'a', 'Array#filter | first parameter is the element');
equal(i, 0, 'Array#filter | second parameter is the index');
equal(a, ['a'], 'Array#filter | third parameter is the array', { prototype: undefined });
equal(this.toString(), 'this', 'Array#filter | scope is passed properly');
}, 'this');
equal([{name:'john',age:25},{name:'fred',age:85}].filter('age'), [], 'Array#filter | simple string mistakenly passed for complex objects');
equal([{name:'john',age:25},{name:'fred',age:85}].filter({name:'john',age:25}), [{name:'john',age:25}], 'Array#filter | filtering john');
equal([{name:'john',age:25},{name:'fred',age:85}].filter({name:'fred',age:85}), [{name:'fred',age:85}], 'Array#filter | filtering fred');
arr = [2, 5, 9];
arr.forEach(function(el, i, a) {
equal(el, a[i], 'Array#forEach | looping successfully');
});
arr = ['a', [1], { foo: 'bar' }, 352];
count = 0;
arr.forEach(function(el, i, a) {
count++;
});
equal(count, 4, 'Array#forEach | complex array | should have looped 4 times');
['a'].forEach(function(el, i, a) {
equal(el, 'a', 'Array#forEach | first parameter is the element');
equal(i, 0, 'Array#forEach | second parameter is the index');
equal(this.toString(), 'this', 'Array#forEach | scope is passed properly');
}, 'this');
// Array#each now splits functionality from forEach
arr = [2, 5, 9];
arr.each(function(el, i, a) {
equal(el, arr[i], 'Array#each | looping successfully');
});
arr = ['a', [1], { foo: 'bar' }, 352];
count = 0;
arr.each(function() {
count++;
});
equal(count, 4, 'Array#each | complex array | should have looped 4 times');
['a'].each(function(el, i, a) {
equal(el, 'a', 'Array#each | first parameter is the element');
equal(i, 0, 'Array#each | second parameter is the index');
equal(a, ['a'], 'Array#each | third parameter is the array', { prototype: undefined });
// Note: psychotic syntax here because equal() is now strictly equal, and the this object is actually an "object" string
// as opposed to a primitive string, but only in Prototype. Calling .toString() in a non-prototype environment would effectively
// try to convert the array to a string, which is also not what we want.
equal(this, a, 'Array#each | scope is also the array', { prototype: (function(){ return this; }).call('this'), mootools: 'this' });
}, 'this');
equal(['foot','goose','moose'].map(function(el) { return el.replace(/o/g, 'e'); }), ['feet', 'geese', 'meese'], 'Array#map | with regexp');
// cool!
equal([1,4,9].map(Math.sqrt), [1,2,3], 'Array#map | passing Math.sqrt directly');
equal([{ foo: 'bar' }].map(function(el) { return el['foo']; }), ['bar'], 'Array#map | with key "foo"');
['a'].map(function(el, i, a) {
equal(el, 'a', 'Array#map | first parameter is the element');
equal(i, 0, 'Array#map | second parameter is the index');
equal(a, ['a'], 'Array#map | third parameter is the array', { prototype: undefined });
equal(this.toString(), 'this', 'Array#map | scope is passed properly');
}, 'this');
equal(['foot','goose','moose'].map('length'), [4,5,5], 'Array#map | length');
equal([{name:'john',age:25},{name:'fred',age:85}].map('age'), [25,85], 'Array#map | age');
equal([{name:'john',age:25},{name:'fred',age:85}].map('name'), ['john','fred'], 'Array#map | name');
equal([{name:'john',age:25},{name:'fred',age:85}].map('cupsize'), [undefined, undefined], 'Array#map | (nonexistent) cupsize');
equal([].map('name'), [], 'Array#map');
equal([1,2,3].map('toString'), ['1','2','3'], 'Array#map | calls a function on a shortcut string');
raisesError(function(){ [1,2,3].map() }, 'Array#map | raises an error if no argument', { prototype: false });
equal([1,2,3].map(undefined), [1,2,3], 'Array#map | undefined');
equal([1,2,3].map(null), [undefined, undefined, undefined], 'Array#map | null');
equal([1,2,3].map(4), [undefined, undefined, undefined], 'Array#map | number');
equal([0,1,2,3,4].reduce(function(a,b) { return a + b; }), 10, 'Array#reduce | a + b');
equal([[0,1],[2,3],[4,5]].reduce(function(a,b) { return a.concat(b); }, []), [0,1,2,3,4,5], 'Array#reduce | concat');
['a'].reduce(function(p, c, i, a) {
equal(p, 'c', 'Array#reduce | a | first parameter is the lhs');
equal(c, 'a', 'Array#reduce | a | second parameter is the rhs');
equal(i, 0, 'Array#reduce | a | third parameter is the index');
equal(a, ['a'], 'Array#reduce | a | fourth parameter is the array');
}, 'c');
[55,66].reduce(function(p, c, i, a) {
equal(p, 55, 'Array#reduce | 55,66 | first parameter is the lhs');
equal(c, 66, 'Array#reduce | 55,66 | second parameter is the rhs');
equal(i, 1, 'Array#reduce | 55,66 | third parameter is the index');
equal(a, [55,66], 'Array#reduce | 55,66 | fourth parameter is the array');
});
[1].reduce(function(p, c, i, a) {
// This assertion should never be called.
equal(true, false, 'Array#reduce | one element array with no rhs passed in does not iterate');
});
equal([1].reduce(function() {}), 1, 'Array#reduce | [1] reduces to 1');
equal([0,1,2,3,4].reduceRight(function(a,b) { return a + b; }), 10, 'Array#reduceRight | a + b');
equal([[0,1],[2,3],[4,5]].reduceRight(function(a,b) { return a.concat(b); }, []), [4,5,2,3,0,1], 'Array#reduceRight | concat');
['a'].reduceRight(function(p, c, i, a) {
equal(p, 'c', 'Array#reduceRight | a | first parameter is the lhs');
equal(c, 'a', 'Array#reduceRight | a | second parameter is the rhs');
equal(i, 0, 'Array#reduceRight | a | third parameter is the index');
equal(a, ['a'], 'Array#reduceRight | a | fourth parameter is the array');
}, 'c');
[55,66].reduceRight(function(p, c, i, a) {
equal(p, 66, 'Array#reduceRight | 55,66 | first parameter is the lhs');
equal(c, 55, 'Array#reduceRight | 55,66 | second parameter is the rhs');
equal(i, 0, 'Array#reduceRight | 55,66 | third parameter is the index');
equal(a, [55,66], 'Array#reduceRight | 55,66 | fourth parameter is the array');
});
[1].reduceRight(function(p, c, i, a) {
// This assertion should never be called.
equal(true, false, 'Array#reduceRight | one element array with no rhs passed in does not iterate');
});
equal([1].reduceRight(function() {}), 1, 'Array#reduceRight | [1] reduces to 1');
var result = [];
var count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
equal(i, count + 1, 'Array#each | index should be correct', { prototype: count, mootools: count });
count++;
}, 1);
equal(count, 2, 'Array#each | should have run 2 times', { prototype: 3, mootools: 3 });
equal(result, ['b','c'], 'Array#each | result', { prototype: ['a','b','c'], mootools: ['a','b','c'] });
result = [];
indexes = [1,2,0];
count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
equal(i, indexes[count], 'Array#each | looping from index 1 | index should be correct', { prototype: indexes.at(count - 1), mootools: indexes.at(count - 1) })
count++;
}, 1, true);
equal(count, 3, 'Array#each | looping from index 1 | should have run 3 times')
equal(result, ['b','c','a'], 'Array#each | looping from index 1 | result', { prototype: ['a','b','c'], mootools: ['a','b','c'] });
result = [];
indexes = [0,1,2];
count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
equal(i, indexes[count], 'Array#each | looping from index 0 | index should be correct')
count++;
}, 0, true);
equal(count, 3, 'Array#each | looping from index 0 | should have run 3 times')
equal(result, ['a','b','c'], 'Array#each | looping from index 0 | result');
result = [];
indexes = [2,0,1];
count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
equal(i, indexes[count], 'Array#each | looping from index 2 | index should be correct', { prototype: indexes.at(count + 1), mootools: indexes.at(count + 1) })
count++;
}, 2, true);
equal(count, 3, 'Array#each | looping from index 2 | should have run 3 times')
equal(result, ['c','a','b'], 'Array#each | looping from index 2 | result', { prototype: ['a','b','c'], mootools: ['a','b','c'] });
result = [];
count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
count++;
}, 3, true);
equal(count, 3, 'Array#each | looping from index 3 | should have run 3 times')
equal(result, ['a','b','c'], 'Array#each | looping from index 3 | result');
result = [];
count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
count++;
}, 4, true);
equal(count, 3, 'Array#each | looping from index 4 | should have run 3 times')
equal(result, ['b','c','a'], 'Array#each | looping from index 4 | result', { prototype: ['a','b','c'], mootools: ['a','b','c'] });
result = [];
count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
count++;
}, 49, true);
equal(count, 3, 'Array#each | looping from index 49 | should have run 3 times')
equal(result, ['b','c','a'], 'Array#each | looping from index 49 | result', { prototype: ['a','b','c'], mootools: ['a','b','c'] });
result = [];
count = 0;
['a','b','c'].each(function(s, i) {
result.push(s);
count++;
}, 'hoofa');
equal(count, 3, 'Array#each | string index should default to 0 | should have run 3 times')
equal(result, ['a','b','c'], 'Array#each | string index should default to 0 | result');
equal(['a','b','c'].each(function(){}), ['a','b','c'], 'Array#each | null function returns the array');
raisesError(function(){ [1].each() }, 'Array#each | raises an error if no callback');
count = 0;
['a','b','c'].each(function() {
count++;
return false;
});
equal(count, 1, 'Array#each | returning false will break the loop', { prototype: 3, mootools: 3 });
count = 0;
['a','b','c'].each(function() {
count++;
return true;
});
equal(count, 3, 'Array#each | returning true will not break the loop');
count = 0;
['a','b','c'].each(function() {
count++;
return;
});
equal(count, 3, 'Array#each | returning undefined will not break the loop');
// Sparse array handling with Array#each
// These tests cannot be run with Prototype/Mootools, as they will lock the browser
skipEnvironments(['prototype','mootools'], function() {
arr = ['a'];
arr[Math.pow(2,32) - 2] = 'b';
expected = ['a','b'];
expectedIndexes = [0, Math.pow(2,32) - 2];
count = 0;
arr.each(function(el, i, a) {
equal(this, arr, 'Array#each | sparse arrays | this object should be the array');
equal(el, expected[count], 'Array#each | sparse arrays | first argument should be the current element');
equal(i, expectedIndexes[count], 'Array#each | sparse arrays | second argument should be the current index');
equal(a, arr, 'Array#each | sparse arrays | third argument should be the array');
count++;
});
equal(count, 2, 'Array#each | sparse arrays | count should match');
arr = [];
arr[-2] = 'd';
arr[2] = 'f';
arr[Math.pow(2,32)] = 'c';
count = 0;
arr.each(function(el, i) {
equal(el, 'f', 'Array#each | sparse arrays | values outside range are not iterated over | el');
equal(i, 2, 'Array#each | sparse arrays | values outside range are not iterated over | index');
count++;
});
equal(count, 1, 'Array#each | sparse arrays | values outside range are not iterated over | count');
});
arr = [];
arr[9] = 'd';
arr[2] = 'f';
arr[5] = 'c';
count = 0;
expected = ['f','c','d'];
expectedIndexes = [2,5,9];
arr.each(function(el, i) {
equal(el, expected[count], 'Array#each | sparse arrays | elements are in expected order');
// TODO REWORK THIS AS IT SHOULD BE STRICT!!
equal(i, expectedIndexes[count], 'Array#each | sparse arrays | index is in expected order', { prototype: count });
count++;
});
equal(count, 3, 'Array#each | sparse arrays | unordered array should match');
count = 0;
arrayOfUndefined.each(function() {
count++;
});
equal(count, 3, 'Array#each | however, simply having an undefined in an array does not qualify it as sparse');
equal(['a','b','c'].find('a'), 'a', 'Array#find | a');
equal(['a','a','c'].find('a'), 'a', 'Array#find | first a');
equal(['a','b','c'].find('q'), undefined, 'Array#find | q');
equal([1,2,3].find(1), 1, 'Array#find | 1');
equal([2,2,3].find(2), 2, 'Array#find | 2');
equal([1,2,3].find(4), undefined, 'Array#find | 4');
equal([{a:1},{b:2},{c:3}].find({a:1}), {a:1}, 'Array#find | a:1', { prototype: undefined });
equal([{a:1},{a:1},{c:3}].find({a:1}), {a:1}, 'Array#find | first a:1', { prototype: undefined });
equal([{a:1},{b:2},{c:3}].find({d:4}), undefined, 'Array#find | d:4');
equal([{a:1},{b:2},{c:3}].find({c:4}), undefined, 'Array#find | c:4');
equal([[1,2],[2,3],[4,5]].find([2,3]), [2,3], 'Array#find | 2,3', { prototype: undefined });
equal([[1,2],[2,3],[4,5]].find([2,4]), undefined, 'Array#find | 2,4');
equal([[1,2],[2,3],[2,3]].find([2,3]), [2,3], 'Array#find | first 2,3', { prototype: undefined });
equal(['foo','bar'].find(/f+/), 'foo', 'Array#find | /f+/', { prototype: undefined });
equal(['foo','bar'].find(/[a-f]/), 'foo', 'Array#find | /a-f/', { prototype: undefined });
equal(['foo','bar'].find(/[a-f]/, 1), 'bar', 'Array#find | /a-f/ from index 1', { prototype: undefined });
equal(['foo','bar'].find(/q+/), undefined, 'Array#find | /q+/');
equal([1,2,3].find(function(e) { return e > 0; }, 0), 1, 'Array#find | greater than 0 from index 0');
equal([1,2,3].find(function(e) { return e > 0; }, 1), 2, 'Array#find | greater than 0 from index 1', { prototype: 1 });
equal([1,2,3].find(function(e) { return e > 0; }, 2), 3, 'Array#find | greater than 0 from index 2', { prototype: 1 });
equal([1,2,3].find(function(e) { return e > 0; }, 3), undefined, 'Array#find | greater than 0 from index 3', { prototype: 1 });
equal([1,2,3].find(function(e) { return e > 1; }, 0), 2, 'Array#find | greater than 1 from index 0');
equal([1,2,3].find(function(e) { return e > 1; }, 1), 2, 'Array#find | greater than 1 from index 1');
equal([1,2,3].find(function(e) { return e > 1; }, 2), 3, 'Array#find | greater than 1 from index 2', { prototype: 2 });
equal([1,2,3].find(function(e) { return e > 2; }, 0), 3, 'Array#find | greater than 2 from index 0');
equal([1,2,3].find(function(e) { return e > 3; }, 0), undefined, 'Array#find | greater than 3 from index 0');
equal([{a:10},{a:8},{a:3}].find(function(e) { return e['a'] > 5; }, 0), {a:10}, 'Array#find | key "a" greater than 5');
equal([{a:10},{a:8},{a:3}].find(function(e) { return e['a'] > 5; }, 1), {a:8}, 'Array#find | key "a" greater than 5 from index 1', { prototype: {a:10} });
equal([{a:10},{a:8},{a:3}].find(function(e) { return e['a'] > 5; }, 2), undefined, 'Array#find | key "a" greater than 5 from index 2', { prototype: {a:10} });
equal([function() {}].find(function(e) {}, 0), undefined, 'Array#find | undefined function');
equal([function() {}].find(function(e) {}, 1), undefined, 'Array#find | null function from index 1');
equal([null, null].find(null, 0), null, 'Array#find | null');
equal([null, null].find(null, 1), null, 'Array#find | null from index 1');
equal([undefined, undefined].find(undefined, 0), undefined, 'Array#find | undefined');
equal([undefined, undefined].find(undefined, 1), undefined, 'Array#find | undefined from index 1');
equal([undefined, 'a'].find(undefined, 1), undefined, 'Array#find | undefined can be found');
count = 0;
[1,2,3].find(function(n) {
count++;
return n == 1;
});
equal(count, 1, 'Array#find | should immediately finish when it finds a match');
equal(['a','b','c'].findAll('a'), ['a'], 'Array#findAll | a');
equal(['a','a','c'].findAll('a'), ['a','a'], 'Array#findAll | a,a');
equal(['a','b','c'].findAll('q'), [], 'Array#findAll | q');
equal([1,2,3].findAll(1), [1], 'Array#findAll | 1');
equal([2,2,3].findAll(2), [2,2], 'Array#findAll | 2,2');
equal([1,2,3].findAll(4), [], 'Array#findAll | 4');
equal([{a:1},{b:2},{c:3}].findAll({a:1}), [{a:1}], 'Array#findAll | a:1', { prototype: [] });
equal([{a:1},{a:1},{c:3}].findAll({a:1}), [{a:1},{a:1}], 'Array#findAll | a:1,a:1', { prototype: [] });
equal([{a:1},{b:2},{c:3}].findAll({d:4}), [], 'Array#findAll | d:4');
equal([{a:1},{b:2},{c:3}].findAll({c:4}), [], 'Array#findAll | c:4');
equal([[1,2],[2,3],[4,5]].findAll([2,3]), [[2,3]], 'Array#findAll | 2,3', { prototype: [] });
equal([[1,2],[2,3],[4,5]].findAll([2,4]), [], 'Array#findAll | 2,4');
equal([[1,2],[2,3],[2,3]].findAll([2,3]), [[2,3],[2,3]], 'Array#findAll | [2,3],[2,3]', { prototype: [] });
equal(['foo','bar'].findAll(/f+/), ['foo'], 'Array#findAll | /f+/', { prototype: [] });
equal(['foo','bar'].findAll(/[a-f]/), ['foo','bar'], 'Array#findAll | /[a-f]/', { prototype: [] });
equal(['foo','bar'].findAll(/[a-f]/, 1), ['bar'], 'Array#findAll | /[a-f]/ from index 1', { prototype: [] });
equal(['foo','bar'].findAll(/[a-f]/, 1, true), ['bar','foo'], 'Array#findAll | /[a-f]/ from index 1', { prototype: [] });
equal(['foo','bar'].findAll( /q+/), [], 'Array#findAll | /q+/');
equal([1,2,3].findAll(function(e) { return e > 0; }, 0), [1,2,3], 'Array#findAll | greater than 0 from index 0');
equal([1,2,3].findAll(function(e) { return e > 0; }, 1), [2,3], 'Array#findAll | greater than 0 from index 1', { prototype: [1,2,3] });
equal([1,2,3].findAll(function(e) { return e > 0; }, 2), [3], 'Array#findAll | greater than 0 from index 2', { prototype: [1,2,3] });
equal([1,2,3].findAll(function(e) { return e > 0; }, 3), [], 'Array#findAll | greater than 0 from index 3', { prototype: [1,2,3] });
equal([1,2,3].findAll(function(e) { return e > 0; }, 4), [], 'Array#findAll | greater than 0 from index 4', { prototype: [1,2,3] });
equal([1,2,3].findAll(function(e) { return e > 1; }, 0), [2,3], 'Array#findAll | greater than 1 from index 0');
equal([1,2,3].findAll(function(e) { return e > 1; }, 1), [2,3], 'Array#findAll | greater than 1 from index 1');
equal([1,2,3].findAll(function(e) { return e > 1; }, 2), [3], 'Array#findAll | greater than 1 from index 2', { prototype: [2,3] });
equal([1,2,3].findAll(function(e) { return e > 2; }, 0), [3], 'Array#findAll | greater than 2 from index 0');
equal([1,2,3].findAll(function(e) { return e > 3; }, 0), [], 'Array#findAll | greater than 3 from index 0');
equal([1,2,3].findAll(function(e) { return e > 0; }, 0, true), [1,2,3], 'Array#findAll | looping | greater than 0 from index 0');
equal([1,2,3].findAll(function(e) { return e > 0; }, 1, true), [2,3,1], 'Array#findAll | looping | greater than 0 from index 1', { prototype: [1,2,3] });
equal([1,2,3].findAll(function(e) { return e > 0; }, 2, true), [3,1,2], 'Array#findAll | looping | greater than 0 from index 2', { prototype: [1,2,3] });
equal([1,2,3].findAll(function(e) { return e > 0; }, 3, true), [1,2,3], 'Array#findAll | looping | greater than 0 from index 3', { prototype: [1,2,3] });
equal([1,2,3].findAll(function(e) { return e > 1; }, 0, true), [2,3], 'Array#findAll | looping | greater than 1 from index 0');
equal([1,2,3].findAll(function(e) { return e > 1; }, 1, true), [2,3], 'Array#findAll | looping | greater than 1 from index 1', { prototype: [2,3] });
equal([1,2,3].findAll(function(e) { return e > 1; }, 2, true), [3,2], 'Array#findAll | looping | greater than 1 from index 2', { prototype: [2,3] });
equal([1,2,3].findAll(function(e) { return e > 2; }, 0, true), [3], 'Array#findAll | looping | greater than 2 from index 0');
equal([1,2,3].findAll(function(e) { return e > 3; }, 0, true), [], 'Array#findAll | looping | greater than 3 from index 0');
equal([{a:10},{a:8},{a:3}].findAll(function(e) { return e['a'] > 5; }, 0), [{a:10},{a:8}], 'Array#findAll | key "a" is greater than 5');
equal([{a:10},{a:8},{a:3}].findAll(function(e) { return e['a'] > 5; }, 1), [{a:8}], 'Array#findAll | key "a" is greater than 5 from index 1', { prototype: [{a:10},{a:8}] });
equal([{a:10},{a:8},{a:3}].findAll(function(e) { return e['a'] > 5; }, 2), [], 'Array#findAll | key "a" is greater than 5 from index 2', { prototype: [{a:10},{a:8}] });
equal([{a:10},{a:8},{a:3}].findAll(function(e) { return e['a'] > 5; }, 0, true), [{a:10},{a:8}], 'Array#findAll | looping | key "a" is greater than 5');
equal([{a:10},{a:8},{a:3}].findAll(function(e) { return e['a'] > 5; }, 1, true), [{a:8},{a:10}], 'Array#findAll | looping | key "a" is greater than 5 from index 1', { prototype: [{a:10},{a:8}] });
equal([{a:10},{a:8},{a:3}].findAll(function(e) { return e['a'] > 5; }, 2, true), [{a:10},{a:8}], 'Array#findAll | looping | key "a" is greater than 5 from index 2', { prototype: [{a:10},{a:8}] });
equal([function() {}].findAll(function(e) {}, 0), [], 'Array#findAll | null function');
equal([function() {}].findAll(function(e) {}, 1), [], 'Array#findAll | null function from index 1');
equal([null, null].findAll(null, 0), [null, null], 'Array#findAll | null');
equal([null, null].findAll(null, 1), [null], 'Array#findAll | null from index 1', { prototype: [null,null] });
equal([function() {}].findAll(function(e) {}, 0, true), [], 'Array#findAll | looping | null function');
equal([function() {}].findAll(function(e) {}, 1, true), [], 'Array#findAll | looping | null function from index 1');
equal([null, null].findAll(null, 0, true), [null, null], 'Array#findAll | looping | null');
equal([null, null].findAll(null, 1, true), [null, null], 'Array#findAll | looping | null from index 1');
// Example: finding last from an index. (reverse order). This means we don't need a findAllFromLastIndex
arr = [{name:'john',age:10,food:'sushi'},{name:'randy',age:23,food:'natto'},{name:'karen',age:32,food:'salad'}];
arr = [1,2,3,4,5,6,7,8,9];
equal(arr.findAll(function(n) { return n % 3 == 0; }, 4), [6,9], 'Array#findAll | n % 3 from index 4', { prototype: [3,6,9] });
equal(arr.reverse().findAll(function(n) { return n % 3 == 0; }, 4), [3], 'Array#findAll | reversed | n % 3 from index 4 reversed', { prototype: [9,6,3] });
arr.reverse(); // Array#reverse is destructive, dammit!
equal(arr.findAll(function(n) { return n % 3 == 0; }, 4, true), [6,9,3], 'Array#findAll | looping | n % 3 from index 4', { prototype: [3,6,9] });
equal(arr.reverse().findAll(function(n) { return n % 3 == 0; }, 4, true), [3,9,6], 'Array#findAll | looping | reversed | n % 3 from index 4 reversed', { prototype: [9,6,3] });
equal([1,1,3].unique(), [1,3], 'Array#unique | 1,1,3');
equal([0,0,0].unique(), [0], 'Array#unique | 0,0,0');
equal(['a','b','c'].unique(), ['a','b','c'], 'Array#unique | a,b,c');
equal(['a','a','c'].unique(), ['a','c'], 'Array#unique | a,a,c');
equal([{ foo:'bar' }, { foo:'bar' }].unique(), [{foo:'bar'}], 'Array#unique | objects uniqued as well', { prototype: [{foo:'bar'},{foo:'bar'}] });
equal([{ first: 'John', last: 'Woo' }, { first: 'Reynold', last: 'Woo' }].unique(function(n){ return n.last; }), [{ first: 'John', last: 'Woo' }], 'Array#unique | can be uniqued via a mapping function');
equal([{ first: 'John', last: 'Woo' }, { first: 'Reynold', last: 'Woo' }].unique('last'), [{ first: 'John', last: 'Woo' }], 'Array#unique | can be uniqued via a mapping shortcut');
[1].unique(function(el,i,a) {
equal(this, [1], 'Array#unique | scope should be the array');
equal(i, 0, 'Array#unique | second param should be the index');
equal(a, [1], 'Array#unique | third param should also be the array');
});
equal([function(){ return 'a' }, function() { return 'a'; }, function() { return 'b'; }].unique().length, 3, 'Array#unique | Functions are always unique');
equal([1,2,3].union([3,4,5]), [1,2,3,4,5], 'Array#union | 1,2,3 + 3,4,5');
equal([1,1,1].union([1,2,3]), [1,2,3], 'Array#union | 1,1,1 + 1,2,3');
equal([0,0,0].union([1,2,3]), [0,1,2,3], 'Array#union | 0,0,0 + 1,2,3');
equal([0,0,0].union([0,0,0]), [0], 'Array#union | 0,0,0 + 0,0,0');
equal([].union([]), [], 'Array#union | 2 empty arrays');
equal([-1,-2,-3].union([-2,-4,-5]), [-1,-2,-3,-4,-5], 'Array#union | -1,-2,-3 + -2,-4,-5');
equal([-1,-2,-3].union([3,4,5]), [-1,-2,-3,3,4,5], 'Array#union | -1,-2,-3 + 3,4,5');
equal([{a:1},{b:2}].union([{b:2},{c:3}]), [{a:1},{b:2},{c:3}], 'Array#union | a:1,b:2 + b:2,c:3', { prototype: [{a:1},{b:2},{b:2},{c:3}] });
equal([1,2,3].union(4), [1,2,3,4], 'Array#union | 1,2,3 + 4');
equal([1,2,3].union(4,8,10), [1,2,3,4,8,10], 'Array#union | 1,2,3 + 4 8 10');
equal([1,2,3].union([4],[8],[10]), [1,2,3,4,8,10], 'Array#union | 1,2,3 + [4] [8] [10]');
arr = [1,2,3];
arr.union([4,5,6]);
equal(arr, [1,2,3], 'Array#union | is non-destructive');
equal([1,2,3].intersect([3,4,5]), [3], 'Array#intersect | 1,2,3 & 3,4,5');
equal(['a','b','c'].intersect(['c','d','e']), ['c'], 'Array#intersect | a,b,c & c,d,e');
equal([1,2,3].intersect([1,2,3]), [1,2,3], 'Array#intersect | 1,2,3 & 1,2,3');
equal([1,2,3].intersect([3,2,1]), [1,2,3], 'Array#intersect | 1,2,3 & 3,2,1');
equal([].intersect([3]), [], 'Array#intersect | empty array & 3');
equal([3].intersect([]), [], 'Array#intersect | 3 & empty array');
equal([].intersect([]), [], 'Array#intersect | 2 empty arrays');
equal([null].intersect([]), [], 'Array#intersect | [null] & empty array');
equal([null].intersect([null]), [null], 'Array#intersect | [null] & [null]', { prototype: [], mootools: [] });
equal([false].intersect([false]), [false], 'Array#intersect | [false] & [false]', { prototype: [] });
equal([false].intersect([0]), [], 'Array#intersect | [false] & [0]');
equal([false].intersect([null]), [], 'Array#intersect | [false] & [null]');
equal([false].intersect([undefined]), [], 'Array#intersect | [false] & [undefined]');
equal([{a:1},{b:2}].intersect([{b:2},{c:3}]), [{b:2}], 'Array#intersect | a:1,b:2 & b:2,c:3', { prototype: [] });
equal([1,1,3].intersect([1,5,6]), [1], 'Array#intersect | 1,1,3 & 1,5,6');
equal([1,2,3].intersect([4,5,6]), [], 'Array#intersect | 1,1,3 & 4,5,6');
equal([1,2,3].intersect([3,4,5],[0,1]), [1,3], 'Array#intersect | handles multiple arguments', { prototype: [3] });
arr = [1,2,3];
arr.intersect([3,4,5]);
equal(arr, [1,2,3], 'Array#intersect | is non-destructive');
// Prototype will blow up here
skipEnvironments(['prototype'], function(){
equal([1,1].intersect(1,1,[1,1]), [1], 'Array#intersect | assure uniqueness');
equal([1,2,3].intersect(1), [1], 'Array#intersect | 1,2,3 + 1');
});
equal([1,2,3].subtract([3,4,5]), [1,2], 'Array#subtract | 1,2,3 + 3,4,5');
equal([1,1,2,2,3,3,4,4,5,5].subtract([2,3,4]), [1,1,5,5], 'Array#subtract | 1,1,2,2,3,3,4,4,5,5 + 2,3,4');
equal(['a','b','c'].subtract(['c','d','e']), ['a','b'], 'Array#subtract | a,b,c + c,d,e');
equal([1,2,3].subtract([1,2,3]), [], 'Array#subtract | 1,2,3 + 1,2,3');
equal([1,2,3].subtract([3,2,1]), [], 'Array#subtract | 1,2,3 + 3,2,1');
equal([].subtract([3]), [], 'Array#subtract | empty array + [3]');
equal([3].subtract([]), [3], 'Array#subtract | [3] + empty array');
equal([].subtract([]), [], 'Array#subtract | 2 empty arrays');
equal([null].subtract([]), [null], 'Array#subtract | [null] + empty array');
equal([null].subtract([null]), [], 'Array#subtract | [null] + [null]', { mootools: [null] });
equal([false].subtract([false]), [], 'Array#subtract | [false] + [false]');
equal([false].subtract([0]), [false], 'Array#subtract | [false] + [0]');
equal([false].subtract([null]), [false], 'Array#subtract | [false] + [null]');
equal([false].subtract([undefined]), [false], 'Array#subtract | [false] + [undefined]');
equal([{a:1},{b:2}].subtract([{b:2},{c:3}]), [{a:1}], 'Array#subtract | a:1,b:2 + b:2,c:3');
equal([1,1,3].subtract([1,5,6]), [3], 'Array#subtract | 1,1,3 + 1,5,6');
equal([1,2,3].subtract([4,5,6]), [1,2,3], 'Array#subtract | 1,2,3 + 4,5,6');
equal([1,2,3].subtract(1), [2,3], 'Array#subtract | 1,2,3 + 1');
equal([1,2,3,4,5].subtract([1],[3],[5]), [2,4], 'Array#subtract | handles multiple arguments');
arr = [1,2,3];
arr.subtract([3]);
equal(arr, [1,2,3], 'Array#subtract | is non-destructive');
equal(['a','b','c'].at(0), 'a', 'Array#at | a,b,c | 0');
equal(['a','b','c'].at(1), 'b', 'Array#at | a,b,c | 1');
equal(['a','b','c'].at(2), 'c', 'Array#at | a,b,c | 2');
equal(['a','b','c'].at(3), 'a', 'Array#at | a,b,c | 3');
equal(['a','b','c'].at(-1), 'c', 'Array#at | a,b,c | -1');
equal(['a','b','c'].at(-2), 'b', 'Array#at | a,b,c | -2');
equal(['a','b','c'].at(-3), 'a', 'Array#at | a,b,c | -3');
equal(['a','b','c'].at(-4), 'c', 'Array#at | a,b,c | -3');
equal(['a','b','c'].at(0, false), 'a', 'Array#at | a,b,c | loop off | 0');
equal(['a','b','c'].at(1, false), 'b', 'Array#at | a,b,c | loop off | 1');
equal(['a','b','c'].at(2, false), 'c', 'Array#at | a,b,c | loop off | 2');
equal(['a','b','c'].at(3, false), undefined, 'Array#at | a,b,c | loop off | 3');
equal(['a','b','c'].at(-1, false), undefined, 'Array#at | a,b,c | loop off | -1');
equal(['a','b','c'].at(-2, false), undefined, 'Array#at | a,b,c | loop off | -2');
equal(['a','b','c'].at(-3, false), undefined, 'Array#at | a,b,c | loop off | -3');
equal(['a','b','c'].at(-4, false), undefined, 'Array#at | a,b,c | loop off | -4');
equal(['a','b','c'].at(), undefined, 'Array#at | a,b,c | no argument');
equal([false].at(0), false, 'Array#at | false | loop off | 0');
equal(['a'].at(0), 'a', 'Array#at | a | 0');
equal(['a'].at(1), 'a', 'Array#at | a | 1');
equal(['a'].at(1, false), undefined, 'Array#at | a | loop off | 1');
equal(['a'].at(-1), 'a', 'Array#at | a | -1');
equal(['a','b','c','d','e','f'].at(0,2,4), ['a','c','e'], 'Array#at | a,b,c,d,e,f | 0,2,4');
equal(['a','b','c','d','e','f'].at(1,3,5), ['b','d','f'], 'Array#at | a,b,c,d,e,f | 1,3,5');
equal(['a','b','c','d','e','f'].at(0,2,4,6), ['a','c','e','a'], 'Array#at | a,b,c,d,e,f | 0,2,4,6');
equal(['a','b','c','d','e','f'].at(0,2,4,6,18), ['a','c','e','a','a'], 'Array#at | a,b,c,d,e,f | 0,2,4,6,18');
equal(['a','b','c','d','e','f'].at(0,2,4,6, false), ['a','c','e', undefined], 'Array#at | a,b,c,d,e,f | 0,2,4,6,false | false');
equal(['a','b','c'].from(), ['a','b','c'], 'Array#from | no argument');
equal(['a','b','c'].from(1), ['b','c'], 'Array#from| 1');
equal(['a','b','c'].from(2), ['c'], 'Array#from | 2');
equal(['a','b','c'].from(3), [], 'Array#from | 3');
equal(['a','b','c'].from(4), [], 'Array#from | 4');
equal(['a','b','c'].from(-1), ['c'], 'Array#from | -1');
equal(['a','b','c'].from(-2), ['b','c'], 'Array#from | -2');
equal(['a','b','c'].from(-3), ['a','b','c'], 'Array#from | -3');
equal(['a','b','c'].from(-4), ['a','b','c'], 'Array#from | -4');
equal(['a','b','c'].to(), ['a','b','c'], 'Array#to | no argument');
equal(['a','b','c'].to(0), [], 'Array#to | no argument');
equal(['a','b','c'].to(1), ['a'], 'Array#to | 1');
equal(['a','b','c'].to(2), ['a','b'], 'Array#to | 2');
equal(['a','b','c'].to(3), ['a','b','c'], 'Array#to | 3');
equal(['a','b','c'].to(4), ['a','b','c'], 'Array#to | 4');
equal(['a','b','c'].to(-1), ['a','b'], 'Array#to | -1');
equal(['a','b','c'].to(-2), ['a'], 'Array#to | -2');
equal(['a','b','c'].to(-3), [], 'Array#to | -3');
equal(['a','b','c'].to(-4), [], 'Array#to | -4');
equal(['a','b','c'].first(), 'a', 'Array#first | no argument');
equal(['a','b','c'].first(1), ['a'], 'Array#first | 1', { prototype: 'a' });
equal(['a','b','c'].first(2), ['a','b'], 'Array#first | 2', { prototype: 'a' });
equal(['a','b','c'].first(3), ['a','b','c'], 'Array#first | 3', { prototype: 'a' });
equal(['a','b','c'].first(4), ['a','b','c'], 'Array#first | 4', { prototype: 'a' });
equal(['a','b','c'].first(-1), [], 'Array#first | -1', { prototype: 'a' });
equal(['a','b','c'].first(-2), [], 'Array#first | -2', { prototype: 'a' });
equal(['a','b','c'].first(-3), [], 'Array#first | -3', { prototype: 'a' });
equal(['a','b','c'].last(), 'c', 'Array#last | no argument');
equal(['a','b','c'].last(1), ['c'], 'Array#last | 1', { prototype: 'c' });
equal(['a','b','c'].last(2), ['b','c'], 'Array#last | 2', { prototype: 'c' });
equal(['a','b','c'].last(3), ['a','b','c'], 'Array#last | 3', { prototype: 'c' });
equal(['a','b','c'].last(4), ['a','b','c'], 'Array#last | 4', { prototype: 'c' });
equal(['a','b','c'].last(-1), [], 'Array#last | -1', { prototype: 'c' });
equal(['a','b','c'].last(-2), [], 'Array#last | -2', { prototype: 'c' });
equal(['a','b','c'].last(-3), [], 'Array#last | -3', { prototype: 'c' });
equal(['a','b','c'].last(-4), [], 'Array#last | -4', { prototype: 'c' });
equal([12,87,55].min(), 12, 'Array#min | no argument', { prototype: 12 });
equal([12,87,55].min(undefined), 12, 'Array#min | undefined', { prototype: 12 });
equal([-12,-87,-55].min(), -87, 'Array#min | -87', { prototype: -87 });
equal([5,5,5].min(), 5, 'Array#min | 5 is uniqued', { prototype: 5 });
equal(['a','b','c'].min(), 'a', 'Array#min | strings are not counted', { prototype: 'a' });
equal([].min(), undefined, 'Array#min | empty array', { prototype: undefined });
equal([null].min(), null, 'Array#min | [null]', { prototype: null });
equal([{a:1,b:5},{a:2,b:5},{a:3,b:5}].min(function(el) { return el['a']; }), {a:1,b:5}, 'Array#min | key "a"', { prototype: 1 });
equal([{a:1,b:5},{a:2,b:4},{a:3,b:3}].min(function(el) { return el['b']; }), {a:3,b:3}, 'Array#min | key "b", 1 found', { prototype: 3 });
equal([{a:1,b:5},{a:3,b:3},{a:3,b:3}].min(function(el) { return el['b']; }), {a:3,b:3}, 'Array#min | key "b", 1 found', { prototype: 3 });
equal([{a:1,b:3},{a:2,b:4},{a:3,b:3}].min(function(el) { return el['b']; }), {a:1,b:3}, 'Array#min | key "b", first found', { prototype: 3 });
equal([{a:1,b:3},{a:2,b:4},{a:3,b:3}].min(function(el) { return el['b']; }, true), [{a:1,b:3},{a:3,b:3}], 'Array#min | key "b", 2 found', { prototype: 3 });
equal([{a:-1,b:-5},{a:-2,b:-4},{a:-3,b:-3}].min(function(el) { return el['b']; }), {a:-1,b:-5}, 'Array#min | key "b", 1 found', { prototype: -5 });
equal(['short','and','mort'].min(function(el) { return el.length; }), 'and', 'Array#min | length', { prototype: 3 });
equal(['short','and','mort','fat'].min(function(el) { return el.length; }, true), ['and','fat'], 'Array#min | and,fat', { prototype: 3 });
equal(['short','and','mort'].min('length'), 'and', 'Array#min | length with shortcut', { prototype: 3 });
equal(['short','and','mort'].min('length', true), ['and'], 'Array#min | length with shortcut', { prototype: 3 });
skipEnvironments(['prototype'], function() {
[1].min(function(el,i,a) {
equal(this, [1], 'Array#min | scope should be the array');
equal(i, 0, 'Array#min | second param should be the index');
equal(a, [1], 'Array#min | third param should also be the array');
return el;
});
});
equal([12,12,12].min(function(n) { return n; }, true), [12,12,12], 'Array#min | should not unique', { prototype: 12 });
raisesError(function() { arrayOfUndefined.min(); }, 'Array#min | should raise an error when comparing undefined');
raisesError(function() { [1].concat(arrayOfUndefined).min(); }, 'Array#min | should raise an error when comparing 1 to undefined');
raisesError(function() { [87,12,55].min(4); }, 'Array#min | number not found in number, so undefined');
raisesError(function() { [12,87,55].min(null); }, 'Array#min | null not found in number, so undefined');
equal([12,87,55].max(), 87, 'Array#max | no argument', { prototype: 87 });
equal([12,87,55].max(undefined), 87, 'Array#max | undefined', { prototype: 87 });
equal([-12,-87,-55].max(), -12, 'Array#max | -12', { prototype: -12 });
equal([5,5,128].max(), 128, 'Array#max | 128', { prototype: 128 });
equal([128,128,128].max(), 128, 'Array#max | 128 is uniqued', { prototype: 128 });
equal(['a','b','c'].max(), 'c', 'Array#max | strings are not counted', { prototype: 'c' });
equal([].max(), undefined, 'Array#max | empty array', { prototype: undefined });
equal([null].max(), null, 'Array#max | [null]', { prototype: null });
equal([{a:1,b:5},{a:2,b:5},{a:3,b:5}].max(function(el) { return el['a']; }), {a:3,b:5}, 'Array#max | key "a"', { prototype: 3 });
equal([{a:1,b:5},{a:2,b:4},{a:3,b:3}].max(function(el) { return el['b']; }), {a:1,b:5}, 'Array#max | key "b" returns b:5', { prototype: 5 });
equal([{a:1,b:3},{a:2,b:4},{a:3,b:3}].max(function(el) { return el['b']; }), {a:2,b:4}, 'Array#max | key "b" returns b:4', { prototype: 4 });
equal([{a:1,b:3},{a:2,b:4},{a:2,b:4}].max(function(el) { return el['b']; }), {a:2,b:4}, 'Array#max | key "b" returns b:4 uniqued', { prototype: 4 });
equal([{a:1,b:3},{a:2,b:1},{a:3,b:3}].max(function(el) { return el['b']; }), {a:1,b:3}, 'Array#max | key "b", first found', { prototype: 3 });
equal([{a:1,b:3},{a:2,b:1},{a:3,b:3}].max(function(el) { return el['b']; }, true), [{a:1,b:3},{a:3,b:3}], 'Array#max | key "b", 2 found', { prototype: 3 });
equal([{a:-1,b:-5},{a:-2,b:-4},{a:-3,b:-3}].max(function(el) { return el['b']; }), {a:-3,b:-3}, 'Array#max | key "b" returns b:-3', { prototype: -3 });
equal(['short','and', 'mort'].max(function(el) { return el.length; }), 'short', 'Array#max | length', { prototype: 5 });
equal(['short','and', 'morts', 'fat'].max(function(el) { return el.length; }, true), ['short','morts'], 'Array#max | short,morts', { prototype: 5 });
skipEnvironments(['prototype'], function() {
[1].max(function(el,i,a) {
equal(this, [1], 'Array#max | scope should be the array');
equal(i, 0, 'Array#max | second param should be the index');
equal(a, [1], 'Array#max | third param should also be the array');
return el;
});
});
equal([12,12,12].max(function(n){ return n; }, true), [12,12,12], 'Array#max | should not unique', { prototype: 12 });
raisesError(function() { arrayOfUndefined.max(); }, 'Array#max | should raise an error when comparing undefined');
raisesError(function() { [1].concat(arrayOfUndefined).max(); }, 'Array#max | should raise an error when comparing 1 to undefined');
raisesError(function() { [87,12,55].max(4); }, 'Array#max | number not found in number, so undefined');
raisesError(function() { [12,87,55].max(null); }, 'Array#max | null not found in number, so undefined');
var people = [
{ name: 'jim', age: 27, hair: 'brown' },
{ name: 'mary', age: 52, hair: 'blonde' },
{ name: 'ronnie', age: 13, hair: 'brown' },
{ name: 'edmund', age: 27, hair: 'blonde' }
];
equal([1,2,3].most(null), 1, 'Array#most | null | returns first');
equal([1,2,3].most(undefined), 1, 'Array#most | undefined | returns first');
equal([1,2,3].most(4), 1, 'Array#most | number | returns first');
equal(people.most(function(person) { return person.age; }).age, 27, 'Array#most | age | age is 27');
equal(people.most(function(person) { return person.age; }, true), [{name:'jim',age:27,hair:'brown'},{name:'edmund',age:27,hair:'blonde'}], 'Array#most | age | returns all');
equal(people.most(function(person) { return person.hair; }), {name:'jim',age:27,hair:'brown'}, 'Array#most | hair');
equal([].most(), undefined, 'Array#most | empty array');
equal([1,2,3].most(), 1, 'Array#most | 1,2,3');
equal([1,2,3,3].most(), 3, 'Array#most | 1,2,3,3');
equal([1,1,2,3,3].most(), 1, 'Array#most | 1,1,2,3,3 | first');
equal([1,1,2,3,3].most(function(n) { return n; }, true), [1,1,3,3], 'Array#most | 1,1,2,3,3 | all');
equal(['a','b','c'].most(), 'a', 'Array#most | a,b,c');
equal(['a','b','c','c'].most(), 'c', 'Array#most | a,b,c,c');
equal(['a','a','b','c','c'].most(), 'a', 'Array#most | a,a,b,c,c | first');
equal(['a','a','b','c','c'].most(function(s){ return s; }, true), ['a','a','c','c'], 'Array#most | a,a,b,c,c | all');
// Leaving this here as a reference for how to collect the actual number of occurences.
equal(people.most(function(person) { return person.age; }, true).length, 2, 'Array#most | collect actual number of occurrences');
[1].most(function(el,i,a) {
equal(this, [1], 'Array#most | scope should be the array');
equal(i, 0, 'Array#most | second param should be the index');
equal(a, [1], 'Array#most | third param should also be the array');
return el;
});
equal([1,2,3].least(null), 1, 'Array#least | null');
equal([1,2,3].least(undefined), 1, 'Array#least | undefined');
equal([1,2,3].least(4), 1, 'Array#least | number');
equal(people.least(), people[0], 'Array#least | contains mary | does not return most');
equal(people.least(function(person) { return person.age; })