diff --git a/flutter-candidate.txt b/flutter-candidate.txt index e8cf229dbc5..25567839e7f 100644 --- a/flutter-candidate.txt +++ b/flutter-candidate.txt @@ -1 +1 @@ -bcc31461856d508846f2d7b87efc9f2682f6c5b8 +7e2a06657c1c8278d477ce7d1db77c51575fdf3d \ No newline at end of file diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart index 11aa1b4c53d..96e364fde76 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_controller.dart @@ -434,6 +434,7 @@ class InspectorController extends DisposableController final node = await group.getRoot( treeType, isSummaryTree: hideImplementationWidgets, + includeFullDetails: false, ); if (node == null || group.disposed || _disposed) { return; diff --git a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart index 8768df2a3a1..0c00081f93a 100644 --- a/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart +++ b/packages/devtools_app/lib/src/screens/inspector_v2/inspector_tree_controller.dart @@ -486,10 +486,6 @@ class InspectorTreeController extends DisposableController ); } - final style = node.diagnostic?.style; - final indented = style != DiagnosticsTreeStyle.flat && - style != DiagnosticsTreeStyle.error; - if (!node.isExpanded && !includeCollapsedRows) return; final children = node.children; final parentDepth = depth; @@ -498,7 +494,7 @@ class InspectorTreeController extends DisposableController final shouldAddTick = children.length > 1 && children.last != child && !children.last.isProperty && - indented; + node.diagnostic?.shouldIndent == true; buildRowsHelper( child, diff --git a/packages/devtools_app/lib/src/shared/diagnostics/diagnostics_node.dart b/packages/devtools_app/lib/src/shared/diagnostics/diagnostics_node.dart index 8b321102d70..6a850531738 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/diagnostics_node.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/diagnostics_node.dart @@ -240,6 +240,15 @@ class RemoteDiagnosticsNode extends DiagnosticableTree { /// will make the name self-evident. bool get showName => getBooleanMember('showName', true); + /// Whether or not the node should be indented in the Inspector Tree. + bool get shouldIndent { + final value = json['shouldIndent'] as bool?; + + return value ?? + style != DiagnosticsTreeStyle.flat && + style != DiagnosticsTreeStyle.error; + } + /// Description to show if the node has no displayed properties or children. String? getEmptyBodyDescription() => getStringMember('emptyBodyDescription'); diff --git a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart index 7e0299e3c8b..ce3488cf84a 100644 --- a/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart +++ b/packages/devtools_app/lib/src/shared/diagnostics/inspector_service.dart @@ -951,17 +951,22 @@ class ObjectGroup extends InspectorObjectGroupBase { Future getRoot( FlutterTreeType type, { bool isSummaryTree = false, + bool includeFullDetails = true, }) { // There is no excuse to call this method on a disposed group. assert(!disposed); switch (type) { case FlutterTreeType.widget: - return getRootWidgetTree(isSummaryTree: isSummaryTree); + return getRootWidgetTree( + isSummaryTree: isSummaryTree, + includeFullDetails: includeFullDetails, + ); } } Future getRootWidgetTree({ required bool isSummaryTree, + required bool includeFullDetails, }) { return parseDiagnosticsNodeDaemon( invokeServiceMethodDaemonParams( @@ -970,6 +975,7 @@ class ObjectGroup extends InspectorObjectGroupBase { 'groupName': groupName, 'isSummaryTree': '$isSummaryTree', 'withPreviews': 'true', + 'fullDetails': '$includeFullDetails', }, ), ); diff --git a/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj b/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj index 996666b3e2e..bb5fef65d14 100644 --- a/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj +++ b/packages/devtools_app/macos/Runner.xcodeproj/project.pbxproj @@ -27,7 +27,6 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 65EE9B0FCDEF2DFDA4FD2516 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4A56105EC2AC1506C64FB1DC /* Pods_RunnerTests.framework */; }; E678665441E5C0F7F629BAD5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5062035DDDD18FB35E98D5B6 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ @@ -79,15 +78,11 @@ 33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = ""; }; 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; - 4A56105EC2AC1506C64FB1DC /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 4CA3E8EEDEABAA0159F4AD05 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; }; 5062035DDDD18FB35E98D5B6 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 68C587FFA5A0B8F46A0C5150 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; - 7C572606400B2FDAA7A9B5F5 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; A7CE48BF63861DD9F3A9FA2F /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - A88E56679D9FCF48A33B3AA7 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -95,7 +90,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 65EE9B0FCDEF2DFDA4FD2516 /* Pods_RunnerTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -191,9 +185,6 @@ 11BB555C0F1767B9B5CB7CE0 /* Pods-Runner.debug.xcconfig */, 68C587FFA5A0B8F46A0C5150 /* Pods-Runner.release.xcconfig */, A7CE48BF63861DD9F3A9FA2F /* Pods-Runner.profile.xcconfig */, - A88E56679D9FCF48A33B3AA7 /* Pods-RunnerTests.debug.xcconfig */, - 7C572606400B2FDAA7A9B5F5 /* Pods-RunnerTests.release.xcconfig */, - 4CA3E8EEDEABAA0159F4AD05 /* Pods-RunnerTests.profile.xcconfig */, ); name = Pods; path = Pods; @@ -203,7 +194,6 @@ isa = PBXGroup; children = ( 5062035DDDD18FB35E98D5B6 /* Pods_Runner.framework */, - 4A56105EC2AC1506C64FB1DC /* Pods_RunnerTests.framework */, ); name = Frameworks; sourceTree = ""; @@ -215,7 +205,6 @@ isa = PBXNativeTarget; buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; buildPhases = ( - 1232036051E13E144CEEF58B /* [CP] Check Pods Manifest.lock */, 331C80D1294CF70F00263BE5 /* Sources */, 331C80D2294CF70F00263BE5 /* Frameworks */, 331C80D3294CF70F00263BE5 /* Resources */, @@ -322,28 +311,6 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 1232036051E13E144CEEF58B /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - "${PODS_PODFILE_DIR_PATH}/Podfile.lock", - "${PODS_ROOT}/Manifest.lock", - ); - name = "[CP] Check Pods Manifest.lock"; - outputFileListPaths = ( - ); - outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt", - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; - showEnvVarsInLog = 0; - }; 3399D490228B24CF009A79C7 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; alwaysOutOfDate = 1; @@ -472,7 +439,6 @@ /* Begin XCBuildConfiguration section */ 331C80DB294CF71000263BE5 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = A88E56679D9FCF48A33B3AA7 /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -487,7 +453,6 @@ }; 331C80DC294CF71000263BE5 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 7C572606400B2FDAA7A9B5F5 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; @@ -502,7 +467,6 @@ }; 331C80DD294CF71000263BE5 /* Profile */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 4CA3E8EEDEABAA0159F4AD05 /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CURRENT_PROJECT_VERSION = 1; diff --git a/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart b/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart index 96b581e18b9..6bac1af25fe 100644 --- a/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart +++ b/packages/devtools_app/test/inspector_v2/inspector_integration_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'package:collection/collection.dart'; import 'package:devtools_app/devtools_app.dart' hide InspectorScreenBodyState, InspectorScreenBody; import 'package:devtools_app/src/screens/inspector/inspector_screen_body.dart' @@ -301,6 +302,59 @@ void main() { }, ); + testWidgetsWithWindowSize( + 'tree nodes contain only essential information', + windowSize, + (WidgetTester tester) async { + const requiredDetailsForTreeNode = [ + 'description', + 'shouldIndent', + 'valueId', + 'widgetRuntimeType', + ]; + const possibleDetailsForTreeNode = [ + 'textPreview', + 'children', + 'createdByLocalProject', + ]; + const extraneousDetailsForTreeNode = [ + 'creationLocation', + 'type', + 'style', + 'hasChildren', + 'stateful', + ]; + + await _loadInspectorUI(tester); + final state = tester.state(find.byType(InspectorScreenBody)) + as InspectorScreenBodyState; + final rowsInTree = state.controller.inspectorTree.rowsInTree.value; + + for (final row in rowsInTree) { + final detailKeys = row?.node.diagnostic?.json.keys ?? const []; + expect( + requiredDetailsForTreeNode.every( + (detail) => detailKeys.contains(detail), + ), + isTrue, + ); + expect( + detailKeys.every( + (detail) => + requiredDetailsForTreeNode.contains(detail) || + possibleDetailsForTreeNode.contains(detail), + ), + isTrue, + ); + expect( + detailKeys + .none((detail) => extraneousDetailsForTreeNode.contains(detail)), + isTrue, + ); + } + }, + ); + group('widget errors', () { testWidgetsWithWindowSize( 'show navigator and error labels',