Digital Office Automation System Backend
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

s-array.js 49KB

il y a 2 mois
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223
  1. describe('Array', function() {
  2. var testSubject;
  3. beforeEach(function() {
  4. testSubject = [2, 3, undefined, true, 'hej', null, false, 0];
  5. delete testSubject[1];
  6. });
  7. function createArrayLikeFromArray(arr) {
  8. var o = {};
  9. Array.prototype.forEach.call(arr, function(e, i) {
  10. o[i]=e;
  11. });
  12. o.length = arr.length;
  13. return o;
  14. };
  15. describe('forEach', function() {
  16. "use strict";
  17. var expected, actual;
  18. beforeEach(function() {
  19. expected = {0:2, 2: undefined, 3:true, 4: 'hej', 5:null, 6:false, 7:0 };
  20. actual = {};
  21. });
  22. it('should pass the right parameters', function() {
  23. var callback = jasmine.createSpy('callback'),
  24. array = ['1'];
  25. array.forEach(callback);
  26. expect(callback).toHaveBeenCalledWith('1', 0, array);
  27. });
  28. it('should not affect elements added to the array after it has begun', function() {
  29. var arr = [1,2,3],
  30. i = 0;
  31. arr.forEach(function(a) {
  32. i++;
  33. arr.push(a+3);
  34. });
  35. expect(arr).toEqual([1,2,3,4,5,6]);
  36. expect(i).toBe(3);
  37. });
  38. it('should set the right context when given none', function() {
  39. var context;
  40. [1].forEach(function() {context = this;});
  41. expect(context).toBe(function() {return this}.call());
  42. });
  43. it('should iterate all', function() {
  44. testSubject.forEach(function(obj, index) {
  45. actual[index] = obj;
  46. });
  47. expect(actual).toExactlyMatch(expected);
  48. });
  49. it('should iterate all using a context', function() {
  50. var o = { a: actual };
  51. testSubject.forEach(function(obj, index) {
  52. this.a[index] = obj;
  53. }, o);
  54. expect(actual).toExactlyMatch(expected);
  55. });
  56. it('should iterate all in an array-like object', function() {
  57. var ts = createArrayLikeFromArray(testSubject);
  58. Array.prototype.forEach.call(ts, function(obj, index) {
  59. actual[index] = obj;
  60. });
  61. expect(actual).toExactlyMatch(expected);
  62. });
  63. it('should iterate all in an array-like object using a context', function() {
  64. var ts = createArrayLikeFromArray(testSubject),
  65. o = { a: actual };
  66. Array.prototype.forEach.call(ts, function(obj, index) {
  67. this.a[index] = obj;
  68. }, o);
  69. expect(actual).toExactlyMatch(expected);
  70. });
  71. describe('strings', function() {
  72. var str = 'Hello, World!',
  73. toString = Object.prototype.toString;
  74. it('should iterate all in a string', function() {
  75. actual = [];
  76. Array.prototype.forEach.call(str, function(item, index) {
  77. actual[index] = item;
  78. });
  79. expect(actual).toExactlyMatch(str.split(''));
  80. });
  81. it('should iterate all in a string using a context', function() {
  82. actual = [];
  83. var o = { a: actual };
  84. Array.prototype.forEach.call(str, function(item, index) {
  85. this.a[index] = item;
  86. }, o);
  87. expect(actual).toExactlyMatch(str.split(''));
  88. });
  89. it('should have String object for third argument of callback', function() {
  90. Array.prototype.forEach.call(str, function(item, index, obj) {
  91. actual = obj;
  92. });
  93. expect(typeof actual).toBe("object");
  94. expect(toString.call(actual)).toBe("[object String]");
  95. });
  96. });
  97. });
  98. describe('some', function() {
  99. var actual, expected, numberOfRuns;
  100. beforeEach(function() {
  101. expected = {0:2, 2: undefined, 3:true };
  102. actual = {};
  103. numberOfRuns = 0;
  104. });
  105. it('should pass the correct values along to the callback', function() {
  106. var callback = jasmine.createSpy('callback');
  107. var array = ['1'];
  108. array.some(callback);
  109. expect(callback).toHaveBeenCalledWith('1', 0, array);
  110. });
  111. it('should not affect elements added to the array after it has begun', function() {
  112. var arr = [1,2,3],
  113. i = 0;
  114. arr.some(function(a) {
  115. i++;
  116. arr.push(a+3);
  117. return i > 3;
  118. });
  119. expect(arr).toEqual([1,2,3,4,5,6]);
  120. expect(i).toBe(3);
  121. });
  122. it('should set the right context when given none', function() {
  123. var context;
  124. [1].some(function() {context = this;});
  125. expect(context).toBe(function() {return this}.call());
  126. });
  127. it('should return false if it runs to the end', function() {
  128. actual = testSubject.some(function() {});
  129. expect(actual).toBeFalsy();
  130. });
  131. it('should return true if it is stopped somewhere', function() {
  132. actual = testSubject.some(function() { return true; });
  133. expect(actual).toBeTruthy();
  134. });
  135. it('should return false if there are no elements', function() {
  136. actual = [].some(function() { return true; });
  137. expect(actual).toBeFalsy();
  138. });
  139. it('should stop after 3 elements', function() {
  140. testSubject.some(function(obj, index) {
  141. actual[index] = obj;
  142. numberOfRuns += 1;
  143. if(numberOfRuns == 3) {
  144. return true;
  145. }
  146. return false;
  147. });
  148. expect(actual).toExactlyMatch(expected);
  149. });
  150. it('should stop after 3 elements using a context', function() {
  151. var o = { a: actual };
  152. testSubject.some(function(obj, index) {
  153. this.a[index] = obj;
  154. numberOfRuns += 1;
  155. if(numberOfRuns == 3) {
  156. return true;
  157. }
  158. return false;
  159. }, o);
  160. expect(actual).toExactlyMatch(expected);
  161. });
  162. it('should stop after 3 elements in an array-like object', function() {
  163. var ts = createArrayLikeFromArray(testSubject);
  164. Array.prototype.some.call(ts, function(obj, index) {
  165. actual[index] = obj;
  166. numberOfRuns += 1;
  167. if(numberOfRuns == 3) {
  168. return true;
  169. }
  170. return false;
  171. });
  172. expect(actual).toExactlyMatch(expected);
  173. });
  174. it('should stop after 3 elements in an array-like object using a context', function() {
  175. var ts = createArrayLikeFromArray(testSubject);
  176. var o = { a: actual };
  177. Array.prototype.some.call(ts, function(obj, index) {
  178. this.a[index] = obj;
  179. numberOfRuns += 1;
  180. if(numberOfRuns == 3) {
  181. return true;
  182. }
  183. return false;
  184. }, o);
  185. expect(actual).toExactlyMatch(expected);
  186. });
  187. });
  188. describe('every', function() {
  189. var actual, expected, numberOfRuns;
  190. beforeEach(function() {
  191. expected = {0:2, 2: undefined, 3:true };
  192. actual = {};
  193. numberOfRuns = 0;
  194. });
  195. it('should pass the correct values along to the callback', function() {
  196. var callback = jasmine.createSpy('callback');
  197. var array = ['1'];
  198. array.every(callback);
  199. expect(callback).toHaveBeenCalledWith('1', 0, array);
  200. });
  201. it('should not affect elements added to the array after it has begun', function() {
  202. var arr = [1,2,3],
  203. i = 0;
  204. arr.every(function(a) {
  205. i++;
  206. arr.push(a+3);
  207. return i <= 3;
  208. });
  209. expect(arr).toEqual([1,2,3,4,5,6]);
  210. expect(i).toBe(3);
  211. });
  212. it('should set the right context when given none', function() {
  213. var context;
  214. [1].every(function() {context = this;});
  215. expect(context).toBe(function() {return this}.call());
  216. });
  217. it('should return true if the array is empty', function() {
  218. actual = [].every(function() { return true; });
  219. expect(actual).toBeTruthy();
  220. actual = [].every(function() { return false; });
  221. expect(actual).toBeTruthy();
  222. });
  223. it('should return true if it runs to the end', function() {
  224. actual = [1,2,3].every(function() { return true; });
  225. expect(actual).toBeTruthy();
  226. });
  227. it('should return false if it is stopped before the end', function() {
  228. actual = [1,2,3].every(function() { return false; });
  229. expect(actual).toBeFalsy();
  230. });
  231. it('should return after 3 elements', function() {
  232. testSubject.every(function(obj, index) {
  233. actual[index] = obj;
  234. numberOfRuns += 1;
  235. if(numberOfRuns == 3) {
  236. return false;
  237. }
  238. return true;
  239. });
  240. expect(actual).toExactlyMatch(expected);
  241. });
  242. it('should stop after 3 elements using a context', function() {
  243. var o = { a: actual };
  244. testSubject.every(function(obj, index) {
  245. this.a[index] = obj;
  246. numberOfRuns += 1;
  247. if(numberOfRuns == 3) {
  248. return false;
  249. }
  250. return true;
  251. }, o);
  252. expect(actual).toExactlyMatch(expected);
  253. });
  254. it('should stop after 3 elements in an array-like object', function() {
  255. var ts = createArrayLikeFromArray(testSubject);
  256. Array.prototype.every.call(ts, function(obj, index) {
  257. actual[index] = obj;
  258. numberOfRuns += 1;
  259. if(numberOfRuns == 3) {
  260. return false;
  261. }
  262. return true;
  263. });
  264. expect(actual).toExactlyMatch(expected);
  265. });
  266. it('should stop after 3 elements in an array-like object using a context', function() {
  267. var ts = createArrayLikeFromArray(testSubject);
  268. var o = { a: actual };
  269. Array.prototype.every.call(ts, function(obj, index) {
  270. this.a[index] = obj;
  271. numberOfRuns += 1;
  272. if(numberOfRuns == 3) {
  273. return false;
  274. }
  275. return true;
  276. }, o);
  277. expect(actual).toExactlyMatch(expected);
  278. });
  279. });
  280. describe('indexOf', function() {
  281. "use strict";
  282. var actual, expected, testSubject;
  283. beforeEach(function() {
  284. testSubject = [2, 3, undefined, true, 'hej', null, 2, false, 0];
  285. delete testSubject[1];
  286. });
  287. it('should find the element', function() {
  288. expected = 4;
  289. actual = testSubject.indexOf('hej');
  290. expect(actual).toEqual(expected);
  291. });
  292. it('should not find the element', function() {
  293. expected = -1;
  294. actual = testSubject.indexOf('mus');
  295. expect(actual).toEqual(expected);
  296. });
  297. it('should find undefined as well', function() {
  298. expected = -1;
  299. actual = testSubject.indexOf(undefined);
  300. expect(actual).not.toEqual(expected);
  301. });
  302. it('should skip unset indexes', function() {
  303. expected = 2;
  304. actual = testSubject.indexOf(undefined);
  305. expect(actual).toEqual(expected);
  306. });
  307. it('should use a strict test', function() {
  308. actual = testSubject.indexOf(null);
  309. expect(actual).toEqual(5);
  310. actual = testSubject.indexOf('2');
  311. expect(actual).toEqual(-1);
  312. });
  313. it('should skip the first if fromIndex is set', function() {
  314. expect(testSubject.indexOf(2, 2)).toEqual(6);
  315. expect(testSubject.indexOf(2, 0)).toEqual(0);
  316. expect(testSubject.indexOf(2, 6)).toEqual(6);
  317. });
  318. it('should work with negative fromIndex', function() {
  319. expect(testSubject.indexOf(2, -3)).toEqual(6);
  320. expect(testSubject.indexOf(2, -9)).toEqual(0);
  321. });
  322. it('should work with fromIndex being greater than the length', function() {
  323. expect(testSubject.indexOf(0, 20)).toEqual(-1);
  324. });
  325. it('should work with fromIndex being negative and greater than the length', function() {
  326. expect(testSubject.indexOf('hej', -20)).toEqual(4);
  327. });
  328. describe('Array-like', function ArrayLike() {
  329. var indexOf = Array.prototype.indexOf,
  330. testAL;
  331. beforeEach(function beforeEach() {
  332. testAL = {};
  333. testSubject = [2, 3, undefined, true, 'hej', null, 2, false, 0];
  334. testSubject.forEach(function (o,i) {
  335. testAL[i] = o;
  336. });
  337. testAL.length = testSubject.length;
  338. });
  339. it('should find the element (array-like)', function() {
  340. expected = 4;
  341. actual = indexOf.call(testAL, 'hej');
  342. expect(actual).toEqual(expected);
  343. });
  344. it('should not find the element (array-like)', function() {
  345. expected = -1;
  346. actual = indexOf.call(testAL, 'mus');
  347. expect(actual).toEqual(expected);
  348. });
  349. it('should find undefined as well (array-like)', function() {
  350. expected = -1;
  351. actual = indexOf.call(testAL, undefined);
  352. expect(actual).not.toEqual(expected);
  353. });
  354. it('should skip unset indexes (array-like)', function() {
  355. expected = 2;
  356. actual = indexOf.call(testAL, undefined);
  357. expect(actual).toEqual(expected);
  358. });
  359. it('should use a strict test (array-like)', function() {
  360. actual = Array.prototype.indexOf.call(testAL, null);
  361. expect(actual).toEqual(5);
  362. actual = Array.prototype.indexOf.call(testAL, '2');
  363. expect(actual).toEqual(-1);
  364. });
  365. it('should skip the first if fromIndex is set (array-like)', function() {
  366. expect(indexOf.call(testAL, 2, 2)).toEqual(6);
  367. expect(indexOf.call(testAL, 2, 0)).toEqual(0);
  368. expect(indexOf.call(testAL, 2, 6)).toEqual(6);
  369. });
  370. it('should work with negative fromIndex (array-like)', function() {
  371. expect(indexOf.call(testAL, 2, -3)).toEqual(6);
  372. expect(indexOf.call(testAL, 2, -9)).toEqual(0);
  373. });
  374. it('should work with fromIndex being greater than the length (array-like)', function() {
  375. expect(indexOf.call(testAL, 0, 20)).toEqual(-1);
  376. });
  377. it('should work with fromIndex being negative and greater than the length (array-like)', function() {
  378. expect(indexOf.call(testAL, 'hej', -20)).toEqual(4);
  379. });
  380. });
  381. });
  382. describe('lastIndexOf', function() {
  383. "use strict";
  384. var actual, expected, testSubject, testAL;
  385. beforeEach(function() {
  386. testSubject = [2, 3, undefined, true, 'hej', null, 2, 3, false, 0];
  387. delete testSubject[1];
  388. delete testSubject[7];
  389. });
  390. describe('Array', function() {
  391. it('should find the element', function() {
  392. expected = 4;
  393. actual = testSubject.lastIndexOf('hej');
  394. expect(actual).toEqual(expected);
  395. });
  396. it('should not find the element', function() {
  397. expected = -1;
  398. actual = testSubject.lastIndexOf('mus');
  399. expect(actual).toEqual(expected);
  400. });
  401. it('should find undefined as well', function() {
  402. expected = -1;
  403. actual = testSubject.lastIndexOf(undefined);
  404. expect(actual).not.toEqual(expected);
  405. });
  406. it('should skip unset indexes', function() {
  407. expected = 2;
  408. actual = testSubject.lastIndexOf(undefined);
  409. expect(actual).toEqual(expected);
  410. });
  411. it('should use a strict test', function() {
  412. actual = testSubject.lastIndexOf(null);
  413. expect(actual).toEqual(5);
  414. actual = testSubject.lastIndexOf('2');
  415. expect(actual).toEqual(-1);
  416. });
  417. it('should skip the first if fromIndex is set', function() {
  418. expect(testSubject.lastIndexOf(2, 2)).toEqual(0);
  419. expect(testSubject.lastIndexOf(2, 0)).toEqual(0);
  420. expect(testSubject.lastIndexOf(2, 6)).toEqual(6);
  421. });
  422. it('should work with negative fromIndex', function() {
  423. expect(testSubject.lastIndexOf(2, -3)).toEqual(6);
  424. expect(testSubject.lastIndexOf(2, -9)).toEqual(0);
  425. });
  426. it('should work with fromIndex being greater than the length', function() {
  427. expect(testSubject.lastIndexOf(2, 20)).toEqual(6);
  428. });
  429. it('should work with fromIndex being negative and greater than the length', function() {
  430. expect(testSubject.lastIndexOf(2, -20)).toEqual(-1);
  431. });
  432. });
  433. describe('Array like', function() {
  434. var lastIndexOf = Array.prototype.lastIndexOf,
  435. testAL;
  436. beforeEach(function() {
  437. testAL = {};
  438. testSubject.forEach(function (o,i) {
  439. testAL[i] = o;
  440. });
  441. testAL.length = testSubject.length;
  442. });
  443. it('should find the element (array-like)', function() {
  444. expected = 4;
  445. actual = lastIndexOf.call(testAL, 'hej');
  446. expect(actual).toEqual(expected);
  447. });
  448. it('should not find the element (array-like)', function() {
  449. expected = -1;
  450. actual = lastIndexOf.call(testAL, 'mus');
  451. expect(actual).toEqual(expected);
  452. });
  453. it('should find undefined as well (array-like)', function() {
  454. expected = -1;
  455. actual = lastIndexOf.call(testAL, undefined);
  456. expect(actual).not.toEqual(expected);
  457. });
  458. it('should skip unset indexes (array-like)', function() {
  459. expected = 2;
  460. actual = lastIndexOf.call(testAL, undefined);
  461. expect(actual).toEqual(expected);
  462. });
  463. it('should use a strict test (array-like)', function() {
  464. actual = lastIndexOf.call(testAL, null);
  465. expect(actual).toEqual(5);
  466. actual = lastIndexOf.call(testAL, '2');
  467. expect(actual).toEqual(-1);
  468. });
  469. it('should skip the first if fromIndex is set', function() {
  470. expect(lastIndexOf.call(testAL, 2, 2)).toEqual(0);
  471. expect(lastIndexOf.call(testAL, 2, 0)).toEqual(0);
  472. expect(lastIndexOf.call(testAL, 2, 6)).toEqual(6);
  473. });
  474. it('should work with negative fromIndex', function() {
  475. expect(lastIndexOf.call(testAL, 2, -3)).toEqual(6);
  476. expect(lastIndexOf.call(testAL, 2, -9)).toEqual(0);
  477. });
  478. it('should work with fromIndex being greater than the length', function() {
  479. expect(lastIndexOf.call(testAL, 2, 20)).toEqual(6);
  480. });
  481. it('should work with fromIndex being negative and greater than the length', function() {
  482. expect(lastIndexOf.call(testAL, 2, -20)).toEqual(-1);
  483. });
  484. });
  485. });
  486. describe('filter', function() {
  487. var filteredArray,
  488. callback = function callback(o, i, arr) {
  489. return (
  490. i != 3 && i != 5
  491. );
  492. };
  493. beforeEach(function() {
  494. testSubject = [2, 3, undefined, true, 'hej', 3, null, false, 0];
  495. delete testSubject[1];
  496. filteredArray = [2, undefined, 'hej', null, false, 0];
  497. });
  498. describe('Array object', function() {
  499. it('should call the callback with the proper arguments', function() {
  500. var callback = jasmine.createSpy('callback'),
  501. arr = ['1'];
  502. arr.filter(callback);
  503. expect(callback).toHaveBeenCalledWith('1', 0, arr);
  504. });
  505. it('should not affect elements added to the array after it has begun', function() {
  506. var arr = [1,2,3],
  507. i = 0;
  508. arr.filter(function(a) {
  509. i++;
  510. if(i <= 4) {
  511. arr.push(a+3);
  512. }
  513. return true;
  514. });
  515. expect(arr).toEqual([1,2,3,4,5,6]);
  516. expect(i).toBe(3);
  517. });
  518. it('should skip non-set values', function() {
  519. var passedValues = {};
  520. testSubject = [1,2,3,4];
  521. delete testSubject[1];
  522. testSubject.filter(function(o, i) {
  523. passedValues[i] = o;
  524. return true;
  525. });
  526. expect(passedValues).toExactlyMatch(testSubject);
  527. });
  528. it('should pass the right context to the filter', function() {
  529. var passedValues = {};
  530. testSubject = [1,2,3,4];
  531. delete testSubject[1];
  532. testSubject.filter(function(o, i) {
  533. this[i] = o;
  534. return true;
  535. }, passedValues);
  536. expect(passedValues).toExactlyMatch(testSubject);
  537. });
  538. it('should set the right context when given none', function() {
  539. var context;
  540. [1].filter(function() {context = this;});
  541. expect(context).toBe(function() {return this}.call());
  542. });
  543. it('should remove only the values for which the callback returns false', function() {
  544. var result = testSubject.filter(callback);
  545. expect(result).toExactlyMatch(filteredArray);
  546. });
  547. it('should leave the original array untouched', function() {
  548. var copy = testSubject.slice();
  549. testSubject.filter(callback);
  550. expect(testSubject).toExactlyMatch(copy);
  551. });
  552. it('should not be affected by same-index mutation', function () {
  553. var results = [1, 2, 3]
  554. .filter(function (value, index, array) {
  555. array[index] = 'a';
  556. return true;
  557. });
  558. expect(results).toEqual([1, 2, 3]);
  559. });
  560. });
  561. describe('Array like', function() {
  562. beforeEach(function() {
  563. testSubject = createArrayLikeFromArray(testSubject);
  564. });
  565. it('should call the callback with the proper arguments', function() {
  566. var callback = jasmine.createSpy('callback'),
  567. arr = createArrayLikeFromArray(['1']);
  568. Array.prototype.filter.call(arr, callback);
  569. expect(callback).toHaveBeenCalledWith('1', 0, arr);
  570. });
  571. it('should not affect elements added to the array after it has begun', function() {
  572. var arr = createArrayLikeFromArray([1,2,3]),
  573. i = 0;
  574. Array.prototype.filter.call(arr, function(a) {
  575. i++;
  576. if(i <= 4) {
  577. arr[i+2] = a+3;
  578. }
  579. return true;
  580. });
  581. delete arr.length;
  582. expect(arr).toExactlyMatch([1,2,3,4,5,6]);
  583. expect(i).toBe(3);
  584. });
  585. it('should skip non-set values', function() {
  586. var passedValues = {};
  587. testSubject = createArrayLikeFromArray([1,2,3,4]);
  588. delete testSubject[1];
  589. Array.prototype.filter.call(testSubject, function(o, i) {
  590. passedValues[i] = o;
  591. return true;
  592. });
  593. delete testSubject.length;
  594. expect(passedValues).toExactlyMatch(testSubject);
  595. });
  596. it('should set the right context when given none', function() {
  597. var context;
  598. Array.prototype.filter.call(createArrayLikeFromArray([1]), function() {context = this;}, undefined);
  599. expect(context).toBe(function() {return this}.call());
  600. });
  601. it('should pass the right context to the filter', function() {
  602. var passedValues = {};
  603. testSubject = createArrayLikeFromArray([1,2,3,4]);
  604. delete testSubject[1];
  605. Array.prototype.filter.call(testSubject, function(o, i) {
  606. this[i] = o;
  607. return true;
  608. }, passedValues);
  609. delete testSubject.length;
  610. expect(passedValues).toExactlyMatch(testSubject);
  611. });
  612. it('should remove only the values for which the callback returns false', function() {
  613. var result = Array.prototype.filter.call(testSubject, callback);
  614. expect(result).toExactlyMatch(filteredArray);
  615. });
  616. it('should leave the original array untouched', function() {
  617. var copy = createArrayLikeFromArray(testSubject);
  618. Array.prototype.filter.call(testSubject, callback);
  619. expect(testSubject).toExactlyMatch(copy);
  620. });
  621. });
  622. });
  623. describe('map', function() {
  624. var callback;
  625. beforeEach(function() {
  626. var i = 0;
  627. callback = function() {
  628. return i++;
  629. };
  630. });
  631. describe('Array object', function() {
  632. it('should call callback with the right parameters', function() {
  633. var callback = jasmine.createSpy('callback'),
  634. array = [1];
  635. array.map(callback);
  636. expect(callback).toHaveBeenCalledWith(1, 0, array);
  637. });
  638. it('should set the context correctly', function() {
  639. var context = {};
  640. testSubject.map(function(o,i) {
  641. this[i] = o;
  642. }, context);
  643. expect(context).toExactlyMatch(testSubject);
  644. });
  645. it('should set the right context when given none', function() {
  646. var context;
  647. [1].map(function() {context = this;});
  648. expect(context).toBe(function() {return this}.call());
  649. });
  650. it('should not change the array it is called on', function() {
  651. var copy = testSubject.slice();
  652. testSubject.map(callback);
  653. expect(testSubject).toExactlyMatch(copy);
  654. });
  655. it('should only run for the number of objects in the array when it started', function() {
  656. var arr = [1,2,3],
  657. i = 0;
  658. arr.map(function(o) {
  659. arr.push(o+3);
  660. i++;
  661. return o;
  662. });
  663. expect(arr).toExactlyMatch([1,2,3,4,5,6]);
  664. expect(i).toBe(3);
  665. });
  666. it('should properly translate the values as according to the callback', function() {
  667. var result = testSubject.map(callback),
  668. expected = [0,0,1,2,3,4,5,6];
  669. delete expected[1];
  670. expect(result).toExactlyMatch(expected);
  671. });
  672. it('should skip non-existing values', function() {
  673. var array = [1,2,3,4],
  674. i = 0;
  675. delete array[2];
  676. array.map(function() {
  677. i++;
  678. });
  679. expect(i).toBe(3);
  680. });
  681. });
  682. describe('Array-like', function() {
  683. beforeEach(function() {
  684. testSubject = createArrayLikeFromArray(testSubject);
  685. });
  686. it('should call callback with the right parameters', function() {
  687. var callback = jasmine.createSpy('callback'),
  688. array = createArrayLikeFromArray([1]);
  689. Array.prototype.map.call(array, callback);
  690. expect(callback).toHaveBeenCalledWith(1, 0, array);
  691. });
  692. it('should set the context correctly', function() {
  693. var context = {};
  694. Array.prototype.map.call(testSubject, function(o,i) {
  695. this[i] = o;
  696. }, context);
  697. delete testSubject.length;
  698. expect(context).toExactlyMatch(testSubject);
  699. });
  700. it('should set the right context when given none', function() {
  701. var context;
  702. Array.prototype.map.call(createArrayLikeFromArray([1]), function() {context = this;});
  703. expect(context).toBe(function() {return this}.call());
  704. });
  705. it('should not change the array it is called on', function() {
  706. var copy = createArrayLikeFromArray(testSubject);
  707. Array.prototype.map.call(testSubject, callback);
  708. expect(testSubject).toExactlyMatch(copy);
  709. });
  710. it('should only run for the number of objects in the array when it started', function() {
  711. var arr = createArrayLikeFromArray([1,2,3]),
  712. i = 0;
  713. Array.prototype.map.call(arr, function(o) {
  714. Array.prototype.push.call(arr, o+3);
  715. i++;
  716. return o;
  717. });
  718. delete arr.length;
  719. expect(arr).toExactlyMatch([1,2,3,4,5,6]);
  720. expect(i).toBe(3);
  721. });
  722. it('should properly translate the values as according to the callback', function() {
  723. var result = Array.prototype.map.call(testSubject, callback),
  724. expected = [0,0,1,2,3,4,5,6];
  725. delete expected[1];
  726. expect(result).toExactlyMatch(expected);
  727. });
  728. it('should skip non-existing values', function() {
  729. var array = createArrayLikeFromArray([1,2,3,4]),
  730. i = 0;
  731. delete array[2];
  732. Array.prototype.map.call(array, function() {
  733. i++;
  734. });
  735. expect(i).toBe(3);
  736. });
  737. });
  738. });
  739. describe('reduce', function() {
  740. beforeEach(function() {
  741. testSubject = [1,2,3];
  742. });
  743. describe('Array', function() {
  744. it('should pass the correct arguments to the callback', function() {
  745. var spy = jasmine.createSpy().andReturn(0);
  746. testSubject.reduce(spy);
  747. expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);
  748. });
  749. it('should start with the right initialValue', function() {
  750. var spy = jasmine.createSpy().andReturn(0);
  751. testSubject.reduce(spy, 0);
  752. expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);
  753. });
  754. it('should not affect elements added to the array after it has begun', function() {
  755. var arr = [1,2,3],
  756. i = 0;
  757. arr.reduce(function(a, b) {
  758. i++;
  759. if(i <= 4) {
  760. arr.push(a+3);
  761. };
  762. return b;
  763. });
  764. expect(arr).toEqual([1,2,3,4,5]);
  765. expect(i).toBe(2);
  766. });
  767. it('should work as expected for empty arrays', function() {
  768. var spy = jasmine.createSpy();
  769. expect(function() {
  770. [].reduce(spy);
  771. }).toThrow();
  772. expect(spy).not.toHaveBeenCalled();
  773. });
  774. it('should throw correctly if no callback is given', function() {
  775. expect(function() {
  776. testSubject.reduce();
  777. }).toThrow();
  778. });
  779. it('should return the expected result', function() {
  780. expect(testSubject.reduce(function(a,b) {
  781. return (a||'').toString()+(b||'').toString();
  782. })).toEqual(testSubject.join(''));
  783. });
  784. it('should not directly affect the passed array', function() {
  785. var copy = testSubject.slice();
  786. testSubject.reduce(function(a,b) {
  787. return a+b;
  788. });
  789. expect(testSubject).toEqual(copy);
  790. });
  791. it('should skip non-set values', function() {
  792. delete testSubject[1];
  793. var visited = {};
  794. testSubject.reduce(function(a,b) {
  795. if(a)
  796. visited[a] = true;
  797. if(b)
  798. visited[b] = true;
  799. return 0;
  800. });
  801. expect(visited).toEqual({ '1': true, '3': true });
  802. });
  803. it('should have the right length', function() {
  804. expect(testSubject.reduce.length).toBe(1);
  805. });
  806. });
  807. describe('Array-like objects', function() {
  808. beforeEach(function() {
  809. testSubject = createArrayLikeFromArray(testSubject);
  810. testSubject.reduce = Array.prototype.reduce;
  811. });
  812. it('should pass the correct arguments to the callback', function() {
  813. var spy = jasmine.createSpy().andReturn(0);
  814. testSubject.reduce(spy);
  815. expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]);
  816. });
  817. it('should start with the right initialValue', function() {
  818. var spy = jasmine.createSpy().andReturn(0);
  819. testSubject.reduce(spy, 0);
  820. expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]);
  821. });
  822. it('should not affect elements added to the array after it has begun', function() {
  823. var arr = createArrayLikeFromArray([1,2,3]),
  824. i = 0;
  825. Array.prototype.reduce.call(arr, function(a, b) {
  826. i++;
  827. if(i <= 4) {
  828. arr[i+2] = a+3;
  829. };
  830. return b;
  831. });
  832. expect(arr).toEqual({
  833. 0: 1,
  834. 1: 2,
  835. 2: 3,
  836. 3: 4,
  837. 4: 5,
  838. length: 3
  839. });
  840. expect(i).toBe(2);
  841. });
  842. it('should work as expected for empty arrays', function() {
  843. var spy = jasmine.createSpy();
  844. expect(function() {
  845. Array.prototype.reduce.call({length: 0}, spy);
  846. }).toThrow();
  847. expect(spy).not.toHaveBeenCalled();
  848. });
  849. it('should throw correctly if no callback is given', function() {
  850. expect(function() {
  851. testSubject.reduce();
  852. }).toThrow();
  853. });
  854. it('should return the expected result', function() {
  855. expect(testSubject.reduce(function(a,b) {
  856. return (a||'').toString()+(b||'').toString();
  857. })).toEqual('123');
  858. });
  859. it('should not directly affect the passed array', function() {
  860. var copy = createArrayLikeFromArray(testSubject);
  861. testSubject.reduce(function(a,b) {
  862. return a+b;
  863. });
  864. delete(testSubject.reduce);
  865. expect(testSubject).toEqual(copy);
  866. });
  867. it('should skip non-set values', function() {
  868. delete testSubject[1];
  869. var visited = {};
  870. testSubject.reduce(function(a,b) {
  871. if(a)
  872. visited[a] = true;
  873. if(b)
  874. visited[b] = true;
  875. return 0;
  876. });
  877. expect(visited).toEqual({ '1': true, '3': true });
  878. });
  879. it('should have the right length', function() {
  880. expect(testSubject.reduce.length).toBe(1);
  881. });
  882. });
  883. });
  884. describe('reduceRight', function() {
  885. beforeEach(function() {
  886. testSubject = [1,2,3];
  887. });
  888. describe('Array', function() {
  889. it('should pass the correct arguments to the callback', function() {
  890. var spy = jasmine.createSpy().andReturn(0);
  891. testSubject.reduceRight(spy);
  892. expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);
  893. });
  894. it('should start with the right initialValue', function() {
  895. var spy = jasmine.createSpy().andReturn(0);
  896. testSubject.reduceRight(spy, 0);
  897. expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);
  898. });
  899. it('should not affect elements added to the array after it has begun', function() {
  900. var arr = [1,2,3],
  901. i = 0;
  902. arr.reduceRight(function(a, b) {
  903. i++;
  904. if(i <= 4) {
  905. arr.push(a+3);
  906. };
  907. return b;
  908. });
  909. expect(arr).toEqual([1,2,3,6,5]);
  910. expect(i).toBe(2);
  911. });
  912. it('should work as expected for empty arrays', function() {
  913. var spy = jasmine.createSpy();
  914. expect(function() {
  915. [].reduceRight(spy);
  916. }).toThrow();
  917. expect(spy).not.toHaveBeenCalled();
  918. });
  919. it('should work as expected for empty arrays with an initial value', function() {
  920. var spy = jasmine.createSpy(),
  921. result;
  922. result = [].reduceRight(spy, '');
  923. expect(spy).not.toHaveBeenCalled();
  924. expect(result).toBe('');
  925. });
  926. it('should throw correctly if no callback is given', function() {
  927. expect(function() {
  928. testSubject.reduceRight();
  929. }).toThrow();
  930. });
  931. it('should return the expected result', function() {
  932. expect(testSubject.reduceRight(function(a,b) {
  933. return (a||'').toString()+(b||'').toString();
  934. })).toEqual('321');
  935. });
  936. it('should not directly affect the passed array', function() {
  937. var copy = testSubject.slice();
  938. testSubject.reduceRight(function(a,b) {
  939. return a+b;
  940. });
  941. expect(testSubject).toEqual(copy);
  942. });
  943. it('should skip non-set values', function() {
  944. delete testSubject[1];
  945. var visited = {};
  946. testSubject.reduceRight(function(a,b) {
  947. if(a)
  948. visited[a] = true;
  949. if(b)
  950. visited[b] = true;
  951. return 0;
  952. });
  953. expect(visited).toEqual({ '1': true, '3': true });
  954. });
  955. it('should have the right length', function() {
  956. expect(testSubject.reduceRight.length).toBe(1);
  957. });
  958. });
  959. describe('Array-like objects', function() {
  960. beforeEach(function() {
  961. testSubject = createArrayLikeFromArray(testSubject);
  962. testSubject.reduceRight = Array.prototype.reduceRight;
  963. });
  964. it('should pass the correct arguments to the callback', function() {
  965. var spy = jasmine.createSpy().andReturn(0);
  966. testSubject.reduceRight(spy);
  967. expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]);
  968. });
  969. it('should start with the right initialValue', function() {
  970. var spy = jasmine.createSpy().andReturn(0);
  971. testSubject.reduceRight(spy, 0);
  972. expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]);
  973. });
  974. it('should not affect elements added to the array after it has begun', function() {
  975. var arr = createArrayLikeFromArray([1,2,3]),
  976. i = 0;
  977. Array.prototype.reduceRight.call(arr, function(a, b) {
  978. i++;
  979. if(i <= 4) {
  980. arr[i+2] = a+3;
  981. };
  982. return b;
  983. });
  984. expect(arr).toEqual({
  985. 0: 1,
  986. 1: 2,
  987. 2: 3,
  988. 3: 6,
  989. 4: 5,
  990. length: 3 // does not get updated on property assignment
  991. });
  992. expect(i).toBe(2);
  993. });
  994. it('should work as expected for empty arrays', function() {
  995. var spy = jasmine.createSpy();
  996. expect(function() {
  997. Array.prototype.reduceRight.call({length:0}, spy);
  998. }).toThrow();
  999. expect(spy).not.toHaveBeenCalled();
  1000. });
  1001. it('should throw correctly if no callback is given', function() {
  1002. expect(function() {
  1003. testSubject.reduceRight();
  1004. }).toThrow();
  1005. });
  1006. it('should return the expected result', function() {
  1007. expect(testSubject.reduceRight(function(a,b) {
  1008. return (a||'').toString()+(b||'').toString();
  1009. })).toEqual('321');
  1010. });
  1011. it('should not directly affect the passed array', function() {
  1012. var copy = createArrayLikeFromArray(testSubject);
  1013. testSubject.reduceRight(function(a,b) {
  1014. return a+b;
  1015. });
  1016. delete(testSubject.reduceRight);
  1017. expect(testSubject).toEqual(copy);
  1018. });
  1019. it('should skip non-set values', function() {
  1020. delete testSubject[1];
  1021. var visited = {};
  1022. testSubject.reduceRight(function(a,b) {
  1023. if(a)
  1024. visited[a] = true;
  1025. if(b)
  1026. visited[b] = true;
  1027. return 0;
  1028. });
  1029. expect(visited).toEqual({ '1': true, '3': true });
  1030. });
  1031. it('should have the right length', function() {
  1032. expect(testSubject.reduceRight.length).toBe(1);
  1033. });
  1034. });
  1035. });
  1036. describe('isArray', function () {
  1037. it('should work for Array', function () {
  1038. var ret = Array.isArray([]);
  1039. expect(ret).toBe(true);
  1040. });
  1041. it('should fail for other objects', function () {
  1042. var objects = [
  1043. "someString",
  1044. true,
  1045. false,
  1046. 42,
  1047. 0,
  1048. {},
  1049. Object.create && Object.create(null) || null,
  1050. /foo/,
  1051. arguments,
  1052. document.getElementsByTagName("div")
  1053. ];
  1054. objects.forEach(function (v) {
  1055. expect(Array.isArray(v)).toBe(false);
  1056. });
  1057. });
  1058. });
  1059. describe('unshift', function () {
  1060. it('should return length', function () {
  1061. expect([].unshift(0)).toEqual(1);
  1062. });
  1063. });
  1064. describe('splice', function () {
  1065. var b = ["b"],
  1066. a = [1, "a", b],
  1067. test;
  1068. var makeArray = function(l, prefix) {
  1069. prefix = prefix || "";
  1070. var a = [];
  1071. while (l--) {
  1072. a.unshift(prefix + Array(l + 1).join(" ") + l)
  1073. }
  1074. return a
  1075. };
  1076. beforeEach(function() {
  1077. test = a.slice(0);
  1078. });
  1079. it('basic implementation test 1', function () {
  1080. expect(test.splice(0)).toEqual(a);
  1081. });
  1082. it('basic implementation test 2', function () {
  1083. test.splice(0, 2);
  1084. expect(test).toEqual([b]);
  1085. });
  1086. it('should return right result 1', function () {
  1087. expect((function() {
  1088. var array = [];
  1089. array.splice(0, 0, 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20);
  1090. 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");
  1091. array.splice(5, 0, "XXX");
  1092. return array.join("|");
  1093. }())).toBe("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");
  1094. });
  1095. it('should return right result 2', function () {
  1096. expect((function() {
  1097. var array = makeArray(6);
  1098. array.splice(array.length - 1, 1, "");
  1099. array.splice(0, 1, 1,2,3,4);
  1100. 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);
  1101. array.splice(4, 0, "99999999999999");
  1102. return array.join("|");
  1103. }())).toBe("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|");
  1104. });
  1105. it('should return right result 3', function () {
  1106. expect((function() {
  1107. var array = [1,2,3];
  1108. array.splice(0);
  1109. array.splice(0, 1, 1,2,3,4,5,6,7,8,9,10);
  1110. 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");
  1111. array.splice(5, 1, "YYY", "XXX");
  1112. array.splice(0, 1);
  1113. array.splice(0, 2);
  1114. array.pop();
  1115. array.push.apply(array, makeArray(10, "-"));
  1116. array.splice(array.length - 2, 10);
  1117. array.splice();
  1118. array.splice(1, 1, 1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9);
  1119. 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);
  1120. array.splice(30, 10);
  1121. array.splice(30, 1);
  1122. array.splice(30, 0);
  1123. array.splice(2, 5, 1,2,3,"P", "LLL", "CCC", "YYY", "XXX");
  1124. array.push(1,2,3,4,5,6);
  1125. array.splice(1, 6, 1,2,3,4,5,6,7,8,9,4,5,6,7,8,9);
  1126. array.splice(3, 7);
  1127. array.unshift(7,8,9,10,11);
  1128. array.pop();
  1129. array.splice(5, 2);
  1130. array.pop();
  1131. array.unshift.apply(array, makeArray(8, "~"));
  1132. array.pop();
  1133. 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);
  1134. array.splice(4, 5, "P", "LLL", "CCC", "YYY", "XXX");
  1135. return array.join("|");
  1136. }())).toBe("~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");
  1137. });
  1138. it('should do nothing if method called with no arguments', function () {
  1139. expect(test.splice()).toEqual([]);
  1140. expect(test).toEqual(a);
  1141. });
  1142. //TODO:: Is this realy TRUE behavior?
  1143. it('should set first argument to 0 if first argument is set but undefined', function () {
  1144. var test2 = test.slice(0);
  1145. expect(test.splice(void 0, 2)).toEqual(test2.splice(0, 2));
  1146. expect(test).toEqual(test2);
  1147. });
  1148. it('should deleted and return all items after "start" when second argument is undefined', function () {
  1149. expect(test.splice(0)).toEqual(a);
  1150. expect(test).toEqual([]);
  1151. });
  1152. it('should deleted and return all items after "start" when second argument is undefined', function () {
  1153. expect(test.splice(2)).toEqual([b]);
  1154. expect(test).toEqual([1, "a"]);
  1155. });
  1156. it('runshould have the right length', function () {
  1157. expect(test.splice.length).toBe(2);
  1158. });
  1159. });
  1160. });