michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: /** michael@0: * Tests that VariablesView methods responsible for styling variables michael@0: * as overridden work properly. michael@0: */ michael@0: michael@0: const TAB_URL = EXAMPLE_URL + "doc_scope-variable-2.html"; michael@0: michael@0: function test() { michael@0: Task.spawn(function() { michael@0: let [tab, debuggee, panel] = yield initDebugger(TAB_URL); michael@0: let win = panel.panelWin; michael@0: let events = win.EVENTS; michael@0: let variables = win.DebuggerView.Variables; michael@0: michael@0: // Allow this generator function to yield first. michael@0: executeSoon(() => debuggee.test()); michael@0: yield waitForSourceAndCaretAndScopes(panel, ".html", 23); michael@0: michael@0: let firstScope = variables.getScopeAtIndex(0); michael@0: let secondScope = variables.getScopeAtIndex(1); michael@0: let thirdScope = variables.getScopeAtIndex(2); michael@0: let globalScope = variables.getScopeAtIndex(3); michael@0: michael@0: ok(firstScope, "The first scope is available."); michael@0: ok(secondScope, "The second scope is available."); michael@0: ok(thirdScope, "The third scope is available."); michael@0: ok(globalScope, "The global scope is available."); michael@0: michael@0: is(firstScope.name, "Function scope [secondNest]", michael@0: "The first scope's name is correct."); michael@0: is(secondScope.name, "Function scope [firstNest]", michael@0: "The second scope's name is correct."); michael@0: is(thirdScope.name, "Function scope [test]", michael@0: "The third scope's name is correct."); michael@0: is(globalScope.name, "Global scope [Window]", michael@0: "The global scope's name is correct."); michael@0: michael@0: is(firstScope.expanded, true, michael@0: "The first scope's expansion state is correct."); michael@0: is(secondScope.expanded, false, michael@0: "The second scope's expansion state is correct."); michael@0: is(thirdScope.expanded, false, michael@0: "The third scope's expansion state is correct."); michael@0: is(globalScope.expanded, false, michael@0: "The global scope's expansion state is correct."); michael@0: michael@0: is(firstScope._store.size, 3, michael@0: "The first scope should have all the variables available."); michael@0: is(secondScope._store.size, 0, michael@0: "The second scope should have no variables available yet."); michael@0: is(thirdScope._store.size, 0, michael@0: "The third scope should have no variables available yet."); michael@0: is(globalScope._store.size, 0, michael@0: "The global scope should have no variables available yet."); michael@0: michael@0: // Test getOwnerScopeForVariableOrProperty with simple variables. michael@0: michael@0: let thisVar = firstScope.get("this"); michael@0: let thisOwner = variables.getOwnerScopeForVariableOrProperty(thisVar); michael@0: is(thisOwner, firstScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (1)."); michael@0: michael@0: let someVar1 = firstScope.get("a"); michael@0: let someOwner1 = variables.getOwnerScopeForVariableOrProperty(someVar1); michael@0: is(someOwner1, firstScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (2)."); michael@0: michael@0: // Test getOwnerScopeForVariableOrProperty with first-degree properties. michael@0: michael@0: let argsVar1 = firstScope.get("arguments"); michael@0: let fetched = waitForDebuggerEvents(panel, events.FETCHED_PROPERTIES); michael@0: argsVar1.expand(); michael@0: yield fetched; michael@0: michael@0: let calleeProp1 = argsVar1.get("callee"); michael@0: let calleeOwner1 = variables.getOwnerScopeForVariableOrProperty(calleeProp1); michael@0: is(calleeOwner1, firstScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (3)."); michael@0: michael@0: // Test getOwnerScopeForVariableOrProperty with second-degree properties. michael@0: michael@0: let protoVar1 = argsVar1.get("__proto__"); michael@0: let fetched = waitForDebuggerEvents(panel, events.FETCHED_PROPERTIES); michael@0: protoVar1.expand(); michael@0: yield fetched; michael@0: michael@0: let constrProp1 = protoVar1.get("constructor"); michael@0: let constrOwner1 = variables.getOwnerScopeForVariableOrProperty(constrProp1); michael@0: is(constrOwner1, firstScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (4)."); michael@0: michael@0: // Test getOwnerScopeForVariableOrProperty with a simple variable michael@0: // from non-topmost scopes. michael@0: michael@0: // Only need to wait for a single FETCHED_VARIABLES event, just for the michael@0: // global scope, because the other local scopes already have the michael@0: // arguments and variables available as evironment bindings. michael@0: let fetched = waitForDebuggerEvents(panel, events.FETCHED_VARIABLES); michael@0: secondScope.expand(); michael@0: thirdScope.expand(); michael@0: globalScope.expand(); michael@0: yield fetched; michael@0: michael@0: let someVar2 = secondScope.get("a"); michael@0: let someOwner2 = variables.getOwnerScopeForVariableOrProperty(someVar2); michael@0: is(someOwner2, secondScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (5)."); michael@0: michael@0: let someVar3 = thirdScope.get("a"); michael@0: let someOwner3 = variables.getOwnerScopeForVariableOrProperty(someVar3); michael@0: is(someOwner3, thirdScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (6)."); michael@0: michael@0: // Test getOwnerScopeForVariableOrProperty with first-degree properies michael@0: // from non-topmost scopes. michael@0: michael@0: let argsVar2 = secondScope.get("arguments"); michael@0: let fetched = waitForDebuggerEvents(panel, events.FETCHED_PROPERTIES); michael@0: argsVar2.expand(); michael@0: yield fetched; michael@0: michael@0: let calleeProp2 = argsVar2.get("callee"); michael@0: let calleeOwner2 = variables.getOwnerScopeForVariableOrProperty(calleeProp2); michael@0: is(calleeOwner2, secondScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (7)."); michael@0: michael@0: let argsVar3 = thirdScope.get("arguments"); michael@0: let fetched = waitForDebuggerEvents(panel, events.FETCHED_PROPERTIES); michael@0: argsVar3.expand(); michael@0: yield fetched; michael@0: michael@0: let calleeProp3 = argsVar3.get("callee"); michael@0: let calleeOwner3 = variables.getOwnerScopeForVariableOrProperty(calleeProp3); michael@0: is(calleeOwner3, thirdScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (8)."); michael@0: michael@0: // Test getOwnerScopeForVariableOrProperty with second-degree properties michael@0: // from non-topmost scopes. michael@0: michael@0: let protoVar2 = argsVar2.get("__proto__"); michael@0: let fetched = waitForDebuggerEvents(panel, events.FETCHED_PROPERTIES); michael@0: protoVar2.expand(); michael@0: yield fetched; michael@0: michael@0: let constrProp2 = protoVar2.get("constructor"); michael@0: let constrOwner2 = variables.getOwnerScopeForVariableOrProperty(constrProp2); michael@0: is(constrOwner2, secondScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (9)."); michael@0: michael@0: let protoVar3 = argsVar3.get("__proto__"); michael@0: let fetched = waitForDebuggerEvents(panel, events.FETCHED_PROPERTIES); michael@0: protoVar3.expand(); michael@0: yield fetched; michael@0: michael@0: let constrProp3 = protoVar3.get("constructor"); michael@0: let constrOwner3 = variables.getOwnerScopeForVariableOrProperty(constrProp3); michael@0: is(constrOwner3, thirdScope, michael@0: "The getOwnerScopeForVariableOrProperty method works properly (10)."); michael@0: michael@0: // Test getParentScopesForVariableOrProperty with simple variables. michael@0: michael@0: let varOwners1 = variables.getParentScopesForVariableOrProperty(someVar1); michael@0: let varOwners2 = variables.getParentScopesForVariableOrProperty(someVar2); michael@0: let varOwners3 = variables.getParentScopesForVariableOrProperty(someVar3); michael@0: michael@0: is(varOwners1.length, 0, michael@0: "There should be no owner scopes for the first variable."); michael@0: michael@0: is(varOwners2.length, 1, michael@0: "There should be one owner scope for the second variable."); michael@0: is(varOwners2[0], firstScope, michael@0: "The only owner scope for the second variable is correct."); michael@0: michael@0: is(varOwners3.length, 2, michael@0: "There should be two owner scopes for the third variable."); michael@0: is(varOwners3[0], firstScope, michael@0: "The first owner scope for the third variable is correct."); michael@0: is(varOwners3[1], secondScope, michael@0: "The second owner scope for the third variable is correct."); michael@0: michael@0: // Test getParentScopesForVariableOrProperty with first-degree properties. michael@0: michael@0: let propOwners1 = variables.getParentScopesForVariableOrProperty(calleeProp1); michael@0: let propOwners2 = variables.getParentScopesForVariableOrProperty(calleeProp2); michael@0: let propOwners3 = variables.getParentScopesForVariableOrProperty(calleeProp3); michael@0: michael@0: is(propOwners1.length, 0, michael@0: "There should be no owner scopes for the first property."); michael@0: michael@0: is(propOwners2.length, 1, michael@0: "There should be one owner scope for the second property."); michael@0: is(propOwners2[0], firstScope, michael@0: "The only owner scope for the second property is correct."); michael@0: michael@0: is(propOwners3.length, 2, michael@0: "There should be two owner scopes for the third property."); michael@0: is(propOwners3[0], firstScope, michael@0: "The first owner scope for the third property is correct."); michael@0: is(propOwners3[1], secondScope, michael@0: "The second owner scope for the third property is correct."); michael@0: michael@0: // Test getParentScopesForVariableOrProperty with second-degree properties. michael@0: michael@0: let secPropOwners1 = variables.getParentScopesForVariableOrProperty(constrProp1); michael@0: let secPropOwners2 = variables.getParentScopesForVariableOrProperty(constrProp2); michael@0: let secPropOwners3 = variables.getParentScopesForVariableOrProperty(constrProp3); michael@0: michael@0: is(secPropOwners1.length, 0, michael@0: "There should be no owner scopes for the first inner property."); michael@0: michael@0: is(secPropOwners2.length, 1, michael@0: "There should be one owner scope for the second inner property."); michael@0: is(secPropOwners2[0], firstScope, michael@0: "The only owner scope for the second inner property is correct."); michael@0: michael@0: is(secPropOwners3.length, 2, michael@0: "There should be two owner scopes for the third inner property."); michael@0: is(secPropOwners3[0], firstScope, michael@0: "The first owner scope for the third inner property is correct."); michael@0: is(secPropOwners3[1], secondScope, michael@0: "The second owner scope for the third inner property is correct."); michael@0: michael@0: yield resumeDebuggerThenCloseAndFinish(panel); michael@0: }); michael@0: }