OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // A general-purpose engine for sending a sequence of protocol commands. | 5 InspectorTest.log('Checks Runtime.getProperties method'); |
6 // The clients provide requests and response handlers, while the engine catches | |
7 // errors and makes sure that once there's nothing to do completeTest() is calle
d. | |
8 // @param step is an object with command, params and callback fields | |
9 function runRequestSeries(step) | |
10 { | |
11 processStep(step); | |
12 | 6 |
13 function processStep(s) | 7 InspectorTest.runAsyncTestSuite([ |
14 { | 8 async function testObject5() { |
15 try { | 9 let objectId = (await Protocol.Runtime.evaluate({ |
16 processStepOrFail(s); | 10 expression: '(function(){var r = Object(5); r.foo = \'cat\';return r;})()' |
17 } catch (e) { | 11 })).result.result.objectId; |
18 InspectorTest.log(e.stack); | 12 let props = await Protocol.Runtime.getProperties({ objectId, ownProperties:
true }); |
19 InspectorTest.completeTest(); | 13 logGetPropertiesResult(props.result); |
20 } | 14 }, |
21 } | |
22 | 15 |
23 function processStepOrFail(s) | 16 async function testNotOwn() { |
24 { | 17 let objectId = (await Protocol.Runtime.evaluate({ |
25 if (!s) { | 18 expression: '({ a: 2, set b(_) {}, get b() {return 5;}, __proto__: { a: 3,
c: 4, get d() {return 6;} }})' |
26 InspectorTest.completeTest(); | 19 })).result.result.objectId; |
27 return; | 20 let props = await Protocol.Runtime.getProperties({ objectId, ownProperties:
false }); |
28 } | 21 logGetPropertiesResult(props.result); |
29 if (!s.command) { | 22 }, |
30 // A simple loopback step. | |
31 var next = s.callback(); | |
32 processStep(next); | |
33 return; | |
34 } | |
35 | 23 |
36 var innerCallback = function(response) | 24 async function testAccessorsOnly() { |
37 { | 25 let objectId = (await Protocol.Runtime.evaluate({ |
38 if ("error" in response) { | 26 expression: '({ a: 2, set b(_) {}, get b() {return 5;}, c: \'c\', set d(_)
{} })' |
39 InspectorTest.log(response.error.message); | 27 })).result.result.objectId; |
40 InspectorTest.completeTest(); | 28 let props = await Protocol.Runtime.getProperties({ objectId, ownProperties:
true, accessorPropertiesOnly: true }); |
41 return; | 29 logGetPropertiesResult(props.result); |
42 } | 30 }, |
43 var next; | |
44 try { | |
45 next = s.callback(response.result); | |
46 } catch (e) { | |
47 InspectorTest.log(e.stack); | |
48 InspectorTest.completeTest(); | |
49 return; | |
50 } | |
51 processStep(next); | |
52 } | |
53 var command = s.command.split("."); | |
54 Protocol[command[0]][command[1]](s.params).then(innerCallback); | |
55 } | |
56 } | |
57 | 31 |
58 var firstStep = { callback: callbackStart5 }; | 32 async function testArray() { |
| 33 let objectId = (await Protocol.Runtime.evaluate({ |
| 34 expression: '[\'red\', \'green\', \'blue\']' |
| 35 })).result.result.objectId; |
| 36 let props = await Protocol.Runtime.getProperties({ objectId, ownProperties:
true }); |
| 37 logGetPropertiesResult(props.result); |
| 38 }, |
59 | 39 |
60 runRequestSeries(firstStep); | 40 async function testBound() { |
| 41 let objectId = (await Protocol.Runtime.evaluate({ |
| 42 expression: 'Number.bind({}, 5)' |
| 43 })).result.result.objectId; |
| 44 let props = await Protocol.Runtime.getProperties({ objectId, ownProperties:
true }); |
| 45 logGetPropertiesResult(props.result); |
| 46 }, |
61 | 47 |
62 // 'Object5' section -- check properties of '5' wrapped as object (has an inter
nal property). | 48 async function testObjectThrowsLength() { |
| 49 let objectId = (await Protocol.Runtime.evaluate({ |
| 50 expression: '({get length() { throw \'Length called\'; }})' |
| 51 })).result.result.objectId; |
| 52 let props = await Protocol.Runtime.getProperties({ objectId, ownProperties:
true }); |
| 53 logGetPropertiesResult(props.result); |
| 54 }, |
63 | 55 |
64 function callbackStart5() | 56 async function testTypedArrayWithoutLength() { |
65 { | 57 let objectId = (await Protocol.Runtime.evaluate({ |
66 // Create an wrapper object with additional property. | 58 expression: '({__proto__: Uint8Array.prototype})' |
67 var expression = "(function(){var r = Object(5); r.foo = 'cat';return r;})()"; | 59 })).result.result.objectId; |
| 60 let props = await Protocol.Runtime.getProperties({ objectId, ownProperties:
true }); |
| 61 logGetPropertiesResult(props.result); |
| 62 }, |
| 63 ]); |
68 | 64 |
69 return { command: "Runtime.evaluate", params: {expression: expression}, callba
ck: callbackEval5 }; | 65 function logGetPropertiesResult(protocolResult) { |
70 } | 66 function hasGetterSetter(property, fieldName) { |
71 function callbackEval5(result) | |
72 { | |
73 var id = result.result.objectId; | |
74 if (id === undefined) | |
75 throw new Error("objectId is expected"); | |
76 return { | |
77 command: "Runtime.getProperties", params: {objectId: id, ownProperties: true
}, callback: callbackProperties5 | |
78 }; | |
79 } | |
80 function callbackProperties5(result) | |
81 { | |
82 logGetPropertiesResult("Object(5)", result); | |
83 return { callback: callbackStartNotOwn }; | |
84 } | |
85 | |
86 | |
87 // 'Not own' section -- check all properties of the object, including ones from
it prototype chain. | |
88 | |
89 function callbackStartNotOwn() | |
90 { | |
91 // Create an wrapper object with additional property. | |
92 var expression = "({ a: 2, set b(_) {}, get b() {return 5;}, __proto__: { a: 3
, c: 4, get d() {return 6;} }})"; | |
93 | |
94 return { command: "Runtime.evaluate", params: {expression: expression}, callba
ck: callbackEvalNotOwn }; | |
95 } | |
96 function callbackEvalNotOwn(result) | |
97 { | |
98 var id = result.result.objectId; | |
99 if (id === undefined) | |
100 throw new Error("objectId is expected"); | |
101 return { | |
102 command: "Runtime.getProperties", params: {objectId: id, ownProperties: fals
e}, callback: callbackPropertiesNotOwn | |
103 }; | |
104 } | |
105 function callbackPropertiesNotOwn(result) | |
106 { | |
107 logGetPropertiesResult("Not own properties", result); | |
108 return { callback: callbackStartAccessorsOnly }; | |
109 } | |
110 | |
111 | |
112 // 'Accessors only' section -- check only accessor properties of the object. | |
113 | |
114 function callbackStartAccessorsOnly() | |
115 { | |
116 // Create an wrapper object with additional property. | |
117 var expression = "({ a: 2, set b(_) {}, get b() {return 5;}, c: 'c', set d(_){
} })"; | |
118 | |
119 return { command: "Runtime.evaluate", params: {expression: expression}, callba
ck: callbackEvalAccessorsOnly }; | |
120 } | |
121 function callbackEvalAccessorsOnly(result) | |
122 { | |
123 var id = result.result.objectId; | |
124 if (id === undefined) | |
125 throw new Error("objectId is expected"); | |
126 return { | |
127 command: "Runtime.getProperties", params: {objectId: id, ownProperties: true
, accessorPropertiesOnly: true}, callback: callbackPropertiesAccessorsOnly | |
128 }; | |
129 } | |
130 function callbackPropertiesAccessorsOnly(result) | |
131 { | |
132 logGetPropertiesResult("Accessor only properties", result); | |
133 return { callback: callbackStartArray }; | |
134 } | |
135 | |
136 | |
137 // 'Array' section -- check properties of an array. | |
138 | |
139 function callbackStartArray() | |
140 { | |
141 var expression = "['red', 'green', 'blue']"; | |
142 return { command: "Runtime.evaluate", params: {expression: expression}, callba
ck: callbackEvalArray }; | |
143 } | |
144 function callbackEvalArray(result) | |
145 { | |
146 var id = result.result.objectId; | |
147 if (id === undefined) | |
148 throw new Error("objectId is expected"); | |
149 return { | |
150 command: "Runtime.getProperties", params: {objectId: id, ownProperties: true
}, callback: callbackPropertiesArray | |
151 }; | |
152 } | |
153 function callbackPropertiesArray(result) | |
154 { | |
155 logGetPropertiesResult("array", result); | |
156 return { callback: callbackStartBound }; | |
157 } | |
158 | |
159 | |
160 // 'Bound' section -- check properties of a bound function (has a bunch of inter
nal properties). | |
161 | |
162 function callbackStartBound() | |
163 { | |
164 var expression = "Number.bind({}, 5)"; | |
165 return { command: "Runtime.evaluate", params: {expression: expression}, callba
ck: callbackEvalBound }; | |
166 } | |
167 function callbackEvalBound(result) | |
168 { | |
169 var id = result.result.objectId; | |
170 if (id === undefined) | |
171 throw new Error("objectId is expected"); | |
172 return { | |
173 command: "Runtime.getProperties", params: {objectId: id, ownProperties: true
}, callback: callbackPropertiesBound | |
174 }; | |
175 } | |
176 function callbackPropertiesBound(result) | |
177 { | |
178 logGetPropertiesResult("Bound function", result); | |
179 return { callback: callbackStartObjectThrowsLength }; | |
180 } | |
181 | |
182 | |
183 // Object throws on length access | |
184 | |
185 function callbackStartObjectThrowsLength() { | |
186 var expression = "({get length() { throw 'Length called'; }})"; | |
187 return { command: "Runtime.evaluate", params: {expression: expression}, callba
ck: callbackEvalObjectThrowsLength }; | |
188 } | |
189 function callbackEvalObjectThrowsLength(result) { | |
190 var id = result.result.objectId; | |
191 if (id === undefined) | |
192 throw new Error("objectId is expected"); | |
193 return { | |
194 command: "Runtime.getProperties", params: {objectId: id, ownProperties: true
}, callback: callbackPropertiesObjectThrowsLength | |
195 }; | |
196 } | |
197 function callbackPropertiesObjectThrowsLength(result) { | |
198 logGetPropertiesResult("Object that throws on length access", result); | |
199 return { callback: callbackStartTypedArrayWithoutLength }; | |
200 } | |
201 | |
202 | |
203 // Typed array without length | |
204 | |
205 function callbackStartTypedArrayWithoutLength() { | |
206 var expression = "({__proto__: Uint8Array.prototype})"; | |
207 return { command: "Runtime.evaluate", params: {expression: expression}, callba
ck: callbackEvalTypedArrayWithoutLength }; | |
208 } | |
209 function callbackEvalTypedArrayWithoutLength(result) { | |
210 var id = result.result.objectId; | |
211 if (id === undefined) | |
212 throw new Error("objectId is expected"); | |
213 return { | |
214 command: "Runtime.getProperties", params: {objectId: id, ownProperties: true
}, callback: callbackPropertiesTypedArrayWithoutLength | |
215 }; | |
216 } | |
217 function callbackPropertiesTypedArrayWithoutLength(result) { | |
218 logGetPropertiesResult("TypedArray without length", result); | |
219 return; // End of test | |
220 } | |
221 | |
222 // A helper function that dumps object properties and internal properties in sor
ted order. | |
223 function logGetPropertiesResult(title, protocolResult) | |
224 { | |
225 function hasGetterSetter(property, fieldName) | |
226 { | |
227 var v = property[fieldName]; | 67 var v = property[fieldName]; |
228 if (!v) | 68 if (!v) return false; |
229 return false; | |
230 return v.type !== "undefined" | 69 return v.type !== "undefined" |
231 } | 70 } |
232 | 71 |
233 InspectorTest.log("Properties of " + title); | |
234 var propertyArray = protocolResult.result; | 72 var propertyArray = protocolResult.result; |
235 propertyArray.sort(NamedThingComparator); | 73 propertyArray.sort(NamedThingComparator); |
236 for (var i = 0; i < propertyArray.length; i++) { | 74 for (var i = 0; i < propertyArray.length; i++) { |
237 var p = propertyArray[i]; | 75 var p = propertyArray[i]; |
238 var v = p.value; | 76 var v = p.value; |
239 var own = p.isOwn ? "own" : "inherited"; | 77 var own = p.isOwn ? "own" : "inherited"; |
240 if (v) | 78 if (v) |
241 InspectorTest.log(" " + p.name + " " + own + " " + v.type + " " + v.value
); | 79 InspectorTest.log(" " + p.name + " " + own + " " + v.type + " " + v.value
); |
242 else | 80 else |
243 InspectorTest.log(" " + p.name + " " + own + " no value" + | 81 InspectorTest.log(" " + p.name + " " + own + " no value" + |
244 (hasGetterSetter(p, "get") ? ", getter" : "") + (hasGetterSetter(p, "set
") ? ", setter" : "")); | 82 (hasGetterSetter(p, "get") ? ", getter" : "") + (hasGetterSetter(p, "set
") ? ", setter" : "")); |
245 } | 83 } |
246 var internalPropertyArray = protocolResult.internalProperties; | 84 var internalPropertyArray = protocolResult.internalProperties; |
247 if (internalPropertyArray) { | 85 if (internalPropertyArray) { |
248 InspectorTest.log("Internal properties"); | 86 InspectorTest.log("Internal properties"); |
249 internalPropertyArray.sort(NamedThingComparator); | 87 internalPropertyArray.sort(NamedThingComparator); |
250 for (var i = 0; i < internalPropertyArray.length; i++) { | 88 for (var i = 0; i < internalPropertyArray.length; i++) { |
251 var p = internalPropertyArray[i]; | 89 var p = internalPropertyArray[i]; |
252 var v = p.value; | 90 var v = p.value; |
253 InspectorTest.log(" " + p.name + " " + v.type + " " + v.value); | 91 InspectorTest.log(" " + p.name + " " + v.type + " " + v.value); |
254 } | 92 } |
255 } | 93 } |
256 | 94 |
257 function NamedThingComparator(o1, o2) | 95 function NamedThingComparator(o1, o2) { |
258 { | |
259 return o1.name === o2.name ? 0 : (o1.name < o2.name ? -1 : 1); | 96 return o1.name === o2.name ? 0 : (o1.name < o2.name ? -1 : 1); |
260 } | 97 } |
261 } | 98 } |
OLD | NEW |