Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* Any copyright is dedicated to the Public Domain.
2 http://creativecommons.org/publicdomain/zero/1.0/ */
4 /**
5 * Make sure that the variables view knows how to edit getters and setters.
6 */
8 const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
10 let gTab, gDebuggee, gPanel, gDebugger;
11 let gL10N, gEditor, gVars, gWatch;
13 function test() {
14 // Debug test slaves are a bit slow at this test.
15 requestLongerTimeout(2);
17 initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
18 gTab = aTab;
19 gDebuggee = aDebuggee;
20 gPanel = aPanel;
21 gDebugger = gPanel.panelWin;
22 gL10N = gDebugger.L10N;
23 gEditor = gDebugger.DebuggerView.editor;
24 gVars = gDebugger.DebuggerView.Variables;
25 gWatch = gDebugger.DebuggerView.WatchExpressions;
27 gVars.switch = function() {};
28 gVars.delete = function() {};
30 waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
31 .then(() => addWatchExpressions())
32 .then(() => testEdit("set", "this._prop = value + ' BEER CAN'", {
33 "myVar.prop": "xlerb BEER CAN",
34 "myVar.prop + 42": "xlerb BEER CAN42",
35 "myVar.prop = 'xlerb'": "xlerb"
36 }))
37 .then(() => testEdit("set", "{ this._prop = value + ' BEACON' }", {
38 "myVar.prop": "xlerb BEACON",
39 "myVar.prop + 42": "xlerb BEACON42",
40 "myVar.prop = 'xlerb'": "xlerb"
41 }))
42 .then(() => testEdit("set", "{ this._prop = value + ' BEACON;'; }", {
43 "myVar.prop": "xlerb BEACON;",
44 "myVar.prop + 42": "xlerb BEACON;42",
45 "myVar.prop = 'xlerb'": "xlerb"
46 }))
47 .then(() => testEdit("set", "{ return this._prop = value + ' BEACON;;'; }", {
48 "myVar.prop": "xlerb BEACON;;",
49 "myVar.prop + 42": "xlerb BEACON;;42",
50 "myVar.prop = 'xlerb'": "xlerb"
51 }))
52 .then(() => testEdit("set", "function(value) { this._prop = value + ' BACON' }", {
53 "myVar.prop": "xlerb BACON",
54 "myVar.prop + 42": "xlerb BACON42",
55 "myVar.prop = 'xlerb'": "xlerb"
56 }))
57 .then(() => testEdit("get", "'brelx BEER CAN'", {
58 "myVar.prop": "brelx BEER CAN",
59 "myVar.prop + 42": "brelx BEER CAN42",
60 "myVar.prop = 'xlerb'": "xlerb"
61 }))
62 .then(() => testEdit("get", "{ 'brelx BEACON' }", {
63 "myVar.prop": undefined,
64 "myVar.prop + 42": NaN,
65 "myVar.prop = 'xlerb'": "xlerb"
66 }))
67 .then(() => testEdit("get", "{ 'brelx BEACON;'; }", {
68 "myVar.prop": undefined,
69 "myVar.prop + 42": NaN,
70 "myVar.prop = 'xlerb'": "xlerb"
71 }))
72 .then(() => testEdit("get", "{ return 'brelx BEACON;;'; }", {
73 "myVar.prop": "brelx BEACON;;",
74 "myVar.prop + 42": "brelx BEACON;;42",
75 "myVar.prop = 'xlerb'": "xlerb"
76 }))
77 .then(() => testEdit("get", "function() { return 'brelx BACON'; }", {
78 "myVar.prop": "brelx BACON",
79 "myVar.prop + 42": "brelx BACON42",
80 "myVar.prop = 'xlerb'": "xlerb"
81 }))
82 .then(() => testEdit("get", "bogus", {
83 "myVar.prop": "ReferenceError: bogus is not defined",
84 "myVar.prop + 42": "ReferenceError: bogus is not defined",
85 "myVar.prop = 'xlerb'": "xlerb"
86 }))
87 .then(() => testEdit("set", "sugob", {
88 "myVar.prop": "ReferenceError: bogus is not defined",
89 "myVar.prop + 42": "ReferenceError: bogus is not defined",
90 "myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
91 }))
92 .then(() => testEdit("get", "", {
93 "myVar.prop": undefined,
94 "myVar.prop + 42": NaN,
95 "myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
96 }))
97 .then(() => testEdit("set", "", {
98 "myVar.prop": "xlerb",
99 "myVar.prop + 42": NaN,
100 "myVar.prop = 'xlerb'": "xlerb"
101 }))
102 .then(() => deleteWatchExpression("myVar.prop = 'xlerb'"))
103 .then(() => testEdit("self", "2507", {
104 "myVar.prop": 2507,
105 "myVar.prop + 42": 2549
106 }))
107 .then(() => deleteWatchExpression("myVar.prop + 42"))
108 .then(() => testEdit("self", "0910", {
109 "myVar.prop": 910
110 }))
111 .then(() => deleteLastWatchExpression("myVar.prop"))
112 .then(() => testWatchExpressionsRemoved())
113 .then(() => resumeDebuggerThenCloseAndFinish(gPanel))
114 .then(null, aError => {
115 ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
116 });
118 EventUtils.sendMouseEvent({ type: "click" },
119 gDebuggee.document.querySelector("button"),
120 gDebuggee);
121 });
122 }
124 function addWatchExpressions() {
125 return promise.resolve(null)
126 .then(() => {
127 let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
128 gWatch.addExpression("myVar.prop");
129 gEditor.focus();
130 return finished;
131 })
132 .then(() => {
133 let exprScope = gVars.getScopeAtIndex(0);
134 ok(exprScope,
135 "There should be a wach expressions scope in the variables view.");
136 is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
137 "The scope's name should be marked as 'Watch Expressions'.");
138 is(exprScope._store.size, 1,
139 "There should be 1 evaluation available.");
141 let w1 = exprScope.get("myVar.prop");
142 let w2 = exprScope.get("myVar.prop + 42");
143 let w3 = exprScope.get("myVar.prop = 'xlerb'");
145 ok(w1, "The first watch expression should be present in the scope.");
146 ok(!w2, "The second watch expression should not be present in the scope.");
147 ok(!w3, "The third watch expression should not be present in the scope.");
149 is(w1.value, 42, "The first value is correct.");
150 })
151 .then(() => {
152 let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
153 gWatch.addExpression("myVar.prop + 42");
154 gEditor.focus();
155 return finished;
156 })
157 .then(() => {
158 let exprScope = gVars.getScopeAtIndex(0);
159 ok(exprScope,
160 "There should be a wach expressions scope in the variables view.");
161 is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
162 "The scope's name should be marked as 'Watch Expressions'.");
163 is(exprScope._store.size, 2,
164 "There should be 2 evaluations available.");
166 let w1 = exprScope.get("myVar.prop");
167 let w2 = exprScope.get("myVar.prop + 42");
168 let w3 = exprScope.get("myVar.prop = 'xlerb'");
170 ok(w1, "The first watch expression should be present in the scope.");
171 ok(w2, "The second watch expression should be present in the scope.");
172 ok(!w3, "The third watch expression should not be present in the scope.");
174 is(w1.value, "42", "The first expression value is correct.");
175 is(w2.value, "84", "The second expression value is correct.");
176 })
177 .then(() => {
178 let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
179 gWatch.addExpression("myVar.prop = 'xlerb'");
180 gEditor.focus();
181 return finished;
182 })
183 .then(() => {
184 let exprScope = gVars.getScopeAtIndex(0);
185 ok(exprScope,
186 "There should be a wach expressions scope in the variables view.");
187 is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
188 "The scope's name should be marked as 'Watch Expressions'.");
189 is(exprScope._store.size, 3,
190 "There should be 3 evaluations available.");
192 let w1 = exprScope.get("myVar.prop");
193 let w2 = exprScope.get("myVar.prop + 42");
194 let w3 = exprScope.get("myVar.prop = 'xlerb'");
196 ok(w1, "The first watch expression should be present in the scope.");
197 ok(w2, "The second watch expression should be present in the scope.");
198 ok(w3, "The third watch expression should be present in the scope.");
200 is(w1.value, "xlerb", "The first expression value is correct.");
201 is(w2.value, "xlerb42", "The second expression value is correct.");
202 is(w3.value, "xlerb", "The third expression value is correct.");
203 });
204 }
206 function deleteWatchExpression(aString) {
207 let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
208 gWatch.deleteExpression({ name: aString });
209 return finished;
210 }
212 function deleteLastWatchExpression(aString) {
213 let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
214 gWatch.deleteExpression({ name: aString });
215 return finished;
216 }
218 function testEdit(aWhat, aString, aExpected) {
219 let localScope = gVars.getScopeAtIndex(1);
220 let myVar = localScope.get("myVar");
222 let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES).then(() => {
223 let propVar = myVar.get("prop");
224 let getterOrSetterOrVar = aWhat != "self" ? propVar.get(aWhat) : propVar;
226 let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS).then(() => {
227 let exprScope = gVars.getScopeAtIndex(0);
228 ok(exprScope,
229 "There should be a wach expressions scope in the variables view.");
230 is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
231 "The scope's name should be marked as 'Watch Expressions'.");
232 is(exprScope._store.size, Object.keys(aExpected).length,
233 "There should be a certain number of evaluations available.");
235 function testExpression(aExpression) {
236 if (!aExpression) {
237 return;
238 }
239 let value = aExpected[aExpression.name];
240 if (isNaN(value)) {
241 ok(isNaN(aExpression.value),
242 "The expression value is correct after the edit.");
243 } else if (value == null) {
244 is(aExpression.value.type, value + "",
245 "The expression value is correct after the edit.");
246 } else {
247 is(aExpression.value, value,
248 "The expression value is correct after the edit.");
249 }
250 }
252 testExpression(exprScope.get(Object.keys(aExpected)[0]));
253 testExpression(exprScope.get(Object.keys(aExpected)[1]));
254 testExpression(exprScope.get(Object.keys(aExpected)[2]));
255 });
257 let editTarget = getterOrSetterOrVar.target;
259 // Allow the target variable to get painted, so that clicking on
260 // its value would scroll the new textbox node into view.
261 executeSoon(() => {
262 let varValue = editTarget.querySelector(".title > .value");
263 EventUtils.sendMouseEvent({ type: "mousedown" }, varValue, gDebugger);
265 let varInput = editTarget.querySelector(".title > .element-value-input");
266 setText(varInput, aString);
267 EventUtils.sendKey("RETURN", gDebugger);
268 });
270 return finished;
271 });
273 myVar.expand();
274 gVars.clearHierarchy();
276 return finished;
277 }
279 function testWatchExpressionsRemoved() {
280 let scope = gVars.getScopeAtIndex(0);
281 ok(scope,
282 "There should be a local scope in the variables view.");
283 isnot(scope.name, gL10N.getStr("watchExpressionsScopeLabel"),
284 "The scope's name should not be marked as 'Watch Expressions'.");
285 isnot(scope._store.size, 0,
286 "There should be some variables available.");
287 }
289 registerCleanupFunction(function() {
290 gTab = null;
291 gDebuggee = null;
292 gPanel = null;
293 gDebugger = null;
294 gL10N = null;
295 gEditor = null;
296 gVars = null;
297 gWatch = null;
298 });