Skip to content

Commit dc682a3

Browse files
committed
Increase test coverage: Array.prototype.splice
Branch coverage: Before: 56/78 After: 78/78 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 0c20f8e commit dc682a3

File tree

2 files changed

+204
-1
lines changed

2 files changed

+204
-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
@@ -1378,8 +1378,9 @@ ecma_builtin_array_prototype_object_splice (ecma_value_t this_arg, /**< this arg
13781378
}
13791379
}
13801380
/* 13. */
1381-
else if (item_count > delete_count)
1381+
else
13821382
{
1383+
JERRY_ASSERT (item_count > delete_count);
13831384
/* 13.b */
13841385
for (k = len - delete_count; k > start && ecma_is_value_empty (ret_value); k--)
13851386
{

tests/jerry/array-prototype-splice.js

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

0 commit comments

Comments
 (0)