diff --git a/packages/cupertino_ui/temporarily_disabled_tests/tab_scaffold_test.dart b/packages/cupertino_ui/test/tab_scaffold_test.dart similarity index 99% rename from packages/cupertino_ui/temporarily_disabled_tests/tab_scaffold_test.dart rename to packages/cupertino_ui/test/tab_scaffold_test.dart index 132f5fb20bf0..f939a2059c51 100644 --- a/packages/cupertino_ui/temporarily_disabled_tests/tab_scaffold_test.dart +++ b/packages/cupertino_ui/test/tab_scaffold_test.dart @@ -2,16 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -@Skip( - 'This file is skipped due to a cross-import that needs to be fixed. Tracked in https://github.com/flutter/flutter/issues/177028.', -) import 'package:cupertino_ui/cupertino_ui.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; -import '../widgets/widget_inspector_test_utils.dart'; import 'navigator_utils.dart'; +import 'widget_inspector_test_utils.dart'; late List selectedTabs; diff --git a/packages/cupertino_ui/test/widget_inspector_test_utils.dart b/packages/cupertino_ui/test/widget_inspector_test_utils.dart new file mode 100644 index 000000000000..2a9db7f1c708 --- /dev/null +++ b/packages/cupertino_ui/test/widget_inspector_test_utils.dart @@ -0,0 +1,121 @@ +// Copyright 2013 The Flutter Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; + +import 'package:cupertino_ui/cupertino_ui.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_test/flutter_test.dart'; + +/// Tuple-like test class for storing a [stream] and [eventKind]. +/// +/// Used to store the [stream] and [eventKind] that a dispatched event would be +/// sent on. +@immutable +class DispatchedEventKey { + const DispatchedEventKey({required this.stream, required this.eventKind}); + + final String stream; + final String eventKind; + + @override + String toString() { + return '[DispatchedEventKey]($stream, $eventKind)'; + } + + @override + bool operator ==(Object other) { + return other is DispatchedEventKey && stream == other.stream && eventKind == other.eventKind; + } + + @override + int get hashCode => Object.hash(stream, eventKind); +} + +class TestWidgetInspectorService extends Object with WidgetInspectorService { + TestWidgetInspectorService() { + selection.addListener(() => selectionChangedCallback?.call()); + } + + final Map extensions = {}; + + final Map>> eventsDispatched = + >>{}; + + final List objectsInspected = []; + + @override + void registerServiceExtension({ + required String name, + required ServiceExtensionCallback callback, + required RegisterServiceExtensionCallback registerExtension, + }) { + assert(!extensions.containsKey(name)); + extensions[name] = callback; + } + + @override + void postEvent(String eventKind, Map eventData, {String stream = 'Extension'}) { + dispatchedEvents(eventKind, stream: stream).add(eventData); + } + + @override + void inspect(Object? object) { + objectsInspected.add(object); + } + + List> dispatchedEvents(String eventKind, {String stream = 'Extension'}) { + return eventsDispatched.putIfAbsent( + DispatchedEventKey(stream: stream, eventKind: eventKind), + () => >[], + ); + } + + List inspectedObjects() { + return objectsInspected; + } + + Iterable> getServiceExtensionStateChangedEvents(String extensionName) { + return dispatchedEvents( + 'Flutter.ServiceExtensionStateChanged', + ).where((Map event) => event['extension'] == extensionName); + } + + Future testExtension(String name, Map arguments) async { + expect(extensions, contains(name)); + // Encode and decode to JSON to match behavior using a real service + // extension where only JSON is allowed. + return (json.decode(json.encode(await extensions[name]!(arguments))) + as Map)['result']; + } + + Future testBoolExtension(String name, Map arguments) async { + expect(extensions, contains(name)); + // Encode and decode to JSON to match behavior using a real service + // extension where only JSON is allowed. + return (json.decode(json.encode(await extensions[name]!(arguments))) + as Map)['enabled'] + .toString(); + } + + int rebuildCount = 0; + + @override + Future forceRebuild() async { + rebuildCount++; + final WidgetsBinding binding = WidgetsBinding.instance; + + if (binding.rootElement != null) { + binding.buildOwner!.reassemble(binding.rootElement!); + } + } + + @override + void resetAllState() { + super.resetAllState(); + eventsDispatched.clear(); + objectsInspected.clear(); + rebuildCount = 0; + } +}