diff options
Diffstat (limited to 'devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js')
-rw-r--r-- | devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js new file mode 100644 index 000000000..5b5fce266 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js @@ -0,0 +1,300 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +/** + * Make sure that the variables view knows how to edit getters and setters. + */ + +const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html"; + +var gTab, gPanel, gDebugger; +var gL10N, gEditor, gVars, gWatch; + +function test() { + // Debug test slaves are a bit slow at this test. + requestLongerTimeout(2); + + let options = { + source: TAB_URL, + line: 1 + }; + initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => { + gTab = aTab; + gPanel = aPanel; + gDebugger = gPanel.panelWin; + gL10N = gDebugger.L10N; + gEditor = gDebugger.DebuggerView.editor; + gVars = gDebugger.DebuggerView.Variables; + gWatch = gDebugger.DebuggerView.WatchExpressions; + + gVars.switch = function () {}; + gVars.delete = function () {}; + + waitForCaretAndScopes(gPanel, 24) + .then(() => addWatchExpressions()) + .then(() => testEdit("set", "this._prop = value + ' BEER CAN'", { + "myVar.prop": "xlerb BEER CAN", + "myVar.prop + 42": "xlerb BEER CAN42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("set", "{ this._prop = value + ' BEACON' }", { + "myVar.prop": "xlerb BEACON", + "myVar.prop + 42": "xlerb BEACON42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("set", "{ this._prop = value + ' BEACON;'; }", { + "myVar.prop": "xlerb BEACON;", + "myVar.prop + 42": "xlerb BEACON;42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("set", "{ return this._prop = value + ' BEACON;;'; }", { + "myVar.prop": "xlerb BEACON;;", + "myVar.prop + 42": "xlerb BEACON;;42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("set", "function(value) { this._prop = value + ' BACON' }", { + "myVar.prop": "xlerb BACON", + "myVar.prop + 42": "xlerb BACON42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("get", "'brelx BEER CAN'", { + "myVar.prop": "brelx BEER CAN", + "myVar.prop + 42": "brelx BEER CAN42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("get", "{ 'brelx BEACON' }", { + "myVar.prop": undefined, + "myVar.prop + 42": NaN, + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("get", "{ 'brelx BEACON;'; }", { + "myVar.prop": undefined, + "myVar.prop + 42": NaN, + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("get", "{ return 'brelx BEACON;;'; }", { + "myVar.prop": "brelx BEACON;;", + "myVar.prop + 42": "brelx BEACON;;42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("get", "function() { return 'brelx BACON'; }", { + "myVar.prop": "brelx BACON", + "myVar.prop + 42": "brelx BACON42", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("get", "bogus", { + "myVar.prop": "ReferenceError: bogus is not defined", + "myVar.prop + 42": "ReferenceError: bogus is not defined", + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => testEdit("set", "sugob", { + "myVar.prop": "ReferenceError: bogus is not defined", + "myVar.prop + 42": "ReferenceError: bogus is not defined", + "myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined" + })) + .then(() => testEdit("get", "", { + "myVar.prop": undefined, + "myVar.prop + 42": NaN, + "myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined" + })) + .then(() => testEdit("set", "", { + "myVar.prop": "xlerb", + "myVar.prop + 42": NaN, + "myVar.prop = 'xlerb'": "xlerb" + })) + .then(() => deleteWatchExpression("myVar.prop = 'xlerb'")) + .then(() => testEdit("self", "2507", { + "myVar.prop": 2507, + "myVar.prop + 42": 2549 + })) + .then(() => deleteWatchExpression("myVar.prop + 42")) + .then(() => testEdit("self", "0910", { + "myVar.prop": 910 + })) + .then(() => deleteLastWatchExpression("myVar.prop")) + .then(() => testWatchExpressionsRemoved()) + .then(() => resumeDebuggerThenCloseAndFinish(gPanel)) + .then(null, aError => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + }); + + generateMouseClickInTab(gTab, "content.document.querySelector('button')"); + }); +} + +function addWatchExpressions() { + return promise.resolve(null) + .then(() => { + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS); + gWatch.addExpression("myVar.prop"); + gEditor.focus(); + return finished; + }) + .then(() => { + let exprScope = gVars.getScopeAtIndex(0); + ok(exprScope, + "There should be a wach expressions scope in the variables view."); + is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"), + "The scope's name should be marked as 'Watch Expressions'."); + is(exprScope._store.size, 1, + "There should be 1 evaluation available."); + + let w1 = exprScope.get("myVar.prop"); + let w2 = exprScope.get("myVar.prop + 42"); + let w3 = exprScope.get("myVar.prop = 'xlerb'"); + + ok(w1, "The first watch expression should be present in the scope."); + ok(!w2, "The second watch expression should not be present in the scope."); + ok(!w3, "The third watch expression should not be present in the scope."); + + is(w1.value, 42, "The first value is correct."); + }) + .then(() => { + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS); + gWatch.addExpression("myVar.prop + 42"); + gEditor.focus(); + return finished; + }) + .then(() => { + let exprScope = gVars.getScopeAtIndex(0); + ok(exprScope, + "There should be a wach expressions scope in the variables view."); + is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"), + "The scope's name should be marked as 'Watch Expressions'."); + is(exprScope._store.size, 2, + "There should be 2 evaluations available."); + + let w1 = exprScope.get("myVar.prop"); + let w2 = exprScope.get("myVar.prop + 42"); + let w3 = exprScope.get("myVar.prop = 'xlerb'"); + + ok(w1, "The first watch expression should be present in the scope."); + ok(w2, "The second watch expression should be present in the scope."); + ok(!w3, "The third watch expression should not be present in the scope."); + + is(w1.value, "42", "The first expression value is correct."); + is(w2.value, "84", "The second expression value is correct."); + }) + .then(() => { + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS); + gWatch.addExpression("myVar.prop = 'xlerb'"); + gEditor.focus(); + return finished; + }) + .then(() => { + let exprScope = gVars.getScopeAtIndex(0); + ok(exprScope, + "There should be a wach expressions scope in the variables view."); + is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"), + "The scope's name should be marked as 'Watch Expressions'."); + is(exprScope._store.size, 3, + "There should be 3 evaluations available."); + + let w1 = exprScope.get("myVar.prop"); + let w2 = exprScope.get("myVar.prop + 42"); + let w3 = exprScope.get("myVar.prop = 'xlerb'"); + + ok(w1, "The first watch expression should be present in the scope."); + ok(w2, "The second watch expression should be present in the scope."); + ok(w3, "The third watch expression should be present in the scope."); + + is(w1.value, "xlerb", "The first expression value is correct."); + is(w2.value, "xlerb42", "The second expression value is correct."); + is(w3.value, "xlerb", "The third expression value is correct."); + }); +} + +function deleteWatchExpression(aString) { + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS); + gWatch.deleteExpression({ name: aString }); + return finished; +} + +function deleteLastWatchExpression(aString) { + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES); + gWatch.deleteExpression({ name: aString }); + return finished; +} + +function testEdit(aWhat, aString, aExpected) { + let localScope = gVars.getScopeAtIndex(1); + let myVar = localScope.get("myVar"); + + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES).then(() => { + let propVar = myVar.get("prop"); + let getterOrSetterOrVar = aWhat != "self" ? propVar.get(aWhat) : propVar; + + let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS).then(() => { + let exprScope = gVars.getScopeAtIndex(0); + ok(exprScope, + "There should be a wach expressions scope in the variables view."); + is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"), + "The scope's name should be marked as 'Watch Expressions'."); + is(exprScope._store.size, Object.keys(aExpected).length, + "There should be a certain number of evaluations available."); + + function testExpression(aExpression) { + if (!aExpression) { + return; + } + let value = aExpected[aExpression.name]; + if (isNaN(value)) { + ok(isNaN(aExpression.value), + "The expression value is correct after the edit."); + } else if (value == null) { + is(aExpression.value.type, value + "", + "The expression value is correct after the edit."); + } else { + is(aExpression.value, value, + "The expression value is correct after the edit."); + } + } + + testExpression(exprScope.get(Object.keys(aExpected)[0])); + testExpression(exprScope.get(Object.keys(aExpected)[1])); + testExpression(exprScope.get(Object.keys(aExpected)[2])); + }); + + let editTarget = getterOrSetterOrVar.target; + + // Allow the target variable to get painted, so that clicking on + // its value would scroll the new textbox node into view. + executeSoon(() => { + let varValue = editTarget.querySelector(".title > .value"); + EventUtils.sendMouseEvent({ type: "mousedown" }, varValue, gDebugger); + + let varInput = editTarget.querySelector(".title > .element-value-input"); + setText(varInput, aString); + EventUtils.sendKey("RETURN", gDebugger); + }); + + return finished; + }); + + myVar.expand(); + gVars.clearHierarchy(); + + return finished; +} + +function testWatchExpressionsRemoved() { + let scope = gVars.getScopeAtIndex(0); + ok(scope, + "There should be a local scope in the variables view."); + isnot(scope.name, gL10N.getStr("watchExpressionsScopeLabel"), + "The scope's name should not be marked as 'Watch Expressions'."); + isnot(scope._store.size, 0, + "There should be some variables available."); +} + +registerCleanupFunction(function () { + gTab = null; + gPanel = null; + gDebugger = null; + gL10N = null; + gEditor = null; + gVars = null; + gWatch = null; +}); |