v8/test/inspector/runtime/custom-preview.js
Alexei Filippov 4eae3bb140 [inspector] Make InjectedScript::getProperties respect custom formatters
BUG=chromium:917136

Change-Id: I02696a3315c22b34705bbc48cddaeb9e6c59fa9f
Reviewed-on: https://chromium-review.googlesource.com/c/1391749
Reviewed-by: Dmitry Gozman <dgozman@chromium.org>
Commit-Queue: Alexei Filippov <alph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58482}
2018-12-27 23:17:57 +00:00

134 lines
5.3 KiB
JavaScript

// Copyright 2018 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
const {session, contextGroup, Protocol} =
InspectorTest.start('RemoteObject.CustomPreview');
(async function test() {
contextGroup.addScript(`
var a = {name: 'a'};
var b = {name: 'b'};
var c = {name: 'c'};
a.formattableBy1 = true;
b.formattableBy2 = true;
c.formattableBy1 = true;
c.formattableBy2 = true;
var formatter1 = {
header: (x) => x.formattableBy1 ? ['span', {}, 'Header formatted by 1 ', x.name] : null,
hasBody: () => true,
body: (x) => ['span', {}, 'Body formatted by 1 ', x.name, ['object', {object: {}}]]
};
var formatter2 = {
header: (x) => x.formattableBy2 ? ['span', {}, 'Header formatted by 2 ', x.name] : null,
hasBody: (x) => true,
body: (x) => ['span', {}, 'Body formatted by 2 ', x.name]
};
var configTest = {};
var formatterWithConfig1 = {
header: function(x, config) {
if (x !== configTest || config)
return null;
return ['span', {}, 'Formatter with config ', ['object', {'object': x, 'config': {'info': 'additional info'}}]];
},
hasBody: (x) => false,
body: (x) => { throw 'Unreachable'; }
}
var formatterWithConfig2 = {
header: function(x, config) {
if (x !== configTest || !config)
return null;
return ['span', {}, 'Header ', 'info: ', config.info];
},
hasBody: (x, config) => config && config.info,
body: (x, config) => ['span', {}, 'body', 'info: ', config.info]
}
this.devtoolsFormatters = [formatter1, formatter2, formatterWithConfig1, formatterWithConfig2];
`);
Protocol.Runtime.enable();
Protocol.Runtime.setCustomObjectFormatterEnabled({enabled: true});
Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
InspectorTest.log('Dump custom previews..');
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));
InspectorTest.log('Change formatters order and dump again..');
await Protocol.Runtime.evaluate({
expression: 'this.devtoolsFormatters = [formatter2, formatter1, formatterWithConfig1, formatterWithConfig2]'
});
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'a'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'b'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'c'}));
await dumpCustomPreviewForEvaluate(await Protocol.Runtime.evaluate({expression: 'configTest'}));
InspectorTest.log('Test Runtime.getProperties');
const {result:{result:{objectId}}} = await Protocol.Runtime.evaluate({expression: '({a})'});
const {result:{result}} = await Protocol.Runtime.getProperties({
objectId, ownProperties: true, generatePreview: true});
await dumpCustomPreview(result.find(value => value.name === 'a').value);
InspectorTest.log('Try to break custom preview..');
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => { throw 1; },
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => {
const arr = [1];
Object.defineProperty(arr, 0, { get: () => { throw 2; }});
return arr;
},
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => [{get header() { throw 3; }}],
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
await Protocol.Runtime.evaluate({
expression: `Object.defineProperty(this, 'devtoolsFormatters', {
get: () => [{header: () => { throw 4; }}],
configurable: true
})`
});
Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
InspectorTest.logMessage(await Protocol.Runtime.onceConsoleAPICalled());
InspectorTest.completeTest();
})()
function dumpCustomPreviewForEvaluate(result) {
return dumpCustomPreview(result.result.result);
}
async function dumpCustomPreview(result) {
const { objectId, customPreview } = result;
InspectorTest.logMessage(customPreview);
if (customPreview.bodyGetterId) {
const body = await Protocol.Runtime.callFunctionOn({
objectId,
functionDeclaration: 'function(bodyGetter) { return bodyGetter.call(this); }',
arguments: [ { objectId: customPreview.bodyGetterId } ],
returnByValue: true
});
InspectorTest.logMessage(body);
}
}