1 /* global describe, it, expect, beforeEach, jasmine, xit */
3 var toStr = Object.prototype.toString;
4 var canDistinguishSparseFromUndefined = 0 in [undefined]; // IE 6 - 8 have a bug where this returns false.
5 var ifHasDenseUndefinedsIt = canDistinguishSparseFromUndefined ? it : xit;
6 var undefinedIfNoSparseBug = canDistinguishSparseFromUndefined ? undefined : { valueOf: function () { return 0; } };
7 var hasStrictMode = (function () {
12 var ifHasStrictIt = hasStrictMode ? it : xit;
14 describe('Array', function () {
17 beforeEach(function () {
18 testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, false, 0];
19 delete testSubject[1];
22 var createArrayLikeFromArray = function createArrayLikeFromArray(arr) {
24 Array.prototype.forEach.call(arr, function (e, i) {
27 o.length = arr.length;
31 describe('#forEach()', function () {
34 beforeEach(function () {
35 expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true, 4: 'hej', 5: null, 6: false, 7: 0 };
39 it('should pass the right parameters', function () {
40 var callback = jasmine.createSpy('callback');
42 array.forEach(callback);
43 expect(callback).toHaveBeenCalledWith('1', 0, array);
46 it('should not affect elements added to the array after it has begun', function () {
49 arr.forEach(function (a) {
53 expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
57 it('should set the right context when given none', function () {
59 [1].forEach(function () { context = this; });
60 expect(context).toBe(function () { return this; }.call());
63 it('should iterate all', function () {
64 testSubject.forEach(function (obj, index) {
67 expect(actual).toExactlyMatch(expected);
70 it('should iterate all using a context', function () {
71 var o = { a: actual };
73 testSubject.forEach(function (obj, index) {
76 expect(actual).toExactlyMatch(expected);
79 it('should iterate all in an array-like object', function () {
80 var ts = createArrayLikeFromArray(testSubject);
81 Array.prototype.forEach.call(ts, function (obj, index) {
84 expect(actual).toExactlyMatch(expected);
87 it('should iterate all in an array-like object using a context', function () {
88 var ts = createArrayLikeFromArray(testSubject);
89 var o = { a: actual };
91 Array.prototype.forEach.call(ts, function (obj, index) {
94 expect(actual).toExactlyMatch(expected);
97 describe('strings', function () {
98 var str = 'Hello, World!';
100 it('should iterate all in a string', function () {
102 Array.prototype.forEach.call(str, function (item, index) {
103 actual[index] = item;
105 expect(actual).toExactlyMatch(str.split(''));
108 it('should iterate all in a string using a context', function () {
110 var o = { a: actual };
111 Array.prototype.forEach.call(str, function (item, index) {
112 this.a[index] = item;
114 expect(actual).toExactlyMatch(str.split(''));
118 it('should have a boxed object as list argument of callback', function () {
120 Array.prototype.forEach.call('foo', function (item, index, list) {
123 expect(typeof listArg).toBe('object');
124 expect(toStr.call(listArg)).toBe('[object String]');
127 ifHasStrictIt('does not autobox the content in strict mode', function () {
129 [1].forEach(function () {
134 expect(typeof context).toBe('string');
137 describe('#some()', function () {
138 var actual, expected, numberOfRuns;
140 beforeEach(function () {
141 expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true };
146 it('should pass the correct values along to the callback', function () {
147 var callback = jasmine.createSpy('callback');
149 array.some(callback);
150 expect(callback).toHaveBeenCalledWith('1', 0, array);
153 it('should not affect elements added to the array after it has begun', function () {
156 arr.some(function (a) {
161 expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
165 it('should set the right context when given none', function () {
166 /* eslint-disable array-callback-return */
168 [1].some(function () { context = this; });
169 expect(context).toBe(function () { return this; }.call());
172 it('should return false if it runs to the end', function () {
173 /* eslint-disable array-callback-return */
174 actual = testSubject.some(function () {});
175 expect(actual).toBeFalsy();
178 it('should return true if it is stopped somewhere', function () {
179 actual = testSubject.some(function () { return true; });
180 expect(actual).toBeTruthy();
183 it('should return false if there are no elements', function () {
184 actual = [].some(function () { return true; });
185 expect(actual).toBeFalsy();
188 it('should stop after 3 elements', function () {
189 testSubject.some(function (obj, index) {
192 return numberOfRuns === 3;
194 expect(actual).toExactlyMatch(expected);
197 it('should stop after 3 elements using a context', function () {
198 var o = { a: actual };
199 testSubject.some(function (obj, index) {
202 return numberOfRuns === 3;
204 expect(actual).toExactlyMatch(expected);
207 it('should stop after 3 elements in an array-like object', function () {
208 var ts = createArrayLikeFromArray(testSubject);
209 Array.prototype.some.call(ts, function (obj, index) {
212 return numberOfRuns === 3;
214 expect(actual).toExactlyMatch(expected);
217 it('should stop after 3 elements in an array-like object using a context', function () {
218 var ts = createArrayLikeFromArray(testSubject);
219 var o = { a: actual };
220 Array.prototype.some.call(ts, function (obj, index) {
223 return numberOfRuns === 3;
225 expect(actual).toExactlyMatch(expected);
228 it('should have a boxed object as list argument of callback', function () {
230 Array.prototype.some.call('foo', function (item, index, list) {
233 expect(typeof listArg).toBe('object');
234 expect(toStr.call(listArg)).toBe('[object String]');
237 describe('#every()', function () {
238 var actual, expected, numberOfRuns;
240 beforeEach(function () {
241 expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true };
246 it('should pass the correct values along to the callback', function () {
247 var callback = jasmine.createSpy('callback');
249 array.every(callback);
250 expect(callback).toHaveBeenCalledWith('1', 0, array);
253 it('should not affect elements added to the array after it has begun', function () {
256 arr.every(function (a) {
261 expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
265 it('should set the right context when given none', function () {
266 /* eslint-disable array-callback-return */
268 [1].every(function () { context = this; });
269 expect(context).toBe(function () { return this; }.call());
272 it('should return true if the array is empty', function () {
273 actual = [].every(function () { return true; });
274 expect(actual).toBeTruthy();
276 actual = [].every(function () { return false; });
277 expect(actual).toBeTruthy();
280 it('should return true if it runs to the end', function () {
281 actual = [1, 2, 3].every(function () { return true; });
282 expect(actual).toBeTruthy();
285 it('should return false if it is stopped before the end', function () {
286 actual = [1, 2, 3].every(function () { return false; });
287 expect(actual).toBeFalsy();
290 it('should return after 3 elements', function () {
291 testSubject.every(function (obj, index) {
294 return numberOfRuns !== 3;
296 expect(actual).toExactlyMatch(expected);
299 it('should stop after 3 elements using a context', function () {
300 var o = { a: actual };
301 testSubject.every(function (obj, index) {
304 return numberOfRuns !== 3;
306 expect(actual).toExactlyMatch(expected);
309 it('should stop after 3 elements in an array-like object', function () {
310 var ts = createArrayLikeFromArray(testSubject);
311 Array.prototype.every.call(ts, function (obj, index) {
314 return numberOfRuns !== 3;
316 expect(actual).toExactlyMatch(expected);
319 it('should stop after 3 elements in an array-like object using a context', function () {
320 var ts = createArrayLikeFromArray(testSubject);
321 var o = { a: actual };
322 Array.prototype.every.call(ts, function (obj, index) {
325 return numberOfRuns !== 3;
327 expect(actual).toExactlyMatch(expected);
330 it('should have a boxed object as list argument of callback', function () {
332 Array.prototype.every.call('foo', function (item, index, list) {
335 expect(typeof listArg).toBe('object');
336 expect(toStr.call(listArg)).toBe('[object String]');
340 describe('#indexOf()', function () {
343 var actual, expected;
345 beforeEach(function () {
346 testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0];
347 delete testSubject[1];
350 it('should find the element', function () {
352 actual = testSubject.indexOf('hej');
353 expect(actual).toBe(expected);
356 it('should not find the element', function () {
358 actual = testSubject.indexOf('mus');
359 expect(actual).toBe(expected);
362 ifHasDenseUndefinedsIt('should find undefined as well', function () {
364 actual = testSubject.indexOf(undefined);
365 expect(actual).not.toBe(expected);
368 ifHasDenseUndefinedsIt('should skip unset indexes', function () {
370 actual = testSubject.indexOf(undefined);
371 expect(actual).toBe(expected);
374 it('should use a strict test', function () {
375 actual = testSubject.indexOf(null);
376 expect(actual).toBe(5);
378 actual = testSubject.indexOf('2');
379 expect(actual).toBe(-1);
382 it('should skip the first if fromIndex is set', function () {
383 expect(testSubject.indexOf(2, 2)).toBe(6);
384 expect(testSubject.indexOf(2, 0)).toBe(0);
385 expect(testSubject.indexOf(2, 6)).toBe(6);
388 it('should work with negative fromIndex', function () {
389 expect(testSubject.indexOf(2, -3)).toBe(6);
390 expect(testSubject.indexOf(2, -9)).toBe(0);
393 it('should work with fromIndex being greater than the length', function () {
394 expect(testSubject.indexOf(0, 20)).toBe(-1);
397 it('should work with fromIndex being negative and greater than the length', function () {
398 expect(testSubject.indexOf('hej', -20)).toBe(4);
401 describe('Array-like', function ArrayLike() {
402 var indexOf = Array.prototype.indexOf;
405 beforeEach(function beforeEach() {
407 testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0];
408 testSubject.forEach(function (o, i) {
411 testAL.length = testSubject.length;
414 it('should find the element (array-like)', function () {
416 actual = indexOf.call(testAL, 'hej');
417 expect(actual).toBe(expected);
420 it('should not find the element (array-like)', function () {
422 actual = indexOf.call(testAL, 'mus');
423 expect(actual).toBe(expected);
426 ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () {
428 actual = indexOf.call(testAL, undefined);
429 expect(actual).not.toBe(expected);
432 ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () {
434 actual = indexOf.call(testAL, undefined);
435 expect(actual).toBe(expected);
438 it('should use a strict test (array-like)', function () {
439 actual = Array.prototype.indexOf.call(testAL, null);
440 expect(actual).toBe(5);
442 actual = Array.prototype.indexOf.call(testAL, '2');
443 expect(actual).toBe(-1);
446 it('should skip the first if fromIndex is set (array-like)', function () {
447 expect(indexOf.call(testAL, 2, 2)).toBe(6);
448 expect(indexOf.call(testAL, 2, 0)).toBe(0);
449 expect(indexOf.call(testAL, 2, 6)).toBe(6);
452 it('should work with negative fromIndex (array-like)', function () {
453 expect(indexOf.call(testAL, 2, -3)).toBe(6);
454 expect(indexOf.call(testAL, 2, -9)).toBe(0);
457 it('should work with fromIndex being greater than the length (array-like)', function () {
458 expect(indexOf.call(testAL, 0, 20)).toBe(-1);
461 it('should work with fromIndex being negative and greater than the length (array-like)', function () {
462 expect(indexOf.call(testAL, 'hej', -20)).toBe(4);
466 describe('#lastIndexOf()', function () {
469 var actual, expected;
471 beforeEach(function () {
472 testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, 3, false, 0];
473 delete testSubject[1];
474 delete testSubject[7];
477 describe('Array', function () {
478 it('should find the element', function () {
480 actual = testSubject.lastIndexOf('hej');
481 expect(actual).toBe(expected);
484 it('should not find the element', function () {
486 actual = testSubject.lastIndexOf('mus');
487 expect(actual).toBe(expected);
490 ifHasDenseUndefinedsIt('should find undefined as well', function () {
492 actual = testSubject.lastIndexOf(undefined);
493 expect(actual).not.toBe(expected);
496 ifHasDenseUndefinedsIt('should skip unset indexes', function () {
498 actual = testSubject.lastIndexOf(undefined);
499 expect(actual).toBe(expected);
502 it('should use a strict test', function () {
503 actual = testSubject.lastIndexOf(null);
504 expect(actual).toBe(5);
506 actual = testSubject.lastIndexOf('2');
507 expect(actual).toBe(-1);
510 it('should skip the first if fromIndex is set', function () {
511 expect(testSubject.lastIndexOf(2, 2)).toBe(0);
512 expect(testSubject.lastIndexOf(2, 0)).toBe(0);
513 expect(testSubject.lastIndexOf(2, 6)).toBe(6);
516 it('should work with negative fromIndex', function () {
517 expect(testSubject.lastIndexOf(2, -3)).toBe(6);
518 expect(testSubject.lastIndexOf(2, -9)).toBe(0);
521 it('should work with fromIndex being greater than the length', function () {
522 expect(testSubject.lastIndexOf(2, 20)).toBe(6);
525 it('should work with fromIndex being negative and greater than the length', function () {
526 expect(testSubject.lastIndexOf(2, -20)).toBe(-1);
530 describe('Array like', function () {
531 var lastIndexOf = Array.prototype.lastIndexOf;
534 beforeEach(function () {
536 testSubject.forEach(function (o, i) {
539 testAL.length = testSubject.length;
542 it('should find the element (array-like)', function () {
544 actual = lastIndexOf.call(testAL, 'hej');
545 expect(actual).toBe(expected);
548 it('should not find the element (array-like)', function () {
550 actual = lastIndexOf.call(testAL, 'mus');
551 expect(actual).toBe(expected);
554 ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () {
556 actual = lastIndexOf.call(testAL, undefined);
557 expect(actual).not.toBe(expected);
560 ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () {
562 actual = lastIndexOf.call(testAL, undefined);
563 expect(actual).toBe(expected);
566 it('should use a strict test (array-like)', function () {
567 actual = lastIndexOf.call(testAL, null);
568 expect(actual).toBe(5);
570 actual = lastIndexOf.call(testAL, '2');
571 expect(actual).toBe(-1);
574 it('should skip the first if fromIndex is set', function () {
575 expect(lastIndexOf.call(testAL, 2, 2)).toBe(0);
576 expect(lastIndexOf.call(testAL, 2, 0)).toBe(0);
577 expect(lastIndexOf.call(testAL, 2, 6)).toBe(6);
580 it('should work with negative fromIndex', function () {
581 expect(lastIndexOf.call(testAL, 2, -3)).toBe(6);
582 expect(lastIndexOf.call(testAL, 2, -9)).toBe(0);
585 it('should work with fromIndex being greater than the length', function () {
586 expect(lastIndexOf.call(testAL, 2, 20)).toBe(6);
589 it('should work with fromIndex being negative and greater than the length', function () {
590 expect(lastIndexOf.call(testAL, 2, -20)).toBe(-1);
595 describe('#filter()', function () {
597 var callback = function callback(o, i) {
598 return i !== 3 && i !== 5;
601 beforeEach(function () {
602 testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', 3, null, false, 0];
603 delete testSubject[1];
604 filteredArray = [2, undefinedIfNoSparseBug, 'hej', null, false, 0];
606 describe('Array object', function () {
607 it('should call the callback with the proper arguments', function () {
608 var predicate = jasmine.createSpy('predicate');
610 arr.filter(predicate);
611 expect(predicate).toHaveBeenCalledWith('1', 0, arr);
614 it('should not affect elements added to the array after it has begun', function () {
617 arr.filter(function (a) {
624 expect(arr).toEqual([1, 2, 3, 4, 5, 6]);
628 ifHasDenseUndefinedsIt('should skip unset values', function () {
629 var passedValues = {};
630 testSubject = [1, 2, 3, 4];
631 delete testSubject[1];
632 testSubject.filter(function (o, i) {
636 expect(passedValues).toExactlyMatch(testSubject);
639 it('should pass the right context to the filter', function () {
640 var passedValues = {};
641 testSubject = [1, 2, 3, 4];
642 delete testSubject[1];
643 testSubject.filter(function (o, i) {
647 expect(passedValues).toExactlyMatch(testSubject);
650 it('should set the right context when given none', function () {
651 /* eslint-disable array-callback-return */
653 [1].filter(function () { context = this; });
654 expect(context).toBe(function () { return this; }.call());
657 it('should remove only the values for which the callback returns false', function () {
658 var result = testSubject.filter(callback);
659 expect(result).toExactlyMatch(filteredArray);
662 it('should leave the original array untouched', function () {
663 var copy = testSubject.slice();
664 testSubject.filter(callback);
665 expect(testSubject).toExactlyMatch(copy);
668 it('should not be affected by same-index mutation', function () {
669 var results = [1, 2, 3].filter(function (value, index, array) {
673 expect(results).toEqual([1, 2, 3]);
677 describe('Array like', function () {
678 beforeEach(function () {
679 testSubject = createArrayLikeFromArray(testSubject);
682 it('should call the predicate with the proper arguments', function () {
683 var predicate = jasmine.createSpy('predicate');
684 var arr = createArrayLikeFromArray(['1']);
685 Array.prototype.filter.call(arr, predicate);
686 expect(predicate).toHaveBeenCalledWith('1', 0, arr);
689 it('should not affect elements added to the array after it has begun', function () {
690 var arr = createArrayLikeFromArray([1, 2, 3]);
692 Array.prototype.filter.call(arr, function (a) {
700 expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]);
704 it('should skip non-set values', function () {
705 var passedValues = createArrayLikeFromArray([]);
706 testSubject = createArrayLikeFromArray([1, 2, 3, 4]);
707 delete testSubject[1];
708 Array.prototype.filter.call(testSubject, function (o, i) {
710 passedValues.length = i + 1;
713 expect(passedValues).toEqual(testSubject);
716 it('should set the right context when given none', function () {
718 Array.prototype.filter.call(createArrayLikeFromArray([1]), function () { context = this; }, undefined);
719 expect(context).toBe(function () { return this; }.call());
722 it('should pass the right context to the filter', function () {
723 var passedValues = {};
724 testSubject = createArrayLikeFromArray([1, 2, 3, 4]);
725 delete testSubject[1];
726 Array.prototype.filter.call(testSubject, function (o, i) {
731 expect(passedValues).toEqual(testSubject);
734 it('should remove only the values for which the callback returns false', function () {
735 var result = Array.prototype.filter.call(testSubject, callback);
736 expect(result).toExactlyMatch(filteredArray);
739 it('should leave the original array untouched', function () {
740 var copy = createArrayLikeFromArray(testSubject);
741 Array.prototype.filter.call(testSubject, callback);
742 expect(testSubject).toExactlyMatch(copy);
746 it('should have a boxed object as list argument of callback', function () {
748 Array.prototype.filter.call('foo', function (item, index, list) {
751 expect(typeof actual).toBe('object');
752 expect(toStr.call(actual)).toBe('[object String]');
755 describe('#map()', function () {
757 beforeEach(function () {
759 callback = function () {
763 describe('Array object', function () {
764 it('should call mapper with the right parameters', function () {
765 var mapper = jasmine.createSpy('mapper');
768 expect(mapper).toHaveBeenCalledWith(1, 0, array);
771 it('should set the context correctly', function () {
773 testSubject.map(function (o, i) {
776 expect(context).toExactlyMatch(testSubject);
779 it('should set the right context when given none', function () {
781 [1].map(function () { context = this; });
782 expect(context).toBe(function () { return this; }.call());
785 it('should not change the array it is called on', function () {
786 var copy = testSubject.slice();
787 testSubject.map(callback);
788 expect(testSubject).toExactlyMatch(copy);
791 it('should only run for the number of objects in the array when it started', function () {
794 arr.map(function (o) {
799 expect(arr).toExactlyMatch([1, 2, 3, 4, 5, 6]);
803 it('should properly translate the values as according to the callback', function () {
804 var result = testSubject.map(callback);
805 var expected = [0, 0, 1, 2, 3, 4, 5, 6];
807 expect(result).toExactlyMatch(expected);
810 it('should skip non-existing values', function () {
811 var array = [1, 2, 3, 4];
814 array.map(function () {
820 describe('Array-like', function () {
821 beforeEach(function () {
822 testSubject = createArrayLikeFromArray(testSubject);
825 it('should call mapper with the right parameters', function () {
826 var mapper = jasmine.createSpy('mapper');
827 var array = createArrayLikeFromArray([1]);
828 Array.prototype.map.call(array, mapper);
829 expect(mapper).toHaveBeenCalledWith(1, 0, array);
832 it('should set the context correctly', function () {
834 Array.prototype.map.call(testSubject, function (o, i) {
838 expect(context).toEqual(testSubject);
841 it('should set the right context when given none', function () {
843 Array.prototype.map.call(createArrayLikeFromArray([1]), function () { context = this; });
844 expect(context).toBe(function () { return this; }.call());
847 it('should not change the array it is called on', function () {
848 var copy = createArrayLikeFromArray(testSubject);
849 Array.prototype.map.call(testSubject, callback);
850 expect(testSubject).toExactlyMatch(copy);
853 it('should only run for the number of objects in the array when it started', function () {
854 var arr = createArrayLikeFromArray([1, 2, 3]);
856 Array.prototype.map.call(arr, function (o) {
857 Array.prototype.push.call(arr, o + 3);
861 expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]);
865 it('should properly translate the values as according to the callback', function () {
866 var result = Array.prototype.map.call(testSubject, callback);
867 var expected = [0, 0, 1, 2, 3, 4, 5, 6];
869 expect(result).toExactlyMatch(expected);
872 it('should skip non-existing values', function () {
873 var array = createArrayLikeFromArray([1, 2, 3, 4]);
876 Array.prototype.map.call(array, function () {
883 it('should have a boxed object as list argument of callback', function () {
885 Array.prototype.map.call('foo', function (item, index, list) {
888 expect(typeof actual).toBe('object');
889 expect(toStr.call(actual)).toBe('[object String]');
893 describe('#reduce()', function () {
894 beforeEach(function () {
895 testSubject = [1, 2, 3];
898 describe('Array', function () {
899 it('should pass the correct arguments to the callback', function () {
900 var spy = jasmine.createSpy().andReturn(0);
901 testSubject.reduce(spy);
902 expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);
905 it('should start with the right initialValue', function () {
906 var spy = jasmine.createSpy().andReturn(0);
907 testSubject.reduce(spy, 0);
908 expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);
911 it('should not affect elements added to the array after it has begun', function () {
914 arr.reduce(function (a, b) {
921 expect(arr).toEqual([1, 2, 3, 4, 5]);
925 it('should work as expected for empty arrays', function () {
926 var spy = jasmine.createSpy();
930 expect(spy).not.toHaveBeenCalled();
933 it('should throw correctly if no callback is given', function () {
935 testSubject.reduce();
939 it('should return the expected result', function () {
940 expect(testSubject.reduce(function (a, b) {
941 return String(a || '') + String(b || '');
942 })).toBe(testSubject.join(''));
945 it('should not directly affect the passed array', function () {
946 var copy = testSubject.slice();
947 testSubject.reduce(function (a, b) {
950 expect(testSubject).toEqual(copy);
953 it('should skip non-set values', function () {
954 delete testSubject[1];
956 testSubject.reduce(function (a, b) {
957 if (a) { visited[a] = true; }
958 if (b) { visited[b] = true; }
962 expect(visited).toEqual({ 1: true, 3: true });
965 it('should have the right length', function () {
966 expect(testSubject.reduce.length).toBe(1);
969 describe('Array-like objects', function () {
970 beforeEach(function () {
971 testSubject = createArrayLikeFromArray(testSubject);
972 testSubject.reduce = Array.prototype.reduce;
975 it('should pass the correct arguments to the callback', function () {
976 var spy = jasmine.createSpy().andReturn(0);
977 testSubject.reduce(spy);
978 expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);
981 it('should start with the right initialValue', function () {
982 var spy = jasmine.createSpy().andReturn(0);
983 testSubject.reduce(spy, 0);
984 expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);
987 it('should not affect elements added to the array after it has begun', function () {
988 var arr = createArrayLikeFromArray([1, 2, 3]);
990 Array.prototype.reduce.call(arr, function (a, b) {
997 expect(arr).toEqual({
1008 it('should work as expected for empty arrays', function () {
1009 var spy = jasmine.createSpy();
1010 expect(function () {
1011 Array.prototype.reduce.call({ length: 0 }, spy);
1013 expect(spy).not.toHaveBeenCalled();
1016 it('should throw correctly if no callback is given', function () {
1017 expect(function () {
1018 testSubject.reduce();
1022 it('should return the expected result', function () {
1023 expect(testSubject.reduce(function (a, b) {
1024 return String(a || '') + String(b || '');
1028 it('should not directly affect the passed array', function () {
1029 var copy = createArrayLikeFromArray(testSubject);
1030 testSubject.reduce(function (a, b) {
1033 delete testSubject.reduce;
1034 expect(testSubject).toEqual(copy);
1037 it('should skip non-set values', function () {
1038 delete testSubject[1];
1040 testSubject.reduce(function (a, b) {
1041 if (a) { visited[a] = true; }
1042 if (b) { visited[b] = true; }
1046 expect(visited).toEqual({ 1: true, 3: true });
1049 it('should have the right length', function () {
1050 expect(testSubject.reduce.length).toBe(1);
1054 it('should have a boxed object as list argument of callback', function () {
1056 Array.prototype.reduce.call('foo', function (accumulator, item, index, list) {
1059 expect(typeof actual).toBe('object');
1060 expect(toStr.call(actual)).toBe('[object String]');
1063 describe('#reduceRight()', function () {
1064 beforeEach(function () {
1065 testSubject = [1, 2, 3];
1068 describe('Array', function () {
1069 it('should pass the correct arguments to the callback', function () {
1070 var spy = jasmine.createSpy().andReturn(0);
1071 testSubject.reduceRight(spy);
1072 expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);
1075 it('should start with the right initialValue', function () {
1076 var spy = jasmine.createSpy().andReturn(0);
1077 testSubject.reduceRight(spy, 0);
1078 expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);
1081 it('should not affect elements added to the array after it has begun', function () {
1082 var arr = [1, 2, 3];
1084 arr.reduceRight(function (a, b) {
1091 expect(arr).toEqual([1, 2, 3, 6, 5]);
1095 it('should work as expected for empty arrays', function () {
1096 var spy = jasmine.createSpy();
1097 expect(function () {
1098 [].reduceRight(spy);
1100 expect(spy).not.toHaveBeenCalled();
1103 it('should work as expected for empty arrays with an initial value', function () {
1104 var spy = jasmine.createSpy();
1107 result = [].reduceRight(spy, '');
1108 expect(spy).not.toHaveBeenCalled();
1109 expect(result).toBe('');
1112 it('should throw correctly if no callback is given', function () {
1113 expect(function () {
1114 testSubject.reduceRight();
1118 it('should return the expected result', function () {
1119 expect(testSubject.reduceRight(function (a, b) {
1120 return String(a || '') + String(b || '');
1124 it('should not directly affect the passed array', function () {
1125 var copy = testSubject.slice();
1126 testSubject.reduceRight(function (a, b) {
1129 expect(testSubject).toEqual(copy);
1132 it('should skip non-set values', function () {
1133 delete testSubject[1];
1135 testSubject.reduceRight(function (a, b) {
1136 if (a) { visited[a] = true; }
1137 if (b) { visited[b] = true; }
1141 expect(visited).toEqual({ 1: true, 3: true });
1144 it('should have the right length', function () {
1145 expect(testSubject.reduceRight.length).toBe(1);
1148 describe('Array-like objects', function () {
1149 beforeEach(function () {
1150 testSubject = createArrayLikeFromArray(testSubject);
1151 testSubject.reduceRight = Array.prototype.reduceRight;
1154 it('should pass the correct arguments to the callback', function () {
1155 var spy = jasmine.createSpy().andReturn(0);
1156 testSubject.reduceRight(spy);
1157 expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);
1160 it('should start with the right initialValue', function () {
1161 var spy = jasmine.createSpy().andReturn(0);
1162 testSubject.reduceRight(spy, 0);
1163 expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);
1166 it('should not affect elements added to the array after it has begun', function () {
1167 var arr = createArrayLikeFromArray([1, 2, 3]);
1169 Array.prototype.reduceRight.call(arr, function (a, b) {
1176 expect(arr).toEqual({
1182 length: 3 // does not get updated on property assignment
1187 it('should work as expected for empty arrays', function () {
1188 var spy = jasmine.createSpy();
1189 expect(function () {
1190 Array.prototype.reduceRight.call({ length: 0 }, spy);
1192 expect(spy).not.toHaveBeenCalled();
1195 it('should throw correctly if no callback is given', function () {
1196 expect(function () {
1197 testSubject.reduceRight();
1201 it('should return the expected result', function () {
1202 expect(testSubject.reduceRight(function (a, b) {
1203 return String(a || '') + String(b || '');
1207 it('should not directly affect the passed array', function () {
1208 var copy = createArrayLikeFromArray(testSubject);
1209 testSubject.reduceRight(function (a, b) {
1212 delete testSubject.reduceRight;
1213 expect(testSubject).toEqual(copy);
1216 it('should skip non-set values', function () {
1217 delete testSubject[1];
1219 testSubject.reduceRight(function (a, b) {
1220 if (a) { visited[a] = true; }
1221 if (b) { visited[b] = true; }
1225 expect(visited).toEqual({ 1: true, 3: true });
1228 it('should have the right length', function () {
1229 expect(testSubject.reduceRight.length).toBe(1);
1233 it('should have a boxed object as list argument of callback', function () {
1235 Array.prototype.reduceRight.call('foo', function (accumulator, item, index, list) {
1238 expect(typeof actual).toBe('object');
1239 expect(toStr.call(actual)).toBe('[object String]');
1243 describe('.isArray()', function () {
1244 it('should be true for Array', function () {
1245 expect(Array.isArray([])).toBe(true);
1248 it('should be false for primitives', function () {
1260 primitives.forEach(function (v) {
1261 expect(Array.isArray(v)).toBe(false);
1265 it('should fail for other objects', function () {
1271 if (Object.create) {
1272 objects.push(Object.create(null));
1275 objects.forEach(function (v) {
1276 expect(Array.isArray(v)).toBe(false);
1280 /* globals document */
1281 if (typeof document !== 'undefined') {
1282 it('should be false for an HTML element', function () {
1283 var el = document.getElementsByTagName('div');
1284 expect(Array.isArray(el)).toBe(false);
1289 describe('#shift()', function () {
1290 it('works on arrays', function () {
1292 var result = arr.shift();
1293 expect(result).toBe(1);
1294 expect(arr.length).toBe(1);
1295 expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);
1296 expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(false);
1297 expect(arr[0]).toBe(2);
1298 expect(arr[1]).toBeUndefined();
1301 it('is generic', function () {
1302 var obj = { 0: 1, 1: 2, length: 2 };
1303 var result = Array.prototype.shift.call(obj);
1304 expect(result).toBe(1);
1305 expect(obj.length).toBe(1);
1306 expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);
1307 expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(false);
1308 expect(obj[0]).toBe(2);
1309 expect(obj[1]).toBeUndefined();
1313 describe('#unshift()', function () {
1314 it('should return length', function () {
1315 expect([].unshift(0)).toBe(1);
1318 it('works on arrays', function () {
1320 var result = arr.unshift(undefined);
1321 expect(result).toBe(2);
1322 expect(arr.length).toBe(2);
1323 expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);
1324 expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(true);
1325 expect(arr[0]).toBeUndefined();
1326 expect(arr[1]).toBe(1);
1329 it('is generic', function () {
1330 var obj = { 0: 1, length: 1 };
1331 var result = Array.prototype.unshift.call(obj, undefined);
1332 expect(result).toBe(2);
1333 expect(obj.length).toBe(2);
1334 expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);
1335 expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(true);
1336 expect(obj[0]).toBeUndefined();
1337 expect(obj[1]).toBe(1);
1341 describe('#splice()', function () {
1343 var a = [1, 'a', b];
1346 var makeArray = function (l, givenPrefix) {
1347 var prefix = givenPrefix || '';
1351 arr.unshift(prefix + Array(length + 1).join(' ') + length);
1356 beforeEach(function () {
1360 it('has the right length', function () {
1361 expect(Array.prototype.splice.length).toBe(2);
1364 /* This test is disabled, because ES6 normalizes actual
1365 * browser behavior, contradicting ES5.
1367 xit('treats undefined deleteCount as 0', function () {
1368 expect(test.splice(0).length).toBe(0);
1369 expect(test.splice(0)).toEqual(test.splice(0, 0));
1372 it('basic implementation test 1', function () {
1373 expect(test.splice(0, 0)).toEqual([]);
1376 it('basic implementation test 2', function () {
1378 expect(test).toEqual([b]);
1381 it('should return right result 1', function () {
1384 array.splice(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
1385 array.splice(1, 0, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26');
1386 array.splice(5, 0, 'XXX');
1388 expect(array).toEqual([1, 'F1', 'F2', 'F3', 'F4', 'XXX', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);
1391 it('should return right result 2', function () {
1392 var array = makeArray(6);
1394 array.splice(array.length - 1, 1, '');
1395 array.splice(0, 1, 1, 2, 3, 4);
1396 array.splice(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45);
1398 array.splice(4, 0, '99999999999999');
1400 expect(array).toEqual([1, 2, 3, 4, '99999999999999', 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 2, 3, 4, ' 1', ' 2', ' 3', ' 4', '']);
1403 it('should return right result 3', function () {
1404 var array = [1, 2, 3];
1406 array.splice(0, array.length);
1407 array.splice(0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
1408 array.splice(1, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26');
1409 array.splice(5, 1, 'YYY', 'XXX');
1413 array.push.apply(array, makeArray(10, '-'));
1414 array.splice(array.length - 2, 10);
1416 array.splice(1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9);
1417 array.splice(1, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8);
1418 array.splice(30, 10);
1419 array.splice(30, 1);
1420 array.splice(30, 0);
1421 array.splice(2, 5, 1, 2, 3, 'P', 'LLL', 'CCC', 'YYY', 'XXX');
1422 array.push(1, 2, 3, 4, 5, 6);
1423 array.splice(1, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 5, 6, 7, 8, 9);
1425 array.unshift(7, 8, 9, 10, 11);
1429 array.unshift.apply(array, makeArray(8, '~'));
1431 array.splice(3, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8);
1432 array.splice(4, 5, 'P', 'LLL', 'CCC', 'YYY', 'XXX');
1434 expect(array).toEqual(['~0', '~ 1', '~ 2', 'F1', 'P', 'LLL', 'CCC', 'YYY', 'XXX', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8, '~ 4', '~ 5', '~ 6', '~ 7', 7, 8, 9, 10, 11, 2, 4, 5, 6, 7, 8, 9, 'CCC', 'YYY', 'XXX', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'YYY', 'XXX', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 3, 4, 5, 6, 7, 8, 9, '-0', '- 1', '- 2', '- 3', '- 4', '- 5', '- 6', '- 7', 1, 2, 3]);
1437 it('should do nothing if method called with no arguments', function () {
1438 expect(test.splice()).toEqual([]);
1439 expect(test).toEqual(a);
1442 it('should set first argument to 0 if first argument is set but undefined', function () {
1443 var test2 = test.slice(0);
1444 expect(test.splice(void 0, 2)).toEqual(test2.splice(0, 2));
1445 expect(test).toEqual(test2);
1448 it('should work with objects - adding 1', function () {
1450 Array.prototype.splice.call(obj, 0, 0, 1, 2, 3);
1451 expect(obj.length).toBe(3);
1454 it('should work with objects - adding 2', function () {
1455 var obj = { 0: 1, length: 1 };
1456 Array.prototype.splice.call(obj, 1, 0, 2, 3);
1457 expect(obj.length).toBe(3);
1460 it('should work with objects - removing', function () {
1461 var obj = { 0: 1, 1: 2, 2: 3, length: 3 };
1462 Array.prototype.splice.call(obj, 0, 3);
1463 expect(obj.length).toBe(0);
1466 it('should work with objects - replacing', function () {
1467 var obj = { 0: 99, length: 1 };
1468 Array.prototype.splice.call(obj, 0, 1, 1, 2, 3);
1469 expect(obj.length).toBe(3);
1470 expect(obj[0]).toBe(1);
1473 ifHasDenseUndefinedsIt('should not break on sparse arrays in Opera', function () {
1474 // test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196
1478 arr.splice(n + 1, 0, 'b');
1479 expect(arr[n]).toBe('a');
1482 ifHasDenseUndefinedsIt('should not break on sparse arrays in Safari 7/8', function () {
1483 // test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196
1484 var justFine = new Array(1e5 - 1);
1486 var tooBig = new Array(1e5);
1489 justFine.splice(1, 1);
1490 expect(8 in justFine).toBe(false);
1491 expect(justFine.indexOf('x')).toBe(9);
1492 tooBig.splice(1, 1);
1493 expect(6 in tooBig).toBe(false);
1494 expect(tooBig.indexOf('x')).toBe(7);
1498 describe('#join()', function () {
1499 it('defaults to a comma separator when none is provided', function () {
1500 expect([1, 2].join()).toBe('1,2');
1503 it('defaults to a comma separator when undefined is provided', function () {
1504 expect([1, 2].join(undefined)).toBe('1,2');
1507 it('works, extended', function () {
1508 expect([].join()).toBe('');
1509 expect([undefined].join()).toBe('');
1510 expect([undefined, undefined].join()).toBe(',');
1511 expect([null, null].join()).toBe(',');
1512 expect([undefined, undefined].join('|')).toBe('|');
1513 expect([null, null].join('|')).toBe('|');
1514 expect([1, 2, 3].join('|')).toBe('1|2|3');
1515 expect([1, 2, 3].join(null)).toBe('1null2null3');
1516 expect([1, 2, 3].join({})).toBe('1[object Object]2[object Object]3');
1517 expect([1, 2, 3].join('')).toBe('123');
1520 it('is generic', function () {
1521 var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 3 };
1522 expect(Array.prototype.join.call(obj, ',')).toBe('1,2,3');
1525 it('works with a string literal', function () {
1527 expect(Array.prototype.join.call(str, ',')).toBe('1,2,3');
1530 it('works with `arguments`', function () {
1531 var args = (function () { return arguments; }(1, 2, 3));
1532 expect(Array.prototype.join.call(args, ',')).toBe('1,2,3');
1536 describe('#push()', function () {
1537 it('works on arrays', function () {
1539 var result = arr.push(undefined);
1540 expect(result).toBe(1);
1541 expect(arr.length).toBe(1);
1542 expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true);
1543 expect(arr[0]).toBeUndefined();
1546 it('is generic', function () {
1548 var result = Array.prototype.push.call(obj, undefined);
1549 expect(result).toBe(1);
1550 expect(obj.length).toBe(1);
1551 expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true);
1552 expect(obj[0]).toBeUndefined();
1556 describe('#pop()', function () {
1557 it('works on arrays', function () {
1558 var arr = [1, 2, 3];
1559 var result = arr.pop();
1560 expect(result).toBe(3);
1561 expect(arr.length).toBe(2);
1562 expect(Object.prototype.hasOwnProperty.call(arr, 2)).toBe(false);
1563 expect(arr[2]).toBeUndefined();
1566 it('is generic', function () {
1567 var obj = { 0: 1, 1: 2, 2: 3, length: 3 };
1568 var result = Array.prototype.pop.call(obj);
1569 expect(result).toBe(3);
1570 expect(obj.length).toBe(2);
1571 expect(Object.prototype.hasOwnProperty.call(obj, 2)).toBe(false);
1572 expect(obj[2]).toBeUndefined();
1576 describe('#slice()', function () {
1577 it('works on arrays', function () {
1578 var arr = [1, 2, 3, 4];
1579 var result = arr.slice(1, 3);
1580 expect(result).toEqual([2, 3]);
1583 it('is generic', function () {
1584 var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 };
1585 var result = Array.prototype.slice.call(obj, 1, 3);
1586 expect(result).toEqual([2, 3]);
1589 it('works with `arguments`', function () {
1590 var obj = (function () {
1593 var result = Array.prototype.slice.call(obj, 1, 3);
1594 expect(result).toEqual([2, 3]);
1597 it('boxed string access', function () {
1599 var result = Array.prototype.slice.call(obj, 1, 3);
1600 expect(result).toEqual(['2', '3']);
1604 describe('#sort()', function () {
1605 describe('usage', function () {
1606 it('requires a function or undefined as first argument', function () {
1607 var actual = [1, 2];
1608 expect(actual.sort()).toBe(actual);
1609 expect(actual.sort(undefined)).toBe(actual);
1610 expect(actual.sort(function () { return 0; })).toBe(actual);
1613 it('requires a non-function or non-undefined to throw a `TypeError`', function () {
1614 expect(function () { [1, 2].sort(null); }).toThrow();
1615 expect(function () { [1, 2].sort(1); }).toThrow();
1616 expect(function () { [1, 2].sort(''); }).toThrow();
1617 expect(function () { [1, 2].sort(true); }).toThrow();
1618 expect(function () { [1, 2].sort({}); }).toThrow();
1619 expect(function () { [1, 2].sort([]); }).toThrow();
1620 expect(function () { [1, 2].sort(new Date()); }).toThrow();
1621 expect(function () { [1, 2].sort(/pattern/); }).toThrow();
1625 describe('ascending', function () {
1626 it('[5,2,4,6,1,3] should result in [1,2,3,4,5,6]', function () {
1627 var actual = [5, 2, 4, 6, 1, 3];
1628 var expected = [1, 2, 3, 4, 5, 6];
1630 expect(actual).toEqual(expected);
1633 it('[5,2,2,6,1,3] should result in [1,2,2,3,5,6]', function () {
1634 var actual = [5, 2, 2, 6, 1, 3];
1635 var expected = [1, 2, 2, 3, 5, 6];
1637 expect(actual).toEqual(expected);
1640 it('[0,0,0,0,0,1] should result in [0,0,0,0,0,1]', function () {
1641 var actual = [0, 0, 0, 0, 0, 1];
1642 var expected = [0, 0, 0, 0, 0, 1];
1644 expect(actual).toEqual(expected);
1647 it('[0,0,0,0,0,-1] should result in [-1,0,0,0,0,0]', function () {
1648 var actual = [0, 0, 0, 0, 0, -1];
1649 var expected = [-1, 0, 0, 0, 0, 0];
1651 expect(actual).toEqual(expected);
1654 it('[f,e,d,a,c,b] should result in [a,b,c,d,e,f]', function () {
1655 var actual = ['f', 'e', 'd', 'a', 'c', 'b'];
1656 var expected = ['a', 'b', 'c', 'd', 'e', 'f'];
1658 expect(actual).toEqual(expected);
1661 it('[f,e,d,,,,a,c,b] should result in [a,b,c,d,e,f,,,]', function () {
1662 var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b'];
1665 var expected = ['a', 'b', 'c', 'd', 'e', 'f'];
1666 expected.length = 8;
1668 expect(actual).toEqual(expected);
1671 it('[f,e,d,,null,,a,c,b] should result in [a,b,c,d,e,f,null,,,]', function () {
1672 var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b'];
1675 var expected = ['a', 'b', 'c', 'd', 'e', 'f', null];
1676 expected.length = 9;
1678 expect(actual).toEqual(expected);
1681 it('[f,e,d,,null,undefined,a,c,b] should result in [a,b,c,d,e,f,null,undefined,,]', function () {
1682 var actual = ['f', 'e', 'd', 1, null, undefined, 'a', 'c', 'b'];
1684 var expected = ['a', 'b', 'c', 'd', 'e', 'f', null, undefined];
1685 expected.length = 9;
1687 expect(actual).toEqual(expected);
1690 it('[] should result in []', function () {
1694 expect(actual).toEqual(expected);
1697 it('[1] should result in [1]', function () {
1701 expect(actual).toEqual(expected);
1704 it('result should find only greater or equal values', function () {
1707 for (i = 0; i < 100; i += 1) {
1708 actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3));
1711 for (i = 0; i < actual.length - 1; i += 1) {
1712 expect(actual[i] <= actual[i + 1]).toBe(true);
1717 describe('descending', function () {
1718 var descending = function (left, right) {
1719 var leftS = String(left);
1720 var rightS = String(right);
1721 if (leftS === rightS) {
1724 if (leftS < rightS) {
1730 it('[5,2,4,6,1,3] should result in [6,5,4,3,2,1]', function () {
1731 var actual = [5, 2, 4, 6, 1, 3];
1732 var expected = [6, 5, 4, 3, 2, 1];
1733 actual.sort(descending);
1734 expect(actual).toEqual(expected);
1737 it('[5,2,2,6,1,3] should result in [6,5,4,2,2,1]', function () {
1738 var actual = [5, 2, 2, 6, 1, 3];
1739 var expected = [6, 5, 3, 2, 2, 1];
1740 actual.sort(descending);
1741 expect(actual).toEqual(expected);
1744 it('[0,0,0,0,0,1] should result in [1,0,0,0,0,0]', function () {
1745 var actual = [0, 0, 0, 0, 0, 1];
1746 var expected = [1, 0, 0, 0, 0, 0];
1747 actual.sort(descending);
1748 expect(actual).toEqual(expected);
1751 it('[0,0,0,0,0,-1] should result in [0,0,0,0,0,-1]', function () {
1752 var actual = [0, 0, 0, 0, 0, -1];
1753 var expected = [0, 0, 0, 0, 0, -1];
1754 actual.sort(descending);
1755 expect(actual).toEqual(expected);
1758 it('[f,e,d,a,c,b] should result in [f,e,d,c,b,a]', function () {
1759 var actual = ['f', 'e', 'd', 'a', 'c', 'b'];
1760 var expected = ['f', 'e', 'd', 'c', 'b', 'a'];
1761 actual.sort(descending);
1762 expect(actual).toEqual(expected);
1765 it('[f,e,d,,,a,c,b] should result in [f,e,d,c,b,a,,,]', function () {
1766 var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b'];
1769 var expected = ['f', 'e', 'd', 'c', 'b', 'a'];
1770 expected.length = 8;
1771 actual.sort(descending);
1772 expect(actual).toEqual(expected);
1775 it('[f,e,d,,null,,a,c,b] should result in [null,f,e,d,c,b,a,,,]', function () {
1776 var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b'];
1779 var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a'];
1780 expected.length = 9;
1781 actual.sort(descending);
1782 expect(actual).toEqual(expected);
1785 it('[f,e,d,undefined,null,,a,c,b] should result in [null,f,e,d,c,b,a,undefined,,]', function () {
1786 var actual = ['f', 'e', 'd', undefined, null, 2, 'a', 'c', 'b'];
1788 var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a', undefined];
1789 expected.length = 9;
1790 actual.sort(descending);
1791 expect(actual).toEqual(expected);
1794 it('[] should result in []', function () {
1797 actual.sort(descending);
1798 expect(actual).toEqual(expected);
1801 it('[1] should result in [1]', function () {
1804 actual.sort(descending);
1805 expect(actual).toEqual(expected);
1808 it('result should find only lesser or equal values', function () {
1811 for (i = 0; i < 100; i += 1) {
1812 actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3));
1814 actual.sort(descending);
1815 for (i = 0; i < actual.length - 1; i += 1) {
1816 expect(actual[i] >= actual[i + 1]).toBe(true);
1821 describe('returned value', function () {
1822 it('should be the source object', function () {
1823 var actual = [1, 3, 2];
1824 expect(actual.sort()).toBe(actual);
1828 describe('when used generically', function () {
1829 var descending = function (left, right) {
1830 var leftS = String(left);
1831 var rightS = String(right);
1832 if (leftS === rightS) {
1835 if (leftS < rightS) {
1841 var args = function () {
1845 it('should not sort objects without length', function () {
1862 Array.prototype.sort.call(actual);
1863 expect(actual).toEqual(expected);
1864 Array.prototype.sort.call(actual, descending);
1865 expect(actual).toEqual(expected);
1868 it('should sort objects ascending with length', function () {
1887 Array.prototype.sort.call(actual);
1888 expect(actual).toEqual(expected);
1891 it('should sort objects descending with length', function () {
1910 Array.prototype.sort.call(actual, descending);
1911 expect(actual).toEqual(expected);
1914 it('should sort objects descending with mixed content types and with length', function () {
1933 Array.prototype.sort.call(actual, descending);
1934 expect(actual).toEqual(expected);
1937 it('should sort `arguments` object ascending', function () {
1938 var actual = args(5, 2, 4, 6, 1, 3);
1939 var expected = args(1, 2, 3, 4, 5, 6);
1940 Array.prototype.sort.call(actual);
1941 expect(actual).toEqual(expected);
1944 it('should sort `arguments` object ascending with mixed content types', function () {
1945 var actual = args(5, 2, 4, null, 1, 3);
1946 var expected = args(1, 2, 3, 4, 5, null);
1947 Array.prototype.sort.call(actual);
1948 expect(actual).toEqual(expected);
1951 it('should sort `arguments` object descending', function () {
1952 var actual = args(5, 2, 4, 6, 1, 3);
1953 var expected = args(6, 5, 4, 3, 2, 1);
1954 Array.prototype.sort.call(actual, descending);
1955 expect(actual).toEqual(expected);
1958 it('should sort `arguments` object descending with mixed content types', function () {
1959 var actual = args(5, 2, 4, null, 1, 3);
1960 var expected = args(null, 5, 4, 3, 2, 1);
1961 Array.prototype.sort.call(actual, descending);
1962 expect(actual).toEqual(expected);