1// Copyright JS Foundation and other contributors, http://js.foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// This test will not pass on FLOAT32 due to precision issues
16
17function setDefaultValues()
18{
19  return [54, undefined, -127, "sunshine"];
20}
21
22var array = setDefaultValues();
23var array1 = array.splice();
24
25assert (array.length == 4);
26assert (array[0] == 54);
27assert (array[1] == undefined);
28assert (array[2] == -127);
29assert (array[3] == "sunshine");
30assert (array1.length == 0);
31
32// --------------------------------------------------------
33array = setDefaultValues(); // 54, undefined, -127, "sunshine"
34var array2 = array.splice(2);
35
36assert (array.length == 2);
37assert (array[0] == 54);
38assert (array[1] == undefined);
39assert (array2.length == 2);
40assert (array2[0] == -127);
41assert (array2[1] == "sunshine");
42
43// --------------------------------------------------------
44array = setDefaultValues(); // 54, undefined, -127, "sunshine"
45var array3 = array.splice(2, 1);
46
47assert (array.length == 3);
48assert (array[0] == 54);
49assert (array[1] == undefined);
50assert (array[2] == "sunshine");
51assert (array3.length == 1);
52assert (array3[0] == -127);
53
54// --------------------------------------------------------
55array = setDefaultValues(); // 54, undefined, -127, "sunshine"
56var array4 = array.splice(0, 3, 6720, "Szeged");
57
58assert (array.length == 3);
59assert (array[0] == 6720);
60assert (array[1] == "Szeged");
61assert (array[2] == "sunshine");
62assert (array4.length == 3);
63assert (array4[0] == 54);
64assert (array4[1] == undefined);
65assert (array4[2] == -127);
66
67// --------------------------------------------------------
68array = setDefaultValues(); // 54, undefined, -127, "sunshine"
69var array5 = array.splice(-2, -2, 6720, "Szeged");
70
71assert (array.length == 6);
72assert (array[0] == 54);
73assert (array[1] == undefined);
74assert (array[2] == 6720);
75assert (array[3] == "Szeged");
76assert (array[4] == -127);
77assert (array[5] == "sunshine");
78assert (array5.length == 0);
79
80// --------------------------------------------------------
81array = setDefaultValues(); // 54, undefined, -127, "sunshine"
82var array6 = array.splice(undefined, undefined, undefined);
83
84assert (array.length == 5);
85assert (array[0] == undefined);
86assert (array[1] == 54);
87assert (array[2] == undefined);
88assert (array[3] == -127);
89assert (array[4] == "sunshine");
90assert (array6.length == 0);
91
92// --------------------------------------------------------
93array = setDefaultValues(); // 54, undefined, -127, "sunshine"
94var array7 = array.splice(Infinity, NaN);
95assert (array.length == 4);
96assert (array[0] == 54);
97assert (array[1] == undefined);
98assert (array[2] == -127);
99assert (array[3] == "sunshine");
100assert (array7.length == 0);
101
102// --------------------------------------------------------
103array = setDefaultValues(); // 54, undefined, -127, "sunshine"
104var array8 = array.splice(-Infinity, Infinity);
105
106assert (array.length == 0);
107assert (array8.length == 4);
108assert (array8[0] == 54);
109assert (array8[1] == undefined);
110assert (array8[2] == -127);
111assert (array8[3] == "sunshine");
112
113// --------------------------------------------------------
114array = setDefaultValues(); // 54, undefined, -127, "sunshine"
115var array9 = array.splice(NaN, -Infinity);
116assert (array.length == 4);
117assert (array[0] == 54);
118assert (array[1] == undefined);
119assert (array[2] == -127);
120assert (array[3] == "sunshine");
121assert (array9.length == 0);
122
123// --------------------------------------------------------
124array = setDefaultValues(); // 54, undefined, -127, "sunshine"
125var array10 = array.splice(-3, 4, Infinity, "university");
126assert (array.length == 3);
127assert (array[0] == 54);
128assert (array[1] == Infinity);
129assert (array[2] == "university");
130assert (array10.length == 3);
131assert (array10[0] == undefined);
132assert (array10[1] == -127);
133assert (array10[2] == "sunshine");
134
135var array = [];
136array[4294967294] = "foo";
137var result = array.splice(4294967294, 1, "x")
138assert(result.length === 1)
139assert(result[0] === "foo")
140assert(array[4294967294] === "x")
141
142array[0] = "bar";
143var result = array.splice(-4294967295, 1, "y");
144assert(result.length === 1)
145assert(result[0] === "bar")
146assert(array[0] === "y")
147
148var arr = [1,2];
149Array.prototype[0] = 3;
150var newArr = arr.splice(0, 1);
151delete Array.prototype[0];
152assert(newArr.hasOwnProperty("0"));
153assert(newArr[0] === 1);
154
155// Checking behavior when unable to get length
156var obj = {splice : Array.prototype.splice};
157Object.defineProperty(obj, 'length', { 'get' : function () { throw new ReferenceError ("foo"); } });
158
159try {
160  obj.splice(1, 2, "item1", "item2");
161  assert (false);
162} catch (e) {
163  assert (e.message === "foo");
164  assert (e instanceof ReferenceError);
165}
166
167// Checking behavior when unable to get element
168var obj = {length : 1, splice : Array.prototype.splice};
169Object.defineProperty(obj, '0', { 'get' : function () { throw new ReferenceError ("foo"); } });
170
171try {
172  obj.splice(0, 1, "item1", "item2");
173  assert (false);
174} catch (e) {
175  assert (e.message === "foo");
176  assert (e instanceof ReferenceError);
177}
178
179/* ES v5.1 15.4.4.12.5.
180   Checking behavior when the first argument of the function is an object, which throws error */
181try {
182  var o = {};
183  Object.defineProperty(o, 'toString', { 'get' : function() { throw new ReferenceError("1"); } });
184  [1, 2].splice(o);
185  assert(false);
186} catch (e) {
187  assert(e instanceof ReferenceError);
188  assert(e.message == "1");
189}
190
191/* ES v5.1 15.4.4.12.7.
192   Checking behavior when the second argument of the function is an object, which throws error */
193try {
194  var o = {};
195  Object.defineProperty(o, 'toString', { 'get' : function() { throw new ReferenceError("2"); } });
196  [1, 2].splice(1, o);
197  assert(false);
198} catch (e) {
199  assert(e instanceof ReferenceError);
200  assert(e.message == "2");
201}
202
203/* ES v5.1 15.4.4.12.9.b
204   Checking behavior when the first element throws error */
205try {
206  var a = [1, 5, 6, 7, 8, 5];
207  Object.defineProperty(a, '0', { 'get' : function() { throw new ReferenceError("foo0"); } });
208  Array.prototype.splice.call(a, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
209  assert(false);
210} catch (e) {
211  assert(e instanceof ReferenceError);
212  assert(e.message == "foo0");
213}
214
215/* ES v5.1 15.4.4.12.12.b.iii.
216   Checking behavior when an element of the array throws error */
217function f0() { throw new TypeError("4"); };
218
219try {
220  obj = {get: f0, valueOf : f0, toString: f0};
221  arr = [1, 2, obj, 4, 5];
222  Object.defineProperty(arr, '4', { 'get' : f0 });
223  arr.splice(1, 3, obj);
224  assert(false);
225} catch (e) {
226  assert(e instanceof TypeError);
227  assert(e.message == "4");
228}
229
230/* ES v5.1 15.4.4.12 12.b.iv.
231   Checking behavior when a modified object is an element of the array */
232function f() {
233  delete arr[3];
234  arr.length = 13;
235  Object.defineProperty(arr, '5', function() { });
236};
237
238try {
239  obj = {get: f, valueOf : f, toString: f};
240  arr = [1, 2, obj, 4, 5];
241  Object.defineProperty(arr, '2',{ 'get' : f } );
242  for(var i = 0; i < arr.length; i++) {
243    var a = arr[i];
244  }
245  arr.splice(1, 4, obj);
246  assert(false);
247} catch (e) {
248  assert(e instanceof TypeError);
249}
250
251/* ES v5.1 15.4.4.12.12.b.v.
252   Checking behavior when elements are getting deleted by an element which only has a get function */
253function f1() {
254  for(var i = 0; i < arr.length; i++) {
255    delete arr[i];
256  }
257};
258
259try{
260  arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
261  delete arr[2];
262  Object.defineProperty(arr, '2', { 'get' : f1 });
263  arr.splice(1, 7, 5);
264} catch (e) {
265  assert(e instanceof TypeError);
266}
267
268/* ES v5.1 15.4.4.12.12.d.i.
269   Checking behavior when a modified object is an element of the array and deletes the elements */
270function f2() {
271  for(var i = 0; i < arr.length; i++) {
272    delete arr[i];
273  }
274};
275
276try {
277  obj = {get: f2, valueOf : f2, toString: f2 };
278  arr = [1, 2, obj, 4, 5];
279  for(var i = 0; i < 6; i++) {
280    Object.defineProperty(arr, i, { 'get' : f2 });
281  }
282  arr.splice(1, 3, obj);
283  assert(false);
284} catch (e) {
285  assert(e instanceof TypeError);
286}
287
288/* ES v5.1 15.4.4.12.13.b.iii.
289   Checking behavior when a yet non existing element will throw an error */
290function f3() { throw new TypeError("6");};
291
292try {
293  arr = [1, 2, 4, 5];
294  Object.defineProperty(arr, '4',{ 'get' : f3 });
295  arr.splice(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
296  assert(false);
297} catch (e) {
298  assert(e instanceof TypeError);
299  assert(e.message == "6");
300}
301
302/* ES v5.1 15.4.4.12.13.b.iv.2.
303   Checking behavior when the last element gets deleted */
304function f4() { delete arr[23]; };
305
306try {
307  arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
308  delete arr[23];
309  Object.defineProperty(arr, '23', { 'get' : f4 });
310  arr.splice(1, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
311  assert(false);
312} catch (e) {
313  assert(e instanceof TypeError);
314}
315
316/* ES v5.1 15.4.4.12.13.b.v.1.
317   Checking behavior when the last element throws error */
318function f5() {
319  for(var i = 0; i < arr.length; i++) {
320    delete arr[i];
321  }
322};
323
324try {
325  arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24];
326  delete arr[23];
327  Object.defineProperty(arr, '23', { 'get' : f5 });
328  arr.splice(1, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
329  assert(false);
330} catch (e) {
331  assert(e instanceof TypeError);
332}
333
334/* ES v5.1 15.4.4.12.15.b.
335   Checking behavior when the issue is the same as above, but splice has more arguments */
336function f6() {
337  for(var i = 0; i < arr.length; i++) {
338    delete arr[i];
339  }
340};
341
342try {
343  arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
344  delete arr[2];
345  Object.defineProperty(arr, '2', { 'get' : f6 });
346  arr.splice(1, 7, 5, 5, 5, 5);
347  assert(false);
348} catch (e) {
349  assert(e instanceof TypeError);
350}
351
352/* ES v5.1 15.4.4.12.16.
353   Checking behavior when the array is empty, large, and not writable */
354try {
355  arr = [];
356  Object.defineProperty(arr, 'length', { value : 999, writable: false });
357  arr.splice(1, 2, 4, 5);
358  assert(false);
359} catch (e) {
360  assert(e instanceof TypeError);
361}
362