blob: 7406fb54bf225e25e4f0cf7ae5c3f60ed13ae4f6 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// Copyright 2014 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28
29function getObjects() {
30 function func() {}
31 return [
32 func,
33 new func(),
34 {x: 5},
35 /regexp/,
36 ['array'],
37 // new Error(),
38 new Date(),
39 new Number(1),
40 new Boolean(true),
41 new String('str'),
42 Object(Symbol())
43 ];
44}
45
46
47var coercibleValues = [
48 1,
49 true,
50 'string',
51 Symbol()
52];
53
54
55var nonCoercibleValues = [
56 undefined,
57 null
58];
59
60
61var valuesWithoutNull = coercibleValues.concat(undefined);
62
63
64function TestSetPrototypeOfCoercibleValues() {
65 for (var i = 0; i < coercibleValues.length; i++) {
66 var value = coercibleValues[i];
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000067 var proto = Object.getPrototypeOf(value);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000068 assertEquals(Object.setPrototypeOf(value, {}), value);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069 assertSame(proto, Object.getPrototypeOf(value));
Ben Murdochb8a8cc12014-11-26 15:28:44 +000070 }
71}
72TestSetPrototypeOfCoercibleValues();
73
74
75function TestSetPrototypeOfNonCoercibleValues() {
76 for (var i = 0; i < nonCoercibleValues.length; i++) {
77 var value = nonCoercibleValues[i];
78 assertThrows(function() {
79 Object.setPrototypeOf(value, {});
80 }, TypeError);
81 }
82}
83TestSetPrototypeOfNonCoercibleValues();
84
85
86function TestSetPrototypeToNonObject(proto) {
87 var objects = getObjects();
88 for (var i = 0; i < objects.length; i++) {
89 var object = objects[i];
90 for (var j = 0; j < valuesWithoutNull.length; j++) {
91 var proto = valuesWithoutNull[j];
92 assertThrows(function() {
93 Object.setPrototypeOf(object, proto);
94 }, TypeError);
95 }
96 }
97}
98TestSetPrototypeToNonObject();
99
100
101function TestSetPrototypeOf(object, proto) {
102 assertEquals(Object.setPrototypeOf(object, proto), object);
103 assertEquals(Object.getPrototypeOf(object), proto);
104}
105
106
107function TestSetPrototypeOfForObjects() {
108 var objects1 = getObjects();
109 var objects2 = getObjects();
110 for (var i = 0; i < objects1.length; i++) {
111 for (var j = 0; j < objects2.length; j++) {
112 TestSetPrototypeOf(objects1[i], objects2[j]);
113 }
114 }
115}
116TestSetPrototypeOfForObjects();
117
118
119function TestSetPrototypeToNull() {
120 var objects = getObjects();
121 for (var i = 0; i < objects.length; i++) {
122 TestSetPrototypeOf(objects[i], null);
123 }
124}
125TestSetPrototypeToNull();
126
127
128function TestSetPrototypeOfNonExtensibleObject() {
129 var objects = getObjects();
130 var proto = {};
131 for (var i = 0; i < objects.length; i++) {
132 var object = objects[i];
133 Object.preventExtensions(object);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000134 // Setting the current prototype must succeed.
135 Object.setPrototypeOf(object, Object.getPrototypeOf(object));
136 // Setting any other must fail.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000137 assertThrows(function() {
138 Object.setPrototypeOf(object, proto);
139 }, TypeError);
140 }
141}
142TestSetPrototypeOfNonExtensibleObject();
143
144
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000145function TestSetPrototypeCyclic() {
146 var objects = [
147 Object.prototype, {},
148 Array.prototype, [],
149 Error.prototype, new TypeError,
150 // etc ...
151 ];
152 for (var i = 0; i < objects.length; i += 2) {
153 var object = objects[i];
154 var value = objects[i + 1];
155 assertThrows(function() {
156 Object.setPrototypeOf(object, value);
157 }, TypeError);
158 }
159}
160TestSetPrototypeCyclic();
161
162
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000163function TestLookup() {
164 var object = {};
165 assertFalse('x' in object);
166 assertFalse('y' in object);
167
168 var oldProto = {
169 x: 'old x',
170 y: 'old y'
171 };
172 Object.setPrototypeOf(object, oldProto);
173 assertEquals(object.x, 'old x');
174 assertEquals(object.y, 'old y');
175
176 var newProto = {
177 x: 'new x'
178 };
179 Object.setPrototypeOf(object, newProto);
180 assertEquals(object.x, 'new x');
181 assertFalse('y' in object);
182}
183TestLookup();