diff options
author | yurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-07 14:12:15 +0000 |
---|---|---|
committer | yurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-07 14:12:15 +0000 |
commit | f587cb53e0138b2d2ff5babb872b46836998552d (patch) | |
tree | d618c261765201bfe9754c8f66023880123c69ba /webkit/glue/devtools | |
parent | ce1eb3bd99a3af516f3efa93229146e3569e5570 (diff) | |
download | chromium_src-f587cb53e0138b2d2ff5babb872b46836998552d.zip chromium_src-f587cb53e0138b2d2ff5babb872b46836998552d.tar.gz chromium_src-f587cb53e0138b2d2ff5babb872b46836998552d.tar.bz2 |
DevTools: allow inspecting __proto__, constructor, prototype properties.BUG=23647
Review URL: http://codereview.chromium.org/262005
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@28247 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/glue/devtools')
-rw-r--r-- | webkit/glue/devtools/js/debugger_agent.js | 6 | ||||
-rw-r--r-- | webkit/glue/devtools/js/devtools.js | 2 | ||||
-rw-r--r-- | webkit/glue/devtools/js/tests.js | 210 |
3 files changed, 191 insertions, 27 deletions
diff --git a/webkit/glue/devtools/js/debugger_agent.js b/webkit/glue/devtools/js/debugger_agent.js index 4a9784a..4b91564 100644 --- a/webkit/glue/devtools/js/debugger_agent.js +++ b/webkit/glue/devtools/js/debugger_agent.js @@ -1120,12 +1120,14 @@ devtools.DebuggerAgent.formatObjectProxy_ = function(v) { description = 'function ' + v.name + '()'; } hasChildren = true; - } else if (goog.isDef(v.value)) { - description = v.value; } else if (v.type == 'undefined') { description = 'undefined'; } else if (v.type == 'null') { description = 'null'; + } else if (goog.isDef(v.value)) { + // Check for undefined and null types before checking the value, otherwise + // null/undefined may have blank value. + description = v.value; } else { description = '<unresolved ref: ' + v.ref + ', type: ' + v.type + '>'; } diff --git a/webkit/glue/devtools/js/devtools.js b/webkit/glue/devtools/js/devtools.js index 92879d0..88c1243 100644 --- a/webkit/glue/devtools/js/devtools.js +++ b/webkit/glue/devtools/js/devtools.js @@ -371,7 +371,7 @@ InjectedScriptAccess.getProperties = function( callback); } else if (objectProxy.isV8Ref) { devtools.tools.getDebuggerAgent().resolveChildren(objectProxy.objectId, - callback, true); + callback, false); } else { orig.apply(this, arguments); } diff --git a/webkit/glue/devtools/js/tests.js b/webkit/glue/devtools/js/tests.js index 50142e7..5cbc404 100644 --- a/webkit/glue/devtools/js/tests.js +++ b/webkit/glue/devtools/js/tests.js @@ -1104,6 +1104,44 @@ TestSuite.prototype._checkScopeSectionDiv = function( /** + * Expands scope sections matching the filter and invokes the callback on + * success. + * @param {function(WebInspector.ObjectPropertiesSection, number):boolean} + * filter + * @param {Function} callback + */ +TestSuite.prototype._expandScopeSections = function(filter, callback) { + var sections = WebInspector.currentPanel.sidebarPanes.scopechain.sections; + + var toBeUpdatedCount = 0; + function updateListener() { + --toBeUpdatedCount; + if (toBeUpdatedCount == 0) { + // Report when all scopes are expanded and populated. + callback(); + } + } + + // Global scope is always the last one. + for (var i = 0; i < sections.length - 1; i++) { + var section = sections[i]; + if (!filter(sections, i)) { + continue; + } + this.addSniffer(section, 'updateProperties', updateListener); + ++toBeUpdatedCount; + var populated = section.populated; + section.expand(); + if (populated) { + // Make sure 'updateProperties' callback will be called at least once + // after it was overridden. + section.update(); + } + } +}; + + +/** * Tests that scopes can be expanded and contain expected data. */ TestSuite.prototype.testExpandScope = function() { @@ -1125,30 +1163,11 @@ TestSuite.prototype.testExpandScope = function() { // Expanding Global scope takes for too long so we skeep it. function expandAllSectionsExceptGlobal() { - var sections = WebInspector.currentPanel.sidebarPanes.scopechain.sections; - - var toBeUpdatedCount = 0; - function updateListener() { - --toBeUpdatedCount; - if (toBeUpdatedCount == 0) { - // When all scopes are expanded and populated check them. - examineScopes(); - } - } - - // Global scope is always the last one. - for (var i = 0; i < sections.length - 1; i++) { - var section = sections[i]; - test.addSniffer(section, 'updateProperties', updateListener); - ++toBeUpdatedCount; - var populated = section.populated; - section.expand(); - if (populated) { - // Make sure 'updateProperties' callback will be called at least once - // after it was overridden. - section.update(); - } - } + test._expandScopeSections(function(sections, i) { + return i < sections.length - 1; + }, + examineScopes /* When all scopes are expanded and populated check + them. */); } // Check scope sections contents. @@ -1196,6 +1215,149 @@ TestSuite.prototype.testExpandScope = function() { /** + * Returns child tree element for a property with given name. + * @param {TreeElement} parent Parent tree element. + * @param {string} childName + * @return {TreeElement} + */ +TestSuite.prototype._findChildProperty = function(parent, childName) { + var children = parent.children; + for (var i = 0; i < children.length; i++) { + var treeElement = children[i]; + var property = treeElement.property; + if (property.name == childName) { + return treeElement; + } + } + this.fail('Cannot find ' + childName); +}; + + +/** + * Tests that all elements in prototype chain of an object have expected + * intrinic proprties(__proto__, constructor, prototype). + */ +TestSuite.prototype.testDebugIntrinsicProperties = function() { + this.showPanel('scripts'); + var test = this; + + this._executeCodeWhenScriptsAreParsed( + 'handleClick()', + ['debugger_intrinsic_properties.html$']); + + this._waitForScriptPause( + { + functionsOnStack: ['callDebugger', 'handleClick', + '(anonymous function)'], + lineNumber: 29, + lineText: ' debugger;' + }, + expandLocalScope); + + var localScopeSection = null; + function expandLocalScope() { + test._expandScopeSections(function(sections, i) { + if (i == 0) { + test.assertTrue(sections[i].object.isLocal, 'Scope #0 is not Local.'); + localScopeSection = sections[i]; + return true; + } + return false; + }, + examineLocalScope); + } + + function examineLocalScope() { + var aTreeElement = test._findChildProperty( + localScopeSection.propertiesTreeOutline, 'a'); + test.assertTrue(!!aTreeElement, 'Not found'); + + var orig = overrideGetProperties(checkA.bind(null, aTreeElement)); + aTreeElement.expand(); + InjectedScriptAccess.getProperties = orig; + } + + function checkA(aTreeElement) { + checkIntrinsicProperties(aTreeElement, + [ + 'constructor', 'function Child()', + '__proto__', 'Object', + 'prototype', 'undefined', + ]); + expandProto(aTreeElement, checkAProto); + } + + function checkAProto(treeElement) { + checkIntrinsicProperties(treeElement, + [ + 'constructor', 'function Child()', + '__proto__', 'Object', + 'prototype', 'undefined', + ]); + expandProto(treeElement, checkAProtoProto); + } + + function checkAProtoProto(treeElement) { + checkIntrinsicProperties(treeElement, + [ + 'constructor', 'function Parent()', + '__proto__', 'Object', + 'prototype', 'undefined', + ]); + expandProto(treeElement, checkAProtoProtoProto); + } + + function checkAProtoProtoProto(treeElement) { + checkIntrinsicProperties(treeElement, + [ + 'constructor', 'function Object()', + '__proto__', 'null', + 'prototype', 'undefined', + ]); + test.releaseControl(); + } + + function overrideGetProperties(afterCallback) { + var orig = InjectedScriptAccess.getProperties; + InjectedScriptAccess.getProperties = function(objectProxy, + ignoreHasOwnProperty, callback) { + orig.call(InjectedScriptAccess, objectProxy, ignoreHasOwnProperty, + function() { + callback.apply(this, arguments); + afterCallback(); + }); + }; + return orig; + } + + function expandProto(treeElement, callback) { + var proto = test._findChildProperty(treeElement, '__proto__'); + test.assertTrue(proto, '__proro__ not found'); + + var orig = overrideGetProperties(callback.bind(null, proto)); + proto.expand(); + InjectedScriptAccess.getProperties = orig; + } + + function checkIntrinsicProperties(treeElement, expectations) { + for (var i = 0; i < expectations.length; i += 2) { + var name = expectations[i]; + var value = expectations[i+1]; + + var propertyTreeElement = test._findChildProperty(treeElement, name); + test.assertTrue(propertyTreeElement, + 'Property "' + name + '" not found.'); + test.assertEquals(value, + propertyTreeElement.property.value.description, + 'Unexpected "' + name + '" value.'); + } + } + + test.takeControl(); +}; + + +/** * Tests 'Pause' button will pause debugger when a snippet is evaluated. */ TestSuite.prototype.testPauseInEval = function() { |