Skip to content

Commit 835b1f9

Browse files
committed
Increase test coverage: Array.prototype.splice
Branch coverage: Before: 52/72 After: 72/72 Also found opportunity for optimization, that "else if" branch is not needed, should be replaced with an "else". JerryScript-DCO-1.0-Signed-off-by: Mate Dabis [email protected]
1 parent cffb299 commit 835b1f9

File tree

2 files changed

+182
-1
lines changed

2 files changed

+182
-1
lines changed

jerry-core/ecma/builtin-objects/ecma-builtin-array-prototype.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1224,8 +1224,9 @@ ecma_builtin_array_prototype_object_splice (const ecma_value_t args[], /**< argu
12241224
}
12251225
}
12261226
/* 13. */
1227-
else if (item_count > delete_count)
1227+
else
12281228
{
1229+
JERRY_ASSERT (item_count > delete_count);
12291230
/* 13.b */
12301231
for (k = len - delete_count; k > start && ecma_is_value_empty (ret_value); k--)
12311232
{

tests/jerry/array-prototype-splice.js

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,183 @@ try {
175175
assert (e.message === "foo");
176176
assert (e instanceof ReferenceError);
177177
}
178+
179+
180+
/* ES v5.1 15.4.4.12.5.
181+
Checking behavior when the first argument of the function is an object, which throws error */
182+
try {
183+
var o = {};
184+
Object.defineProperty(o, 'toString', { 'get' : function() { throw new ReferenceError("1"); } });
185+
[1, 2].splice(o);
186+
assert(false);
187+
} catch (e) {
188+
assert(e instanceof ReferenceError);
189+
assert(e.message == "1");
190+
}
191+
192+
/* ES v5.1 15.4.4.12.7.
193+
Checking behavior when the second argument of the function is an object, which throws error */
194+
try {
195+
var o = {};
196+
Object.defineProperty(o, 'toString', { 'get' : function() { throw new ReferenceError("2"); } });
197+
[1, 2].splice(1, o);
198+
assert(false);
199+
} catch (e) {
200+
assert(e instanceof ReferenceError);
201+
assert(e.message == "2");
202+
}
203+
204+
/* ES v5.1 15.4.4.12.9.b
205+
Checking behavior when the first element throws error */
206+
try {
207+
var a = [1, 5, 6, 7, 8, 5];
208+
Object.defineProperty(a, '0', { 'get' : function() { throw new ReferenceError("foo0"); } });
209+
Array.prototype.splice.call(a, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3);
210+
assert(false);
211+
} catch (e) {
212+
assert(e instanceof ReferenceError);
213+
assert(e.message == "foo0");
214+
}
215+
216+
/* ES v5.1 15.4.4.12.12.b.iii.
217+
Checking behavior when an element of the array throws error */
218+
try {
219+
f = function() { throw new TypeError("4"); };
220+
obj = {get: f, valueOf : f, toString: f};
221+
arr = [1, 2, obj, 4, 5];
222+
Object.defineProperty(arr, '4', { 'get' : f });
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 */
232+
try {
233+
f = function() {
234+
delete arr[3];
235+
arr.length = 13;
236+
Object.defineProperty(arr, '5', function() { });
237+
};
238+
obj = {get: f, valueOf : f, toString: f};
239+
arr = [1, 2, obj, 4, 5];
240+
Object.defineProperty(arr, '2',{ 'get' : f } );
241+
for(var i = 0; i < arr.length; i++) {
242+
var a = arr[i];
243+
}
244+
arr.splice(1, 4, obj);
245+
assert(false);
246+
} catch (e) {
247+
assert(e instanceof TypeError);
248+
}
249+
250+
/* ES v5.1 15.4.4.12.12.b.v.
251+
Checking behavior when elements are getting deleted by an element which only has a get function */
252+
try{
253+
f = function() {
254+
for(var i = 0; i < arr.length; i++) {
255+
delete arr[i];
256+
}
257+
};
258+
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
259+
delete arr[2];
260+
Object.defineProperty(arr, '2', { 'get' : f });
261+
arr.splice(1, 7, 5);
262+
} catch (e) {
263+
assert(e instanceof TypeError);
264+
}
265+
266+
/* ES v5.1 15.4.4.12.12.d.i.
267+
Checking behavior when a modified object is an element of the array and deletes the elements */
268+
try {
269+
f = function() {
270+
for(var i = 0; i < arr.length; i++) {
271+
delete arr[i];
272+
}
273+
};
274+
obj = {get: f, valueOf : f, toString: f };
275+
arr = [1, 2, obj, 4, 5];
276+
for(var i = 0; i < 6; i++)
277+
{
278+
Object.defineProperty(arr, i, { 'get' : f });
279+
}
280+
arr.splice(1, 3, obj);
281+
assert(false);
282+
} catch (e) {
283+
assert(e instanceof TypeError);
284+
}
285+
286+
/* ES v5.1 15.4.4.12.13.b.iii.
287+
Checking behavior when a yet non existing element will throw an error */
288+
try {
289+
f = function () { throw new TypeError("6");};
290+
arr = [1, 2, 4, 5];
291+
Object.defineProperty(arr, '4',{ 'get' : f });
292+
arr.splice(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
293+
assert(false);
294+
} catch (e) {
295+
assert(e instanceof TypeError);
296+
assert(e.message == "6");
297+
}
298+
299+
/* ES v5.1 15.4.4.12.13.b.iv.2.
300+
Checking behavior when the last element gets deleted */
301+
try {
302+
f = function () { delete arr[23]; };
303+
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];
304+
delete arr[23];
305+
Object.defineProperty(arr, '23', { 'get' : f });
306+
arr.splice(1, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
307+
assert(false);
308+
} catch (e) {
309+
assert(e instanceof TypeError);
310+
}
311+
312+
/* ES v5.1 15.4.4.12.13.b.v.1.
313+
Checking behavior when the last element throws error */
314+
try {
315+
f = function() {
316+
for(var i = 0; i < arr.length; i++)
317+
{
318+
delete arr[i];
319+
}
320+
};
321+
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];
322+
delete arr[23];
323+
Object.defineProperty(arr, '23', { 'get' : f });
324+
arr.splice(1, 7, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5);
325+
assert(false);
326+
} catch (e) {
327+
assert(e instanceof TypeError);
328+
}
329+
330+
/* ES v5.1 15.4.4.12.15.b.
331+
Checking behavior when the issue is the same as above, but splice has more arguments */
332+
try {
333+
f = function() {
334+
for(var i = 0; i < arr.length; i++)
335+
{
336+
delete arr[i];
337+
}
338+
};
339+
arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
340+
delete arr[2];
341+
Object.defineProperty(arr, '2', { 'get' : f });
342+
arr.splice(1, 7, 5, 5, 5, 5);
343+
assert(false);
344+
} catch (e) {
345+
assert(e instanceof TypeError);
346+
}
347+
348+
/* ES v5.1 15.4.4.12.16.
349+
Checking behavior when the array is empty, large, and not writable */
350+
try {
351+
arr = [];
352+
Object.defineProperty(arr, 'length', { value : 999, writable: false });
353+
arr.splice(1, 2, 4, 5);
354+
assert(false);
355+
} catch (e) {
356+
assert(e instanceof TypeError);
357+
}

0 commit comments

Comments
 (0)