Accept Diagnosticable as input in inspector API. (#128962)
This commit is contained in:
parent
5ab5d82a39
commit
7214cb28be
@ -1762,7 +1762,7 @@ mixin WidgetInspectorService {
|
|||||||
|
|
||||||
DiagnosticsNode? _idToDiagnosticsNode(String? diagnosticsOrDiagnosticableId) {
|
DiagnosticsNode? _idToDiagnosticsNode(String? diagnosticsOrDiagnosticableId) {
|
||||||
// TODO(polina-c): start always assuming Diagnosticable, when DevTools stops sending DiagnosticsNode to
|
// TODO(polina-c): start always assuming Diagnosticable, when DevTools stops sending DiagnosticsNode to
|
||||||
// getChildrenSummaryTree and getProperties.
|
// APIs that invoke this method.
|
||||||
// https://github.com/flutter/devtools/issues/3951
|
// https://github.com/flutter/devtools/issues/3951
|
||||||
final Object? theObject = toObject(diagnosticsOrDiagnosticableId);
|
final Object? theObject = toObject(diagnosticsOrDiagnosticableId);
|
||||||
if (theObject is DiagnosticsNode) {
|
if (theObject is DiagnosticsNode) {
|
||||||
@ -1788,17 +1788,17 @@ mixin WidgetInspectorService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a JSON representation of the children of the [DiagnosticsNode]
|
/// Returns a JSON representation of the children of the [DiagnosticsNode]
|
||||||
/// object that `diagnosticsNodeId` references providing information needed
|
/// object that [diagnosticsOrDiagnosticableId] references providing information needed
|
||||||
/// for the details subtree view.
|
/// for the details subtree view.
|
||||||
///
|
///
|
||||||
/// The details subtree shows properties inline and includes all children
|
/// The details subtree shows properties inline and includes all children
|
||||||
/// rather than a filtered set of important children.
|
/// rather than a filtered set of important children.
|
||||||
String getChildrenDetailsSubtree(String diagnosticsNodeId, String groupName) {
|
String getChildrenDetailsSubtree(String diagnosticsOrDiagnosticableId, String groupName) {
|
||||||
return _safeJsonEncode(_getChildrenDetailsSubtree(diagnosticsNodeId, groupName));
|
return _safeJsonEncode(_getChildrenDetailsSubtree(diagnosticsOrDiagnosticableId, groupName));
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Object> _getChildrenDetailsSubtree(String? diagnosticsNodeId, String groupName) {
|
List<Object> _getChildrenDetailsSubtree(String? diagnosticsOrDiagnosticableId, String groupName) {
|
||||||
final DiagnosticsNode? node = toObject(diagnosticsNodeId) as DiagnosticsNode?;
|
final DiagnosticsNode? node = _idToDiagnosticsNode(diagnosticsOrDiagnosticableId);
|
||||||
// With this value of minDepth we only expand one extra level of important nodes.
|
// With this value of minDepth we only expand one extra level of important nodes.
|
||||||
final InspectorSerializationDelegate delegate = InspectorSerializationDelegate(groupName: groupName, includeProperties: true, service: this);
|
final InspectorSerializationDelegate delegate = InspectorSerializationDelegate(groupName: groupName, includeProperties: true, service: this);
|
||||||
return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenFiltered(node, delegate), delegate, parent: node);
|
return _nodesToJson(node == null ? const <DiagnosticsNode>[] : _getChildrenFiltered(node, delegate), delegate, parent: node);
|
||||||
@ -1910,19 +1910,19 @@ mixin WidgetInspectorService {
|
|||||||
/// * [getChildrenDetailsSubtree], a method to get children of a node
|
/// * [getChildrenDetailsSubtree], a method to get children of a node
|
||||||
/// in the details subtree.
|
/// in the details subtree.
|
||||||
String getDetailsSubtree(
|
String getDetailsSubtree(
|
||||||
String id,
|
String diagnosticsOrDiagnosticableId,
|
||||||
String groupName, {
|
String groupName, {
|
||||||
int subtreeDepth = 2,
|
int subtreeDepth = 2,
|
||||||
}) {
|
}) {
|
||||||
return _safeJsonEncode(_getDetailsSubtree( id, groupName, subtreeDepth));
|
return _safeJsonEncode(_getDetailsSubtree(diagnosticsOrDiagnosticableId, groupName, subtreeDepth));
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, Object?>? _getDetailsSubtree(
|
Map<String, Object?>? _getDetailsSubtree(
|
||||||
String? id,
|
String? diagnosticsOrDiagnosticableId,
|
||||||
String? groupName,
|
String? groupName,
|
||||||
int subtreeDepth,
|
int subtreeDepth,
|
||||||
) {
|
) {
|
||||||
final DiagnosticsNode? root = toObject(id) as DiagnosticsNode?;
|
final DiagnosticsNode? root = _idToDiagnosticsNode(diagnosticsOrDiagnosticableId);
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -1942,6 +1942,8 @@ mixin WidgetInspectorService {
|
|||||||
/// If the currently selected [Element] is identical to the [Element]
|
/// If the currently selected [Element] is identical to the [Element]
|
||||||
/// referenced by `previousSelectionId` then the previous [DiagnosticsNode] is
|
/// referenced by `previousSelectionId` then the previous [DiagnosticsNode] is
|
||||||
/// reused.
|
/// reused.
|
||||||
|
// TODO(polina-c): delete [previousSelectionId] when it is not used in DevTools
|
||||||
|
// https://github.com/flutter/devtools/issues/3951
|
||||||
@protected
|
@protected
|
||||||
String getSelectedWidget(String? previousSelectionId, String groupName) {
|
String getSelectedWidget(String? previousSelectionId, String groupName) {
|
||||||
return _safeJsonEncode(_getSelectedWidget(previousSelectionId, groupName));
|
return _safeJsonEncode(_getSelectedWidget(previousSelectionId, groupName));
|
||||||
@ -2020,18 +2022,18 @@ mixin WidgetInspectorService {
|
|||||||
Future<Map<String, Object?>> _getLayoutExplorerNode(
|
Future<Map<String, Object?>> _getLayoutExplorerNode(
|
||||||
Map<String, String> parameters,
|
Map<String, String> parameters,
|
||||||
) {
|
) {
|
||||||
final String? id = parameters['id'];
|
final String? diagnosticsOrDiagnosticableId = parameters['id'];
|
||||||
final int subtreeDepth = int.parse(parameters['subtreeDepth']!);
|
final int subtreeDepth = int.parse(parameters['subtreeDepth']!);
|
||||||
final String? groupName = parameters['groupName'];
|
final String? groupName = parameters['groupName'];
|
||||||
Map<String, dynamic>? result = <String, dynamic>{};
|
Map<String, dynamic>? result = <String, dynamic>{};
|
||||||
final Object? root = toObject(id);
|
final DiagnosticsNode? root = _idToDiagnosticsNode(diagnosticsOrDiagnosticableId);
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
return Future<Map<String, dynamic>>.value(<String, dynamic>{
|
return Future<Map<String, dynamic>>.value(<String, dynamic>{
|
||||||
'result': result,
|
'result': result,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
result = _nodeToJson(
|
result = _nodeToJson(
|
||||||
root as DiagnosticsNode,
|
root,
|
||||||
InspectorSerializationDelegate(
|
InspectorSerializationDelegate(
|
||||||
groupName: groupName,
|
groupName: groupName,
|
||||||
summaryTree: true,
|
summaryTree: true,
|
||||||
@ -2232,6 +2234,8 @@ mixin WidgetInspectorService {
|
|||||||
/// If the currently selected [Element] is identical to the [Element]
|
/// If the currently selected [Element] is identical to the [Element]
|
||||||
/// referenced by `previousSelectionId` then the previous [DiagnosticsNode] is
|
/// referenced by `previousSelectionId` then the previous [DiagnosticsNode] is
|
||||||
/// reused.
|
/// reused.
|
||||||
|
// TODO(polina-c): delete paramater [previousSelectionId] when it is not used in DevTools
|
||||||
|
// https://github.com/flutter/devtools/issues/3951
|
||||||
String getSelectedSummaryWidget(String previousSelectionId, String groupName) {
|
String getSelectedSummaryWidget(String previousSelectionId, String groupName) {
|
||||||
return _safeJsonEncode(_getSelectedSummaryWidget(previousSelectionId, groupName));
|
return _safeJsonEncode(_getSelectedSummaryWidget(previousSelectionId, groupName));
|
||||||
}
|
}
|
||||||
|
@ -900,6 +900,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('WidgetInspectorService getProperties for $DiagnosticsNode', () {
|
test('WidgetInspectorService getProperties for $DiagnosticsNode', () {
|
||||||
|
// TODO(polina-c): delete this test once getChildrenDetailsSubtree stops accepting DiagnosticsNode.
|
||||||
|
// https://github.com/flutter/devtools/issues/3951
|
||||||
final DiagnosticsNode diagnostic = const Text('a', textDirection: TextDirection.ltr).toDiagnosticsNode();
|
final DiagnosticsNode diagnostic = const Text('a', textDirection: TextDirection.ltr).toDiagnosticsNode();
|
||||||
const String group = 'group';
|
const String group = 'group';
|
||||||
service.disposeAllGroups();
|
service.disposeAllGroups();
|
||||||
@ -2124,6 +2126,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('ext.flutter.inspector.getProperties for $DiagnosticsNode', () async {
|
test('ext.flutter.inspector.getProperties for $DiagnosticsNode', () async {
|
||||||
|
// TODO(polina-c): delete this test once getChildrenDetailsSubtree stops accepting DiagnosticsNode.
|
||||||
|
// https://github.com/flutter/devtools/issues/3951
|
||||||
final DiagnosticsNode diagnostic = const Text('a', textDirection: TextDirection.ltr).toDiagnosticsNode();
|
final DiagnosticsNode diagnostic = const Text('a', textDirection: TextDirection.ltr).toDiagnosticsNode();
|
||||||
const String group = 'group';
|
const String group = 'group';
|
||||||
final String id = service.toId(diagnostic, group)!;
|
final String id = service.toId(diagnostic, group)!;
|
||||||
@ -5090,7 +5094,9 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
|
|||||||
expect(box2.localToGlobal(Offset.zero), equals(position2));
|
expect(box2.localToGlobal(Offset.zero), equals(position2));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('getChildrenDetailsSubtree', (WidgetTester tester) async {
|
testWidgets('getChildrenDetailsSubtree with $DiagnosticsNode', (WidgetTester tester) async {
|
||||||
|
// TODO(polina-c): delete this test once getChildrenDetailsSubtree stops accepting DiagnosticsNode.
|
||||||
|
// https://github.com/flutter/devtools/issues/3951
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
title: 'Hello, World',
|
title: 'Hello, World',
|
||||||
@ -5150,6 +5156,66 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService {
|
|||||||
expect(appBars.single, isNot(contains('children')));
|
expect(appBars.single, isNot(contains('children')));
|
||||||
}, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag.
|
}, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag.
|
||||||
|
|
||||||
|
testWidgets('getChildrenDetailsSubtree with $Diagnosticable', (WidgetTester tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
title: 'Hello, World',
|
||||||
|
theme: ThemeData(
|
||||||
|
primarySwatch: Colors.blue,
|
||||||
|
),
|
||||||
|
home: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('Hello, World'),
|
||||||
|
),
|
||||||
|
body: const Center(
|
||||||
|
child: Text('Hello, World!'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
service.setSelection(find.text('Hello, World!').evaluate().first, 'my-group');
|
||||||
|
|
||||||
|
// Figure out the pubRootDirectory
|
||||||
|
final Map<String, Object?> jsonObject = (await service.testExtension(
|
||||||
|
WidgetInspectorServiceExtensions.getSelectedWidget.name,
|
||||||
|
<String, String>{'objectGroup': 'my-group'},
|
||||||
|
))! as Map<String, Object?>;
|
||||||
|
final Map<String, Object?> creationLocation = jsonObject['creationLocation']! as Map<String, Object?>;
|
||||||
|
expect(creationLocation, isNotNull);
|
||||||
|
final String file = creationLocation['file']! as String;
|
||||||
|
expect(file, endsWith('widget_inspector_test.dart'));
|
||||||
|
final List<String> segments = Uri.parse(file).pathSegments;
|
||||||
|
// Strip a couple subdirectories away to generate a plausible pub rootdirectory.
|
||||||
|
final String pubRootTest = '/${segments.take(segments.length - 2).join('/')}';
|
||||||
|
service.resetPubRootDirectories();
|
||||||
|
service.addPubRootDirectories(<String>[pubRootTest]);
|
||||||
|
|
||||||
|
final String summary = service.getRootWidgetSummaryTree('foo1');
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
|
final List<Object?> childrenOfRoot = json.decode(summary)['children'] as List<Object?>;
|
||||||
|
final List<Object?> childrenOfMaterialApp = (childrenOfRoot.first! as Map<String, Object?>)['children']! as List<Object?>;
|
||||||
|
final Map<String, Object?> scaffold = childrenOfMaterialApp.first! as Map<String, Object?>;
|
||||||
|
expect(scaffold['description'], 'Scaffold');
|
||||||
|
final String objectId = scaffold['valueId']! as String;
|
||||||
|
final String details = service.getDetailsSubtree(objectId, 'foo2');
|
||||||
|
// ignore: avoid_dynamic_calls
|
||||||
|
final List<Object?> detailedChildren = json.decode(details)['children'] as List<Object?>;
|
||||||
|
|
||||||
|
final List<Map<String, Object?>> appBars = <Map<String, Object?>>[];
|
||||||
|
void visitChildren(List<Object?> children) {
|
||||||
|
for (final Map<String, Object?> child in children.cast<Map<String, Object?>>()) {
|
||||||
|
if (child['description'] == 'AppBar') {
|
||||||
|
appBars.add(child);
|
||||||
|
}
|
||||||
|
if (child.containsKey('children')) {
|
||||||
|
visitChildren(child['children']! as List<Object?>);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visitChildren(detailedChildren);
|
||||||
|
expect(appBars.single, isNot(contains('children')));
|
||||||
|
}, skip: !WidgetInspectorService.instance.isWidgetCreationTracked()); // [intended] Test requires --track-widget-creation flag.
|
||||||
|
|
||||||
testWidgets('InspectorSerializationDelegate addAdditionalPropertiesCallback', (WidgetTester tester) async {
|
testWidgets('InspectorSerializationDelegate addAdditionalPropertiesCallback', (WidgetTester tester) async {
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
MaterialApp(
|
MaterialApp(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user