|
1 /* Any copyright is dedicated to the Public Domain. |
|
2 http://creativecommons.org/publicdomain/zero/1.0/ */ |
|
3 |
|
4 /** |
|
5 * Tests that values are correctly serialized and sent in enteredFrame |
|
6 * and exitedFrame packets. |
|
7 */ |
|
8 |
|
9 var gDebuggee; |
|
10 var gClient; |
|
11 var gTraceClient; |
|
12 |
|
13 function run_test() |
|
14 { |
|
15 initTestTracerServer(); |
|
16 gDebuggee = addTestGlobal("test-tracer-actor"); |
|
17 gClient = new DebuggerClient(DebuggerServer.connectPipe()); |
|
18 gClient.connect(function() { |
|
19 attachTestTab(gClient, "test-tracer-actor", function(aResponse, aTabClient) { |
|
20 gClient.attachTracer(aResponse.traceActor, function(aResponse, aTraceClient) { |
|
21 gTraceClient = aTraceClient; |
|
22 test_enter_exit_frame(); |
|
23 }); |
|
24 }); |
|
25 }); |
|
26 do_test_pending(); |
|
27 } |
|
28 |
|
29 function test_enter_exit_frame() |
|
30 { |
|
31 const traceStopped = promise.defer(); |
|
32 |
|
33 gClient.addListener("traces", (aEvent, { traces }) => { |
|
34 for (let t of traces) { |
|
35 check_trace(t); |
|
36 if (t.sequence === 27) { |
|
37 traceStopped.resolve(); |
|
38 } |
|
39 } |
|
40 }); |
|
41 |
|
42 start_trace() |
|
43 .then(eval_code) |
|
44 .then(() => traceStopped.promise) |
|
45 .then(stop_trace) |
|
46 .then(function() { |
|
47 finishClient(gClient); |
|
48 }); |
|
49 } |
|
50 |
|
51 function start_trace() |
|
52 { |
|
53 let deferred = promise.defer(); |
|
54 gTraceClient.startTrace(["arguments", "return"], null, function() { deferred.resolve(); }); |
|
55 return deferred.promise; |
|
56 } |
|
57 |
|
58 function eval_code() |
|
59 { |
|
60 gDebuggee.eval("(" + function() { |
|
61 function identity(x) { |
|
62 return x; |
|
63 } |
|
64 |
|
65 let circular = {}; |
|
66 circular.self = circular; |
|
67 |
|
68 // Make sure there is only 3 properties per object because that is the value |
|
69 // of MAX_PROPERTIES in the server. |
|
70 let obj = { |
|
71 num: 0, |
|
72 str: "foo", |
|
73 bool: false, |
|
74 }; |
|
75 let obj2 = { |
|
76 undef: undefined, |
|
77 nil: null, |
|
78 inf: Infinity |
|
79 }; |
|
80 let obj3 = { |
|
81 ninf: -Infinity, |
|
82 nan: NaN, |
|
83 nzero: -0 |
|
84 }; |
|
85 let obj4 = { |
|
86 obj: circular, |
|
87 arr: [1,2,3,4,5] |
|
88 }; |
|
89 |
|
90 identity(); |
|
91 identity(0); |
|
92 identity(""); |
|
93 identity(false); |
|
94 identity(undefined); |
|
95 identity(null); |
|
96 identity(Infinity); |
|
97 identity(-Infinity); |
|
98 identity(NaN); |
|
99 identity(-0); |
|
100 identity(obj); |
|
101 identity(obj2); |
|
102 identity(obj3); |
|
103 identity(obj4); |
|
104 } + ")()"); |
|
105 } |
|
106 |
|
107 function stop_trace() |
|
108 { |
|
109 let deferred = promise.defer(); |
|
110 gTraceClient.stopTrace(null, function() { deferred.resolve(); }); |
|
111 return deferred.promise; |
|
112 } |
|
113 |
|
114 function check_trace(aTrace) |
|
115 { |
|
116 let value = (aTrace.type === "enteredFrame" && aTrace.arguments) |
|
117 ? aTrace.arguments[0] |
|
118 : aTrace.return; |
|
119 switch(aTrace.sequence) { |
|
120 case 2: |
|
121 do_check_eq(typeof aTrace.arguments, "object"); |
|
122 do_check_eq(aTrace.arguments.length, 0); |
|
123 break; |
|
124 case 3: |
|
125 check_value(value, "object", "undefined"); |
|
126 break; |
|
127 case 4: |
|
128 case 5: |
|
129 check_value(value, "number", 0); |
|
130 break; |
|
131 case 6: |
|
132 case 7: |
|
133 check_value(value, "string", ""); |
|
134 break; |
|
135 case 8: |
|
136 case 9: |
|
137 check_value(value, "boolean", false); |
|
138 break; |
|
139 case 10: |
|
140 case 11: |
|
141 check_value(value, "object", "undefined"); |
|
142 break; |
|
143 case 12: |
|
144 case 13: |
|
145 check_value(value, "object", "null"); |
|
146 break; |
|
147 case 14: |
|
148 case 15: |
|
149 check_value(value, "object", "Infinity"); |
|
150 break; |
|
151 case 16: |
|
152 case 17: |
|
153 check_value(value, "object", "-Infinity"); |
|
154 break; |
|
155 case 18: |
|
156 case 19: |
|
157 check_value(value, "object", "NaN"); |
|
158 break; |
|
159 case 20: |
|
160 case 21: |
|
161 check_value(value, "object", "-0"); |
|
162 break; |
|
163 case 22: |
|
164 case 23: |
|
165 check_obj(aTrace.type, value); |
|
166 break; |
|
167 case 24: |
|
168 case 25: |
|
169 check_obj2(aTrace.type, value); |
|
170 break; |
|
171 case 26: |
|
172 case 27: |
|
173 check_obj3(aTrace.type, value); |
|
174 break; |
|
175 case 28: |
|
176 case 29: |
|
177 check_obj4(aTrace.type, value); |
|
178 break; |
|
179 } |
|
180 } |
|
181 |
|
182 function check_value(aActual, aExpectedType, aExpectedValue) |
|
183 { |
|
184 do_check_eq(typeof aActual, aExpectedType); |
|
185 do_check_eq(aExpectedType === "object" ? aActual.type : aActual, aExpectedValue); |
|
186 } |
|
187 |
|
188 function check_obj(aType, aObj) { |
|
189 do_check_eq(typeof aObj, "object"); |
|
190 do_check_eq(typeof aObj.ownProperties, "object"); |
|
191 |
|
192 do_check_eq(typeof aObj.ownProperties.num, "object"); |
|
193 do_check_eq(aObj.ownProperties.num.value, 0); |
|
194 |
|
195 do_check_eq(typeof aObj.ownProperties.str, "object"); |
|
196 do_check_eq(aObj.ownProperties.str.value, "foo"); |
|
197 |
|
198 do_check_eq(typeof aObj.ownProperties.bool, "object"); |
|
199 do_check_eq(aObj.ownProperties.bool.value, false); |
|
200 } |
|
201 |
|
202 function check_obj2(aType, aObj) { |
|
203 do_check_eq(typeof aObj.ownProperties.undef, "object"); |
|
204 do_check_eq(typeof aObj.ownProperties.undef.value, "object"); |
|
205 do_check_eq(aObj.ownProperties.undef.value.type, "undefined"); |
|
206 |
|
207 do_check_eq(typeof aObj.ownProperties.nil, "object"); |
|
208 do_check_eq(typeof aObj.ownProperties.nil.value, "object"); |
|
209 do_check_eq(aObj.ownProperties.nil.value.type, "null"); |
|
210 |
|
211 do_check_eq(typeof aObj.ownProperties.inf, "object"); |
|
212 do_check_eq(typeof aObj.ownProperties.inf.value, "object"); |
|
213 do_check_eq(aObj.ownProperties.inf.value.type, "Infinity"); |
|
214 } |
|
215 |
|
216 function check_obj3(aType, aObj) { |
|
217 do_check_eq(typeof aObj.ownProperties.ninf, "object"); |
|
218 do_check_eq(typeof aObj.ownProperties.ninf.value, "object"); |
|
219 do_check_eq(aObj.ownProperties.ninf.value.type, "-Infinity"); |
|
220 |
|
221 do_check_eq(typeof aObj.ownProperties.nan, "object"); |
|
222 do_check_eq(typeof aObj.ownProperties.nan.value, "object"); |
|
223 do_check_eq(aObj.ownProperties.nan.value.type, "NaN"); |
|
224 |
|
225 do_check_eq(typeof aObj.ownProperties.nzero, "object"); |
|
226 do_check_eq(typeof aObj.ownProperties.nzero.value, "object"); |
|
227 do_check_eq(aObj.ownProperties.nzero.value.type, "-0"); |
|
228 } |
|
229 |
|
230 function check_obj4(aType, aObj) { |
|
231 // Sub-objects aren't added. |
|
232 do_check_eq(typeof aObj.ownProperties.obj, "undefined"); |
|
233 do_check_eq(typeof aObj.ownProperties.arr, "undefined"); |
|
234 } |