array_splice_515632.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. // Test cases for BLUE 515632
  6. // Found that arguments to Array.prototype.splice which altered the length
  7. // of the array caused an assert.
  8. if (this.WScript && this.WScript.LoadScriptFile) { // Check for running in ch
  9. this.WScript.LoadScriptFile("..\\UnitTestFramework\\UnitTestFramework.js");
  10. }
  11. function getArray() {
  12. var a = new Array(10);
  13. for(var i = 0; i < a.length; i++) {
  14. a[i] = i;
  15. }
  16. return a;
  17. }
  18. var tests = [
  19. {
  20. name: "Arguments to Array.prototype.splice reduce the length of array by one",
  21. body: function () {
  22. var a = getArray();
  23. var pop = { valueOf: function() { a.pop(); return 0; } };
  24. var s = a.splice(0, pop);
  25. // pop decreases the length of the array but we've already calculated the length by that
  26. // time. When we are done with splice, we'll set the length back to the original value
  27. // which means we should now have n undefined values at the end of the array where n is
  28. // equal to the number of calls to pop.
  29. assert.areEqual([], s, "Result of splice is empty array");
  30. assert.areEqual(10, a.length, "Array has unchanged length");
  31. for(var i = 0; i < 9; i++) {
  32. assert.areEqual(i, a[i], "Array elements before the last are unchanged");
  33. }
  34. assert.areEqual(undefined, a[9], "Array is unchanged except last element is undefined now");
  35. }
  36. },
  37. {
  38. name: "Arguments to Array.prototype.splice reduce the length of array and we don't start splice at 0",
  39. body: function () {
  40. var a = getArray();
  41. var pop = { valueOf: function() { a.pop(); return 0; } };
  42. var s = a.splice(3, pop);
  43. assert.areEqual([], s, "Result of splice is empty array");
  44. assert.areEqual(10, a.length, "Array has unchanged length");
  45. for(var i = 0; i < 9; i++) {
  46. assert.areEqual(i, a[i], "Array elements before the last are unchanged");
  47. }
  48. assert.areEqual(undefined, a[9], "Array is unchanged except last element is undefined now");
  49. }
  50. },
  51. {
  52. name: "Arguments to Array.prototype.splice reduce the length of array, we don't start splice at 0, and we have a delete length",
  53. body: function () {
  54. var a = getArray();
  55. var pop = { valueOf: function() { a.pop(); return 2; } };
  56. var s = a.splice(3, pop);
  57. assert.areEqual([3,4], s, "Result of splice contains removed elements");
  58. assert.areEqual(8, a.length, "Array has length reduced by length of removed");
  59. for(var i = 0; i < 3; i++) {
  60. assert.areEqual(i, a[i], "Array elements before the removed are unchanged");
  61. }
  62. assert.areEqual(5, a[3], "Array elements after the removed are correct");
  63. assert.areEqual(6, a[4], "Array elements after the removed are correct");
  64. assert.areEqual(7, a[5], "Array elements after the removed are correct");
  65. assert.areEqual(8, a[6], "Array elements after the removed are correct");
  66. assert.areEqual(undefined, a[7], "Last element of array is undefined now");
  67. }
  68. },
  69. {
  70. name: "Arguments to Array.prototype.splice increases the length of array by one",
  71. body: function () {
  72. var a = getArray();
  73. var push = { valueOf: function() { a.push(10); return 0; } };
  74. var s = a.splice(0, push);
  75. // push increases the length of the array but we've already calculated the length by that
  76. // time and when we are done with splice, we'll set the length back to the original value.
  77. assert.areEqual(0, s.length, "Result of splice has length of zero");
  78. assert.areEqual([], s, "Result of splice is empty array");
  79. assert.areEqual(10, a.length, "Array has unchanged length");
  80. assert.areEqual([0,1,2,3,4,5,6,7,8,9], a, "Array is unchanged by the splice call");
  81. }
  82. },
  83. {
  84. name: "Arguments to Array.prototype.splice increases the length of array with start and length",
  85. body: function () {
  86. var a = getArray();
  87. var push = { valueOf: function() { a.push(10); a.push(11); return 3; } };
  88. var s = a.splice(4, push);
  89. assert.areEqual(3, s.length, "Result of splice has the correct number of elements");
  90. assert.areEqual([4,5,6], s, "Result of splice contains removed elements");
  91. assert.areEqual(7, a.length, "Array has length reduced by length of removed");
  92. assert.areEqual([0,1,2,3,7,8,9], a, "Array elements before/after the removed are correct");
  93. }
  94. },
  95. {
  96. name: "Arguments to Array.prototype.splice reduces the length of array to 0",
  97. body: function () {
  98. var a = getArray();
  99. var kill = { valueOf: function() { while(a.length > 0) { a.pop(); } return 0; } };
  100. var s = a.splice(0, kill);
  101. assert.areEqual(0, s.length, "Result of splice has length of zero");
  102. assert.areEqual([], s, "Result of splice is empty");
  103. assert.areEqual(10, a.length, "Array length is unchanged");
  104. for(var i = 0; i < 10; i++) {
  105. assert.areEqual(undefined, a[i], "Array elements are all undefined");
  106. }
  107. }
  108. },
  109. {
  110. name: "Arguments to Array.prototype.splice reduces the length of array to 0 and we delete some elements",
  111. body: function () {
  112. var a = getArray();
  113. var kill = { valueOf: function() { while(a.length > 0) { a.pop(); } return 2; } };
  114. var s = a.splice(5, kill);
  115. assert.areEqual(2, s.length, "Result of splice is array of undefined values");
  116. for(var i = 0; i < 2; i++) {
  117. assert.areEqual(undefined, s[i], "Splice result elements are all undefined");
  118. }
  119. assert.areEqual(8, a.length, "Array length is reduced by number of removed elements");
  120. for(var i = 0; i < 8; i++) {
  121. assert.areEqual(undefined, a[i], "Array elements are all undefined");
  122. }
  123. }
  124. },
  125. {
  126. name: "Arguments to Array.prototype.splice reduces the length of array to 0 and we delete some elements, taking some elements from the unchanged length and some from the changed length",
  127. body: function () {
  128. var a = getArray();
  129. var kill = { valueOf: function() { while(a.length > 6) { a.pop(); } return 2; } };
  130. var s = a.splice(5, kill);
  131. assert.areEqual(2, s.length, "Result of splice contains an element from array and undefined (since array size was shrunk)");
  132. assert.areEqual(5, s[0], "Splice result first element is from array");
  133. assert.areEqual(undefined, s[1], "Splice result remaining elements are undefined");
  134. assert.areEqual(8, a.length, "Array length is reduced by number of removed elements");
  135. for(var i = 0; i < 5; i++) {
  136. assert.areEqual(i, a[i], "Array elements are unchanged except where popped");
  137. }
  138. for(var i = 5; i < 8; i++) {
  139. assert.areEqual(undefined, a[i], "Array elements after the popped point are undefined");
  140. }
  141. }
  142. }
  143. ];
  144. testRunner.runTests(tests);