Skip to content

Commit 001e86b

Browse files
committed
Increase branch coverage: Array.prototype functions
Added new test cases to improve branch coverage in Array.prototype routines. The following script is made for testing branch coverage with all the test suites (--jerry-test-suite --test262 --unittests --jerry-tests), or with only one .js file. https://github.com/matedabis/jerryscript/blob/gcov_coverage_tester/tests/gcov-tests/gcovtester.py While measuring the branch coverage we dont count JERRY_ASSERT s. The results are measured by running all the test scripts, with the modifications in the PRs. Branch coverage including pando-project#2682 and pando-project#2674: -before: 399 / 476 -after: 472 / 476 There are 28 functions in ecma-builtin-array-prototype.c, we hit 14 from them. The other 14 functions are either already covered, or we could not improve the coverage of it. More information about the coverage improvement and the branches not reached: https://gist.github.com/matedabis/d7b9fc0690aa2f4be6aa160fdf482e0e While improving the coverage we found an unnecessary condition check, which can not be false in any cases. Co-authored-by: Csaba Repasi [email protected] JerryScript-DCO-1.0-Signed-off-by: Csaba Repasi [email protected] JerryScript-DCO-1.0-Signed-off-by: Mate Dabis [email protected]
1 parent 90f37a5 commit 001e86b

12 files changed

+549
-2
lines changed

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ ecma_builtin_array_prototype_object_reverse (ecma_value_t this_arg, /**< this ar
579579
ECMA_FINALIZE (put_value);
580580
}
581581
/* 6.j */
582-
else if (lower_exist && !upper_exist)
582+
else if (lower_exist)
583583
{
584584
ECMA_TRY_CATCH (del_value, ecma_op_object_delete (obj_p, lower_str_p, true), ret_value);
585585
ECMA_TRY_CATCH (put_value, ecma_op_object_put (obj_p, upper_str_p, lower_value, true), ret_value);
@@ -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-concat.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,17 @@ try {
7474
assert(e.message === "foo");
7575
assert(e instanceof ReferenceError);
7676
}
77+
78+
/* ES v5.1 15.4.4.4.5.
79+
Checking behavior when unable to get element from a given array */
80+
arr1 = [];
81+
arr2 = [];
82+
arr3 = [];
83+
Object.defineProperty(arr2, '0', { 'get' : function () {throw new ReferenceError ("foo"); } });
84+
85+
try {
86+
arr1.concat(arr2, arr3);
87+
assert(false);
88+
} catch (e) {
89+
assert(e instanceof ReferenceError);
90+
}

tests/jerry/array-prototype-join.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,16 @@ obj_2[3] = 4;
7474
obj_2.join = Array.prototype.join;
7575

7676
assert (obj_2.join() === "1,2,3");
77+
78+
/* ES v5.1 15.4.4.5.7.
79+
Checking behavior when an element throws error */
80+
try {
81+
var f = function () { throw new TypeError("ooo");};
82+
var arr = [0, 1, 2, 3];
83+
Object.defineProperty(arr, '0', { 'get' : f });
84+
Array.prototype.join.call(arr);
85+
assert(false);
86+
} catch (e) {
87+
assert(e instanceof TypeError);
88+
assert(e.message == "ooo");
89+
}

tests/jerry/array-prototype-pop.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,27 @@ try {
7272
assert(e.message === "foo");
7373
assert(e instanceof ReferenceError);
7474
}
75+
76+
/* ES v5.1 15.4.4.6.5.c
77+
Checking behavior when unable to delete property */
78+
var obj = {pop : Array.prototype.pop, length : 2};
79+
Object.defineProperty(obj, '1', function () {});
80+
81+
try {
82+
obj.pop();
83+
assert(false);
84+
} catch (e) {
85+
assert(e instanceof TypeError);
86+
}
87+
88+
/* ES v5.1 15.4.4.6.5.d
89+
Checking behavior when array is not modifiable */
90+
var obj = {pop : Array.prototype.pop, length : 2};
91+
Object.freeze(obj);
92+
93+
try {
94+
obj.pop();
95+
assert(false);
96+
} catch (e) {
97+
assert(e instanceof TypeError);
98+
}

tests/jerry/array-prototype-push.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,15 @@ try {
7474
}
7575
assert(o.length === 1);
7676
assert(o[0] === "z");
77+
78+
/* ES v5.1 15.4.4.7.5.
79+
Checking behavior when array is non-extensible while pushing */
80+
var arr = [];
81+
Object.freeze(arr);
82+
83+
try {
84+
arr.push(1, 2);
85+
assert(false);
86+
} catch (e) {
87+
assert(e instanceof TypeError);
88+
}

tests/jerry/array-prototype-reverse.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,77 @@ try {
4343
assert(e.message === "foo");
4444
assert(e instanceof ReferenceError);
4545
}
46+
47+
/* ES v5.1 15.4.4.8.6.e.
48+
Checking behavior when unable to get the last element */
49+
var obj = { reverse : Array.prototype.reverse, length : 4 };
50+
Object.defineProperty(obj, '3', { 'get' : function () {throw new ReferenceError ("foo"); } });
51+
52+
try {
53+
obj.reverse();
54+
assert(false);
55+
} catch (e) {
56+
assert(e.message === "foo");
57+
assert(e instanceof ReferenceError);
58+
}
59+
60+
/* ES v5.1 15.4.4.8.6.h.i.
61+
Checking behavior when first 3 elements are not writable */
62+
try {
63+
var arr = [0, 1, 2, 3, 4, 5, 6,,,,,,,,,0, 1, 2, 3, 4, 5, 6];
64+
Object.defineProperty(arr, '0', { writable : false });
65+
Object.defineProperty(arr, '1', { writable : false });
66+
Object.defineProperty(arr, '2', { writable : false });
67+
Array.prototype.reverse.call(arr);
68+
assert(false);
69+
} catch (e) {
70+
assert(e instanceof TypeError);
71+
}
72+
73+
/* ES v5.1 15.4.4.8.6.h.ii.
74+
Checking behavior when last 3 elements are not writable */
75+
try {
76+
var arr = [0, 1, 2, 3, 4, 5, 6,,,,,,,,,0, 1, 2, 3, 4, 5, 6];
77+
Object.defineProperty(arr, '20', { writable : false });
78+
Object.defineProperty(arr, '21', { writable : false });
79+
Object.defineProperty(arr, '22', { writable : false });
80+
Array.prototype.reverse.call(arr);
81+
assert(false);
82+
} catch (e) {
83+
assert(e instanceof TypeError);
84+
}
85+
86+
/* ES v5.1 15.4.4.8.6.i.i.
87+
Checking behavior when first elements do not exist and the array is freezed */
88+
try {
89+
var arr = [,,,,,,,,,,,,,,,,0, 1, 2, 3, 4, 5, 6];
90+
arr = Object.freeze(arr);
91+
Array.prototype.reverse.call(arr);
92+
assert(false);
93+
} catch (e) {
94+
assert(e instanceof TypeError);
95+
}
96+
97+
/* ES v5.1 15.4.4.8.6.i.ii.
98+
Checking behavior when unable to get the first 2 elements */
99+
var obj = { reverse : Array.prototype.reverse, length : 4 };
100+
Object.defineProperty(obj, '2', { value : 0 });
101+
Object.defineProperty(obj, '3', { value : 0 });
102+
try {
103+
obj.reverse();
104+
assert(false);
105+
} catch (e) {
106+
assert(e instanceof TypeError);
107+
}
108+
109+
/* ES v5.1 15.4.4.8.6.j.i.
110+
Checking behavior when unable to get the last 2 elements */
111+
var obj = { reverse : Array.prototype.reverse, length : 4 };
112+
Object.defineProperty(obj, '0', { value : 0 });
113+
Object.defineProperty(obj, '1', { value : 0 });
114+
try {
115+
obj.reverse();
116+
assert(false);
117+
} catch (e) {
118+
assert(e instanceof TypeError);
119+
}

tests/jerry/array-prototype-shift.js

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,61 @@ try {
7777
assert(e.message === "foo");
7878
assert(e instanceof ReferenceError);
7979
}
80+
81+
/* ES v5.1 15.4.4.9.7.c.
82+
Checking behavior when the array is freezed */
83+
try {
84+
f = function () { throw new ReferenceError("getter"); };
85+
arr = { length : 9 };
86+
Object.defineProperty(arr, '8', { 'get' : f });
87+
Array.prototype.shift.call(arr);
88+
assert(false);
89+
} catch (e) {
90+
assert(e instanceof ReferenceError);
91+
assert(e.message == "getter");
92+
}
93+
94+
/* ES v5.1 15.4.4.9.7.d.ii.
95+
Checking behavior when the array is freezed */
96+
try {
97+
arr = { length : 9 };
98+
Object.defineProperty(arr, '8', { value : 8 });
99+
Object.defineProperty(arr, '7', { value : 7 });
100+
Array.prototype.shift.call(arr);
101+
assert(false);
102+
} catch (e) {
103+
assert(e instanceof TypeError);
104+
}
105+
106+
/* ES v5.1 15.4.4.9.7.e.i.
107+
Checking behavior when the first element is null */
108+
try {
109+
arr = { length : 9 };
110+
Object.defineProperty(arr, '0', { value : null });
111+
Array.prototype.shift.call(arr);
112+
assert(false);
113+
} catch (e) {
114+
assert(e instanceof TypeError);
115+
}
116+
117+
/* ES v5.1 15.4.4.9.8.
118+
Checking behavior when last element is not writable */
119+
try {
120+
arr = { length : 9 };
121+
Object.defineProperty(arr, '8', { writable : false });
122+
Array.prototype.shift.call(arr);
123+
assert(false);
124+
} catch (e) {
125+
assert(e instanceof TypeError);
126+
}
127+
128+
/* ES v5.1 15.4.4.9.9.
129+
Checking behavior when the array is freezed */
130+
try {
131+
arr = { length : 9 };
132+
Object.freeze(arr);
133+
Array.prototype.shift.call(arr);
134+
assert(false);
135+
} catch (e) {
136+
assert(e instanceof TypeError);
137+
}

tests/jerry/array-prototype-slice.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,3 +110,44 @@ try {
110110
assert (e.message === "foo");
111111
assert (e instanceof ReferenceError);
112112
}
113+
114+
/* ES v5.1 15.4.4.10.5.
115+
Checking behavior when start value throws exception */
116+
var arg1 = { };
117+
Object.defineProperty(arg1, 'valueOf', { 'get' : function () { throw new ReferenceError ("foo"); } });
118+
var obj = { slice : Array.prototype.slice };
119+
120+
try {
121+
obj.slice(arg1);
122+
assert(false);
123+
} catch (e) {
124+
assert(e.message === 'foo');
125+
assert(e instanceof ReferenceError);
126+
}
127+
128+
/* ES v5.1 15.4.4.10.7.
129+
Checking behavior when end value throws exception */
130+
var arg2 = { };
131+
Object.defineProperty(arg2, 'valueOf', { 'get' : function () { throw new ReferenceError ("foo"); } });
132+
var obj = { slice : Array.prototype.slice };
133+
134+
try {
135+
obj.slice(0, arg2);
136+
assert(false);
137+
} catch (e) {
138+
assert(e.message === 'foo');
139+
assert(e instanceof ReferenceError);
140+
}
141+
142+
/* ES v5.1 15.4.4.10.10.
143+
Checking behavior when unable to get element */
144+
var obj = { length : 3, slice : Array.prototype.slice };
145+
Object.defineProperty(obj, '1', { 'get' : function () { throw new ReferenceError ("foo"); } });
146+
147+
try {
148+
obj.slice(0, 3);
149+
assert (false);
150+
} catch (e) {
151+
assert (e.message === "foo");
152+
assert (e instanceof ReferenceError);
153+
}

tests/jerry/array-prototype-sort.js

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,3 +92,95 @@ try {
9292
assert(e.message === "foo");
9393
assert(e instanceof ReferenceError);
9494
}
95+
96+
// Checking behavior when unable to get elements
97+
var obj = { sort : Array.prototype.sort, length : 2};
98+
Object.defineProperty(obj, '0', { 'get' : function () { throw new ReferenceError ("foo"); } });
99+
Object.defineProperty(obj, '1', { 'get' : function () { throw new ReferenceError ("bar"); } });
100+
101+
try {
102+
obj.sort();
103+
assert(false);
104+
} catch (e) {
105+
assert(e.message === "foo");
106+
assert(e instanceof ReferenceError);
107+
}
108+
109+
// Checking behavior when array is non-extensible while sorting
110+
var arr = [1, 0];
111+
112+
try {
113+
arr.sort(function () { Object.freeze(arr) });
114+
assert(false);
115+
} catch (e) {
116+
assert(e instanceof TypeError);
117+
}
118+
119+
// Checking behavior when unable to delete property
120+
var obj = {sort : Array.prototype.sort, '0' : 2, '1' : 1, length : 4};
121+
Object.defineProperty(obj, '3', function () {});
122+
123+
try {
124+
obj.sort();
125+
assert(false);
126+
} catch (e) {
127+
assert(e instanceof TypeError);
128+
}
129+
130+
// Checking behavior when unable to get the last element
131+
var arr = [1, 2, ];
132+
Object.defineProperty(arr, '2', { 'get' : function () { throw new ReferenceError ("foo"); } });
133+
134+
try {
135+
arr.sort();
136+
assert(false);
137+
} catch (e) {
138+
assert(e.message === 'foo');
139+
assert(e instanceof ReferenceError);
140+
}
141+
142+
// Checking behavior when lhs_value throws exception at comparefn
143+
f = function () { throw new ReferenceError('foo'); };
144+
obj = { 'toString' : f };
145+
arr = [obj, 1];
146+
147+
try {
148+
arr.sort();
149+
assert(false);
150+
} catch (e) {
151+
assert(e.message === 'foo');
152+
assert(e instanceof ReferenceError);
153+
}
154+
155+
// Checking behavior when rhs_value throws exception at comparefn
156+
f = function () { throw new ReferenceError('foo'); };
157+
obj = { 'toString' : f };
158+
arr = [1, obj];
159+
160+
try {
161+
arr.sort();
162+
assert(false);
163+
} catch (e) {
164+
assert(e.message === 'foo');
165+
assert(e instanceof ReferenceError);
166+
}
167+
168+
// Sorting when array elements are the same string
169+
arr = ['foo', 'foo'];
170+
arr.sort();
171+
172+
assert(arr[0] === 'foo');
173+
assert(arr[1] === 'foo');
174+
175+
// Checking behavior when comparefn's call value cannot be converted to number
176+
obj = { };
177+
Object.defineProperty(obj, 'toString', function () { });
178+
f = function () { return obj };
179+
arr = [1, 2];
180+
181+
try {
182+
arr.sort(f);
183+
assert(false);
184+
} catch (e) {
185+
assert(e instanceof TypeError);
186+
}

0 commit comments

Comments
 (0)