summaryrefslogtreecommitdiffstats
path: root/webkit/glue/devtools
diff options
context:
space:
mode:
authoryurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-07 14:12:15 +0000
committeryurys@google.com <yurys@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-07 14:12:15 +0000
commitf587cb53e0138b2d2ff5babb872b46836998552d (patch)
treed618c261765201bfe9754c8f66023880123c69ba /webkit/glue/devtools
parentce1eb3bd99a3af516f3efa93229146e3569e5570 (diff)
downloadchromium_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.js6
-rw-r--r--webkit/glue/devtools/js/devtools.js2
-rw-r--r--webkit/glue/devtools/js/tests.js210
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() {