summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js
diff options
context:
space:
mode:
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.js300
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;
+});