From a916c0c7bc20ded52fd4d90ca46022c13ec02c03 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:52:00 -0700 Subject: [PATCH 01/13] Added method and doc --- .../lib/src/widgets/service_extensions.dart | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/packages/flutter/lib/src/widgets/service_extensions.dart b/packages/flutter/lib/src/widgets/service_extensions.dart index 53ce821cd4b02..e7e9fbf4cf10b 100644 --- a/packages/flutter/lib/src/widgets/service_extensions.dart +++ b/packages/flutter/lib/src/widgets/service_extensions.dart @@ -386,6 +386,11 @@ enum WidgetInspectorServiceExtensions { /// If the parameter `withPreviews` is true, text previews will be included /// for [Element]s with a corresponding [RenderObject] of type /// [RenderParagraph]. + /// + /// Note: This service extension returns detailed [DiagnosticsNode] data for + /// the entire tree, and as such the payload can be quite large. If you need a + /// lightweight response without all the details, use [getLightRootWidgetTree] + /// instead. /// /// See also: /// @@ -393,6 +398,26 @@ enum WidgetInspectorServiceExtensions { /// extension is registered. getRootWidgetTree, + /// Name of service extension that, when called, will return lightweight + /// [DiagnosticsNode] data for the root [Element] of the widget tree. + /// + /// If the parameter `isSummaryTree` is true, the tree will only include + /// [Element]s that were created by user code. + /// + /// If the parameter `withPreviews` is true, text previews will be included + /// for [Element]s with a corresponding [RenderObject] of type + /// [RenderParagraph]. + /// + /// Note: This service extension returns only the information required to + /// build a representation of the widget tree. If you need more detailed + /// [DiagnosticsNode] data, use [getRootWidgetTree] instead. + /// + /// See also: + /// + /// * [WidgetInspectorService.initServiceExtensions], where the service + /// extension is registered. + getLightRootWidgetTree, + /// Name of service extension that, when called, will return the /// [DiagnosticsNode] data for the root [Element] of the summary tree, which /// only includes [Element]s that were created by user code. From 72357f0bd77cf2b41134c354737b84f16dffbd78 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:27:56 -0700 Subject: [PATCH 02/13] Send minimal tree information to DevTools --- .../lib/src/foundation/diagnostics.dart | 188 +++++++++++++----- packages/flutter/lib/src/painting/colors.dart | 13 +- .../flutter/lib/src/widgets/framework.dart | 11 +- .../flutter/lib/src/widgets/icon_data.dart | 13 +- .../lib/src/widgets/widget_inspector.dart | 41 +++- 5 files changed, 199 insertions(+), 67 deletions(-) diff --git a/packages/flutter/lib/src/foundation/diagnostics.dart b/packages/flutter/lib/src/foundation/diagnostics.dart index 6847d1433fe6a..5f03c714ff950 100644 --- a/packages/flutter/lib/src/foundation/diagnostics.dart +++ b/packages/flutter/lib/src/foundation/diagnostics.dart @@ -1605,49 +1605,64 @@ abstract class DiagnosticsNode { /// by this method and interactive tree views in the Flutter IntelliJ /// plugin. @mustCallSuper - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { Map result = {}; assert(() { final bool hasChildren = getChildren().isNotEmpty; - result = { + final Map essentialDetails = { 'description': toDescription(), - 'type': runtimeType.toString(), - if (name != null) - 'name': name, - if (!showSeparator) - 'showSeparator': showSeparator, - if (level != DiagnosticLevel.info) - 'level': level.name, - if (!showName) - 'showName': showName, - if (emptyBodyDescription != null) - 'emptyBodyDescription': emptyBodyDescription, - if (style != DiagnosticsTreeStyle.sparse) - 'style': style!.name, - if (allowTruncate) - 'allowTruncate': allowTruncate, - if (hasChildren) - 'hasChildren': hasChildren, - if (linePrefix?.isNotEmpty ?? false) - 'linePrefix': linePrefix, - if (!allowWrap) - 'allowWrap': allowWrap, - if (allowNameWrap) - 'allowNameWrap': allowNameWrap, - ...delegate.additionalNodeProperties(this), - if (delegate.includeProperties) - 'properties': toJsonList( - delegate.filterProperties(getProperties(), this), - this, - delegate, - ), + 'shouldIndent': style != DiagnosticsTreeStyle.flat && + style != DiagnosticsTreeStyle.error, + ...delegate.additionalNodeProperties(this, fullDetails: fullDetails), if (delegate.subtreeDepth > 0) 'children': toJsonList( delegate.filterChildren(getChildren(), this), this, delegate, + fullDetails: fullDetails, ), }; + + if (!fullDetails) { + result = essentialDetails; + } else { + result = { + ...essentialDetails, + 'type': runtimeType.toString(), + if (name != null) + 'name': name, + if (!showSeparator) + 'showSeparator': showSeparator, + if (level != DiagnosticLevel.info) + 'level': level.name, + if (!showName) + 'showName': showName, + if (emptyBodyDescription != null) + 'emptyBodyDescription': emptyBodyDescription, + if (style != DiagnosticsTreeStyle.sparse) + 'style': style!.name, + if (allowTruncate) + 'allowTruncate': allowTruncate, + if (hasChildren) + 'hasChildren': hasChildren, + if (linePrefix?.isNotEmpty ?? false) + 'linePrefix': linePrefix, + if (!allowWrap) + 'allowWrap': allowWrap, + if (allowNameWrap) + 'allowNameWrap': allowNameWrap, + if (delegate.includeProperties) + 'properties': toJsonList( + delegate.filterProperties(getProperties(), this), + this, + delegate, + fullDetails: fullDetails, + ), + }; + } return true; }()); return result; @@ -1661,7 +1676,9 @@ abstract class DiagnosticsNode { static List> toJsonList( List? nodes, DiagnosticsNode? parent, - DiagnosticsSerializationDelegate delegate, + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + } ) { bool truncated = false; if (nodes == null) { @@ -1674,7 +1691,7 @@ abstract class DiagnosticsNode { truncated = true; } final List> json = nodes.map>((DiagnosticsNode node) { - return node.toJsonMap(delegate.delegateForNode(node)); + return node.toJsonMap(delegate.delegateForNode(node), fullDetails: fullDetails,); }).toList(); if (truncated) { json.last['truncated'] = true; @@ -1857,8 +1874,17 @@ class StringProperty extends DiagnosticsProperty { final bool quoted; @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } json['quoted'] = quoted; return json; } @@ -1913,8 +1939,18 @@ abstract class _NumProperty extends DiagnosticsProperty { }) : super.lazy(); @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } + if (unit != null) { json['unit'] = unit; } @@ -2097,8 +2133,17 @@ class FlagProperty extends DiagnosticsProperty { ); @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } if (ifTrue != null) { json['ifTrue'] = ifTrue; } @@ -2219,8 +2264,17 @@ class IterableProperty extends DiagnosticsProperty> { } @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } if (value != null) { json['values'] = value!.map((T value) => value.toString()).toList(); } @@ -2357,8 +2411,17 @@ class ObjectFlagProperty extends DiagnosticsProperty { } @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } if (ifPresent != null) { json['ifPresent'] = ifPresent; } @@ -2435,8 +2498,17 @@ class FlagsSummary extends DiagnosticsProperty> { } @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } if (value.isNotEmpty) { json['values'] = _formattedValues().toList(); } @@ -2555,7 +2627,10 @@ class DiagnosticsProperty extends DiagnosticsNode { final bool allowNameWrap; @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { final T? v = value; List>? properties; if (delegate.expandPropertyValues && delegate.includeProperties && v is Diagnosticable && getProperties().isEmpty) { @@ -2565,9 +2640,16 @@ class DiagnosticsProperty extends DiagnosticsNode { delegate.filterProperties(v.toDiagnosticsNode().getProperties(), this), this, delegate, + fullDetails: fullDetails, ); } - final Map json = super.toJsonMap(delegate); + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } if (properties != null) { json['properties'] = properties; } @@ -3503,7 +3585,10 @@ abstract class DiagnosticsSerializationDelegate { /// /// This method is called for every [DiagnosticsNode] that's included in /// the serialization. - Map additionalNodeProperties(DiagnosticsNode node); + Map additionalNodeProperties( + DiagnosticsNode node, { + required bool fullDetails, + }); /// Filters the list of [DiagnosticsNode]s that will be included as children /// for the given `owner` node. @@ -3595,7 +3680,10 @@ class _DefaultDiagnosticsSerializationDelegate implements DiagnosticsSerializati }); @override - Map additionalNodeProperties(DiagnosticsNode node) { + Map additionalNodeProperties( + DiagnosticsNode node, { + required bool fullDetails, + }) { return const {}; } diff --git a/packages/flutter/lib/src/painting/colors.dart b/packages/flutter/lib/src/painting/colors.dart index a897c0b33d660..92fce24422df9 100644 --- a/packages/flutter/lib/src/painting/colors.dart +++ b/packages/flutter/lib/src/painting/colors.dart @@ -495,8 +495,17 @@ class ColorProperty extends DiagnosticsProperty { }); @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } if (value != null) { json['valueProperties'] = { 'red': value!.red, diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index a1553a2ba121e..5442b965c5ae5 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -5379,13 +5379,18 @@ class _ElementDiagnosticableTreeNode extends DiagnosticableTreeNode { final bool stateful; @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap(delegate, fullDetails: fullDetails,); final Element element = value as Element; if (!element.debugIsDefunct) { json['widgetRuntimeType'] = element.widget.runtimeType.toString(); } - json['stateful'] = stateful; + if (fullDetails) { + json['stateful'] = stateful; + } return json; } } diff --git a/packages/flutter/lib/src/widgets/icon_data.dart b/packages/flutter/lib/src/widgets/icon_data.dart index ca118126d1a5f..d0d4d15a9dae7 100644 --- a/packages/flutter/lib/src/widgets/icon_data.dart +++ b/packages/flutter/lib/src/widgets/icon_data.dart @@ -121,8 +121,17 @@ class IconDataProperty extends DiagnosticsProperty { }); @override - Map toJsonMap(DiagnosticsSerializationDelegate delegate) { - final Map json = super.toJsonMap(delegate); + Map toJsonMap( + DiagnosticsSerializationDelegate delegate, { + required bool fullDetails, + }) { + final Map json = super.toJsonMap( + delegate, + fullDetails: fullDetails, + ); + if (!fullDetails) { + return json; + } if (value != null) { json['valueProperties'] = { 'codePoint': value!.codePoint, diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index d233170fdccd6..bc2d84f8221e4 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -1729,9 +1729,11 @@ mixin WidgetInspectorService { Map? _nodeToJson( DiagnosticsNode? node, - InspectorSerializationDelegate delegate, + InspectorSerializationDelegate delegate, { + bool fullDetails = true, + } ) { - return node?.toJsonMap(delegate); + return node?.toJsonMap(delegate, fullDetails: fullDetails); } bool _isValueCreatedByLocalProject(Object? value) { @@ -1801,8 +1803,14 @@ mixin WidgetInspectorService { List nodes, InspectorSerializationDelegate delegate, { required DiagnosticsNode? parent, + bool fullDetails = true, }) { - return DiagnosticsNode.toJsonList(nodes, parent, delegate); + return DiagnosticsNode.toJsonList( + nodes, + parent, + delegate, + fullDetails: fullDetails, + ); } /// Returns a JSON representation of the properties of the [DiagnosticsNode] @@ -1976,11 +1984,13 @@ mixin WidgetInspectorService { final String groupName = parameters['groupName']!; final bool isSummaryTree = parameters['isSummaryTree'] == 'true'; final bool withPreviews = parameters['withPreviews'] == 'true'; + final bool fullDetails = parameters['abbreviated'] != 'true'; final Map? result = _getRootWidgetTreeImpl( groupName: groupName, isSummaryTree: isSummaryTree, withPreviews: withPreviews, + fullDetails: fullDetails, ); return Future>.value({ @@ -1992,6 +2002,7 @@ mixin WidgetInspectorService { required String groupName, required bool isSummaryTree, required bool withPreviews, + bool fullDetails = true, Map? Function( DiagnosticsNode, InspectorSerializationDelegate)? addAdditionalPropertiesCallback, @@ -2032,6 +2043,7 @@ mixin WidgetInspectorService { ? combinedAddAdditionalPropertiesCallback : null, ), + fullDetails: fullDetails, ); } @@ -2196,7 +2208,10 @@ mixin WidgetInspectorService { if (value is! RenderObject && delegate.expandPropertyValues) 'renderObject': renderObject .toDiagnosticsNode() - .toJsonMap(renderObjectSerializationDelegate), + .toJsonMap( + renderObjectSerializationDelegate, + fullDetails: true, + ), }; final RenderObject? renderParent = renderObject.parent; @@ -2211,6 +2226,7 @@ mixin WidgetInspectorService { subtreeDepth: 0, includeProperties: true, ), + fullDetails: true, ); // TODO(jacobr): also describe the path back up the tree to // the RenderParentElement from the current element. It @@ -3788,19 +3804,24 @@ class InspectorSerializationDelegate implements DiagnosticsSerializationDelegate bool get _interactive => groupName != null; @override - Map additionalNodeProperties(DiagnosticsNode node) { + Map additionalNodeProperties( + DiagnosticsNode node, { + required bool fullDetails, + }) { final Map result = {}; final Object? value = node.value; + if (summaryTree && fullDetails) { + result['summaryTree'] = true; + } if (_interactive) { result['valueId'] = service.toId(value, groupName!); } - if (summaryTree) { - result['summaryTree'] = true; - } final _Location? creationLocation = _getCreationLocation(value); if (creationLocation != null) { - result['locationId'] = _toLocationId(creationLocation); - result['creationLocation'] = creationLocation.toJsonMap(); + if (fullDetails) { + result['locationId'] = _toLocationId(creationLocation); + result['creationLocation'] = creationLocation.toJsonMap(); + } if (service._isLocalCreationLocation(creationLocation.file)) { _nodesCreatedByLocalProject.add(node); result['createdByLocalProject'] = true; From c9f4caa48de7770fd961321d6558f896b5ca7e07 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 15:42:16 -0700 Subject: [PATCH 03/13] Fix static analysis errors in tests --- .../foundation/diagnostics_json_test.dart | 193 ++++++++++++------ .../test/foundation/diagnostics_test.dart | 5 +- .../flutter/test/painting/colors_test.dart | 10 +- .../flutter/test/widgets/icon_data_test.dart | 10 +- .../test/widgets/widget_inspector_test.dart | 18 +- 5 files changed, 165 insertions(+), 71 deletions(-) diff --git a/packages/flutter/test/foundation/diagnostics_json_test.dart b/packages/flutter/test/foundation/diagnostics_json_test.dart index 53bad0e833d91..4928caf3c77c9 100644 --- a/packages/flutter/test/foundation/diagnostics_json_test.dart +++ b/packages/flutter/test/foundation/diagnostics_json_test.dart @@ -10,7 +10,10 @@ void main() { test('Element diagnostics json includes widgetRuntimeType', () async { final Element element = _TestElement(); - final Map json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate()); + final Map json = element.toDiagnosticsNode().toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + ); expect(json['widgetRuntimeType'], 'Placeholder'); expect(json['stateful'], isFalse); }); @@ -18,7 +21,10 @@ void main() { test('StatefulElement diagnostics are stateful', () { final Element element = StatefulElement(const Tooltip(message: 'foo')); - final Map json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate()); + final Map json = element.toDiagnosticsNode().toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + ); expect(json['widgetRuntimeType'], 'Tooltip'); expect(json['stateful'], isTrue); }); @@ -67,13 +73,23 @@ void main() { ); test('default', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate()); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + ); expect(result.containsKey('properties'), isFalse); expect(result.containsKey('children'), isFalse); }); test('subtreeDepth 1', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 1)); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + const DiagnosticsSerializationDelegate(subtreeDepth: 1), + fullDetails: true, + ); expect(result.containsKey('properties'), isFalse); final List> children = result['children']! as List>; expect(children[0].containsKey('children'), isFalse); @@ -82,7 +98,12 @@ void main() { }); test('subtreeDepth 5', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 5)); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + const DiagnosticsSerializationDelegate(subtreeDepth: 5), + fullDetails: true, + ); expect(result.containsKey('properties'), isFalse); final List> children = result['children']! as List>; expect(children[0]['children'], hasLength(0)); @@ -91,16 +112,26 @@ void main() { }); test('includeProperties', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(includeProperties: true)); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + const DiagnosticsSerializationDelegate(includeProperties: true), + fullDetails: true, + ); expect(result.containsKey('children'), isFalse); expect(result['properties'], hasLength(7)); }); test('includeProperties with subtreedepth 1', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate( - includeProperties: true, - subtreeDepth: 1, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + const DiagnosticsSerializationDelegate( + subtreeDepth: 1, + includeProperties: true + ), + fullDetails: true, + ); expect(result['properties'], hasLength(7)); final List> children = result['children']! as List>; expect(children, hasLength(3)); @@ -110,13 +141,18 @@ void main() { }); test('additionalNodeProperties', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(const TestDiagnosticsSerializationDelegate( - includeProperties: true, - subtreeDepth: 1, - additionalNodePropertiesMap: { - 'foo': true, - }, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + const TestDiagnosticsSerializationDelegate( + includeProperties: true, + subtreeDepth: 1, + additionalNodePropertiesMap: { + 'foo': true, + }, + ), + fullDetails: true, + ); expect(result['foo'], isTrue); final List> properties = result['properties']! as List>; expect(properties, hasLength(7)); @@ -128,12 +164,17 @@ void main() { }); test('filterProperties - sublist', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( - includeProperties: true, - propertyFilter: (List nodes, DiagnosticsNode owner) { - return nodes.whereType().toList(); - }, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + TestDiagnosticsSerializationDelegate( + includeProperties: true, + propertyFilter: (List nodes, DiagnosticsNode owner) { + return nodes.whereType().toList(); + }, + ), + fullDetails: true, + ); final List> properties = result['properties']! as List>; expect(properties, hasLength(3)); expect(properties.every((Map property) => property['type'] == 'StringProperty'), isTrue); @@ -141,54 +182,74 @@ void main() { test('filterProperties - replace', () { bool replaced = false; - final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( - includeProperties: true, - propertyFilter: (List nodes, DiagnosticsNode owner) { - if (replaced) { - return nodes; - } - replaced = true; - return [ - StringProperty('foo', 'bar'), - ]; - }, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + TestDiagnosticsSerializationDelegate( + includeProperties: true, + propertyFilter: (List nodes, DiagnosticsNode owner) { + if (replaced) { + return nodes; + } + replaced = true; + return [ + StringProperty('foo', 'bar'), + ]; + }, + ), + fullDetails: true, + ); final List> properties = result['properties']! as List>; expect(properties, hasLength(1)); expect(properties.single['name'], 'foo'); }); test('filterChildren - sublist', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( - subtreeDepth: 1, - childFilter: (List nodes, DiagnosticsNode owner) { - return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList(); - }, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + TestDiagnosticsSerializationDelegate( + subtreeDepth: 1, + childFilter: (List nodes, DiagnosticsNode owner) { + return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList(); + }, + ), + fullDetails: true, + ); final List> children = result['children']! as List>; expect(children, hasLength(1)); }); test('filterChildren - replace', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( - subtreeDepth: 1, - childFilter: (List nodes, DiagnosticsNode owner) { - return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList(); - }, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + TestDiagnosticsSerializationDelegate( + subtreeDepth: 1, + childFilter: (List nodes, DiagnosticsNode owner) { + return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList(); + }, + ), + fullDetails: true, + ); final List> children = result['children']! as List>; expect(children, hasLength(3)); expect(children.first['name'], 'child node B1'); }); test('nodeTruncator', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( - subtreeDepth: 5, - includeProperties: true, - nodeTruncator: (List nodes, DiagnosticsNode? owner) { - return nodes.take(2).toList(); - }, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + TestDiagnosticsSerializationDelegate( + subtreeDepth: 5, + includeProperties: true, + nodeTruncator: (List nodes, DiagnosticsNode? owner) { + return nodes.take(2).toList(); + }, + ), + fullDetails: true, + ); final List> children = result['children']! as List>; expect(children, hasLength(3)); expect(children.last['truncated'], isTrue); @@ -199,13 +260,18 @@ void main() { }); test('delegateForAddingNodes', () { - final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( - subtreeDepth: 5, - includeProperties: true, - nodeDelegator: (DiagnosticsNode node, DiagnosticsSerializationDelegate delegate) { - return delegate.copyWith(includeProperties: false); - }, - )); + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + TestDiagnosticsSerializationDelegate( + subtreeDepth: 5, + includeProperties: true, + nodeDelegator: (DiagnosticsNode node, DiagnosticsSerializationDelegate delegate) { + return delegate.copyWith(includeProperties: false); + }, + ), + fullDetails: true, + ); final List> properties = result['properties']! as List>; expect(properties, hasLength(7)); expect(properties.every((Map property) => !property.containsKey('properties')), isTrue); @@ -279,7 +345,10 @@ class TestDiagnosticsSerializationDelegate implements DiagnosticsSerializationDe final NodeDelegator? nodeDelegator; @override - Map additionalNodeProperties(DiagnosticsNode node) { + Map additionalNodeProperties( + DiagnosticsNode node, { + required bool fullDetails, + }) { return additionalNodePropertiesMap; } diff --git a/packages/flutter/test/foundation/diagnostics_test.dart b/packages/flutter/test/foundation/diagnostics_test.dart index 7b3f5c2435712..cf22ff5616675 100644 --- a/packages/flutter/test/foundation/diagnostics_test.dart +++ b/packages/flutter/test/foundation/diagnostics_test.dart @@ -49,7 +49,10 @@ enum ExampleEnum { /// Encode and decode to JSON to make sure all objects in the JSON for the /// [DiagnosticsNode] are valid JSON. Map simulateJsonSerialization(DiagnosticsNode node) { - return json.decode(json.encode(node.toJsonMap(const DiagnosticsSerializationDelegate()))) as Map; + return json.decode(json.encode(node.toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + ))) as Map; } void validateNodeJsonSerialization(DiagnosticsNode node) { diff --git a/packages/flutter/test/painting/colors_test.dart b/packages/flutter/test/painting/colors_test.dart index 97917619341da..8138ab2150211 100644 --- a/packages/flutter/test/painting/colors_test.dart +++ b/packages/flutter/test/painting/colors_test.dart @@ -472,14 +472,20 @@ void main() { test('ColorDiagnosticsProperty includes valueProperties in JSON', () { ColorProperty property = ColorProperty('foo', const Color.fromARGB(10, 20, 30, 40)); - final Map valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties']! as Map; + final Map valueProperties = property.toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + )['valueProperties']! as Map; expect(valueProperties['alpha'], 10); expect(valueProperties['red'], 20); expect(valueProperties['green'], 30); expect(valueProperties['blue'], 40); property = ColorProperty('foo', null); - final Map json = property.toJsonMap(const DiagnosticsSerializationDelegate()); + final Map json = property.toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + ); expect(json.containsKey('valueProperties'), isFalse); }); diff --git a/packages/flutter/test/widgets/icon_data_test.dart b/packages/flutter/test/widgets/icon_data_test.dart index 53591172a0f6b..8449b380dd873 100644 --- a/packages/flutter/test/widgets/icon_data_test.dart +++ b/packages/flutter/test/widgets/icon_data_test.dart @@ -10,11 +10,17 @@ import 'package:flutter_test/flutter_test.dart'; void main() { test('IconDataDiagnosticsProperty includes valueProperties in JSON', () { IconDataProperty property = IconDataProperty('foo', const IconData(101010)); - final Map valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties']! as Map; + final Map valueProperties = property.toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + )['valueProperties']! as Map; expect(valueProperties['codePoint'], 101010); property = IconDataProperty('foo', null); - final Map json = property.toJsonMap(const DiagnosticsSerializationDelegate()); + final Map json = property.toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + ); expect(json.containsKey('valueProperties'), isFalse); }); } diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index e7c673158c288..f8b0ecd28469e 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -1301,6 +1301,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service: service, includeProperties: true, ), + fullDetails: true, ), isNotNull, ); @@ -5271,11 +5272,12 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { if (node.value case Element(:final RenderObject renderObject)) 'renderObject': renderObject.toDiagnosticsNode().toJsonMap( delegate.copyWith(subtreeDepth: 0), + fullDetails: true, ), 'callbackExecuted': true, }, ); - final Map json = node.toJsonMap(delegate); + final Map json = node.toJsonMap(delegate, fullDetails: true,); expect(json['callbackExecuted'], true); expect(json.containsKey('renderObject'), true); expect(json['renderObject'], isA>()); @@ -5296,7 +5298,10 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service: service, includeProperties: true, ); - expect(node.toJsonMap(emptyDelegate), node.toJsonMap(defaultDelegate)); + expect( + node.toJsonMap(emptyDelegate, fullDetails: true), + node.toJsonMap(defaultDelegate, fullDetails: true), + ); }); testWidgets('debugIsLocalCreationLocation test', (WidgetTester tester) async { @@ -5387,7 +5392,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(node.name, isEmpty); expect(node.value, equals('http://the-deeplink/')); expect( - node.toJsonMap(const DiagnosticsSerializationDelegate()), + node.toJsonMap(const DiagnosticsSerializationDelegate(), fullDetails: true,), equals({ 'description': 'description of the deep link', 'type': 'DevToolsDeepLinkProperty', @@ -5404,7 +5409,12 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } static String generateTestPubRootDirectory(TestWidgetInspectorService service) { - final Map jsonObject = const SizedBox().toDiagnosticsNode().toJsonMap(InspectorSerializationDelegate(service: service)); + final Map jsonObject = const SizedBox() + .toDiagnosticsNode() + .toJsonMap( + InspectorSerializationDelegate(service: service), + fullDetails: true, + ); final Map creationLocation = jsonObject['creationLocation']! as Map; expect(creationLocation, isNotNull); final String file = creationLocation['file']! as String; From 0306e4759a400cd280dda676306f5ec341174d33 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:05:27 -0700 Subject: [PATCH 04/13] Add Widget Inspector test cases --- .../test/widgets/widget_inspector_test.dart | 154 ++++++++++++++++++ 1 file changed, 154 insertions(+) diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index f8b0ecd28469e..23aa85075b416 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -1983,6 +1983,14 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { return childJson['createdByLocalProject'] == true; } + /// Returns whether the child is missing the "type" field. + /// + /// This should always be true for nodes in the abbreviated widget + /// tree. + bool isMissingType(Map childJson) { + return childJson['type'] == null; + } + /// Returns whether the child has a description matching [description]. bool hasDescription( Map childJson, { @@ -2279,6 +2287,79 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ))! as Map; + expect( + allChildrenSatisfyCondition(rootJson, + condition: isMissingType, + ), + isFalse, + ); + expect( + allChildrenSatisfyCondition(rootJson, + condition: wasCreatedByLocalProject, + ), + isFalse, + ); + expect( + oneChildSatisfiesCondition(rootJson, condition: (Map child) { + return hasDescription(child, description: 'Text') && + wasCreatedByLocalProject(child) && + !hasTextPreview(child, preview: 'a'); + }, + ), + isTrue, + ); + expect( + oneChildSatisfiesCondition(rootJson, condition: (Map child) { + return hasDescription(child, description: 'Text') && + wasCreatedByLocalProject(child) && + !hasTextPreview(child, preview: 'b'); + }, + ), + isTrue, + ); + expect( + oneChildSatisfiesCondition(rootJson, condition: (Map child) { + return hasDescription(child, description: 'Text') && + wasCreatedByLocalProject(child) && + !hasTextPreview(child, preview: 'c'); + }, + ), + isTrue, + ); + }); + + testWidgets( + 'abbreviated tree using ext.flutter.inspector.getRootWidgetTree', + (WidgetTester tester) async { + const String group = 'test-group'; + + await pumpWidgetTreeWithABC(tester); + final Element elementA = findElementABC('a'); + final Map jsonA = + await selectedWidgetResponseForElement(elementA); + + final Map creationLocation = + verifyAndReturnCreationLocation(jsonA); + final String testFile = verifyAndReturnTestFile(creationLocation); + addPubRootDirectoryFor(testFile); + + final Map rootJson = (await service.testExtension( + WidgetInspectorServiceExtensions.getRootWidgetTree.name, + { + 'groupName': group, + 'isSummaryTree': 'false', + 'withPreviews': 'false', + 'abbreviated': 'true', + }, + ))! as Map; + + expect( + allChildrenSatisfyCondition(rootJson, + condition: isMissingType, + ), + isTrue, + ); + expect( allChildrenSatisfyCondition(rootJson, condition: wasCreatedByLocalProject, @@ -2338,6 +2419,79 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }, ))! as Map; + expect( + allChildrenSatisfyCondition(rootJson, + condition: isMissingType, + ), + isFalse, + ); + expect( + allChildrenSatisfyCondition(rootJson, + condition: wasCreatedByLocalProject, + ), + isFalse, + ); + expect( + oneChildSatisfiesCondition(rootJson, condition: (Map child) { + return hasDescription(child, description: 'Text') && + wasCreatedByLocalProject(child) && + hasTextPreview(child, preview: 'a'); + }, + ), + isTrue, + ); + expect( + oneChildSatisfiesCondition(rootJson, condition: (Map child) { + return hasDescription(child, description: 'Text') && + wasCreatedByLocalProject(child) && + hasTextPreview(child, preview: 'b'); + }, + ), + isTrue, + ); + expect( + oneChildSatisfiesCondition(rootJson, condition: (Map child) { + return hasDescription(child, description: 'Text') && + wasCreatedByLocalProject(child) && + hasTextPreview(child, preview: 'c'); + }, + ), + isTrue, + ); + }); + + testWidgets( + 'abbreviated tree with previews using ext.flutter.inspector.getRootWidgetTree', + (WidgetTester tester) async { + const String group = 'test-group'; + + await pumpWidgetTreeWithABC(tester); + final Element elementA = findElementABC('a'); + final Map jsonA = + await selectedWidgetResponseForElement(elementA); + + final Map creationLocation = + verifyAndReturnCreationLocation(jsonA); + final String testFile = verifyAndReturnTestFile(creationLocation); + addPubRootDirectoryFor(testFile); + + final Map rootJson = (await service.testExtension( + WidgetInspectorServiceExtensions.getRootWidgetTree.name, + { + 'groupName': group, + 'isSummaryTree': 'false', + 'withPreviews': 'true', + 'abbreviated': 'true', + }, + ))! as Map; + + + expect( + allChildrenSatisfyCondition(rootJson, + condition: isMissingType, + ), + isTrue, + ); expect( allChildrenSatisfyCondition(rootJson, condition: wasCreatedByLocalProject, From 4de609460e7f7ed7811df0f1b318bbd9764db679 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:09:58 -0700 Subject: [PATCH 05/13] format --- .../flutter/test/widgets/widget_inspector_test.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index 23aa85075b416..77a4d2096a9e3 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -5426,12 +5426,15 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { if (node.value case Element(:final RenderObject renderObject)) 'renderObject': renderObject.toDiagnosticsNode().toJsonMap( delegate.copyWith(subtreeDepth: 0), - fullDetails: true, + fullDetails: true, ), 'callbackExecuted': true, }, ); - final Map json = node.toJsonMap(delegate, fullDetails: true,); + final Map json = node.toJsonMap( + delegate, + fullDetails: true, + ); expect(json['callbackExecuted'], true); expect(json.containsKey('renderObject'), true); expect(json['renderObject'], isA>()); @@ -5546,7 +5549,10 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(node.name, isEmpty); expect(node.value, equals('http://the-deeplink/')); expect( - node.toJsonMap(const DiagnosticsSerializationDelegate(), fullDetails: true,), + node.toJsonMap( + const DiagnosticsSerializationDelegate(), + fullDetails: true, + ), equals({ 'description': 'description of the deep link', 'type': 'DevToolsDeepLinkProperty', From d3ce5444f033d9330d4a7596bf498d7101b910d8 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:26:36 -0700 Subject: [PATCH 06/13] Make fullDetails optional rather than required --- .../lib/src/foundation/diagnostics.dart | 22 +++++----- packages/flutter/lib/src/painting/colors.dart | 2 +- .../flutter/lib/src/widgets/framework.dart | 2 +- .../flutter/lib/src/widgets/icon_data.dart | 2 +- .../lib/src/widgets/widget_inspector.dart | 8 ++-- .../foundation/diagnostics_json_test.dart | 44 +++++++------------ .../test/foundation/diagnostics_test.dart | 3 +- .../flutter/test/painting/colors_test.dart | 6 +-- .../flutter/test/widgets/icon_data_test.dart | 6 +-- .../test/widgets/widget_inspector_test.dart | 20 +++------ 10 files changed, 43 insertions(+), 72 deletions(-) diff --git a/packages/flutter/lib/src/foundation/diagnostics.dart b/packages/flutter/lib/src/foundation/diagnostics.dart index 5f03c714ff950..56413d96ec1c7 100644 --- a/packages/flutter/lib/src/foundation/diagnostics.dart +++ b/packages/flutter/lib/src/foundation/diagnostics.dart @@ -1607,7 +1607,7 @@ abstract class DiagnosticsNode { @mustCallSuper Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { Map result = {}; assert(() { @@ -1677,7 +1677,7 @@ abstract class DiagnosticsNode { List? nodes, DiagnosticsNode? parent, DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, } ) { bool truncated = false; @@ -1876,7 +1876,7 @@ class StringProperty extends DiagnosticsProperty { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, @@ -1941,7 +1941,7 @@ abstract class _NumProperty extends DiagnosticsProperty { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, @@ -2135,7 +2135,7 @@ class FlagProperty extends DiagnosticsProperty { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, @@ -2266,7 +2266,7 @@ class IterableProperty extends DiagnosticsProperty> { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, @@ -2413,7 +2413,7 @@ class ObjectFlagProperty extends DiagnosticsProperty { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, @@ -2500,7 +2500,7 @@ class FlagsSummary extends DiagnosticsProperty> { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, @@ -2629,7 +2629,7 @@ class DiagnosticsProperty extends DiagnosticsNode { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final T? v = value; List>? properties; @@ -3587,7 +3587,7 @@ abstract class DiagnosticsSerializationDelegate { /// the serialization. Map additionalNodeProperties( DiagnosticsNode node, { - required bool fullDetails, + bool fullDetails = true, }); /// Filters the list of [DiagnosticsNode]s that will be included as children @@ -3682,7 +3682,7 @@ class _DefaultDiagnosticsSerializationDelegate implements DiagnosticsSerializati @override Map additionalNodeProperties( DiagnosticsNode node, { - required bool fullDetails, + bool fullDetails = true, }) { return const {}; } diff --git a/packages/flutter/lib/src/painting/colors.dart b/packages/flutter/lib/src/painting/colors.dart index 92fce24422df9..b74862657687a 100644 --- a/packages/flutter/lib/src/painting/colors.dart +++ b/packages/flutter/lib/src/painting/colors.dart @@ -497,7 +497,7 @@ class ColorProperty extends DiagnosticsProperty { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, diff --git a/packages/flutter/lib/src/widgets/framework.dart b/packages/flutter/lib/src/widgets/framework.dart index 5442b965c5ae5..d62671075c211 100644 --- a/packages/flutter/lib/src/widgets/framework.dart +++ b/packages/flutter/lib/src/widgets/framework.dart @@ -5381,7 +5381,7 @@ class _ElementDiagnosticableTreeNode extends DiagnosticableTreeNode { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap(delegate, fullDetails: fullDetails,); final Element element = value as Element; diff --git a/packages/flutter/lib/src/widgets/icon_data.dart b/packages/flutter/lib/src/widgets/icon_data.dart index d0d4d15a9dae7..d13ce97863204 100644 --- a/packages/flutter/lib/src/widgets/icon_data.dart +++ b/packages/flutter/lib/src/widgets/icon_data.dart @@ -123,7 +123,7 @@ class IconDataProperty extends DiagnosticsProperty { @override Map toJsonMap( DiagnosticsSerializationDelegate delegate, { - required bool fullDetails, + bool fullDetails = true, }) { final Map json = super.toJsonMap( delegate, diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index bc2d84f8221e4..6d76fcdcbd850 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -2209,8 +2209,7 @@ mixin WidgetInspectorService { 'renderObject': renderObject .toDiagnosticsNode() .toJsonMap( - renderObjectSerializationDelegate, - fullDetails: true, + renderObjectSerializationDelegate ), }; @@ -2225,8 +2224,7 @@ mixin WidgetInspectorService { delegate.copyWith( subtreeDepth: 0, includeProperties: true, - ), - fullDetails: true, + ) ); // TODO(jacobr): also describe the path back up the tree to // the RenderParentElement from the current element. It @@ -3806,7 +3804,7 @@ class InspectorSerializationDelegate implements DiagnosticsSerializationDelegate @override Map additionalNodeProperties( DiagnosticsNode node, { - required bool fullDetails, + bool fullDetails = true, }) { final Map result = {}; final Object? value = node.value; diff --git a/packages/flutter/test/foundation/diagnostics_json_test.dart b/packages/flutter/test/foundation/diagnostics_json_test.dart index 4928caf3c77c9..1f03b5d075691 100644 --- a/packages/flutter/test/foundation/diagnostics_json_test.dart +++ b/packages/flutter/test/foundation/diagnostics_json_test.dart @@ -11,8 +11,7 @@ void main() { final Element element = _TestElement(); final Map json = element.toDiagnosticsNode().toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() ); expect(json['widgetRuntimeType'], 'Placeholder'); expect(json['stateful'], isFalse); @@ -22,8 +21,7 @@ void main() { final Element element = StatefulElement(const Tooltip(message: 'foo')); final Map json = element.toDiagnosticsNode().toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() ); expect(json['widgetRuntimeType'], 'Tooltip'); expect(json['stateful'], isTrue); @@ -76,8 +74,7 @@ void main() { final Map result = testTree .toDiagnosticsNode() .toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() ); expect(result.containsKey('properties'), isFalse); expect(result.containsKey('children'), isFalse); @@ -87,8 +84,7 @@ void main() { final Map result = testTree .toDiagnosticsNode() .toJsonMap( - const DiagnosticsSerializationDelegate(subtreeDepth: 1), - fullDetails: true, + const DiagnosticsSerializationDelegate(subtreeDepth: 1) ); expect(result.containsKey('properties'), isFalse); final List> children = result['children']! as List>; @@ -101,8 +97,7 @@ void main() { final Map result = testTree .toDiagnosticsNode() .toJsonMap( - const DiagnosticsSerializationDelegate(subtreeDepth: 5), - fullDetails: true, + const DiagnosticsSerializationDelegate(subtreeDepth: 5) ); expect(result.containsKey('properties'), isFalse); final List> children = result['children']! as List>; @@ -115,8 +110,7 @@ void main() { final Map result = testTree .toDiagnosticsNode() .toJsonMap( - const DiagnosticsSerializationDelegate(includeProperties: true), - fullDetails: true, + const DiagnosticsSerializationDelegate(includeProperties: true) ); expect(result.containsKey('children'), isFalse); expect(result['properties'], hasLength(7)); @@ -129,8 +123,7 @@ void main() { const DiagnosticsSerializationDelegate( subtreeDepth: 1, includeProperties: true - ), - fullDetails: true, + ) ); expect(result['properties'], hasLength(7)); final List> children = result['children']! as List>; @@ -150,8 +143,7 @@ void main() { additionalNodePropertiesMap: { 'foo': true, }, - ), - fullDetails: true, + ) ); expect(result['foo'], isTrue); final List> properties = result['properties']! as List>; @@ -172,8 +164,7 @@ void main() { propertyFilter: (List nodes, DiagnosticsNode owner) { return nodes.whereType().toList(); }, - ), - fullDetails: true, + ) ); final List> properties = result['properties']! as List>; expect(properties, hasLength(3)); @@ -196,8 +187,7 @@ void main() { StringProperty('foo', 'bar'), ]; }, - ), - fullDetails: true, + ) ); final List> properties = result['properties']! as List>; expect(properties, hasLength(1)); @@ -213,8 +203,7 @@ void main() { childFilter: (List nodes, DiagnosticsNode owner) { return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList(); }, - ), - fullDetails: true, + ) ); final List> children = result['children']! as List>; expect(children, hasLength(1)); @@ -229,8 +218,7 @@ void main() { childFilter: (List nodes, DiagnosticsNode owner) { return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList(); }, - ), - fullDetails: true, + ) ); final List> children = result['children']! as List>; expect(children, hasLength(3)); @@ -247,8 +235,7 @@ void main() { nodeTruncator: (List nodes, DiagnosticsNode? owner) { return nodes.take(2).toList(); }, - ), - fullDetails: true, + ) ); final List> children = result['children']! as List>; expect(children, hasLength(3)); @@ -269,8 +256,7 @@ void main() { nodeDelegator: (DiagnosticsNode node, DiagnosticsSerializationDelegate delegate) { return delegate.copyWith(includeProperties: false); }, - ), - fullDetails: true, + ) ); final List> properties = result['properties']! as List>; expect(properties, hasLength(7)); @@ -347,7 +333,7 @@ class TestDiagnosticsSerializationDelegate implements DiagnosticsSerializationDe @override Map additionalNodeProperties( DiagnosticsNode node, { - required bool fullDetails, + bool fullDetails = true, }) { return additionalNodePropertiesMap; } diff --git a/packages/flutter/test/foundation/diagnostics_test.dart b/packages/flutter/test/foundation/diagnostics_test.dart index cf22ff5616675..b18c8a22d5fb2 100644 --- a/packages/flutter/test/foundation/diagnostics_test.dart +++ b/packages/flutter/test/foundation/diagnostics_test.dart @@ -50,8 +50,7 @@ enum ExampleEnum { /// [DiagnosticsNode] are valid JSON. Map simulateJsonSerialization(DiagnosticsNode node) { return json.decode(json.encode(node.toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() ))) as Map; } diff --git a/packages/flutter/test/painting/colors_test.dart b/packages/flutter/test/painting/colors_test.dart index 8138ab2150211..e018f8aa8fb73 100644 --- a/packages/flutter/test/painting/colors_test.dart +++ b/packages/flutter/test/painting/colors_test.dart @@ -473,8 +473,7 @@ void main() { test('ColorDiagnosticsProperty includes valueProperties in JSON', () { ColorProperty property = ColorProperty('foo', const Color.fromARGB(10, 20, 30, 40)); final Map valueProperties = property.toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() )['valueProperties']! as Map; expect(valueProperties['alpha'], 10); expect(valueProperties['red'], 20); @@ -483,8 +482,7 @@ void main() { property = ColorProperty('foo', null); final Map json = property.toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() ); expect(json.containsKey('valueProperties'), isFalse); }); diff --git a/packages/flutter/test/widgets/icon_data_test.dart b/packages/flutter/test/widgets/icon_data_test.dart index 8449b380dd873..ac44e6fc90ef0 100644 --- a/packages/flutter/test/widgets/icon_data_test.dart +++ b/packages/flutter/test/widgets/icon_data_test.dart @@ -11,15 +11,13 @@ void main() { test('IconDataDiagnosticsProperty includes valueProperties in JSON', () { IconDataProperty property = IconDataProperty('foo', const IconData(101010)); final Map valueProperties = property.toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() )['valueProperties']! as Map; expect(valueProperties['codePoint'], 101010); property = IconDataProperty('foo', null); final Map json = property.toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() ); expect(json.containsKey('valueProperties'), isFalse); }); diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index 77a4d2096a9e3..f779030068b89 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -1300,8 +1300,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { InspectorSerializationDelegate( service: service, includeProperties: true, - ), - fullDetails: true, + ) ), isNotNull, ); @@ -5425,15 +5424,13 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { (DiagnosticsNode node, InspectorSerializationDelegate delegate) => { if (node.value case Element(:final RenderObject renderObject)) 'renderObject': renderObject.toDiagnosticsNode().toJsonMap( - delegate.copyWith(subtreeDepth: 0), - fullDetails: true, + delegate.copyWith(subtreeDepth: 0) ), 'callbackExecuted': true, }, ); final Map json = node.toJsonMap( - delegate, - fullDetails: true, + delegate ); expect(json['callbackExecuted'], true); expect(json.containsKey('renderObject'), true); @@ -5455,10 +5452,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { service: service, includeProperties: true, ); - expect( - node.toJsonMap(emptyDelegate, fullDetails: true), - node.toJsonMap(defaultDelegate, fullDetails: true), - ); + expect(node.toJsonMap(emptyDelegate), node.toJsonMap(defaultDelegate)); }); testWidgets('debugIsLocalCreationLocation test', (WidgetTester tester) async { @@ -5550,8 +5544,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(node.value, equals('http://the-deeplink/')); expect( node.toJsonMap( - const DiagnosticsSerializationDelegate(), - fullDetails: true, + const DiagnosticsSerializationDelegate() ), equals({ 'description': 'description of the deep link', @@ -5572,8 +5565,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { final Map jsonObject = const SizedBox() .toDiagnosticsNode() .toJsonMap( - InspectorSerializationDelegate(service: service), - fullDetails: true, + InspectorSerializationDelegate(service: service) ); final Map creationLocation = jsonObject['creationLocation']! as Map; expect(creationLocation, isNotNull); From 8abec437e8351132e7a309d676aa5e6d09e97cee Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:36:01 -0700 Subject: [PATCH 07/13] Some clean up --- .../lib/src/widgets/widget_inspector.dart | 6 +- .../foundation/diagnostics_json_test.dart | 174 ++++++------------ .../test/foundation/diagnostics_test.dart | 4 +- .../flutter/test/painting/colors_test.dart | 8 +- .../flutter/test/widgets/icon_data_test.dart | 8 +- .../test/widgets/widget_inspector_test.dart | 4 +- 6 files changed, 70 insertions(+), 134 deletions(-) diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index 6d76fcdcbd850..05e887a21a957 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -2208,9 +2208,7 @@ mixin WidgetInspectorService { if (value is! RenderObject && delegate.expandPropertyValues) 'renderObject': renderObject .toDiagnosticsNode() - .toJsonMap( - renderObjectSerializationDelegate - ), + .toJsonMap(renderObjectSerializationDelegate), }; final RenderObject? renderParent = renderObject.parent; @@ -2224,7 +2222,7 @@ mixin WidgetInspectorService { delegate.copyWith( subtreeDepth: 0, includeProperties: true, - ) + ), ); // TODO(jacobr): also describe the path back up the tree to // the RenderParentElement from the current element. It diff --git a/packages/flutter/test/foundation/diagnostics_json_test.dart b/packages/flutter/test/foundation/diagnostics_json_test.dart index 1f03b5d075691..29db623fb15b3 100644 --- a/packages/flutter/test/foundation/diagnostics_json_test.dart +++ b/packages/flutter/test/foundation/diagnostics_json_test.dart @@ -10,9 +10,7 @@ void main() { test('Element diagnostics json includes widgetRuntimeType', () async { final Element element = _TestElement(); - final Map json = element.toDiagnosticsNode().toJsonMap( - const DiagnosticsSerializationDelegate() - ); + final Map json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate()); expect(json['widgetRuntimeType'], 'Placeholder'); expect(json['stateful'], isFalse); }); @@ -20,9 +18,7 @@ void main() { test('StatefulElement diagnostics are stateful', () { final Element element = StatefulElement(const Tooltip(message: 'foo')); - final Map json = element.toDiagnosticsNode().toJsonMap( - const DiagnosticsSerializationDelegate() - ); + final Map json = element.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate()); expect(json['widgetRuntimeType'], 'Tooltip'); expect(json['stateful'], isTrue); }); @@ -71,21 +67,13 @@ void main() { ); test('default', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - const DiagnosticsSerializationDelegate() - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate()); expect(result.containsKey('properties'), isFalse); expect(result.containsKey('children'), isFalse); }); test('subtreeDepth 1', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - const DiagnosticsSerializationDelegate(subtreeDepth: 1) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 1)); expect(result.containsKey('properties'), isFalse); final List> children = result['children']! as List>; expect(children[0].containsKey('children'), isFalse); @@ -94,11 +82,7 @@ void main() { }); test('subtreeDepth 5', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - const DiagnosticsSerializationDelegate(subtreeDepth: 5) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(subtreeDepth: 5)); expect(result.containsKey('properties'), isFalse); final List> children = result['children']! as List>; expect(children[0]['children'], hasLength(0)); @@ -107,24 +91,16 @@ void main() { }); test('includeProperties', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - const DiagnosticsSerializationDelegate(includeProperties: true) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate(includeProperties: true)); expect(result.containsKey('children'), isFalse); expect(result['properties'], hasLength(7)); }); test('includeProperties with subtreedepth 1', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - const DiagnosticsSerializationDelegate( - subtreeDepth: 1, - includeProperties: true - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate( + includeProperties: true, + subtreeDepth: 1, + )); expect(result['properties'], hasLength(7)); final List> children = result['children']! as List>; expect(children, hasLength(3)); @@ -134,17 +110,13 @@ void main() { }); test('additionalNodeProperties', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - const TestDiagnosticsSerializationDelegate( - includeProperties: true, - subtreeDepth: 1, - additionalNodePropertiesMap: { - 'foo': true, - }, - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(const TestDiagnosticsSerializationDelegate( + includeProperties: true, + subtreeDepth: 1, + additionalNodePropertiesMap: { + 'foo': true, + }, + )); expect(result['foo'], isTrue); final List> properties = result['properties']! as List>; expect(properties, hasLength(7)); @@ -156,16 +128,12 @@ void main() { }); test('filterProperties - sublist', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - TestDiagnosticsSerializationDelegate( - includeProperties: true, - propertyFilter: (List nodes, DiagnosticsNode owner) { - return nodes.whereType().toList(); - }, - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( + includeProperties: true, + propertyFilter: (List nodes, DiagnosticsNode owner) { + return nodes.whereType().toList(); + }, + )); final List> properties = result['properties']! as List>; expect(properties, hasLength(3)); expect(properties.every((Map property) => property['type'] == 'StringProperty'), isTrue); @@ -173,70 +141,54 @@ void main() { test('filterProperties - replace', () { bool replaced = false; - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - TestDiagnosticsSerializationDelegate( - includeProperties: true, - propertyFilter: (List nodes, DiagnosticsNode owner) { - if (replaced) { - return nodes; - } - replaced = true; - return [ - StringProperty('foo', 'bar'), - ]; - }, - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( + includeProperties: true, + propertyFilter: (List nodes, DiagnosticsNode owner) { + if (replaced) { + return nodes; + } + replaced = true; + return [ + StringProperty('foo', 'bar'), + ]; + }, + )); final List> properties = result['properties']! as List>; expect(properties, hasLength(1)); expect(properties.single['name'], 'foo'); }); test('filterChildren - sublist', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - TestDiagnosticsSerializationDelegate( - subtreeDepth: 1, - childFilter: (List nodes, DiagnosticsNode owner) { - return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList(); - }, - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( + subtreeDepth: 1, + childFilter: (List nodes, DiagnosticsNode owner) { + return nodes.where((DiagnosticsNode node) => node.getProperties().isEmpty).toList(); + }, + )); final List> children = result['children']! as List>; expect(children, hasLength(1)); }); test('filterChildren - replace', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - TestDiagnosticsSerializationDelegate( - subtreeDepth: 1, - childFilter: (List nodes, DiagnosticsNode owner) { - return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList(); - }, - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( + subtreeDepth: 1, + childFilter: (List nodes, DiagnosticsNode owner) { + return nodes.expand((DiagnosticsNode node) => node.getChildren()).toList(); + }, + )); final List> children = result['children']! as List>; expect(children, hasLength(3)); expect(children.first['name'], 'child node B1'); }); test('nodeTruncator', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - TestDiagnosticsSerializationDelegate( - subtreeDepth: 5, - includeProperties: true, - nodeTruncator: (List nodes, DiagnosticsNode? owner) { - return nodes.take(2).toList(); - }, - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( + subtreeDepth: 5, + includeProperties: true, + nodeTruncator: (List nodes, DiagnosticsNode? owner) { + return nodes.take(2).toList(); + }, + )); final List> children = result['children']! as List>; expect(children, hasLength(3)); expect(children.last['truncated'], isTrue); @@ -247,17 +199,13 @@ void main() { }); test('delegateForAddingNodes', () { - final Map result = testTree - .toDiagnosticsNode() - .toJsonMap( - TestDiagnosticsSerializationDelegate( - subtreeDepth: 5, - includeProperties: true, - nodeDelegator: (DiagnosticsNode node, DiagnosticsSerializationDelegate delegate) { - return delegate.copyWith(includeProperties: false); - }, - ) - ); + final Map result = testTree.toDiagnosticsNode().toJsonMap(TestDiagnosticsSerializationDelegate( + subtreeDepth: 5, + includeProperties: true, + nodeDelegator: (DiagnosticsNode node, DiagnosticsSerializationDelegate delegate) { + return delegate.copyWith(includeProperties: false); + }, + )); final List> properties = result['properties']! as List>; expect(properties, hasLength(7)); expect(properties.every((Map property) => !property.containsKey('properties')), isTrue); diff --git a/packages/flutter/test/foundation/diagnostics_test.dart b/packages/flutter/test/foundation/diagnostics_test.dart index b18c8a22d5fb2..7b3f5c2435712 100644 --- a/packages/flutter/test/foundation/diagnostics_test.dart +++ b/packages/flutter/test/foundation/diagnostics_test.dart @@ -49,9 +49,7 @@ enum ExampleEnum { /// Encode and decode to JSON to make sure all objects in the JSON for the /// [DiagnosticsNode] are valid JSON. Map simulateJsonSerialization(DiagnosticsNode node) { - return json.decode(json.encode(node.toJsonMap( - const DiagnosticsSerializationDelegate() - ))) as Map; + return json.decode(json.encode(node.toJsonMap(const DiagnosticsSerializationDelegate()))) as Map; } void validateNodeJsonSerialization(DiagnosticsNode node) { diff --git a/packages/flutter/test/painting/colors_test.dart b/packages/flutter/test/painting/colors_test.dart index e018f8aa8fb73..97917619341da 100644 --- a/packages/flutter/test/painting/colors_test.dart +++ b/packages/flutter/test/painting/colors_test.dart @@ -472,18 +472,14 @@ void main() { test('ColorDiagnosticsProperty includes valueProperties in JSON', () { ColorProperty property = ColorProperty('foo', const Color.fromARGB(10, 20, 30, 40)); - final Map valueProperties = property.toJsonMap( - const DiagnosticsSerializationDelegate() - )['valueProperties']! as Map; + final Map valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties']! as Map; expect(valueProperties['alpha'], 10); expect(valueProperties['red'], 20); expect(valueProperties['green'], 30); expect(valueProperties['blue'], 40); property = ColorProperty('foo', null); - final Map json = property.toJsonMap( - const DiagnosticsSerializationDelegate() - ); + final Map json = property.toJsonMap(const DiagnosticsSerializationDelegate()); expect(json.containsKey('valueProperties'), isFalse); }); diff --git a/packages/flutter/test/widgets/icon_data_test.dart b/packages/flutter/test/widgets/icon_data_test.dart index ac44e6fc90ef0..53591172a0f6b 100644 --- a/packages/flutter/test/widgets/icon_data_test.dart +++ b/packages/flutter/test/widgets/icon_data_test.dart @@ -10,15 +10,11 @@ import 'package:flutter_test/flutter_test.dart'; void main() { test('IconDataDiagnosticsProperty includes valueProperties in JSON', () { IconDataProperty property = IconDataProperty('foo', const IconData(101010)); - final Map valueProperties = property.toJsonMap( - const DiagnosticsSerializationDelegate() - )['valueProperties']! as Map; + final Map valueProperties = property.toJsonMap(const DiagnosticsSerializationDelegate())['valueProperties']! as Map; expect(valueProperties['codePoint'], 101010); property = IconDataProperty('foo', null); - final Map json = property.toJsonMap( - const DiagnosticsSerializationDelegate() - ); + final Map json = property.toJsonMap(const DiagnosticsSerializationDelegate()); expect(json.containsKey('valueProperties'), isFalse); }); } diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index f779030068b89..94630a5ee4424 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -1300,7 +1300,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { InspectorSerializationDelegate( service: service, includeProperties: true, - ) + ), ), isNotNull, ); @@ -5424,7 +5424,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { (DiagnosticsNode node, InspectorSerializationDelegate delegate) => { if (node.value case Element(:final RenderObject renderObject)) 'renderObject': renderObject.toDiagnosticsNode().toJsonMap( - delegate.copyWith(subtreeDepth: 0) + delegate.copyWith(subtreeDepth: 0), ), 'callbackExecuted': true, }, From 02a0be79ddf93c90f4fcc3b197f11e52b7f88145 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:39:57 -0700 Subject: [PATCH 08/13] More clean up --- .../lib/src/widgets/service_extensions.dart | 25 ------------------- .../test/widgets/widget_inspector_test.dart | 14 +++-------- 2 files changed, 3 insertions(+), 36 deletions(-) diff --git a/packages/flutter/lib/src/widgets/service_extensions.dart b/packages/flutter/lib/src/widgets/service_extensions.dart index e7e9fbf4cf10b..53ce821cd4b02 100644 --- a/packages/flutter/lib/src/widgets/service_extensions.dart +++ b/packages/flutter/lib/src/widgets/service_extensions.dart @@ -386,11 +386,6 @@ enum WidgetInspectorServiceExtensions { /// If the parameter `withPreviews` is true, text previews will be included /// for [Element]s with a corresponding [RenderObject] of type /// [RenderParagraph]. - /// - /// Note: This service extension returns detailed [DiagnosticsNode] data for - /// the entire tree, and as such the payload can be quite large. If you need a - /// lightweight response without all the details, use [getLightRootWidgetTree] - /// instead. /// /// See also: /// @@ -398,26 +393,6 @@ enum WidgetInspectorServiceExtensions { /// extension is registered. getRootWidgetTree, - /// Name of service extension that, when called, will return lightweight - /// [DiagnosticsNode] data for the root [Element] of the widget tree. - /// - /// If the parameter `isSummaryTree` is true, the tree will only include - /// [Element]s that were created by user code. - /// - /// If the parameter `withPreviews` is true, text previews will be included - /// for [Element]s with a corresponding [RenderObject] of type - /// [RenderParagraph]. - /// - /// Note: This service extension returns only the information required to - /// build a representation of the widget tree. If you need more detailed - /// [DiagnosticsNode] data, use [getRootWidgetTree] instead. - /// - /// See also: - /// - /// * [WidgetInspectorService.initServiceExtensions], where the service - /// extension is registered. - getLightRootWidgetTree, - /// Name of service extension that, when called, will return the /// [DiagnosticsNode] data for the root [Element] of the summary tree, which /// only includes [Element]s that were created by user code. diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index 94630a5ee4424..149fd48987ec7 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -5429,9 +5429,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { 'callbackExecuted': true, }, ); - final Map json = node.toJsonMap( - delegate - ); + final Map json = node.toJsonMap(delegate); expect(json['callbackExecuted'], true); expect(json.containsKey('renderObject'), true); expect(json['renderObject'], isA>()); @@ -5543,9 +5541,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { expect(node.name, isEmpty); expect(node.value, equals('http://the-deeplink/')); expect( - node.toJsonMap( - const DiagnosticsSerializationDelegate() - ), + node.toJsonMap(const DiagnosticsSerializationDelegate()), equals({ 'description': 'description of the deep link', 'type': 'DevToolsDeepLinkProperty', @@ -5562,11 +5558,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } static String generateTestPubRootDirectory(TestWidgetInspectorService service) { - final Map jsonObject = const SizedBox() - .toDiagnosticsNode() - .toJsonMap( - InspectorSerializationDelegate(service: service) - ); + final Map jsonObject = const SizedBox().toDiagnosticsNode().toJsonMap(InspectorSerializationDelegate(service: service)); final Map creationLocation = jsonObject['creationLocation']! as Map; expect(creationLocation, isNotNull); final String file = creationLocation['file']! as String; From e5be27cea38269c5738120fb0055b20e4e5c3dc6 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Mon, 21 Oct 2024 16:49:27 -0700 Subject: [PATCH 09/13] Add diagnostics test --- .../foundation/diagnostics_json_test.dart | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/packages/flutter/test/foundation/diagnostics_json_test.dart b/packages/flutter/test/foundation/diagnostics_json_test.dart index 29db623fb15b3..867605d62c67d 100644 --- a/packages/flutter/test/foundation/diagnostics_json_test.dart +++ b/packages/flutter/test/foundation/diagnostics_json_test.dart @@ -24,6 +24,16 @@ void main() { }); group('Serialization', () { + const List essentialDiagnosticKeys = [ + 'description', + 'shouldIndent', + ]; + const List detailedDiagnosticKeys = [ + 'type', + 'hasChildren', + 'allowWrap', + ]; + final TestTree testTree = TestTree( properties: [ StringProperty('stringProperty1', 'value1', quoted: false), @@ -70,6 +80,46 @@ void main() { final Map result = testTree.toDiagnosticsNode().toJsonMap(const DiagnosticsSerializationDelegate()); expect(result.containsKey('properties'), isFalse); expect(result.containsKey('children'), isFalse); + + for (final String keyName in essentialDiagnosticKeys) { + expect( + result.containsKey(keyName), + isTrue, + reason: '$keyName is included.', + ); + } + for (final String keyName in detailedDiagnosticKeys) { + expect( + result.containsKey(keyName), + isTrue, + reason: '$keyName is included.', + ); + } + }); + + test('without full details', () { + final Map result = testTree + .toDiagnosticsNode() + .toJsonMap( + const DiagnosticsSerializationDelegate(), fullDetails: false + ); + expect(result.containsKey('properties'), isFalse); + expect(result.containsKey('children'), isFalse); + + for (final String keyName in essentialDiagnosticKeys) { + expect( + result.containsKey(keyName), + isTrue, + reason: '$keyName is included.', + ); + } + for (final String keyName in detailedDiagnosticKeys) { + expect( + result.containsKey(keyName), + isFalse, + reason: '$keyName is not included.', + ); + } }); test('subtreeDepth 1', () { From 37d4776dc2fe99e961c3ec992e1173666c12c004 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 22 Oct 2024 08:55:32 -0700 Subject: [PATCH 10/13] Remove trailing whitespace --- packages/flutter/lib/src/foundation/diagnostics.dart | 2 +- packages/flutter/test/widgets/widget_inspector_test.dart | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/foundation/diagnostics.dart b/packages/flutter/lib/src/foundation/diagnostics.dart index 56413d96ec1c7..a585be58f6559 100644 --- a/packages/flutter/lib/src/foundation/diagnostics.dart +++ b/packages/flutter/lib/src/foundation/diagnostics.dart @@ -1630,7 +1630,7 @@ abstract class DiagnosticsNode { result = essentialDetails; } else { result = { - ...essentialDetails, + ...essentialDetails, 'type': runtimeType.toString(), if (name != null) 'name': name, diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index 149fd48987ec7..cf503e0ffd12a 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -1983,7 +1983,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { } /// Returns whether the child is missing the "type" field. - /// + /// /// This should always be true for nodes in the abbreviated widget /// tree. bool isMissingType(Map childJson) { From 2c20904e0de50c76b57a39076a9d44ccc242f2e9 Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 22 Oct 2024 09:39:03 -0700 Subject: [PATCH 11/13] Respond to PR comments --- .../lib/src/foundation/diagnostics.dart | 80 +++++++++---------- .../lib/src/widgets/widget_inspector.dart | 3 +- 2 files changed, 41 insertions(+), 42 deletions(-) diff --git a/packages/flutter/lib/src/foundation/diagnostics.dart b/packages/flutter/lib/src/foundation/diagnostics.dart index a585be58f6559..5d50c0ef22a15 100644 --- a/packages/flutter/lib/src/foundation/diagnostics.dart +++ b/packages/flutter/lib/src/foundation/diagnostics.dart @@ -1626,43 +1626,39 @@ abstract class DiagnosticsNode { ), }; - if (!fullDetails) { - result = essentialDetails; - } else { - result = { - ...essentialDetails, - 'type': runtimeType.toString(), - if (name != null) - 'name': name, - if (!showSeparator) - 'showSeparator': showSeparator, - if (level != DiagnosticLevel.info) - 'level': level.name, - if (!showName) - 'showName': showName, - if (emptyBodyDescription != null) - 'emptyBodyDescription': emptyBodyDescription, - if (style != DiagnosticsTreeStyle.sparse) - 'style': style!.name, - if (allowTruncate) - 'allowTruncate': allowTruncate, - if (hasChildren) - 'hasChildren': hasChildren, - if (linePrefix?.isNotEmpty ?? false) - 'linePrefix': linePrefix, - if (!allowWrap) - 'allowWrap': allowWrap, - if (allowNameWrap) - 'allowNameWrap': allowNameWrap, - if (delegate.includeProperties) - 'properties': toJsonList( - delegate.filterProperties(getProperties(), this), - this, - delegate, - fullDetails: fullDetails, - ), - }; - } + result = !fullDetails ? essentialDetails : { + ...essentialDetails, + 'type': runtimeType.toString(), + if (name != null) + 'name': name, + if (!showSeparator) + 'showSeparator': showSeparator, + if (level != DiagnosticLevel.info) + 'level': level.name, + if (!showName) + 'showName': showName, + if (emptyBodyDescription != null) + 'emptyBodyDescription': emptyBodyDescription, + if (style != DiagnosticsTreeStyle.sparse) + 'style': style!.name, + if (allowTruncate) + 'allowTruncate': allowTruncate, + if (hasChildren) + 'hasChildren': hasChildren, + if (linePrefix?.isNotEmpty ?? false) + 'linePrefix': linePrefix, + if (!allowWrap) + 'allowWrap': allowWrap, + if (allowNameWrap) + 'allowNameWrap': allowNameWrap, + if (delegate.includeProperties) + 'properties': toJsonList( + delegate.filterProperties(getProperties(), this), + this, + delegate, + fullDetails: fullDetails, + ), + }; return true; }()); return result; @@ -1677,9 +1673,8 @@ abstract class DiagnosticsNode { List? nodes, DiagnosticsNode? parent, DiagnosticsSerializationDelegate delegate, { - bool fullDetails = true, - } - ) { + bool fullDetails = true, + }) { bool truncated = false; if (nodes == null) { return const >[]; @@ -1691,7 +1686,10 @@ abstract class DiagnosticsNode { truncated = true; } final List> json = nodes.map>((DiagnosticsNode node) { - return node.toJsonMap(delegate.delegateForNode(node), fullDetails: fullDetails,); + return node.toJsonMap( + delegate.delegateForNode(node), + fullDetails: fullDetails, + ); }).toList(); if (truncated) { json.last['truncated'] = true; diff --git a/packages/flutter/lib/src/widgets/widget_inspector.dart b/packages/flutter/lib/src/widgets/widget_inspector.dart index 05e887a21a957..072b94e9209f2 100644 --- a/packages/flutter/lib/src/widgets/widget_inspector.dart +++ b/packages/flutter/lib/src/widgets/widget_inspector.dart @@ -1984,7 +1984,8 @@ mixin WidgetInspectorService { final String groupName = parameters['groupName']!; final bool isSummaryTree = parameters['isSummaryTree'] == 'true'; final bool withPreviews = parameters['withPreviews'] == 'true'; - final bool fullDetails = parameters['abbreviated'] != 'true'; + // If the "fullDetails" parameter is not provided, default to true. + final bool fullDetails = parameters['fullDetails'] != 'false'; final Map? result = _getRootWidgetTreeImpl( groupName: groupName, From 11aa3f03623a14bcad8c70ef9c1b1e974f0607dc Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 22 Oct 2024 10:40:52 -0700 Subject: [PATCH 12/13] Update widget_inspector_test --- .../flutter/test/widgets/widget_inspector_test.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index cf503e0ffd12a..3d5d295dc2529 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -1984,8 +1984,8 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { /// Returns whether the child is missing the "type" field. /// - /// This should always be true for nodes in the abbreviated widget - /// tree. + /// This should always be true for nodes in the widget tree without + /// full details. bool isMissingType(Map childJson) { return childJson['type'] == null; } @@ -2328,7 +2328,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }); testWidgets( - 'abbreviated tree using ext.flutter.inspector.getRootWidgetTree', + 'tree without full details using ext.flutter.inspector.getRootWidgetTree', (WidgetTester tester) async { const String group = 'test-group'; @@ -2348,7 +2348,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { 'groupName': group, 'isSummaryTree': 'false', 'withPreviews': 'false', - 'abbreviated': 'true', + 'fullDetails': 'false', }, ))! as Map; @@ -2460,7 +2460,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { }); testWidgets( - 'abbreviated tree with previews using ext.flutter.inspector.getRootWidgetTree', + 'tree without full details and with previews using ext.flutter.inspector.getRootWidgetTree', (WidgetTester tester) async { const String group = 'test-group'; @@ -2480,7 +2480,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { 'groupName': group, 'isSummaryTree': 'false', 'withPreviews': 'true', - 'abbreviated': 'true', + 'fullDetails': 'false', }, ))! as Map; From 5f754ed51e55751c7a62a851078931a8617061ff Mon Sep 17 00:00:00 2001 From: Elliott Brooks <21270878+elliette@users.noreply.github.com> Date: Tue, 22 Oct 2024 11:29:41 -0700 Subject: [PATCH 13/13] Another test failure --- packages/flutter/test/widgets/widget_inspector_test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/flutter/test/widgets/widget_inspector_test.dart b/packages/flutter/test/widgets/widget_inspector_test.dart index 3d5d295dc2529..e4e9c2fb5c760 100644 --- a/packages/flutter/test/widgets/widget_inspector_test.dart +++ b/packages/flutter/test/widgets/widget_inspector_test.dart @@ -5544,6 +5544,7 @@ class _TestWidgetInspectorService extends TestWidgetInspectorService { node.toJsonMap(const DiagnosticsSerializationDelegate()), equals({ 'description': 'description of the deep link', + 'shouldIndent': true, 'type': 'DevToolsDeepLinkProperty', 'name': '', 'style': 'singleLine',