From 343dcf95fc3773e24082f316434a261d8e163a67 Mon Sep 17 00:00:00 2001 From: adsonpleal Date: Tue, 17 Dec 2024 17:29:16 -0300 Subject: [PATCH 1/3] Add shared preferences dev tool --- CODEOWNERS | 4 + .../shared_preferences/CHANGELOG.md | 4 + .../extension/devtools/.gitignore | 1 + .../extension/devtools/.pubignore | 1 + .../extension/devtools/config.yaml | 4 + .../lib/src/shared_preferences_async.dart | 9 + ...d_preferences_devtools_extension_data.dart | 138 + .../lib/src/shared_preferences_legacy.dart | 9 + .../shared_preferences/pubspec.yaml | 3 +- ...ferences_devtools_extension_data_test.dart | 452 +++ .../shared_preferences/tool/pre_publish.dart | 53 + .../shared_preferences_tool/LICENSE | 25 + .../shared_preferences_tool/README.md | 52 + .../shared_preferences_tool/lib/main.dart | 64 + .../lib/src/async_state.dart | 146 + .../lib/src/shared_preferences_state.dart | 270 ++ .../shared_preferences_state_notifier.dart | 161 + .../shared_preferences_state_provider.dart | 293 ++ .../lib/src/shared_preferences_tool_eval.dart | 169 + .../lib/src/ui/api_switch.dart | 49 + .../lib/src/ui/data_panel.dart | 404 ++ .../lib/src/ui/error_panel.dart | 34 + .../lib/src/ui/keys_panel.dart | 269 ++ .../lib/src/ui/shared_preferences_body.dart | 30 + .../shared_preferences_tool/pubspec.yaml | 24 + ...hared_preferences_state_notifier_test.dart | 246 ++ ...preferences_state_notifier_test.mocks.dart | 269 ++ .../src/shared_preferences_state_test.dart | 130 + .../shared_preferences_tool_eval_test.dart | 267 ++ ...ared_preferences_tool_eval_test.mocks.dart | 3305 +++++++++++++++++ .../test/src/ui/data_panel_test.dart | 390 ++ .../test/src/ui/error_panel_test.dart | 38 + .../test/src/ui/keys_panel_test.dart | 205 + .../src/ui/shared_preferences_body_test.dart | 46 + .../notifier_mocking_helpers.dart | 31 + .../notifier_mocking_helpers.mocks.dart | 186 + .../shared_preferences_tool/web/index.html | 58 + .../shared_preferences_tool/web/manifest.json | 11 + script/configs/allowed_unpinned_deps.yaml | 2 + 39 files changed, 7851 insertions(+), 1 deletion(-) create mode 100644 packages/shared_preferences/shared_preferences/extension/devtools/.gitignore create mode 100644 packages/shared_preferences/shared_preferences/extension/devtools/.pubignore create mode 100644 packages/shared_preferences/shared_preferences/extension/devtools/config.yaml create mode 100644 packages/shared_preferences/shared_preferences/lib/src/shared_preferences_devtools_extension_data.dart create mode 100644 packages/shared_preferences/shared_preferences/test/shared_preferences_devtools_extension_data_test.dart create mode 100644 packages/shared_preferences/shared_preferences/tool/pre_publish.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/LICENSE create mode 100644 packages/shared_preferences/shared_preferences_tool/README.md create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/main.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/async_state.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_notifier.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_provider.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_tool_eval.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/ui/api_switch.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/ui/data_panel.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/ui/error_panel.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/ui/keys_panel.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/lib/src/ui/shared_preferences_body.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/pubspec.yaml create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.mocks.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_test.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/ui/data_panel_test.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/ui/error_panel_test.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/ui/keys_panel_test.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/ui/shared_preferences_body_test.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.mocks.dart create mode 100644 packages/shared_preferences/shared_preferences_tool/web/index.html create mode 100644 packages/shared_preferences/shared_preferences_tool/web/manifest.json diff --git a/CODEOWNERS b/CODEOWNERS index 2b4ab355401..b46402a7a5e 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -124,3 +124,7 @@ packages/local_auth/local_auth_windows/** @cbracken packages/path_provider/path_provider_windows/** @cbracken packages/shared_preferences/shared_preferences_windows/** @cbracken packages/url_launcher/url_launcher_windows/** @cbracken + +# - DevTools extensions +# @adsonpleal is the actual maintainer of shared_preferences_tool but is not yet a committer, so can't be listed as the owner. +packages/shared_preferences/shared_preferences_tool/** @tarrinneal diff --git a/packages/shared_preferences/shared_preferences/CHANGELOG.md b/packages/shared_preferences/shared_preferences/CHANGELOG.md index 81708ac6532..b9518cf1686 100644 --- a/packages/shared_preferences/shared_preferences/CHANGELOG.md +++ b/packages/shared_preferences/shared_preferences/CHANGELOG.md @@ -1,3 +1,7 @@ +## 2.4.0 + +* Adds shared preferences devtools extension. + ## 2.3.3 * Clarifies scope of prefix handling in README. diff --git a/packages/shared_preferences/shared_preferences/extension/devtools/.gitignore b/packages/shared_preferences/shared_preferences/extension/devtools/.gitignore new file mode 100644 index 00000000000..378eac25d31 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/extension/devtools/.gitignore @@ -0,0 +1 @@ +build diff --git a/packages/shared_preferences/shared_preferences/extension/devtools/.pubignore b/packages/shared_preferences/shared_preferences/extension/devtools/.pubignore new file mode 100644 index 00000000000..71860a75dbf --- /dev/null +++ b/packages/shared_preferences/shared_preferences/extension/devtools/.pubignore @@ -0,0 +1 @@ +!build diff --git a/packages/shared_preferences/shared_preferences/extension/devtools/config.yaml b/packages/shared_preferences/shared_preferences/extension/devtools/config.yaml new file mode 100644 index 00000000000..34fb24e9876 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/extension/devtools/config.yaml @@ -0,0 +1,4 @@ +name: shared_preferences +issueTracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 +version: 1.0.0 +materialIconCodePoint: '0xe683' diff --git a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_async.dart b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_async.dart index 516788542fd..ee83433ca7a 100644 --- a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_async.dart +++ b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_async.dart @@ -8,6 +8,8 @@ import 'package:flutter/foundation.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; +import 'shared_preferences_devtools_extension_data.dart'; + /// Provides a persistent store for simple data. /// /// Data is persisted to and fetched from the disk asynchronously. @@ -401,3 +403,10 @@ class SharedPreferencesWithCache { return _cacheOptions.allowList?.contains(key) ?? true; } } + +// Include an unused import to ensure this library is included +// when running `flutter run -d chrome`. +// Check this discussion for more info: https://github.com/flutter/packages/pull/6749/files/6eb1b4fdce1eba107294770d581713658ff971e9#discussion_r1755375409 +// ignore: unused_element +final bool _fieldToKeepDevtoolsExtensionReachable = + fieldToKeepDevtoolsExtensionLibraryAlive; diff --git a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_devtools_extension_data.dart b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_devtools_extension_data.dart new file mode 100644 index 00000000000..2b762f112b6 --- /dev/null +++ b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_devtools_extension_data.dart @@ -0,0 +1,138 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:convert'; +import 'dart:developer' as developer; + +import 'package:flutter/foundation.dart'; + +import '../shared_preferences.dart'; + +const String _eventPrefix = 'shared_preferences.'; + +/// A typedef for the post event function. +@visibleForTesting +typedef PostEvent = void Function( + String eventKind, + Map eventData, +); + +/// A helper class that provides data to the DevTools extension. +/// +/// It is only visible for testing and eval. +@visibleForTesting +class SharedPreferencesDevToolsExtensionData { + /// The default constructor for [SharedPreferencesDevToolsExtensionData]. + /// + /// Accepts an optional [PostEvent] that should only be overwritten when testing. + const SharedPreferencesDevToolsExtensionData([ + this._postEvent = developer.postEvent, + ]); + + final PostEvent _postEvent; + + /// Requests all legacy and async keys and post an event with the result. + Future requestAllKeys() async { + final SharedPreferences legacyPrefs = await SharedPreferences.getInstance(); + final Set legacyKeys = legacyPrefs.getKeys(); + final Set asyncKeys = await SharedPreferencesAsync().getKeys(); + + _postEvent('${_eventPrefix}all_keys', >{ + 'asyncKeys': asyncKeys.toList(), + 'legacyKeys': legacyKeys.toList(), + }); + } + + /// Requests the value for a given key and posts an event with the result. + Future requestValue(String key, bool legacy) async { + final Object? value; + if (legacy) { + final SharedPreferences legacyPrefs = + await SharedPreferences.getInstance(); + value = legacyPrefs.get(key); + } else { + value = await SharedPreferencesAsync().getAll(allowList: { + key + }).then((Map map) => map.values.firstOrNull); + } + + _postEvent('${_eventPrefix}value', { + 'value': value, + // It is safe to use `runtimeType` here. This code + // will only ever run in debug mode. + 'kind': value.runtimeType.toString(), + }); + } + + /// Requests the value change for the given key and posts an empty event when finished. + Future requestValueChange( + String key, + String serializedValue, + String kind, + bool legacy, + ) async { + final Object? value = jsonDecode(serializedValue); + if (legacy) { + final SharedPreferences legacyPrefs = + await SharedPreferences.getInstance(); + // we need to check the kind because sometimes a double + // gets interpreted as an int. If this was not an issue + // we'd only need to do a simple pattern matching on value. + switch (kind) { + case 'int': + await legacyPrefs.setInt(key, value! as int); + case 'bool': + await legacyPrefs.setBool(key, value! as bool); + case 'double': + await legacyPrefs.setDouble(key, value! as double); + case 'String': + await legacyPrefs.setString(key, value! as String); + case 'List': + await legacyPrefs.setStringList( + key, + (value! as List).cast(), + ); + } + } else { + final SharedPreferencesAsync prefs = SharedPreferencesAsync(); + // we need to check the kind because sometimes a double + // gets interpreted as an int. If this was not an issue + // we'd only need to do a simple pattern matching on value. + switch (kind) { + case 'int': + await prefs.setInt(key, value! as int); + case 'bool': + await prefs.setBool(key, value! as bool); + case 'double': + await prefs.setDouble(key, value! as double); + case 'String': + await prefs.setString(key, value! as String); + case 'List': + await prefs.setStringList( + key, + (value! as List).cast(), + ); + } + } + _postEvent('${_eventPrefix}change_value', {}); + } + + /// Requests a key removal and posts an empty event when removed. + Future requestRemoveKey(String key, bool legacy) async { + if (legacy) { + final SharedPreferences legacyPrefs = + await SharedPreferences.getInstance(); + await legacyPrefs.remove(key); + } else { + await SharedPreferencesAsync().remove(key); + } + _postEvent('${_eventPrefix}remove', {}); + } +} + +/// Include a variable to keep the library alive in web builds. +/// It must be a `final` variable. +/// Check this discussion for more info: https://github.com/flutter/packages/pull/6749/files/6eb1b4fdce1eba107294770d581713658ff971e9#discussion_r1755375409 +// ignore: prefer_const_declarations +final bool fieldToKeepDevtoolsExtensionLibraryAlive = false; diff --git a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart index 72deffe5fe9..aa7dbbf31ca 100644 --- a/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart +++ b/packages/shared_preferences/shared_preferences/lib/src/shared_preferences_legacy.dart @@ -8,6 +8,8 @@ import 'package:flutter/foundation.dart' show visibleForTesting; import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart'; import 'package:shared_preferences_platform_interface/types.dart'; +import 'shared_preferences_devtools_extension_data.dart'; + /// Wraps NSUserDefaults (on iOS) and SharedPreferences (on Android), providing /// a persistent store for simple data. /// @@ -285,3 +287,10 @@ Either update the implementation to support setPrefix, or do not call setPrefix. _completer = null; } } + +// Include an unused import to ensure this library is included +// when running `flutter run -d chrome`. +// Check this discussion for more info: https://github.com/flutter/packages/pull/6749/files/6eb1b4fdce1eba107294770d581713658ff971e9#discussion_r1755375409 +// ignore: unused_element +final bool _fieldToKeepDevtoolsExtensionReachable = + fieldToKeepDevtoolsExtensionLibraryAlive; diff --git a/packages/shared_preferences/shared_preferences/pubspec.yaml b/packages/shared_preferences/shared_preferences/pubspec.yaml index 6c715ff7e3a..fa36ae4a15a 100644 --- a/packages/shared_preferences/shared_preferences/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences/pubspec.yaml @@ -3,7 +3,7 @@ description: Flutter plugin for reading and writing simple key-value pairs. Wraps NSUserDefaults on iOS and SharedPreferences on Android. repository: https://github.com/flutter/packages/tree/main/packages/shared_preferences/shared_preferences issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22 -version: 2.3.3 +version: 2.4.0 environment: sdk: ^3.4.0 @@ -40,6 +40,7 @@ dev_dependencies: sdk: flutter integration_test: sdk: flutter + path: ^1.9.0 topics: - persistence diff --git a/packages/shared_preferences/shared_preferences/test/shared_preferences_devtools_extension_data_test.dart b/packages/shared_preferences/shared_preferences/test/shared_preferences_devtools_extension_data_test.dart new file mode 100644 index 00000000000..9be78eda15d --- /dev/null +++ b/packages/shared_preferences/shared_preferences/test/shared_preferences_devtools_extension_data_test.dart @@ -0,0 +1,452 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// 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:flutter_test/flutter_test.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:shared_preferences/src/shared_preferences_devtools_extension_data.dart'; +import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; + +import 'shared_preferences_async_test.dart'; + +typedef _Event = (String eventKind, Map eventData); + +class _FakePostEvent { + final List<_Event> eventLog = <_Event>[]; + + void call( + String eventKind, + Map eventData, + ) { + eventLog.add((eventKind, eventData)); + } +} + +void main() { + group('DevtoolsExtension', () { + late SharedPreferencesAsync asyncPreferences; + late _FakePostEvent fakePostEvent; + late SharedPreferencesDevToolsExtensionData extension; + + setUp(() { + SharedPreferencesAsyncPlatform.instance = FakeSharedPreferencesAsync(); + asyncPreferences = SharedPreferencesAsync(); + fakePostEvent = _FakePostEvent(); + extension = SharedPreferencesDevToolsExtensionData(fakePostEvent.call); + }); + + test('should request all keys', () async { + SharedPreferences.setMockInitialValues({ + 'key1': 1, + 'key2': true, + }); + await asyncPreferences.setBool('key3', true); + await asyncPreferences.setInt('key4', 1); + + await extension.requestAllKeys(); + + expect(fakePostEvent.eventLog.length, equals(1)); + final ( + String eventKind, + Map eventData, + ) = fakePostEvent.eventLog.first; + expect( + eventKind, + equals('shared_preferences.all_keys'), + ); + expect( + eventData, + equals(>{ + 'asyncKeys': ['key3', 'key4'], + 'legacyKeys': ['key1', 'key2'], + }), + ); + }); + + group('async api', () { + Future testAsyncApiRequestValue( + String key, { + required Map expectedData, + }) async { + const bool legacy = false; + + await extension.requestValue( + key, + legacy, + ); + + expect(fakePostEvent.eventLog.length, equals(1)); + final ( + String eventKind, + Map eventData, + ) = fakePostEvent.eventLog.first; + expect( + eventKind, + equals('shared_preferences.value'), + ); + expect( + eventData, + equals(expectedData), + ); + } + + test('should request bool value from async api', () async { + const String key = 'key'; + const bool expectedValue = true; + await asyncPreferences.setBool(key, expectedValue); + + await testAsyncApiRequestValue( + key, + expectedData: { + 'value': expectedValue, + 'kind': 'bool', + }, + ); + }); + + test('should request int value from async api', () async { + const String key = 'key'; + const int expectedValue = 42; + await asyncPreferences.setInt(key, expectedValue); + + await testAsyncApiRequestValue( + key, + expectedData: { + 'value': expectedValue, + 'kind': 'int', + }, + ); + }); + + test('should request double value from async api', () async { + const String key = 'key'; + const double expectedValue = 42.2; + await asyncPreferences.setDouble(key, expectedValue); + + await testAsyncApiRequestValue( + key, + expectedData: { + 'value': expectedValue, + 'kind': 'double', + }, + ); + }); + + test('should request string value from async api', () async { + const String key = 'key'; + const String expectedValue = 'value'; + await asyncPreferences.setString(key, expectedValue); + + await testAsyncApiRequestValue( + key, + expectedData: { + 'value': expectedValue, + 'kind': 'String', + }, + ); + }); + + test('should request string list value from async api', () async { + const String key = 'key'; + const List expectedValue = ['string1', 'string2']; + await asyncPreferences.setStringList(key, expectedValue); + + await testAsyncApiRequestValue( + key, + expectedData: { + 'value': expectedValue, + 'kind': 'List', + }, + ); + }); + + Future testAsyncApiValueChange( + String key, + Object expectedValue, + ) async { + const bool legacy = false; + + await extension.requestValueChange( + key, + jsonEncode(expectedValue), + expectedValue.runtimeType.toString(), + legacy, + ); + + expect(fakePostEvent.eventLog.length, equals(1)); + final ( + String eventKind, + Map eventData, + ) = fakePostEvent.eventLog.first; + expect( + eventKind, + equals('shared_preferences.change_value'), + ); + expect( + eventData, + equals({}), + ); + } + + test('should request int value change on async api', () async { + const String key = 'key'; + const int expectedValue = 42; + await asyncPreferences.setInt(key, 24); + + await testAsyncApiValueChange(key, expectedValue); + + expect( + await asyncPreferences.getInt(key), + equals(expectedValue), + ); + }); + + test('should request bool value change on async api', () async { + const String key = 'key'; + const bool expectedValue = false; + await asyncPreferences.setBool(key, true); + + await testAsyncApiValueChange(key, expectedValue); + + expect( + await asyncPreferences.getBool(key), + equals(expectedValue), + ); + }); + + test('should request double value change on async api', () async { + const String key = 'key'; + const double expectedValue = 22.22; + await asyncPreferences.setDouble(key, 11.1); + + await testAsyncApiValueChange(key, expectedValue); + + expect( + await asyncPreferences.getDouble(key), + equals(expectedValue), + ); + }); + + test('should request string value change on async api', () async { + const String key = 'key'; + const String expectedValue = 'new value'; + await asyncPreferences.setString(key, 'old value'); + + await testAsyncApiValueChange(key, expectedValue); + + expect( + await asyncPreferences.getString(key), + equals(expectedValue), + ); + }); + + test('should request string list value change on async api', () async { + const String key = 'key'; + const List expectedValue = ['string1', 'string2']; + await asyncPreferences.setStringList(key, ['old1', 'old2']); + + await testAsyncApiValueChange(key, expectedValue); + + expect( + await asyncPreferences.getStringList(key), + equals(expectedValue), + ); + }); + }); + + group('legacy api', () { + Future testLegacyApiRequestValue( + String key, { + required Map expectedData, + }) async { + const bool legacy = true; + + await extension.requestValue( + key, + legacy, + ); + + expect(fakePostEvent.eventLog.length, equals(1)); + final ( + String eventKind, + Map eventData, + ) = fakePostEvent.eventLog.first; + expect( + eventKind, + equals('shared_preferences.value'), + ); + expect(eventData, equals(expectedData)); + } + + test('should request bool value from legacy api', () async { + const String key = 'key'; + const bool expectedValue = false; + SharedPreferences.setMockInitialValues({ + key: expectedValue, + }); + + await testLegacyApiRequestValue(key, expectedData: { + 'value': expectedValue, + 'kind': 'bool', + }); + }); + + test('should request int value from legacy api', () async { + const String key = 'key'; + const int expectedValue = 42; + SharedPreferences.setMockInitialValues({ + key: expectedValue, + }); + + await testLegacyApiRequestValue(key, expectedData: { + 'value': expectedValue, + 'kind': 'int', + }); + }); + + test('should request double value from legacy api', () async { + const String key = 'key'; + const double expectedValue = 42.2; + SharedPreferences.setMockInitialValues({ + key: expectedValue, + }); + + await testLegacyApiRequestValue(key, expectedData: { + 'value': expectedValue, + 'kind': 'double', + }); + }); + + test('should request string value from legacy api', () async { + const String key = 'key'; + const String expectedValue = 'value'; + SharedPreferences.setMockInitialValues({ + key: expectedValue, + }); + + await testLegacyApiRequestValue(key, expectedData: { + 'value': expectedValue, + 'kind': 'String', + }); + }); + + test('should request string list value from legacy api', () async { + const String key = 'key'; + const List expectedValue = ['string1', 'string2']; + SharedPreferences.setMockInitialValues({ + key: expectedValue, + }); + + await testLegacyApiRequestValue(key, expectedData: { + 'value': expectedValue, + 'kind': 'List', + }); + }); + + Future testLegacyApiValueChange( + String key, + Object expectedValue, + ) async { + const bool legacy = true; + + await extension.requestValueChange( + key, + jsonEncode(expectedValue), + expectedValue.runtimeType.toString(), + legacy, + ); + + expect(fakePostEvent.eventLog.length, equals(1)); + final ( + String eventKind, + Map eventData, + ) = fakePostEvent.eventLog.first; + expect( + eventKind, + equals('shared_preferences.change_value'), + ); + expect( + eventData, + equals({}), + ); + } + + test('should request int value change on legacy api', () async { + const String key = 'key'; + const int expectedValue = 42; + SharedPreferences.setMockInitialValues({ + key: 24, + }); + + await testLegacyApiValueChange(key, expectedValue); + + expect( + (await SharedPreferences.getInstance()).getInt(key), + equals(expectedValue), + ); + }); + + test('should request bool value change on legacy api', () async { + const String key = 'key'; + const bool expectedValue = false; + SharedPreferences.setMockInitialValues({ + key: true, + }); + + await testLegacyApiValueChange(key, expectedValue); + + expect( + (await SharedPreferences.getInstance()).getBool(key), + equals(expectedValue), + ); + }); + + test('should request double value change on legacy api', () async { + const String key = 'key'; + const double expectedValue = 1.11; + SharedPreferences.setMockInitialValues({ + key: 2.22, + }); + + await testLegacyApiValueChange(key, expectedValue); + + expect( + (await SharedPreferences.getInstance()).getDouble(key), + equals(expectedValue), + ); + }); + + test('should request string value change on legacy api', () async { + const String key = 'key'; + const String expectedValue = 'new value'; + SharedPreferences.setMockInitialValues({ + key: 'old value', + }); + + await testLegacyApiValueChange(key, expectedValue); + + expect( + (await SharedPreferences.getInstance()).getString(key), + equals(expectedValue), + ); + }); + + test('should request string list value change on legacy api', () async { + const String key = 'key'; + const List expectedValue = ['string1', 'string2']; + SharedPreferences.setMockInitialValues({ + key: ['old1', 'old2'], + }); + + await testLegacyApiValueChange(key, expectedValue); + + expect( + (await SharedPreferences.getInstance()).getStringList(key), + equals(expectedValue), + ); + }); + }); + }); +} diff --git a/packages/shared_preferences/shared_preferences/tool/pre_publish.dart b/packages/shared_preferences/shared_preferences/tool/pre_publish.dart new file mode 100644 index 00000000000..0b423ffca5c --- /dev/null +++ b/packages/shared_preferences/shared_preferences/tool/pre_publish.dart @@ -0,0 +1,53 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:io'; + +import 'package:path/path.dart' as p; + +Future _runCommand({ + required String message, + required String executable, + required List arguments, +}) async { + stdout.write(message); + // The `packages/shared_preferences` directory. + final Directory sharedPreferencesToolParent = Directory( + p.dirname(Platform.script.path), + ).parent.parent; + + final ProcessResult pubGetResult = await Process.run( + executable, + arguments, + workingDirectory: p.join( + sharedPreferencesToolParent.path, + 'shared_preferences_tool', + ), + ); + + stdout.write(pubGetResult.stdout); + + if (pubGetResult.stderr != null) { + stderr.write(pubGetResult.stderr); + } +} + +Future main() async { + await _runCommand( + message: "Running 'flutter pub get' in shared_preferences_tool\n", + executable: 'flutter', + arguments: ['pub', 'get'], + ); + await _runCommand( + message: "Running 'build_and_copy' in shared_preferences_tool\n", + executable: 'dart', + arguments: [ + 'run', + 'devtools_extensions', + 'build_and_copy', + '--source=.', + '--dest=../shared_preferences/extension/devtools', + ], + ); +} diff --git a/packages/shared_preferences/shared_preferences_tool/LICENSE b/packages/shared_preferences/shared_preferences_tool/LICENSE new file mode 100644 index 00000000000..c6823b81eb8 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/shared_preferences/shared_preferences_tool/README.md b/packages/shared_preferences/shared_preferences_tool/README.md new file mode 100644 index 00000000000..844f822e3bc --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/README.md @@ -0,0 +1,52 @@ +A [DevTools extension](https://pub.dev/packages/devtools_extensions) for Flutter's [shared_preferences](https://pub.dev/packages/shared_preferences) package. + +## Features + +This package contains the source code for the `package:shared_preferences` DevTools extension. With this tool, you can: + +- List all keys stored in your app's `SharedPreferences`. +- Search for specific keys. +- Edit or remove values directly, with changes reflected in your app instantly. + +It supports all data types available in `SharedPreferences`: + +- `String` +- `int` +- `double` +- `bool` +- `List` + +## Running this project locally + +1. Run the [example](../shared_preferences/example/) project in the `shared_preferences` package and copy its debug service URL. +2. Run the `shared_preferences_tool` project by running the following command: + +```shell +flutter run -d chrome --dart-define=use_simulated_environment=true +``` + +For more information, see the [devtools_extensions](https://pub.dev/packages/devtools_extensions) package documentation. + +## Publishing this DevTools extension + +The Flutter web app in this package is built and distributed as part of. +`package:shared_preferences`. If there are changes to this tool that are +ready to publish as part of `shared_preferences`, then the publish +workflow for `shared_preferences` should follow these steps prior to publishing. + +1. Build the DevTools extension and move the assets to `shared_preferences`. + + ```sh + cd shared_preferences_tool; + flutter pub get; + dart run devtools_extensions build_and_copy --source=. --dest=../shared_preferences/extension/devtools + ``` + +2. Validate that `shared_preferences` is properly configured to distribute this extension. + + ```sh + cd shared_preferences_tool; + dart run devtools_extensions validate --package=../shared_preferences + ``` + +3. Publish `shared_preferences` as normal. diff --git a/packages/shared_preferences/shared_preferences_tool/lib/main.dart b/packages/shared_preferences/shared_preferences_tool/lib/main.dart new file mode 100644 index 00000000000..6b3eb3bad22 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/main.dart @@ -0,0 +1,64 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/service.dart'; +import 'package:devtools_extensions/devtools_extensions.dart'; +import 'package:flutter/material.dart'; + +import 'src/shared_preferences_state_provider.dart'; +import 'src/ui/shared_preferences_body.dart'; + +void main() { + runApp(const _SharedPreferencesTool()); +} + +class _SharedPreferencesTool extends StatelessWidget { + const _SharedPreferencesTool(); + + @override + Widget build(BuildContext context) { + return const DevToolsExtension( + child: _ConnectionManager(), + ); + } +} + +class _ConnectionManager extends StatefulWidget { + const _ConnectionManager(); + + @override + State<_ConnectionManager> createState() => _ConnectionManagerState(); +} + +class _ConnectionManagerState extends State<_ConnectionManager> { + @override + void initState() { + super.initState(); + // Used to move the application back to the loading state on the simulated + // environment when the developer disconnects the app. + serviceManager.registerLifecycleCallback( + ServiceManagerLifecycle.afterCloseVmService, + (_) { + setState(() {}); + }, + ); + } + + @override + Widget build(BuildContext context) { + return FutureBuilder( + future: serviceManager.onServiceAvailable, + builder: (BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + return const SharedPreferencesStateProvider( + child: SharedPreferencesBody(), + ); + }); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/async_state.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/async_state.dart new file mode 100644 index 00000000000..0d103e65049 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/async_state.dart @@ -0,0 +1,146 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter/foundation.dart'; + +@immutable + +/// A class that represents the state of an asynchronous operation. +/// +/// It has three possible states: +/// +/// 1. [AsyncState.loading] - The operation is in progress. +/// 2. [AsyncState.data] - The operation has completed successfully with data. +/// 3. [AsyncState.error] - The operation has completed with an error. +/// +/// Since this is a sealed class we can check the state in a switch statement/expression. +/// Check the [Switch statements](https://dart.dev/language/branches#switch-statements) documentation. +sealed class AsyncState { + const AsyncState(); + + const factory AsyncState.loading() = AsyncStateLoading._; + + const factory AsyncState.data(T data) = AsyncStateData._; + + const factory AsyncState.error(Object error, StackTrace? stackTrace) = + AsyncStateError._; + + /// Returns a [AsyncState] with the same type `T` but with the data transformed by the `onData` function. + /// If the current state is not [AsyncStateData], it returns the current state. + AsyncState whenData( + T Function(T data) onData, + ) { + return switch (this) { + AsyncStateData(data: final T data) => AsyncState.data(onData(data)), + _ => this, + }; + } + + /// Returns a [AsyncState] with the value R transformed by the `onData` + /// function. + /// + /// If the current state is [AsyncStateLoading] or [AsyncStateError], it + /// returns the current state, but with the type mapped. + /// If the current state is [AsyncStateData], it returns a new data state with + /// the data transformed by the `onData` function. + AsyncState mapWhenData( + R Function(T data) onData, + ) { + return flatMapWhenData((T data) => AsyncState.data(onData(data))); + } + + /// Transforms the data within an [AsyncState] into another [AsyncState] of a + /// different type using the `onData` function. + /// + /// If the current state is [AsyncStateLoading] or [AsyncStateError], it + /// returns the current state, but with the type mapped. + /// If the current state is [AsyncStateData], it returns the result of the + /// `onData` function. + AsyncState flatMapWhenData( + AsyncState Function(T data) onData, + ) { + return switch (this) { + AsyncStateData(data: final T data) => onData(data), + AsyncStateError( + error: final Object error, + stackTrace: final StackTrace? stackTrace, + ) => + AsyncState.error(error, stackTrace), + AsyncState() => AsyncState.loading(), + }; + } + + /// Returns the data `T` if the current state is [AsyncStateData], otherwise returns `null`. + T? get dataOrNull { + return switch (this) { + AsyncStateData(data: final T data) => data, + _ => null, + }; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + switch (this) { + AsyncStateLoading() => other is AsyncStateLoading, + AsyncStateData(data: final T data) => + other is AsyncStateData && other.data == data, + AsyncStateError( + error: final Object error, + stackTrace: final StackTrace? stackTrace, + ) => + other is AsyncStateError && + other.error == error && + other.stackTrace == stackTrace, + }; + } + + @override + int get hashCode => switch (this) { + AsyncStateLoading() => 0, + AsyncStateData(data: final T data) => data.hashCode, + AsyncStateError( + error: final Object error, + stackTrace: final StackTrace? stackTrace, + ) => + error.hashCode ^ stackTrace.hashCode, + }; + + @override + String toString() { + return switch (this) { + AsyncStateLoading() => 'AsyncState.loading()', + AsyncStateData(data: final T data) => 'AsyncState.data($data)', + AsyncStateError( + error: final Object error, + stackTrace: final StackTrace? stackTrace, + ) => + 'AsyncState.error($error, $stackTrace)', + }; + } +} + +/// A class that represents the state of an asynchronous operation that is in progress. +class AsyncStateLoading extends AsyncState { + const AsyncStateLoading._(); +} + +/// A class that represents the state of an asynchronous operation that has completed successfully with data. +class AsyncStateData extends AsyncState { + const AsyncStateData._(this.data); + + /// The data of the operation. + final T data; +} + +/// A class that represents the state of an asynchronous operation that has completed with an error. +class AsyncStateError extends AsyncState { + const AsyncStateError._(this.error, this.stackTrace); + + /// The error of the operation. + final Object error; + + /// The stack trace of the error. + final StackTrace? stackTrace; +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state.dart new file mode 100644 index 00000000000..26b2d52e86b --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state.dart @@ -0,0 +1,270 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// 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:flutter/foundation.dart'; + +import 'async_state.dart'; + +const Object _undefined = Object(); + +@immutable + +/// A class that represents the state of the shared preferences tool. +class SharedPreferencesState { + /// Default constructor for [SharedPreferencesState]. + const SharedPreferencesState({ + this.allKeys = const AsyncState>.loading(), + this.selectedKey, + this.editing = false, + this.legacyApi = false, + }); + + /// A list of all keys in the shared preferences of the target debug session using the selected API. + final AsyncState> allKeys; + + /// The user selected key and its value in the shared preferences + /// of the target debug session. + final SelectedSharedPreferencesKey? selectedKey; + + /// Whether the user is editing the value of the selected key or not. + final bool editing; + + /// Whether the user has selected the legacy api or not. + final bool legacyApi; + + /// Creates a copy of this [SharedPreferencesState] but replacing the given + /// fields with the new values. + SharedPreferencesState Function({ + AsyncState> allKeys, + SelectedSharedPreferencesKey? selectedKey, + bool editing, + bool legacyApi, + }) get copyWith => ({ + Object allKeys = _undefined, + Object? selectedKey = _undefined, + Object editing = _undefined, + Object legacyApi = _undefined, + }) { + return SharedPreferencesState( + allKeys: allKeys == _undefined + ? this.allKeys + : allKeys as AsyncState>, + selectedKey: selectedKey == _undefined + ? this.selectedKey + : selectedKey as SelectedSharedPreferencesKey?, + editing: editing == _undefined ? this.editing : editing as bool, + legacyApi: + legacyApi == _undefined ? this.legacyApi : legacyApi as bool, + ); + }; + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other is SharedPreferencesState && + other.allKeys == allKeys && + other.selectedKey == selectedKey && + other.editing == editing && + other.legacyApi == legacyApi); + } + + @override + int get hashCode => Object.hash( + allKeys, + selectedKey, + editing, + legacyApi, + ); + + @override + String toString() { + return 'SharedPreferencesState(allKeys: $allKeys, selectedKey: $selectedKey, editing: $editing)'; + } +} + +@immutable + +/// A class that represents the selected key and its value in the shared +/// preferences of the target debug session. +class SelectedSharedPreferencesKey { + /// Default constructor for [SelectedSharedPreferencesKey]. + const SelectedSharedPreferencesKey({ + required this.key, + required this.value, + }); + + /// The user selected key. + final String key; + + /// The value of the selected key in the shared preferences of the target + /// debug session. + final AsyncState value; + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other is SelectedSharedPreferencesKey && + other.key == key && + other.value == value); + } + + @override + int get hashCode => key.hashCode ^ value.hashCode; + + @override + String toString() { + return 'SelectedSharedPreferencesKey(key: $key, value: $value)'; + } +} + +abstract interface class _SharedPreferencesData { + T get value; +} + +@immutable + +/// A class that represents the data of a shared preference in the target +/// debug session. +sealed class SharedPreferencesData implements _SharedPreferencesData { + const SharedPreferencesData(); + + const factory SharedPreferencesData.string({ + required String value, + }) = SharedPreferencesDataString._; + + const factory SharedPreferencesData.int({ + required int value, + }) = SharedPreferencesDataInt._; + + const factory SharedPreferencesData.double({ + required double value, + }) = SharedPreferencesDataDouble._; + + const factory SharedPreferencesData.bool({ + required bool value, + }) = SharedPreferencesDataBool._; + + const factory SharedPreferencesData.stringList({ + required List value, + }) = SharedPreferencesDataStringList._; + + /// The string representation of the value. + String get valueAsString { + return switch (this) { + final SharedPreferencesDataStringList data => '\n${[ + for (final (int index, String str) in data.value.indexed) + '$index -> $str', + ].join('\n')}', + _ => '$value', + }; + } + + /// The kind of the value as a String. + String get kind { + return switch (this) { + SharedPreferencesDataString() => 'String', + SharedPreferencesDataInt() => 'int', + SharedPreferencesDataDouble() => 'double', + SharedPreferencesDataBool() => 'bool', + SharedPreferencesDataStringList() => 'List', + }; + } + + /// Changes the value of the shared preference to the new value. + /// + /// This is just a in memory change and does not affect the actual shared + /// preference value. + SharedPreferencesData changeValue(String newValue) { + return switch (this) { + SharedPreferencesDataString() => + SharedPreferencesData.string(value: newValue), + SharedPreferencesDataInt() => + SharedPreferencesData.int(value: int.parse(newValue)), + SharedPreferencesDataDouble() => + SharedPreferencesData.double(value: double.parse(newValue)), + SharedPreferencesDataBool() => + SharedPreferencesData.bool(value: bool.parse(newValue)), + SharedPreferencesDataStringList() => SharedPreferencesData.stringList( + value: (jsonDecode(newValue) as List).cast(), + ), + }; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other is SharedPreferencesData && + switch (this) { + final SharedPreferencesDataStringList data => + other is SharedPreferencesDataStringList && + listEquals(other.value, data.value), + _ => other.value == value, + }); + } + + @override + int get hashCode => value.hashCode; + + @override + String toString() { + return 'SharedPreferencesData($valueAsString)'; + } +} + +/// A class that represents a shared preference with a string value. +class SharedPreferencesDataString extends SharedPreferencesData { + const SharedPreferencesDataString._({ + required this.value, + }); + + /// The string value of the shared preference. + @override + final String value; +} + +/// A class that represents a shared preference with an integer value. +class SharedPreferencesDataInt extends SharedPreferencesData { + const SharedPreferencesDataInt._({ + required this.value, + }); + + /// The integer value of the shared preference. + @override + final int value; +} + +/// A class that represents a shared preference with a double value. +class SharedPreferencesDataDouble extends SharedPreferencesData { + const SharedPreferencesDataDouble._({ + required this.value, + }); + + /// The double value of the shared preference. + @override + final double value; +} + +/// A class that represents a shared preference with a boolean value. +class SharedPreferencesDataBool extends SharedPreferencesData { + const SharedPreferencesDataBool._({ + required this.value, + }); + + /// The boolean value of the shared preference. + @override + final bool value; +} + +/// A class that represents a shared preference with a list of string values. +class SharedPreferencesDataStringList extends SharedPreferencesData { + const SharedPreferencesDataStringList._({ + required this.value, + }); + + /// The list of string values of the shared preference. + @override + final List value; +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_notifier.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_notifier.dart new file mode 100644 index 00000000000..a2607ee1750 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_notifier.dart @@ -0,0 +1,161 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/utils.dart'; +import 'package:flutter/material.dart'; + +import 'async_state.dart'; +import 'shared_preferences_state.dart'; +import 'shared_preferences_tool_eval.dart'; + +/// A [ValueNotifier] that manages the state of the shared preferences tool. +class SharedPreferencesStateNotifier + extends ValueNotifier { + /// Default constructor that takes an instance of [SharedPreferencesToolEval]. + /// + /// You don't need to call this constructor directly. Use [SharedPreferencesStateNotifierProvider] instead. + SharedPreferencesStateNotifier( + this._eval, + ) : super(const SharedPreferencesState()); + + final SharedPreferencesToolEval _eval; + + List _asyncKeys = const []; + List _legacyKeys = const []; + + bool get _legacyApi => value.legacyApi; + + List get _keysForSelectedApi => _legacyApi ? _legacyKeys : _asyncKeys; + + /// Retrieves all keys from the shared preferences of the target debug session. + /// + /// If this is called when data already exists, it will update the list of keys. + Future fetchAllKeys() async { + value = value.copyWith( + selectedKey: null, + allKeys: const AsyncState>.loading(), + ); + + try { + final KeysResult allKeys = await _eval.fetchAllKeys(); + _legacyKeys = allKeys.legacyKeys; + // Platforms other than Android also add the legacy keys to the async keys + // in the pattern `flutter.$key`, so we need to remove them to avoid duplicates. + const String legacyPrefix = 'flutter.'; + _asyncKeys = [ + for (final String key in allKeys.asyncKeys) + if (!(key.startsWith(legacyPrefix) && + _legacyKeys.contains(key.replaceAll(legacyPrefix, '')))) + key, + ]; + + value = value.copyWith( + allKeys: AsyncState>.data(_keysForSelectedApi), + ); + } catch (error, stackTrace) { + value = value.copyWith( + allKeys: AsyncState>.error(error, stackTrace), + ); + } + } + + /// Set the key as selected and retrieve the value from the shared preferences of the target debug session. + Future selectKey(String key) async { + stopEditing(); + + value = value.copyWith( + selectedKey: SelectedSharedPreferencesKey( + key: key, + value: const AsyncState.loading(), + ), + ); + + try { + final SharedPreferencesData keyValue = + await _eval.fetchValue(key, _legacyApi); + value = value.copyWith( + selectedKey: SelectedSharedPreferencesKey( + key: key, + value: AsyncState.data(keyValue), + ), + ); + } catch (error, stackTrace) { + value = value.copyWith( + selectedKey: SelectedSharedPreferencesKey( + key: key, + value: AsyncState.error( + error, + stackTrace, + ), + ), + ); + } + } + + /// Filters the keys based on the provided token. + /// + /// This function uses [caseInsensitiveFuzzyMatch] to filter the keys. + void filter(String token) { + value = value.copyWith( + allKeys: AsyncState>.data( + _keysForSelectedApi.where((String key) { + return key.caseInsensitiveFuzzyMatch(token); + }).toList(), + ), + ); + } + + /// Changes the value of the selected key in the shared preferences of the target debug session. + Future changeValue( + SharedPreferencesData newValue, + ) async { + if (value.selectedKey case final SelectedSharedPreferencesKey selectedKey) { + value = value.copyWith( + selectedKey: SelectedSharedPreferencesKey( + key: selectedKey.key, + value: const AsyncState.loading(), + ), + ); + await _eval.changeValue(selectedKey.key, newValue, _legacyApi); + await selectKey(selectedKey.key); + stopEditing(); + } + } + + /// Deletes the selected key from the shared preferences of the target debug session. + Future deleteSelectedKey() async { + if (value.selectedKey case final SelectedSharedPreferencesKey selectedKey) { + value = value.copyWith( + allKeys: const AsyncState>.loading(), + selectedKey: SelectedSharedPreferencesKey( + key: selectedKey.key, + value: const AsyncState.loading(), + ), + ); + await _eval.deleteKey(selectedKey.key, _legacyApi); + await fetchAllKeys(); + stopEditing(); + } + } + + /// Change the editing state to true, allowing the user to edit the value of the selected key. + void startEditing() { + value = value.copyWith(editing: true); + } + + /// Change the editing state to false, preventing the user from editing the value of the selected key. + void stopEditing() { + value = value.copyWith(editing: false); + } + + /// Change the API used to fetch the shared preferences of the target debug session. + void selectApi({required bool legacyApi}) { + value = value.copyWith( + legacyApi: legacyApi, + allKeys: AsyncState>.data( + legacyApi ? _legacyKeys : _asyncKeys, + ), + ); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_provider.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_provider.dart new file mode 100644 index 00000000000..e24840608b8 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_state_provider.dart @@ -0,0 +1,293 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/service.dart'; +import 'package:devtools_extensions/devtools_extensions.dart'; +import 'package:flutter/widgets.dart'; +import 'package:vm_service/vm_service.dart'; + +import 'async_state.dart'; +import 'shared_preferences_state.dart'; +import 'shared_preferences_state_notifier.dart'; +import 'shared_preferences_tool_eval.dart'; + +/// A class that provides a [SharedPreferencesStateNotifier] to its descendants +/// without listening to state changes. +/// +/// Check [SharedPreferencesStateProviderExtension] for more info. +class _StateInheritedWidget extends InheritedWidget { + /// Default constructor for [_StateInheritedWidget]. + const _StateInheritedWidget({ + required super.child, + required this.notifier, + }); + + final SharedPreferencesStateNotifier notifier; + + @override + bool updateShouldNotify(covariant _StateInheritedWidget oldWidget) { + return oldWidget.notifier != notifier; + } +} + +enum _StateInheritedModelAspect { + keysList, + selectedKey, + selectedKeyData, + editing, + legacyApi, +} + +/// An inherited model that provides a [SharedPreferencesState] to its descendants. +/// +/// Notifies the descendants depending on the aspect of the state that changed. +/// This is meant to prevent unnecessary rebuilds. +/// For more info check [InheritedModel] and [MediaQuery]. +class _SharedPreferencesStateInheritedModel + extends InheritedModel<_StateInheritedModelAspect> { + const _SharedPreferencesStateInheritedModel({ + required super.child, + required this.state, + }); + + final SharedPreferencesState state; + + @override + bool updateShouldNotify( + covariant _SharedPreferencesStateInheritedModel oldWidget, + ) { + return oldWidget.state != state; + } + + @override + bool updateShouldNotifyDependent( + covariant _SharedPreferencesStateInheritedModel oldWidget, + Set<_StateInheritedModelAspect> dependencies, + ) { + return dependencies.any( + (_StateInheritedModelAspect aspect) => switch (aspect) { + _StateInheritedModelAspect.keysList => + state.allKeys != oldWidget.state.allKeys, + _StateInheritedModelAspect.selectedKey => + state.selectedKey != oldWidget.state.selectedKey, + _StateInheritedModelAspect.selectedKeyData => + state.selectedKey?.value != oldWidget.state.selectedKey?.value, + _StateInheritedModelAspect.editing => + state.editing != oldWidget.state.editing, + _StateInheritedModelAspect.legacyApi => + state.legacyApi != oldWidget.state.legacyApi, + }, + ); + } +} + +@visibleForTesting + +/// A class that provides a [SharedPreferencesStateNotifier] to its descendants. +/// +/// Only used for testing. You can override the notifier with a mock when testing. +class InnerSharedPreferencesStateProvider extends StatelessWidget { + /// Default constructor for [InnerSharedPreferencesStateProvider]. + const InnerSharedPreferencesStateProvider({ + super.key, + required this.notifier, + required this.child, + }); + + /// The [SharedPreferencesStateNotifier] to provide. + final SharedPreferencesStateNotifier notifier; + + /// The required child widget. + final Widget child; + + @override + Widget build(BuildContext context) { + return _StateInheritedWidget( + notifier: notifier, + child: ValueListenableBuilder( + valueListenable: notifier, + builder: ( + BuildContext context, + SharedPreferencesState value, + _, + ) { + return _SharedPreferencesStateInheritedModel( + state: value, + child: child, + ); + }, + ), + ); + } +} + +/// A provider that creates a [SharedPreferencesStateNotifier] and provides it to its descendants. +class SharedPreferencesStateProvider extends StatefulWidget { + /// Default constructor for [SharedPreferencesStateProvider]. + const SharedPreferencesStateProvider({ + super.key, + required this.child, + }); + + /// Returns the async state of the list of all keys. + /// [_SharedPreferencesStateInheritedModel] ancestor. + /// + /// Use of this method will cause the given [context] to rebuild whenever the + /// list of keys changes, including loading and error states. + /// This will not cause a rebuild when any other part of the state changes. + static AsyncState> keysListStateOf(BuildContext context) { + return context + .dependOnInheritedWidgetOfExactType< + _SharedPreferencesStateInheritedModel>( + aspect: _StateInheritedModelAspect.keysList, + )! + .state + .allKeys; + } + + /// Returns the selected key from the closest + /// [_SharedPreferencesStateInheritedModel] ancestor. + /// + /// Use of this method will cause the given [context] to rebuild whenever the + /// selected key changes, including loading and error states. + /// This will not cause a rebuild when any other part of the state changes. + static SelectedSharedPreferencesKey? selectedKeyOf(BuildContext context) { + return context + .dependOnInheritedWidgetOfExactType< + _SharedPreferencesStateInheritedModel>( + aspect: _StateInheritedModelAspect.selectedKey, + )! + .state + .selectedKey; + } + + /// Returns the selected key from the closest + /// [_SharedPreferencesStateInheritedModel] ancestor. + /// + /// Throws an error if the selected key is null. + static SelectedSharedPreferencesKey requireSelectedKeyOf( + BuildContext context) { + return selectedKeyOf(context)!; + } + + /// Returns the async state of the selected key data from the closest + /// [_SharedPreferencesStateInheritedModel] ancestor. + /// Use of this method will cause the given [context] to rebuild whenever the + /// selected key data changes, including loading and error states. + /// This will not cause a rebuild when any other part of the state changes. + static AsyncState? selectedKeyDataOf( + BuildContext context, + ) { + return context + .dependOnInheritedWidgetOfExactType< + _SharedPreferencesStateInheritedModel>( + aspect: _StateInheritedModelAspect.selectedKeyData, + )! + .state + .selectedKey + ?.value; + } + + /// Returns whether the selected key is being edited from the closest + /// _SharedPreferencesStateInheritedModel ancestor. + /// Use of this method will cause the given [context] to rebuild whenever the + /// editing state changes, including loading and error states. + /// This will not cause a rebuild when any other part of the state changes. + static bool editingOf(BuildContext context) { + return context + .dependOnInheritedWidgetOfExactType< + _SharedPreferencesStateInheritedModel>( + aspect: _StateInheritedModelAspect.editing, + )! + .state + .editing; + } + + /// Returns whether the legacy api is selected or not from the closest + /// _SharedPreferencesStateInheritedModel ancestor. + /// Use of this method will cause the given [context] to rebuild whenever the + /// editing state changes, including loading and error states. + /// This will not cause a rebuild when any other part of the state changes. + static bool legacyApiOf(BuildContext context) { + return context + .dependOnInheritedWidgetOfExactType< + _SharedPreferencesStateInheritedModel>( + aspect: _StateInheritedModelAspect.legacyApi, + )! + .state + .legacyApi; + } + + /// The required child widget. + final Widget child; + + @override + State createState() => + _SharedPreferencesStateProviderState(); +} + +class _SharedPreferencesStateProviderState + extends State { + late final SharedPreferencesStateNotifier _notifier; + + @override + void initState() { + super.initState(); + final VmService service = serviceManager.service!; + final EvalOnDartLibrary extensionEval = EvalOnDartLibrary( + 'package:shared_preferences/src/shared_preferences_devtools_extension_data.dart', + service, + serviceManager: serviceManager, + ); + final SharedPreferencesToolEval toolEval = SharedPreferencesToolEval( + service, + extensionEval, + ); + _notifier = SharedPreferencesStateNotifier(toolEval); + _notifier.fetchAllKeys(); + } + + @override + void dispose() { + _notifier.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return InnerSharedPreferencesStateProvider( + notifier: _notifier, + child: widget.child, + ); + } +} + +/// An extension that provides a [SharedPreferencesStateNotifier] to its +/// descendants. +extension SharedPreferencesStateProviderExtension on BuildContext { + /// Returns the [SharedPreferencesStateNotifier] from the closest + /// [StateInheritedNotifier] ancestor. + /// + /// This will not introduce a dependency. So changes to the notifier's value + /// will not trigger a rebuild. + /// + /// This is useful for calling methods on the notifier whenever there is a + /// user interaction, this way we can depend on specific parts of the state, + /// without the need to rebuild the whole widget tree whenever there is a + /// change. + /// + /// Example: + /// + /// ```dart + /// Widget build(BuildContext context) { + /// return DevToolsButton( + /// onPressed: () => context.sharedPreferencesStateNotifier.stopEditing(), + /// label: 'Cancel', + /// ); + /// } + /// ```` + SharedPreferencesStateNotifier get sharedPreferencesStateNotifier { + return getInheritedWidgetOfExactType<_StateInheritedWidget>()!.notifier; + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_tool_eval.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_tool_eval.dart new file mode 100644 index 00000000000..8ade5e27079 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/shared_preferences_tool_eval.dart @@ -0,0 +1,169 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; + +import 'package:devtools_app_shared/service.dart'; +import 'package:vm_service/vm_service.dart'; + +import 'shared_preferences_state.dart'; + +/// A representation of the keys in the shared preferences of the target debug +/// session. +typedef KeysResult = ({ + List asyncKeys, + List legacyKeys, +}); + +/// A class that provides methods to interact with the shared preferences +/// of the target debug session. +/// +/// It abstracts the calls to [EvalOnDartLibrary]. +class SharedPreferencesToolEval { + /// Default constructor for [SharedPreferencesToolEval]. + /// Do not call this constructor directly. + /// Use [SharedPreferencesStateNotifierProvider] instead. + SharedPreferencesToolEval( + this._service, + this._eval, + ); + + final VmService _service; + final EvalOnDartLibrary _eval; + + Disposable? _allKeysDisposable; + Disposable? _valueDisposable; + Disposable? _changeValueDisposable; + Disposable? _removeValueDisposable; + + /// Fetches all keys in the shared preferences of the target debug session. + /// Returns a string list of all keys. + Future fetchAllKeys() async { + _allKeysDisposable?.dispose(); + _allKeysDisposable = Disposable(); + final Map data = await _evalMethod( + method: 'requestAllKeys()', + eventKind: 'all_keys', + isAlive: _allKeysDisposable, + ); + + List castList(String key) { + return (data[key]! as List).cast(); + } + + return ( + asyncKeys: castList('asyncKeys'), + legacyKeys: castList('legacyKeys'), + ); + } + + Future> _evalMethod({ + required String method, + required String eventKind, + Disposable? isAlive, + }) async { + final Completer> completer = + Completer>(); + + late final StreamSubscription streamSubscription; + streamSubscription = _service.onExtensionEvent.listen((Event event) { + // The event prefix and event kind are defined in `shared_preferences_devtools_extension_data.dart` + // from the `shared_preferences` package. + if (event.extensionKind == 'shared_preferences.$eventKind') { + streamSubscription.cancel(); + completer.complete(event.extensionData!.data); + } + }); + + await _eval.eval( + 'SharedPreferencesDevToolsExtensionData().$method', + isAlive: isAlive, + ); + + return completer.future; + } + + /// Fetches the value of the shared preference with the given [key]. + /// Returns a [SharedPreferencesData] object that represents the value. + /// The type of the value is determined by the type of the shared preference. + Future fetchValue(String key, bool legacy) async { + _valueDisposable?.dispose(); + _valueDisposable = Disposable(); + + final Map data = await _evalMethod( + method: "requestValue('$key', $legacy)", + eventKind: 'value', + isAlive: _valueDisposable, + ); + + final Object value = data['value']!; + final Object? kind = data['kind']; + + // we need to check the kind because sometimes a double + // gets interpreted as an int. If this was not and issue + // we'd only need to do a simple pattern matching on value. + return switch (kind) { + 'int' => SharedPreferencesData.int( + value: value as int, + ), + 'bool' => SharedPreferencesData.bool( + value: value as bool, + ), + 'double' => SharedPreferencesData.double( + value: value as double, + ), + 'String' => SharedPreferencesData.string( + value: value as String, + ), + String() when kind.contains('List') => SharedPreferencesData.stringList( + value: (value as List).cast(), + ), + _ => throw UnsupportedError( + 'Unsupported value type: $kind', + ), + }; + } + + /// Changes the value of the key in the shared preferences of the target debug + /// session. + Future changeValue( + String key, + SharedPreferencesData value, + bool legacy, + ) async { + _changeValueDisposable?.dispose(); + _changeValueDisposable = Disposable(); + + final String serializedValue = jsonEncode(value.value); + final String kind = value.kind; + await _evalMethod( + method: + "requestValueChange('$key', '$serializedValue', '$kind', $legacy)", + eventKind: 'change_value', + isAlive: _changeValueDisposable, + ); + } + + /// Deletes the key from the shared preferences of the target debug session. + Future deleteKey(String key, bool legacy) async { + _removeValueDisposable?.dispose(); + _removeValueDisposable = Disposable(); + + await _evalMethod( + method: "requestRemoveKey('$key', $legacy)", + eventKind: 'remove', + isAlive: _removeValueDisposable, + ); + } + + /// Disposes all the disposables used in this class. + void dispose() { + _allKeysDisposable?.dispose(); + _valueDisposable?.dispose(); + _changeValueDisposable?.dispose(); + _removeValueDisposable?.dispose(); + _eval.dispose(); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/ui/api_switch.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/api_switch.dart new file mode 100644 index 00000000000..6f973fea5a5 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/api_switch.dart @@ -0,0 +1,49 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/ui.dart'; +import 'package:flutter/material.dart'; + +import '../shared_preferences_state_provider.dart'; + +/// A switch to toggle between the legacy and async APIs. +class ApiSwitch extends StatelessWidget { + /// Default constructor for [ApiSwitch]. + const ApiSwitch({ + super.key, + }); + + @override + Widget build(BuildContext context) { + final bool legacyApi = SharedPreferencesStateProvider.legacyApiOf(context); + + return Container( + padding: const EdgeInsets.symmetric(vertical: denseSpacing), + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: Theme.of(context).focusColor), + ), + ), + child: Center( + child: DevToolsToggleButtonGroup( + selectedStates: [legacyApi, !legacyApi], + onPressed: (int index) { + context.sharedPreferencesStateNotifier + .selectApi(legacyApi: index == 0); + }, + children: const [ + Padding( + padding: EdgeInsets.all(densePadding), + child: Text('Legacy API'), + ), + Padding( + padding: EdgeInsets.all(densePadding), + child: Text('Async API'), + ), + ], + ), + ), + ); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/ui/data_panel.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/data_panel.dart new file mode 100644 index 00000000000..73a215694b4 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/data_panel.dart @@ -0,0 +1,404 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// 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:devtools_app_shared/ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../async_state.dart'; +import '../shared_preferences_state.dart'; +import '../shared_preferences_state_notifier.dart'; +import '../shared_preferences_state_provider.dart'; +import 'error_panel.dart'; + +/// A panel that displays the data of the selected key. +class DataPanel extends StatefulWidget { + /// Default constructor for [DataPanel]. + const DataPanel({super.key}); + + @override + State createState() => _DataPanelState(); +} + +class _DataPanelState extends State { + String? currentValue; + + void _setCurrentValue(String value) { + setState(() { + currentValue = value; + }); + } + + @override + Widget build(BuildContext context) { + final AsyncState? selectedKeyData = + SharedPreferencesStateProvider.selectedKeyDataOf(context); + + return RoundedOutlinedBorder( + clip: true, + child: switch (selectedKeyData) { + null => const Center( + child: Text('Select a key to view its data.'), + ), + AsyncStateLoading() => const Center( + child: CircularProgressIndicator(), + ), + final AsyncStateError value => ErrorPanel( + error: value.error, + stackTrace: value.stackTrace, + ), + AsyncStateData( + data: final SharedPreferencesData data, + ) => + Column( + children: [ + _Header( + currentValue: currentValue, + data: data, + ), + Expanded( + child: _Content( + data: data, + setCurrentValue: _setCurrentValue, + ), + ), + ], + ), + }, + ); + } +} + +class _Header extends StatelessWidget { + const _Header({ + required this.currentValue, + required this.data, + }); + + final String? currentValue; + final SharedPreferencesData data; + + @override + Widget build(BuildContext context) { + final bool editing = SharedPreferencesStateProvider.editingOf(context); + // it is safe to assume that the selected key is not null + // because the header is only shown when a key is selected + final String selectedKey = + SharedPreferencesStateProvider.requireSelectedKeyOf(context).key; + + return AreaPaneHeader( + roundedTopBorder: false, + includeTopBorder: false, + tall: true, + title: Text( + selectedKey, + style: Theme.of(context).textTheme.titleSmall, + ), + actions: [ + if (editing) ...[ + DevToolsButton( + onPressed: () { + context.sharedPreferencesStateNotifier.stopEditing(); + }, + label: 'Cancel', + ), + if (currentValue case final String currentValue? + when currentValue != data.valueAsString && + (data is SharedPreferencesDataString || + currentValue.isNotEmpty)) ...[ + const SizedBox(width: denseRowSpacing), + DevToolsButton( + onPressed: () async { + try { + await context.sharedPreferencesStateNotifier.changeValue( + data.changeValue(currentValue), + ); + } catch (error) { + if (context.mounted) { + context.showSnackBar('Error: $error'); + } + } + }, + label: 'Apply changes', + ), + ], + ] else ...[ + DevToolsButton( + onPressed: () { + // we need to get the notifier here because it is not present in + // the context when the dialog is built + final SharedPreferencesStateNotifier notifier = + context.sharedPreferencesStateNotifier; + showDialog( + context: context, + builder: (BuildContext context) => _ConfirmRemoveDialog( + selectedKey: selectedKey, + notifier: notifier, + ), + ); + }, + label: 'Remove', + ), + const SizedBox(width: denseRowSpacing), + DevToolsButton( + onPressed: () => + context.sharedPreferencesStateNotifier.startEditing(), + label: 'Edit', + ), + ], + ], + ); + } +} + +class _ConfirmRemoveDialog extends StatelessWidget { + const _ConfirmRemoveDialog({ + required this.selectedKey, + required this.notifier, + }); + + final String selectedKey; + final SharedPreferencesStateNotifier notifier; + + @override + Widget build(BuildContext context) { + return DevToolsDialog( + title: const Text('Remove Key'), + content: Text( + 'Are you sure you want to remove $selectedKey?', + ), + actions: [ + const DialogCancelButton(), + DialogTextButton( + child: const Text('REMOVE'), + onPressed: () async { + Navigator.of(context).pop(); + try { + await notifier.deleteSelectedKey(); + } catch (error) { + if (context.mounted) { + context.showSnackBar('Error: $error'); + } + } + }, + ), + ], + ); + } +} + +class _Content extends StatelessWidget { + const _Content({ + required this.data, + required this.setCurrentValue, + }); + + final SharedPreferencesData data; + final ValueChanged setCurrentValue; + + @override + Widget build(BuildContext context) { + final bool editing = SharedPreferencesStateProvider.editingOf(context); + + return SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.all(largeSpacing), + child: SelectionArea( + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + Text('Type: ${data.kind}'), + const SizedBox(height: denseSpacing), + if (editing) ...[ + const Text('Value:'), + const SizedBox(height: denseSpacing), + switch (data) { + final SharedPreferencesDataBool state => _EditBoolean( + initialValue: state.value, + setCurrentValue: setCurrentValue, + ), + final SharedPreferencesDataStringList state => + _EditStringList( + initialData: state.value, + onChanged: setCurrentValue, + ), + _ => TextFormField( + autofocus: true, + initialValue: data.valueAsString, + inputFormatters: switch (data) { + SharedPreferencesDataInt() => [ + FilteringTextInputFormatter.allow( + RegExp(r'^-?\d*'), + ), + ], + SharedPreferencesDataDouble() => [ + FilteringTextInputFormatter.allow( + RegExp(r'^-?\d*\.?\d*'), + ), + ], + _ => [], + }, + onChanged: setCurrentValue, + ) + }, + ] else ...[ + Text('Value: ${data.valueAsString}'), + ], + ], + ), + ), + ), + ); + } +} + +class _EditBoolean extends StatelessWidget { + const _EditBoolean({ + required this.setCurrentValue, + required this.initialValue, + }); + + final ValueChanged setCurrentValue; + final bool initialValue; + + @override + Widget build(BuildContext context) { + return DropdownMenu( + initialSelection: initialValue, + onSelected: (bool? value) { + setCurrentValue(value.toString()); + }, + dropdownMenuEntries: const >[ + DropdownMenuEntry( + label: 'true', + value: true, + ), + DropdownMenuEntry( + label: 'false', + value: false, + ), + ], + ); + } +} + +class _EditStringList extends StatefulWidget { + const _EditStringList({ + required this.initialData, + required this.onChanged, + }); + + final List initialData; + final ValueChanged onChanged; + + @override + State<_EditStringList> createState() => _EditStringListState(); +} + +class _EditStringListState extends State<_EditStringList> { + late final List<(int key, String value)> _currentList; + int _keyCounter = 0; + + void _addElementAt(int index) { + setState(() { + _currentList.insert(index, (_keyCounter++, '')); + }); + _updateValue(); + } + + void _updateValue() { + widget.onChanged(jsonEncode( + [ + for (final (_, String value) in _currentList) value, + ], + )); + } + + @override + void initState() { + super.initState(); + _currentList = <(int, String)>[ + for (final String str in widget.initialData) (_keyCounter++, str), + ]; + } + + @override + Widget build(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + mainAxisSize: MainAxisSize.min, + children: [ + for (final (int index, (int keyValue, String str)) + in _currentList.indexed) ...[ + if (index > 0) const SizedBox(height: largeSpacing), + _AddListElement( + onPressed: () => _addElementAt(index), + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: densePadding), + child: Row( + children: [ + Expanded( + child: TextFormField( + key: Key('list_element_$keyValue'), + initialValue: str, + onChanged: (String value) { + setState(() { + _currentList[index] = (keyValue, value); + }); + _updateValue(); + }, + ), + ), + DevToolsButton( + icon: Icons.remove, + onPressed: () { + setState(() { + _currentList.removeAt(index); + }); + _updateValue(); + }, + ) + ], + ), + ), + ], + const SizedBox(height: largeSpacing), + _AddListElement( + onPressed: () => _addElementAt(_currentList.length), + ), + ], + ); + } +} + +class _AddListElement extends StatelessWidget { + const _AddListElement({ + required this.onPressed, + }); + + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return Center( + child: DevToolsButton( + icon: Icons.add, + onPressed: onPressed, + ), + ); + } +} + +extension on BuildContext { + void showSnackBar(String message) { + ScaffoldMessenger.of(this).showSnackBar( + SnackBar( + content: Text(message), + ), + ); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/ui/error_panel.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/error_panel.dart new file mode 100644 index 00000000000..1e490a65b55 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/error_panel.dart @@ -0,0 +1,34 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/ui.dart'; +import 'package:flutter/material.dart'; + +/// A panel that displays an error message and a stack trace. +class ErrorPanel extends StatelessWidget { + /// Default constructor for [ErrorPanel]. + const ErrorPanel({ + super.key, + required this.error, + required this.stackTrace, + }); + + /// The error message to display. + /// This will be displayed as a string. + final Object error; + + /// The stack trace to display. + final StackTrace? stackTrace; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(densePadding), + child: Text( + 'Error:\n$error\n\n$stackTrace', + style: Theme.of(context).errorTextStyle, + ), + ); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/ui/keys_panel.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/keys_panel.dart new file mode 100644 index 00000000000..e5cf533b834 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/keys_panel.dart @@ -0,0 +1,269 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/ui.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +import '../async_state.dart'; +import '../shared_preferences_state.dart'; +import '../shared_preferences_state_provider.dart'; +import 'api_switch.dart'; +import 'error_panel.dart'; + +/// A panel that displays the keys stored in shared preferences. +class KeysPanel extends StatefulWidget { + /// Default constructor for [KeysPanel]. + const KeysPanel({super.key}); + + @override + State createState() => _KeysPanelState(); +} + +class _KeysPanelState extends State { + bool searching = false; + final FocusNode searchFocusNode = FocusNode(); + + @override + void dispose() { + searchFocusNode.dispose(); + super.dispose(); + } + + void _startSearching() { + setState(() { + searching = true; + }); + } + + @override + Widget build(BuildContext context) { + void stopSearching() { + setState(() { + searching = false; + }); + context.sharedPreferencesStateNotifier.filter(''); + } + + return RoundedOutlinedBorder( + clip: true, + child: Column( + children: [ + AreaPaneHeader( + roundedTopBorder: false, + includeTopBorder: false, + tall: true, + title: Row( + children: [ + Text( + 'Stored Keys', + style: Theme.of(context).textTheme.titleSmall, + ), + if (searching) ...[ + const SizedBox( + width: denseSpacing, + ), + Expanded( + child: _SearchField( + searchFocusNode: searchFocusNode, + stopSearching: stopSearching, + ), + ), + ] else ...[ + const Spacer(), + _ToolbarAction( + tooltipMessage: 'Search', + icon: Icons.search, + onPressed: _startSearching, + ), + ], + const SizedBox( + width: denseRowSpacing, + ), + _ToolbarAction( + tooltipMessage: 'Refresh', + icon: Icons.refresh, + onPressed: () { + stopSearching(); + context.sharedPreferencesStateNotifier.fetchAllKeys(); + }, + ), + ], + ), + ), + const ApiSwitch(), + const Expanded( + child: _StateMapper(), + ), + ], + ), + ); + } +} + +// TODO(adsonpleal): replace this with `ToolbarAction` once it's available in `devtools_app_shared`, https://github.com/flutter/devtools/issues/7793. +class _ToolbarAction extends StatelessWidget { + const _ToolbarAction({ + required this.tooltipMessage, + required this.icon, + required this.onPressed, + }); + + final String tooltipMessage; + final IconData icon; + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return DevToolsTooltip( + message: tooltipMessage, + child: TextButton( + style: TextButton.styleFrom( + padding: EdgeInsets.zero, + tapTargetSize: MaterialTapTargetSize.shrinkWrap, + ), + onPressed: onPressed, + child: Icon( + icon, + size: actionsIconSize, + color: Theme.of(context).colorScheme.onSurface, + ), + ), + ); + } +} + +class _SearchField extends StatelessWidget { + const _SearchField({ + required this.searchFocusNode, + required this.stopSearching, + }); + + final FocusNode searchFocusNode; + final VoidCallback stopSearching; + + @override + Widget build(BuildContext context) { + return KeyboardListener( + focusNode: searchFocusNode, + onKeyEvent: (KeyEvent value) { + if (value.logicalKey == LogicalKeyboardKey.escape) { + stopSearching(); + } + }, + child: TextField( + autofocus: true, + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric( + horizontal: densePadding, + ), + hintText: 'Search', + border: const OutlineInputBorder(), + suffix: _ToolbarAction( + tooltipMessage: 'Stop searching', + icon: Icons.close, + onPressed: stopSearching, + ), + ), + onChanged: (String newValue) { + context.sharedPreferencesStateNotifier.filter(newValue); + }, + ), + ); + } +} + +class _StateMapper extends StatelessWidget { + const _StateMapper(); + + @override + Widget build(BuildContext context) { + return switch (SharedPreferencesStateProvider.keysListStateOf(context)) { + final AsyncStateData> value => _KeysList( + keys: value.data, + ), + final AsyncStateError> value => ErrorPanel( + error: value.error, + stackTrace: value.stackTrace, + ), + AsyncStateLoading>() => const Center( + child: CircularProgressIndicator(), + ), + }; + } +} + +class _KeysList extends StatefulWidget { + const _KeysList({ + required this.keys, + }); + + final List keys; + + @override + State<_KeysList> createState() => _KeysListState(); +} + +class _KeysListState extends State<_KeysList> { + final ScrollController scrollController = ScrollController(); + + @override + void dispose() { + scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scrollbar( + controller: scrollController, + child: ListView( + controller: scrollController, + children: [ + for (final String keyName in widget.keys) + _KeyItem( + keyName: keyName, + ), + ], + ), + ); + } +} + +class _KeyItem extends StatelessWidget { + const _KeyItem({ + required this.keyName, + }); + + final String keyName; + + @override + Widget build(BuildContext context) { + final SelectedSharedPreferencesKey? selectedKey = + SharedPreferencesStateProvider.selectedKeyOf(context); + final bool isSelected = selectedKey?.key == keyName; + final ColorScheme colorScheme = Theme.of(context).colorScheme; + final Color? backgroundColor = + isSelected ? colorScheme.selectedRowBackgroundColor : null; + + return InkWell( + onTap: () { + context.sharedPreferencesStateNotifier.selectKey(keyName); + }, + child: Container( + color: backgroundColor, + padding: const EdgeInsets.only( + left: defaultSpacing, + right: densePadding, + top: densePadding, + bottom: densePadding, + ), + child: Text( + keyName, + style: Theme.of(context).textTheme.titleSmall, + ), + ), + ); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/lib/src/ui/shared_preferences_body.dart b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/shared_preferences_body.dart new file mode 100644 index 00000000000..8ccc65c202d --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/lib/src/ui/shared_preferences_body.dart @@ -0,0 +1,30 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/ui.dart'; +import 'package:flutter/material.dart'; + +import 'data_panel.dart'; +import 'keys_panel.dart'; + +/// The main body of the shared preferences tool. +/// It contains the [KeysPanel] and the [DataPanel]. +class SharedPreferencesBody extends StatelessWidget { + /// Default constructor for [SharedPreferencesBody]. + const SharedPreferencesBody({super.key}); + + @override + Widget build(BuildContext context) { + final Axis splitAxis = SplitPane.axisFor(context, 0.85); + + return SplitPane( + axis: splitAxis, + initialFractions: const [0.33, 0.67], + children: const [ + KeysPanel(), + DataPanel(), + ], + ); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/pubspec.yaml b/packages/shared_preferences/shared_preferences_tool/pubspec.yaml new file mode 100644 index 00000000000..3f06964acec --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/pubspec.yaml @@ -0,0 +1,24 @@ +name: shared_preferences_tool +description: "DevTools extension for package:shared_preferences. Manage SharedPreferences efficiently. Edit, search, and view keys." +publish_to: 'none' + +version: 1.0.0+1 + +environment: + sdk: '>=3.4.0 <4.0.0' + +dependencies: + devtools_app_shared: ^0.3.0 + devtools_extensions: ^0.3.0 + flutter: + sdk: flutter + vm_service: ^14.3.0 + +dev_dependencies: + build_runner: ^2.4.10 + flutter_test: + sdk: flutter + mockito: 5.4.4 + +flutter: + uses-material-design: true diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.dart new file mode 100644 index 00000000000..5c6288e3621 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.dart @@ -0,0 +1,246 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:devtools_app_shared/service.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:shared_preferences_tool/src/async_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state_notifier.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_tool_eval.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec() +]) +import 'shared_preferences_state_notifier_test.mocks.dart'; + +void main() { + group('SharedPreferencesStateNotifier', () { + late MockSharedPreferencesToolEval evalMock; + late SharedPreferencesStateNotifier notifier; + + setUpAll(() { + provideDummy(const SharedPreferencesData.int(value: 42)); + }); + + setUp(() { + evalMock = MockSharedPreferencesToolEval(); + notifier = SharedPreferencesStateNotifier(evalMock); + }); + + test('should start with the default state', () { + expect( + notifier.value, + const SharedPreferencesState(), + ); + }); + + test('should fetch all keys', () async { + const List asyncKeys = ['key1', 'key2']; + const List legacyKeys = ['key11', 'key22']; + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: asyncKeys, + legacyKeys: legacyKeys, + ), + ); + + await notifier.fetchAllKeys(); + + expect(notifier.value.allKeys.dataOrNull, asyncKeys); + }); + + test('should filter out keys with "flutter." prefix async keys', () async { + const List asyncKeys = ['flutter.key1', 'key2']; + const List legacyKeys = ['key1', 'key3']; + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: asyncKeys, + legacyKeys: legacyKeys, + ), + ); + + await notifier.fetchAllKeys(); + + expect( + notifier.value.allKeys.dataOrNull, + equals(['key2']), + ); + }); + + test('should select key', () async { + const List keys = ['key1', 'key2']; + const SharedPreferencesData keyValue = + SharedPreferencesData.string(value: 'value'); + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: keys, + legacyKeys: const [], + ), + ); + when(evalMock.fetchValue('key1', false)).thenAnswer( + (_) async => keyValue, + ); + await notifier.fetchAllKeys(); + + await notifier.selectKey('key1'); + + expect( + notifier.value.selectedKey, + equals( + const SelectedSharedPreferencesKey( + key: 'key1', + value: AsyncState.data(keyValue), + ), + ), + ); + }); + + test('should select key for legacy api', () async { + const List keys = ['key1', 'key2']; + const SharedPreferencesData keyValue = + SharedPreferencesData.string(value: 'value'); + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: const [], + legacyKeys: keys, + ), + ); + when(evalMock.fetchValue('key1', true)).thenAnswer( + (_) async => keyValue, + ); + await notifier.fetchAllKeys(); + notifier.selectApi(legacyApi: true); + + await notifier.selectKey('key1'); + + expect( + notifier.value, + equals( + const SharedPreferencesState( + allKeys: AsyncState>.data(keys), + selectedKey: SelectedSharedPreferencesKey( + key: 'key1', + value: AsyncState.data(keyValue), + ), + legacyApi: true, + ), + ), + ); + }); + + test('should filter keys and clear filter', () async { + const List asyncKeys = ['key1', 'key2']; + const List legacyKeys = ['key11', 'key22']; + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: asyncKeys, + legacyKeys: legacyKeys, + ), + ); + await notifier.fetchAllKeys(); + + notifier.filter('key1'); + + expect(notifier.value.allKeys.dataOrNull, equals(['key1'])); + + notifier.filter(''); + + expect(notifier.value.allKeys.dataOrNull, equals(asyncKeys)); + }); + + test('should start/stop editing', () async { + const List asyncKeys = ['key1', 'key2']; + const List legacyKeys = ['key11', 'key22']; + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: asyncKeys, + legacyKeys: legacyKeys, + ), + ); + await notifier.fetchAllKeys(); + notifier.startEditing(); + + expect(notifier.value.editing, equals(true)); + + notifier.stopEditing(); + + expect(notifier.value.editing, equals(false)); + }); + + test('should change value', () async { + const List asyncKeys = ['key1', 'key2']; + const List legacyKeys = ['key11', 'key22']; + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: asyncKeys, + legacyKeys: legacyKeys, + ), + ); + const SharedPreferencesData keyValue = SharedPreferencesData.string( + value: 'value', + ); + when(evalMock.fetchValue('key1', false)).thenAnswer( + (_) async => keyValue, + ); + await notifier.fetchAllKeys(); + await notifier.selectKey('key1'); + + await notifier.deleteSelectedKey(); + + verify(evalMock.deleteKey('key1', false)).called(1); + }); + + test('should change value', () async { + const List asyncKeys = ['key1', 'key2']; + const List legacyKeys = ['key11', 'key22']; + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: asyncKeys, + legacyKeys: legacyKeys, + ), + ); + const SharedPreferencesData keyValue = + SharedPreferencesData.string(value: 'value'); + when(evalMock.fetchValue('key1', false)) + .thenAnswer((_) async => keyValue); + await notifier.fetchAllKeys(); + await notifier.selectKey('key1'); + + await notifier.changeValue( + const SharedPreferencesData.string(value: 'newValue'), + ); + + verify( + evalMock.changeValue( + 'key1', + const SharedPreferencesData.string(value: 'newValue'), + false, + ), + ).called(1); + }); + + test('should change select legacy api and async api', () async { + const List asyncKeys = ['key1', 'key2']; + const List legacyKeys = ['key11', 'key22']; + when(evalMock.fetchAllKeys()).thenAnswer( + (_) async => ( + asyncKeys: asyncKeys, + legacyKeys: legacyKeys, + ), + ); + await notifier.fetchAllKeys(); + + notifier.selectApi(legacyApi: true); + + expect(notifier.value.legacyApi, equals(true)); + + notifier.selectApi(legacyApi: false); + + expect(notifier.value.legacyApi, equals(false)); + }); + }); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.mocks.dart b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.mocks.dart new file mode 100644 index 00000000000..32000ac343a --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_notifier_test.mocks.dart @@ -0,0 +1,269 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in shared_preferences_tool/test/src/shared_preferences_state_notifier_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i2; + +import 'package:devtools_app_shared/service.dart' as _i6; +import 'package:mockito/mockito.dart' as _i1; +import 'package:mockito/src/dummies.dart' as _i5; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart' + as _i4; +import 'package:shared_preferences_tool/src/shared_preferences_tool_eval.dart' + as _i3; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeCompleter_0 extends _i1.SmartFake implements _i2.Completer { + _FakeCompleter_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [SharedPreferencesToolEval]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockSharedPreferencesToolEval extends _i1.Mock + implements _i3.SharedPreferencesToolEval { + @override + _i2.Future<({List asyncKeys, List legacyKeys})> + fetchAllKeys() => (super.noSuchMethod( + Invocation.method( + #fetchAllKeys, + [], + ), + returnValue: _i2.Future< + ({ + List asyncKeys, + List legacyKeys + })>.value((asyncKeys: [], legacyKeys: [])), + returnValueForMissingStub: _i2.Future< + ({ + List asyncKeys, + List legacyKeys + })>.value((asyncKeys: [], legacyKeys: [])), + ) as _i2.Future<({List asyncKeys, List legacyKeys})>); + + @override + _i2.Future<_i4.SharedPreferencesData> fetchValue( + String? key, + bool? legacy, + ) => + (super.noSuchMethod( + Invocation.method( + #fetchValue, + [ + key, + legacy, + ], + ), + returnValue: _i2.Future<_i4.SharedPreferencesData>.value( + _i5.dummyValue<_i4.SharedPreferencesData>( + this, + Invocation.method( + #fetchValue, + [ + key, + legacy, + ], + ), + )), + returnValueForMissingStub: _i2.Future<_i4.SharedPreferencesData>.value( + _i5.dummyValue<_i4.SharedPreferencesData>( + this, + Invocation.method( + #fetchValue, + [ + key, + legacy, + ], + ), + )), + ) as _i2.Future<_i4.SharedPreferencesData>); + + @override + _i2.Future changeValue( + String? key, + _i4.SharedPreferencesData? value, + bool? legacy, + ) => + (super.noSuchMethod( + Invocation.method( + #changeValue, + [ + key, + value, + legacy, + ], + ), + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), + ) as _i2.Future); + + @override + _i2.Future deleteKey( + String? key, + bool? legacy, + ) => + (super.noSuchMethod( + Invocation.method( + #deleteKey, + [ + key, + legacy, + ], + ), + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), + ) as _i2.Future); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [ConnectedApp]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockConnectedApp extends _i1.Mock implements _i6.ConnectedApp { + @override + _i2.Completer get initialized => (super.noSuchMethod( + Invocation.getter(#initialized), + returnValue: _FakeCompleter_0( + this, + Invocation.getter(#initialized), + ), + returnValueForMissingStub: _FakeCompleter_0( + this, + Invocation.getter(#initialized), + ), + ) as _i2.Completer); + + @override + set initialized(_i2.Completer? _initialized) => super.noSuchMethod( + Invocation.setter( + #initialized, + _initialized, + ), + returnValueForMissingStub: null, + ); + + @override + bool get connectedAppInitialized => (super.noSuchMethod( + Invocation.getter(#connectedAppInitialized), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + String get operatingSystem => (super.noSuchMethod( + Invocation.getter(#operatingSystem), + returnValue: _i5.dummyValue( + this, + Invocation.getter(#operatingSystem), + ), + returnValueForMissingStub: _i5.dummyValue( + this, + Invocation.getter(#operatingSystem), + ), + ) as String); + + @override + _i2.Future get isFlutterApp => (super.noSuchMethod( + Invocation.getter(#isFlutterApp), + returnValue: _i2.Future.value(false), + returnValueForMissingStub: _i2.Future.value(false), + ) as _i2.Future); + + @override + _i2.Future get isProfileBuild => (super.noSuchMethod( + Invocation.getter(#isProfileBuild), + returnValue: _i2.Future.value(false), + returnValueForMissingStub: _i2.Future.value(false), + ) as _i2.Future); + + @override + _i2.Future get isDartWebApp => (super.noSuchMethod( + Invocation.getter(#isDartWebApp), + returnValue: _i2.Future.value(false), + returnValueForMissingStub: _i2.Future.value(false), + ) as _i2.Future); + + @override + bool get isFlutterWebAppNow => (super.noSuchMethod( + Invocation.getter(#isFlutterWebAppNow), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get isFlutterNativeAppNow => (super.noSuchMethod( + Invocation.getter(#isFlutterNativeAppNow), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get isDebugFlutterAppNow => (super.noSuchMethod( + Invocation.getter(#isDebugFlutterAppNow), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i2.Future get isDartCliApp => (super.noSuchMethod( + Invocation.getter(#isDartCliApp), + returnValue: _i2.Future.value(false), + returnValueForMissingStub: _i2.Future.value(false), + ) as _i2.Future); + + @override + bool get isDartCliAppNow => (super.noSuchMethod( + Invocation.getter(#isDartCliAppNow), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i2.Future initializeValues({void Function()? onComplete}) => + (super.noSuchMethod( + Invocation.method( + #initializeValues, + [], + {#onComplete: onComplete}, + ), + returnValue: _i2.Future.value(), + returnValueForMissingStub: _i2.Future.value(), + ) as _i2.Future); + + @override + Map toJson() => (super.noSuchMethod( + Invocation.method( + #toJson, + [], + ), + returnValue: {}, + returnValueForMissingStub: {}, + ) as Map); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_test.dart new file mode 100644 index 00000000000..7b46baeb583 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_state_test.dart @@ -0,0 +1,130 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences_tool/src/async_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; + +void main() { + group('SharedPreferencesState', () { + test('should be possible to set selected key to null', () { + const SharedPreferencesState state = SharedPreferencesState( + selectedKey: SelectedSharedPreferencesKey( + key: 'key', + value: AsyncState.loading(), + ), + ); + + expect( + state.copyWith(selectedKey: null), + equals(const SharedPreferencesState()), + ); + }); + }); + + group('SharedPreferencesData', () { + test('value as string should return formatted value', () { + const SharedPreferencesData stringData = + SharedPreferencesData.string(value: 'value'); + expect(stringData.valueAsString, 'value'); + + const SharedPreferencesData intData = SharedPreferencesData.int(value: 1); + expect(intData.valueAsString, '1'); + + const SharedPreferencesData doubleData = + SharedPreferencesData.double(value: 1.1); + expect(doubleData.valueAsString, '1.1'); + + const SharedPreferencesData boolData = + SharedPreferencesData.bool(value: true); + expect(boolData.valueAsString, 'true'); + + const SharedPreferencesData stringListData = + SharedPreferencesData.stringList(value: ['value1', 'value2']); + expect(stringListData.valueAsString, '\n0 -> value1\n1 -> value2'); + }); + }); + + test('should return pretty type', () { + const SharedPreferencesData stringData = + SharedPreferencesData.string(value: 'value'); + expect(stringData.kind, 'String'); + + const SharedPreferencesData intData = SharedPreferencesData.int(value: 1); + expect(intData.kind, 'int'); + + const SharedPreferencesData doubleData = + SharedPreferencesData.double(value: 1.0); + expect(doubleData.kind, 'double'); + + const SharedPreferencesData boolData = + SharedPreferencesData.bool(value: true); + expect(boolData.kind, 'bool'); + + const SharedPreferencesData stringListData = + SharedPreferencesData.stringList(value: ['value1', 'value2']); + expect(stringListData.kind, 'List'); + }); + + test('should change value', () { + const SharedPreferencesData stringData = + SharedPreferencesData.string(value: 'value'); + const String newStringValue = 'newValue'; + expect( + stringData.changeValue(newStringValue), + isA().having( + (SharedPreferencesDataString data) => data.value, + 'value', + equals(newStringValue), + ), + ); + + const SharedPreferencesData intData = SharedPreferencesData.int(value: 1); + const String newIntValue = '2'; + expect( + intData.changeValue(newIntValue), + isA().having( + (SharedPreferencesDataInt data) => data.value, + 'value', + equals(int.parse(newIntValue)), + ), + ); + + const SharedPreferencesData doubleData = + SharedPreferencesData.double(value: 1.0); + const String newDoubleValue = '2.0'; + expect( + doubleData.changeValue(newDoubleValue), + isA().having( + (SharedPreferencesDataDouble data) => data.value, + 'value', + equals(double.parse(newDoubleValue)), + ), + ); + + const SharedPreferencesData boolData = + SharedPreferencesData.bool(value: true); + const String newBoolValue = 'false'; + expect( + boolData.changeValue(newBoolValue), + isA().having( + (SharedPreferencesDataBool data) => data.value, + 'value', + equals(false), + ), + ); + + const SharedPreferencesData stringListData = + SharedPreferencesData.stringList(value: ['value1', 'value2']); + const String newStringListValue = '["newValue1", "newValue2"]'; + expect( + stringListData.changeValue(newStringListValue), + isA().having( + (SharedPreferencesDataStringList data) => data.value, + 'value', + equals(['newValue1', 'newValue2']), + ), + ); + }); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart new file mode 100644 index 00000000000..3220526a37d --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart @@ -0,0 +1,267 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'dart:async'; + +import 'package:devtools_app_shared/service.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_tool_eval.dart'; +import 'package:vm_service/vm_service.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), + MockSpec(), +]) +import 'shared_preferences_tool_eval_test.mocks.dart'; + +void main() { + group('SharedPreferencesToolEval', () { + late MockEvalOnDartLibrary eval; + late MockVmService vmService; + late SharedPreferencesToolEval sharedPreferencesToolEval; + + void stubEvalMethod({ + required String eventKind, + required String method, + required Map response, + }) { + final StreamController eventStream = StreamController(); + when(vmService.onExtensionEvent).thenAnswer((_) => eventStream.stream); + when( + eval.eval( + 'SharedPreferencesDevToolsExtensionData().$method', + isAlive: anyNamed('isAlive'), + ), + ).thenAnswer((_) async { + eventStream.add( + Event( + extensionKind: 'shared_preferences.$eventKind', + extensionData: ExtensionData.parse(response), + ), + ); + return null; + }); + } + + setUp(() { + eval = MockEvalOnDartLibrary(); + vmService = MockVmService(); + sharedPreferencesToolEval = SharedPreferencesToolEval(vmService, eval); + }); + + test('should fetch all keys', () async { + final List expectedAsyncKeys = ['key1', 'key2']; + const List expectedLegacyKeys = ['key3', 'key4']; + stubEvalMethod( + eventKind: 'all_keys', + method: 'requestAllKeys()', + response: { + 'asyncKeys': expectedAsyncKeys, + 'legacyKeys': expectedLegacyKeys, + }, + ); + + final KeysResult allKeys = await sharedPreferencesToolEval.fetchAllKeys(); + + expect( + allKeys.asyncKeys, + equals(expectedAsyncKeys), + ); + expect( + allKeys.legacyKeys, + equals(expectedLegacyKeys), + ); + }); + + test('should fetch int value', () async { + const String key = 'testKey'; + const int expectedValue = 42; + stubEvalMethod( + eventKind: 'value', + method: "requestValue('$key', false)", + response: { + 'value': expectedValue, + 'kind': 'int', + }, + ); + + final SharedPreferencesData data = + await sharedPreferencesToolEval.fetchValue(key, false); + + expect( + data, + equals( + const SharedPreferencesData.int( + value: expectedValue, + ), + ), + ); + }); + + test('should fetch bool value', () async { + const String key = 'testKey'; + const bool expectedValue = true; + stubEvalMethod( + eventKind: 'value', + method: "requestValue('$key', false)", + response: { + 'value': expectedValue, + 'kind': 'bool', + }, + ); + + final SharedPreferencesData data = + await sharedPreferencesToolEval.fetchValue(key, false); + + expect( + data, + equals( + const SharedPreferencesData.bool( + value: expectedValue, + ), + ), + ); + }); + + test('should fetch double value', () async { + const String key = 'testKey'; + const double expectedValue = 11.1; + stubEvalMethod( + eventKind: 'value', + method: "requestValue('$key', false)", + response: { + 'value': expectedValue, + 'kind': 'double', + }, + ); + + final SharedPreferencesData data = + await sharedPreferencesToolEval.fetchValue(key, false); + + expect( + data, + equals( + const SharedPreferencesData.double( + value: expectedValue, + ), + ), + ); + }); + + test('should fetch string value', () async { + const String key = 'testKey'; + const String expectedValue = 'value'; + stubEvalMethod( + eventKind: 'value', + method: "requestValue('$key', false)", + response: { + 'value': expectedValue, + 'kind': 'String', + }, + ); + + final SharedPreferencesData data = + await sharedPreferencesToolEval.fetchValue(key, false); + + expect( + data, + equals( + const SharedPreferencesData.string( + value: expectedValue, + ), + ), + ); + }); + + test('should fetch string list value', () async { + const String key = 'testKey'; + const List expectedValue = ['value1', 'value2']; + stubEvalMethod( + eventKind: 'value', + method: "requestValue('$key', true)", + response: { + 'value': expectedValue, + 'kind': 'List', + }, + ); + + final SharedPreferencesData data = + await sharedPreferencesToolEval.fetchValue(key, true); + + expect( + data, + equals( + const SharedPreferencesData.stringList( + value: expectedValue, + ), + ), + ); + }); + + test('should throw error on unsupported value', () { + const String key = 'testKey'; + stubEvalMethod( + eventKind: 'value', + method: "requestValue('$key', true)", + response: { + 'value': 'error', + 'kind': 'SomeClass', + }, + ); + + expect( + () => sharedPreferencesToolEval.fetchValue(key, true), + throwsUnsupportedError, + ); + }); + + test('should change value', () async { + const String key = 'testKey'; + const String method = "requestValueChange('$key', 'true', 'bool', false)"; + stubEvalMethod( + eventKind: 'change_value', + method: method, + response: {}, + ); + + await sharedPreferencesToolEval.changeValue( + key, + const SharedPreferencesData.bool(value: true), + false, + ); + + verify( + eval.eval( + 'SharedPreferencesDevToolsExtensionData().$method', + isAlive: anyNamed('isAlive'), + ), + ).called(1); + }); + + test('should delete key', () async { + const String key = 'testKey'; + const String method = "requestRemoveKey('$key', false)"; + stubEvalMethod( + eventKind: 'remove', + method: method, + response: {}, + ); + + await sharedPreferencesToolEval.deleteKey( + key, + false, + ); + + verify( + eval.eval( + 'SharedPreferencesDevToolsExtensionData().$method', + isAlive: anyNamed('isAlive'), + ), + ).called(1); + }); + }); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart new file mode 100644 index 00000000000..c76289b2cc8 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart @@ -0,0 +1,3305 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:ui' as _i8; + +import 'package:devtools_app_shared/src/service/eval_on_dart_library.dart' + as _i5; +import 'package:devtools_app_shared/src/service/service_manager.dart' as _i3; +import 'package:flutter/foundation.dart' as _i7; +import 'package:flutter/widgets.dart' as _i9; +import 'package:mockito/mockito.dart' as _i2; +import 'package:mockito/src/dummies.dart' as _i6; +import 'package:vm_service/vm_service.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeServiceManager_0 extends _i2.SmartFake + implements _i3.ServiceManager { + _FakeServiceManager_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVmService_1 extends _i2.SmartFake implements _i1.VmService { + _FakeVmService_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeClass_2 extends _i2.SmartFake implements _i1.Class { + _FakeClass_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeInstance_3 extends _i2.SmartFake implements _i1.Instance { + _FakeInstance_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeInstanceRef_4 extends _i2.SmartFake implements _i1.InstanceRef { + _FakeInstanceRef_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeBreakpoint_5 extends _i2.SmartFake implements _i1.Breakpoint { + _FakeBreakpoint_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeSuccess_6 extends _i2.SmartFake implements _i1.Success { + _FakeSuccess_6( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIdZone_7 extends _i2.SmartFake implements _i1.IdZone { + _FakeIdZone_7( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeResponse_8 extends _i2.SmartFake implements _i1.Response { + _FakeResponse_8( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeAllocationProfile_9 extends _i2.SmartFake + implements _i1.AllocationProfile { + _FakeAllocationProfile_9( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeCpuSamples_10 extends _i2.SmartFake implements _i1.CpuSamples { + _FakeCpuSamples_10( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeClassList_11 extends _i2.SmartFake implements _i1.ClassList { + _FakeClassList_11( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFlagList_12 extends _i2.SmartFake implements _i1.FlagList { + _FakeFlagList_12( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeInboundReferences_13 extends _i2.SmartFake + implements _i1.InboundReferences { + _FakeInboundReferences_13( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeInstanceSet_14 extends _i2.SmartFake implements _i1.InstanceSet { + _FakeInstanceSet_14( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIsolate_15 extends _i2.SmartFake implements _i1.Isolate { + _FakeIsolate_15( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeIsolateGroup_16 extends _i2.SmartFake implements _i1.IsolateGroup { + _FakeIsolateGroup_16( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeEvent_17 extends _i2.SmartFake implements _i1.Event { + _FakeEvent_17( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeMemoryUsage_18 extends _i2.SmartFake implements _i1.MemoryUsage { + _FakeMemoryUsage_18( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeScriptList_19 extends _i2.SmartFake implements _i1.ScriptList { + _FakeScriptList_19( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeObj_20 extends _i2.SmartFake implements _i1.Obj { + _FakeObj_20( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePerfettoCpuSamples_21 extends _i2.SmartFake + implements _i1.PerfettoCpuSamples { + _FakePerfettoCpuSamples_21( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePerfettoTimeline_22 extends _i2.SmartFake + implements _i1.PerfettoTimeline { + _FakePerfettoTimeline_22( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakePortList_23 extends _i2.SmartFake implements _i1.PortList { + _FakePortList_23( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeRetainingPath_24 extends _i2.SmartFake implements _i1.RetainingPath { + _FakeRetainingPath_24( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeProcessMemoryUsage_25 extends _i2.SmartFake + implements _i1.ProcessMemoryUsage { + _FakeProcessMemoryUsage_25( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeStack_26 extends _i2.SmartFake implements _i1.Stack { + _FakeStack_26( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeProtocolList_27 extends _i2.SmartFake implements _i1.ProtocolList { + _FakeProtocolList_27( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeSourceReport_28 extends _i2.SmartFake implements _i1.SourceReport { + _FakeSourceReport_28( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVersion_29 extends _i2.SmartFake implements _i1.Version { + _FakeVersion_29( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeVM_30 extends _i2.SmartFake implements _i1.VM { + _FakeVM_30( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeTimeline_31 extends _i2.SmartFake implements _i1.Timeline { + _FakeTimeline_31( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeTimelineFlags_32 extends _i2.SmartFake implements _i1.TimelineFlags { + _FakeTimelineFlags_32( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeTimestamp_33 extends _i2.SmartFake implements _i1.Timestamp { + _FakeTimestamp_33( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeUriList_34 extends _i2.SmartFake implements _i1.UriList { + _FakeUriList_34( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeReloadReport_35 extends _i2.SmartFake implements _i1.ReloadReport { + _FakeReloadReport_35( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFuture_36 extends _i2.SmartFake implements _i4.Future { + _FakeFuture_36( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [EvalOnDartLibrary]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockEvalOnDartLibrary extends _i2.Mock implements _i5.EvalOnDartLibrary { + @override + bool get oneRequestAtATime => (super.noSuchMethod( + Invocation.getter(#oneRequestAtATime), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get disableBreakpoints => (super.noSuchMethod( + Invocation.getter(#disableBreakpoints), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get logExceptions => (super.noSuchMethod( + Invocation.getter(#logExceptions), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i3.ServiceManager<_i1.VmService> get serviceManager => (super.noSuchMethod( + Invocation.getter(#serviceManager), + returnValue: _FakeServiceManager_0<_i1.VmService>( + this, + Invocation.getter(#serviceManager), + ), + returnValueForMissingStub: _FakeServiceManager_0<_i1.VmService>( + this, + Invocation.getter(#serviceManager), + ), + ) as _i3.ServiceManager<_i1.VmService>); + + @override + String get libraryName => (super.noSuchMethod( + Invocation.getter(#libraryName), + returnValue: _i6.dummyValue( + this, + Invocation.getter(#libraryName), + ), + returnValueForMissingStub: _i6.dummyValue( + this, + Invocation.getter(#libraryName), + ), + ) as String); + + @override + _i1.VmService get service => (super.noSuchMethod( + Invocation.getter(#service), + returnValue: _FakeVmService_1( + this, + Invocation.getter(#service), + ), + returnValueForMissingStub: _FakeVmService_1( + this, + Invocation.getter(#service), + ), + ) as _i1.VmService); + + @override + set allPendingRequestsDone(_i4.Completer? _allPendingRequestsDone) => + super.noSuchMethod( + Invocation.setter( + #allPendingRequestsDone, + _allPendingRequestsDone, + ), + returnValueForMissingStub: null, + ); + + @override + bool get disposed => (super.noSuchMethod( + Invocation.getter(#disposed), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + List<_i7.Listenable> get listenables => (super.noSuchMethod( + Invocation.getter(#listenables), + returnValue: <_i7.Listenable>[], + returnValueForMissingStub: <_i7.Listenable>[], + ) as List<_i7.Listenable>); + + @override + List get listeners => (super.noSuchMethod( + Invocation.getter(#listeners), + returnValue: [], + returnValueForMissingStub: [], + ) as List); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future<_i1.InstanceRef?> eval( + String? expression, { + required _i5.Disposable? isAlive, + Map? scope, + bool? shouldLogError = true, + }) => + (super.noSuchMethod( + Invocation.method( + #eval, + [expression], + { + #isAlive: isAlive, + #scope: scope, + #shouldLogError: shouldLogError, + }, + ), + returnValue: _i4.Future<_i1.InstanceRef?>.value(), + returnValueForMissingStub: _i4.Future<_i1.InstanceRef?>.value(), + ) as _i4.Future<_i1.InstanceRef?>); + + @override + _i4.Future<_i1.InstanceRef?> invoke( + _i1.InstanceRef? instanceRef, + String? name, + List? argRefs, { + required _i5.Disposable? isAlive, + bool? shouldLogError = true, + }) => + (super.noSuchMethod( + Invocation.method( + #invoke, + [ + instanceRef, + name, + argRefs, + ], + { + #isAlive: isAlive, + #shouldLogError: shouldLogError, + }, + ), + returnValue: _i4.Future<_i1.InstanceRef?>.value(), + returnValueForMissingStub: _i4.Future<_i1.InstanceRef?>.value(), + ) as _i4.Future<_i1.InstanceRef?>); + + @override + _i4.Future<_i1.Class?> getClass( + _i1.ClassRef? instance, + _i5.Disposable? isAlive, + ) => + (super.noSuchMethod( + Invocation.method( + #getClass, + [ + instance, + isAlive, + ], + ), + returnValue: _i4.Future<_i1.Class?>.value(), + returnValueForMissingStub: _i4.Future<_i1.Class?>.value(), + ) as _i4.Future<_i1.Class?>); + + @override + _i4.Future<_i1.Class> safeGetClass( + _i1.ClassRef? instance, + _i5.Disposable? isAlive, + ) => + (super.noSuchMethod( + Invocation.method( + #safeGetClass, + [ + instance, + isAlive, + ], + ), + returnValue: _i4.Future<_i1.Class>.value(_FakeClass_2( + this, + Invocation.method( + #safeGetClass, + [ + instance, + isAlive, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Class>.value(_FakeClass_2( + this, + Invocation.method( + #safeGetClass, + [ + instance, + isAlive, + ], + ), + )), + ) as _i4.Future<_i1.Class>); + + @override + _i4.Future<_i1.Func?> getFunc( + _i1.FuncRef? instance, + _i5.Disposable? isAlive, + ) => + (super.noSuchMethod( + Invocation.method( + #getFunc, + [ + instance, + isAlive, + ], + ), + returnValue: _i4.Future<_i1.Func?>.value(), + returnValueForMissingStub: _i4.Future<_i1.Func?>.value(), + ) as _i4.Future<_i1.Func?>); + + @override + _i4.Future<_i1.Instance?> getInstance( + _i4.FutureOr<_i1.InstanceRef>? instanceRefFuture, + _i5.Disposable? isAlive, + ) => + (super.noSuchMethod( + Invocation.method( + #getInstance, + [ + instanceRefFuture, + isAlive, + ], + ), + returnValue: _i4.Future<_i1.Instance?>.value(), + returnValueForMissingStub: _i4.Future<_i1.Instance?>.value(), + ) as _i4.Future<_i1.Instance?>); + + @override + _i4.Future<_i1.Instance> safeGetInstance( + _i4.FutureOr<_i1.InstanceRef>? instanceRefFuture, + _i5.Disposable? isAlive, + ) => + (super.noSuchMethod( + Invocation.method( + #safeGetInstance, + [ + instanceRefFuture, + isAlive, + ], + ), + returnValue: _i4.Future<_i1.Instance>.value(_FakeInstance_3( + this, + Invocation.method( + #safeGetInstance, + [ + instanceRefFuture, + isAlive, + ], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Instance>.value(_FakeInstance_3( + this, + Invocation.method( + #safeGetInstance, + [ + instanceRefFuture, + isAlive, + ], + ), + )), + ) as _i4.Future<_i1.Instance>); + + @override + _i4.Future getHashCode( + _i1.InstanceRef? instance, { + required _i5.Disposable? isAlive, + }) => + (super.noSuchMethod( + Invocation.method( + #getHashCode, + [instance], + {#isAlive: isAlive}, + ), + returnValue: _i4.Future.value(0), + returnValueForMissingStub: _i4.Future.value(0), + ) as _i4.Future); + + @override + _i4.Future<_i1.Instance> evalInstance( + String? expression, { + required _i5.Disposable? isAlive, + Map? scope, + }) => + (super.noSuchMethod( + Invocation.method( + #evalInstance, + [expression], + { + #isAlive: isAlive, + #scope: scope, + }, + ), + returnValue: _i4.Future<_i1.Instance>.value(_FakeInstance_3( + this, + Invocation.method( + #evalInstance, + [expression], + { + #isAlive: isAlive, + #scope: scope, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Instance>.value(_FakeInstance_3( + this, + Invocation.method( + #evalInstance, + [expression], + { + #isAlive: isAlive, + #scope: scope, + }, + ), + )), + ) as _i4.Future<_i1.Instance>); + + @override + _i4.Future<_i1.InstanceRef?> asyncEval( + String? expression, { + required _i5.Disposable? isAlive, + Map? scope, + }) => + (super.noSuchMethod( + Invocation.method( + #asyncEval, + [expression], + { + #isAlive: isAlive, + #scope: scope, + }, + ), + returnValue: _i4.Future<_i1.InstanceRef?>.value(), + returnValueForMissingStub: _i4.Future<_i1.InstanceRef?>.value(), + ) as _i4.Future<_i1.InstanceRef?>); + + @override + _i4.Future<_i1.InstanceRef> safeEval( + String? expression, { + required _i5.Disposable? isAlive, + Map? scope, + }) => + (super.noSuchMethod( + Invocation.method( + #safeEval, + [expression], + { + #isAlive: isAlive, + #scope: scope, + }, + ), + returnValue: _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( + this, + Invocation.method( + #safeEval, + [expression], + { + #isAlive: isAlive, + #scope: scope, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( + this, + Invocation.method( + #safeEval, + [expression], + { + #isAlive: isAlive, + #scope: scope, + }, + ), + )), + ) as _i4.Future<_i1.InstanceRef>); + + @override + _i4.Future addRequest( + _i5.Disposable? isAlive, + _i4.Future Function()? request, + ) => + (super.noSuchMethod( + Invocation.method( + #addRequest, + [ + isAlive, + request, + ], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future getObjHelper( + _i1.ObjRef? instance, + _i5.Disposable? isAlive, { + int? offset, + int? count, + }) => + (super.noSuchMethod( + Invocation.method( + #getObjHelper, + [ + instance, + isAlive, + ], + { + #offset: offset, + #count: count, + }, + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + void addAutoDisposeListener( + _i7.Listenable? listenable, [ + _i8.VoidCallback? listener, + String? id, + ]) => + super.noSuchMethod( + Invocation.method( + #addAutoDisposeListener, + [ + listenable, + listener, + id, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void autoDisposeStreamSubscription( + _i4.StreamSubscription? subscription) => + super.noSuchMethod( + Invocation.method( + #autoDisposeStreamSubscription, + [subscription], + ), + returnValueForMissingStub: null, + ); + + @override + void autoDisposeFocusNode(_i9.FocusNode? node) => super.noSuchMethod( + Invocation.method( + #autoDisposeFocusNode, + [node], + ), + returnValueForMissingStub: null, + ); + + @override + void cancelStreamSubscriptions() => super.noSuchMethod( + Invocation.method( + #cancelStreamSubscriptions, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void cancelListeners({List? excludeIds = const []}) => + super.noSuchMethod( + Invocation.method( + #cancelListeners, + [], + {#excludeIds: excludeIds}, + ), + returnValueForMissingStub: null, + ); + + @override + void cancelListener(_i8.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #cancelListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void cancelFocusNodes() => super.noSuchMethod( + Invocation.method( + #cancelFocusNodes, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void callOnceWhenReady({ + required _i8.VoidCallback? callback, + required _i7.ValueListenable? trigger, + required bool Function(T)? readyWhen, + }) => + super.noSuchMethod( + Invocation.method( + #callOnceWhenReady, + [], + { + #callback: callback, + #trigger: trigger, + #readyWhen: readyWhen, + }, + ), + returnValueForMissingStub: null, + ); +} + +/// A class which mocks [VmService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockVmService extends _i2.Mock implements _i1.VmService { + @override + _i4.Stream get onSend => (super.noSuchMethod( + Invocation.getter(#onSend), + returnValue: _i4.Stream.empty(), + returnValueForMissingStub: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Stream get onReceive => (super.noSuchMethod( + Invocation.getter(#onReceive), + returnValue: _i4.Stream.empty(), + returnValueForMissingStub: _i4.Stream.empty(), + ) as _i4.Stream); + + @override + _i4.Future get onDone => (super.noSuchMethod( + Invocation.getter(#onDone), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Stream<_i1.Event> get onVMEvent => (super.noSuchMethod( + Invocation.getter(#onVMEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onIsolateEvent => (super.noSuchMethod( + Invocation.getter(#onIsolateEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onDebugEvent => (super.noSuchMethod( + Invocation.getter(#onDebugEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onProfilerEvent => (super.noSuchMethod( + Invocation.getter(#onProfilerEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onGCEvent => (super.noSuchMethod( + Invocation.getter(#onGCEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onExtensionEvent => (super.noSuchMethod( + Invocation.getter(#onExtensionEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onTimelineEvent => (super.noSuchMethod( + Invocation.getter(#onTimelineEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onLoggingEvent => (super.noSuchMethod( + Invocation.getter(#onLoggingEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onServiceEvent => (super.noSuchMethod( + Invocation.getter(#onServiceEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onHeapSnapshotEvent => (super.noSuchMethod( + Invocation.getter(#onHeapSnapshotEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onStdoutEvent => (super.noSuchMethod( + Invocation.getter(#onStdoutEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> get onStderrEvent => (super.noSuchMethod( + Invocation.getter(#onStderrEvent), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Stream<_i1.Event> onEvent(String? streamId) => (super.noSuchMethod( + Invocation.method( + #onEvent, + [streamId], + ), + returnValue: _i4.Stream<_i1.Event>.empty(), + returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), + ) as _i4.Stream<_i1.Event>); + + @override + _i4.Future<_i1.Breakpoint> addBreakpoint( + String? isolateId, + String? scriptId, + int? line, { + int? column, + }) => + (super.noSuchMethod( + Invocation.method( + #addBreakpoint, + [ + isolateId, + scriptId, + line, + ], + {#column: column}, + ), + returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #addBreakpoint, + [ + isolateId, + scriptId, + line, + ], + {#column: column}, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #addBreakpoint, + [ + isolateId, + scriptId, + line, + ], + {#column: column}, + ), + )), + ) as _i4.Future<_i1.Breakpoint>); + + @override + _i4.Future<_i1.Breakpoint> addBreakpointWithScriptUri( + String? isolateId, + String? scriptUri, + int? line, { + int? column, + }) => + (super.noSuchMethod( + Invocation.method( + #addBreakpointWithScriptUri, + [ + isolateId, + scriptUri, + line, + ], + {#column: column}, + ), + returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #addBreakpointWithScriptUri, + [ + isolateId, + scriptUri, + line, + ], + {#column: column}, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #addBreakpointWithScriptUri, + [ + isolateId, + scriptUri, + line, + ], + {#column: column}, + ), + )), + ) as _i4.Future<_i1.Breakpoint>); + + @override + _i4.Future<_i1.Breakpoint> addBreakpointAtEntry( + String? isolateId, + String? functionId, + ) => + (super.noSuchMethod( + Invocation.method( + #addBreakpointAtEntry, + [ + isolateId, + functionId, + ], + ), + returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #addBreakpointAtEntry, + [ + isolateId, + functionId, + ], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #addBreakpointAtEntry, + [ + isolateId, + functionId, + ], + ), + )), + ) as _i4.Future<_i1.Breakpoint>); + + @override + _i4.Future<_i1.Success> clearCpuSamples(String? isolateId) => + (super.noSuchMethod( + Invocation.method( + #clearCpuSamples, + [isolateId], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #clearCpuSamples, + [isolateId], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #clearCpuSamples, + [isolateId], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> clearVMTimeline() => (super.noSuchMethod( + Invocation.method( + #clearVMTimeline, + [], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #clearVMTimeline, + [], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #clearVMTimeline, + [], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.IdZone> createIdZone( + String? isolateId, + String? backingBufferKind, + String? idAssignmentPolicy, { + int? capacity, + }) => + (super.noSuchMethod( + Invocation.method( + #createIdZone, + [ + isolateId, + backingBufferKind, + idAssignmentPolicy, + ], + {#capacity: capacity}, + ), + returnValue: _i4.Future<_i1.IdZone>.value(_FakeIdZone_7( + this, + Invocation.method( + #createIdZone, + [ + isolateId, + backingBufferKind, + idAssignmentPolicy, + ], + {#capacity: capacity}, + ), + )), + returnValueForMissingStub: _i4.Future<_i1.IdZone>.value(_FakeIdZone_7( + this, + Invocation.method( + #createIdZone, + [ + isolateId, + backingBufferKind, + idAssignmentPolicy, + ], + {#capacity: capacity}, + ), + )), + ) as _i4.Future<_i1.IdZone>); + + @override + _i4.Future<_i1.Success> deleteIdZone( + String? isolateId, + String? idZoneId, + ) => + (super.noSuchMethod( + Invocation.method( + #deleteIdZone, + [ + isolateId, + idZoneId, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #deleteIdZone, + [ + isolateId, + idZoneId, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #deleteIdZone, + [ + isolateId, + idZoneId, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> invalidateIdZone( + String? isolateId, + String? idZoneId, + ) => + (super.noSuchMethod( + Invocation.method( + #invalidateIdZone, + [ + isolateId, + idZoneId, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #invalidateIdZone, + [ + isolateId, + idZoneId, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #invalidateIdZone, + [ + isolateId, + idZoneId, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Response> invoke( + String? isolateId, + String? targetId, + String? selector, + List? argumentIds, { + bool? disableBreakpoints, + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #invoke, + [ + isolateId, + targetId, + selector, + argumentIds, + ], + { + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #invoke, + [ + isolateId, + targetId, + selector, + argumentIds, + ], + { + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #invoke, + [ + isolateId, + targetId, + selector, + argumentIds, + ], + { + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + )), + ) as _i4.Future<_i1.Response>); + + @override + _i4.Future<_i1.Response> evaluate( + String? isolateId, + String? targetId, + String? expression, { + Map? scope, + bool? disableBreakpoints, + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #evaluate, + [ + isolateId, + targetId, + expression, + ], + { + #scope: scope, + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #evaluate, + [ + isolateId, + targetId, + expression, + ], + { + #scope: scope, + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #evaluate, + [ + isolateId, + targetId, + expression, + ], + { + #scope: scope, + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + )), + ) as _i4.Future<_i1.Response>); + + @override + _i4.Future<_i1.Response> evaluateInFrame( + String? isolateId, + int? frameIndex, + String? expression, { + Map? scope, + bool? disableBreakpoints, + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #evaluateInFrame, + [ + isolateId, + frameIndex, + expression, + ], + { + #scope: scope, + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #evaluateInFrame, + [ + isolateId, + frameIndex, + expression, + ], + { + #scope: scope, + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #evaluateInFrame, + [ + isolateId, + frameIndex, + expression, + ], + { + #scope: scope, + #disableBreakpoints: disableBreakpoints, + #idZoneId: idZoneId, + }, + ), + )), + ) as _i4.Future<_i1.Response>); + + @override + _i4.Future<_i1.AllocationProfile> getAllocationProfile( + String? isolateId, { + bool? reset, + bool? gc, + }) => + (super.noSuchMethod( + Invocation.method( + #getAllocationProfile, + [isolateId], + { + #reset: reset, + #gc: gc, + }, + ), + returnValue: + _i4.Future<_i1.AllocationProfile>.value(_FakeAllocationProfile_9( + this, + Invocation.method( + #getAllocationProfile, + [isolateId], + { + #reset: reset, + #gc: gc, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.AllocationProfile>.value(_FakeAllocationProfile_9( + this, + Invocation.method( + #getAllocationProfile, + [isolateId], + { + #reset: reset, + #gc: gc, + }, + ), + )), + ) as _i4.Future<_i1.AllocationProfile>); + + @override + _i4.Future<_i1.CpuSamples> getAllocationTraces( + String? isolateId, { + int? timeOriginMicros, + int? timeExtentMicros, + String? classId, + }) => + (super.noSuchMethod( + Invocation.method( + #getAllocationTraces, + [isolateId], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + #classId: classId, + }, + ), + returnValue: _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( + this, + Invocation.method( + #getAllocationTraces, + [isolateId], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + #classId: classId, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( + this, + Invocation.method( + #getAllocationTraces, + [isolateId], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + #classId: classId, + }, + ), + )), + ) as _i4.Future<_i1.CpuSamples>); + + @override + _i4.Future<_i1.ClassList> getClassList(String? isolateId) => + (super.noSuchMethod( + Invocation.method( + #getClassList, + [isolateId], + ), + returnValue: _i4.Future<_i1.ClassList>.value(_FakeClassList_11( + this, + Invocation.method( + #getClassList, + [isolateId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.ClassList>.value(_FakeClassList_11( + this, + Invocation.method( + #getClassList, + [isolateId], + ), + )), + ) as _i4.Future<_i1.ClassList>); + + @override + _i4.Future<_i1.CpuSamples> getCpuSamples( + String? isolateId, + int? timeOriginMicros, + int? timeExtentMicros, + ) => + (super.noSuchMethod( + Invocation.method( + #getCpuSamples, + [ + isolateId, + timeOriginMicros, + timeExtentMicros, + ], + ), + returnValue: _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( + this, + Invocation.method( + #getCpuSamples, + [ + isolateId, + timeOriginMicros, + timeExtentMicros, + ], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( + this, + Invocation.method( + #getCpuSamples, + [ + isolateId, + timeOriginMicros, + timeExtentMicros, + ], + ), + )), + ) as _i4.Future<_i1.CpuSamples>); + + @override + _i4.Future<_i1.FlagList> getFlagList() => (super.noSuchMethod( + Invocation.method( + #getFlagList, + [], + ), + returnValue: _i4.Future<_i1.FlagList>.value(_FakeFlagList_12( + this, + Invocation.method( + #getFlagList, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.FlagList>.value(_FakeFlagList_12( + this, + Invocation.method( + #getFlagList, + [], + ), + )), + ) as _i4.Future<_i1.FlagList>); + + @override + _i4.Future<_i1.InboundReferences> getInboundReferences( + String? isolateId, + String? targetId, + int? limit, { + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #getInboundReferences, + [ + isolateId, + targetId, + limit, + ], + {#idZoneId: idZoneId}, + ), + returnValue: + _i4.Future<_i1.InboundReferences>.value(_FakeInboundReferences_13( + this, + Invocation.method( + #getInboundReferences, + [ + isolateId, + targetId, + limit, + ], + {#idZoneId: idZoneId}, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.InboundReferences>.value(_FakeInboundReferences_13( + this, + Invocation.method( + #getInboundReferences, + [ + isolateId, + targetId, + limit, + ], + {#idZoneId: idZoneId}, + ), + )), + ) as _i4.Future<_i1.InboundReferences>); + + @override + _i4.Future<_i1.InstanceSet> getInstances( + String? isolateId, + String? objectId, + int? limit, { + bool? includeSubclasses, + bool? includeImplementers, + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #getInstances, + [ + isolateId, + objectId, + limit, + ], + { + #includeSubclasses: includeSubclasses, + #includeImplementers: includeImplementers, + #idZoneId: idZoneId, + }, + ), + returnValue: _i4.Future<_i1.InstanceSet>.value(_FakeInstanceSet_14( + this, + Invocation.method( + #getInstances, + [ + isolateId, + objectId, + limit, + ], + { + #includeSubclasses: includeSubclasses, + #includeImplementers: includeImplementers, + #idZoneId: idZoneId, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.InstanceSet>.value(_FakeInstanceSet_14( + this, + Invocation.method( + #getInstances, + [ + isolateId, + objectId, + limit, + ], + { + #includeSubclasses: includeSubclasses, + #includeImplementers: includeImplementers, + #idZoneId: idZoneId, + }, + ), + )), + ) as _i4.Future<_i1.InstanceSet>); + + @override + _i4.Future<_i1.InstanceRef> getInstancesAsList( + String? isolateId, + String? objectId, { + bool? includeSubclasses, + bool? includeImplementers, + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #getInstancesAsList, + [ + isolateId, + objectId, + ], + { + #includeSubclasses: includeSubclasses, + #includeImplementers: includeImplementers, + #idZoneId: idZoneId, + }, + ), + returnValue: _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( + this, + Invocation.method( + #getInstancesAsList, + [ + isolateId, + objectId, + ], + { + #includeSubclasses: includeSubclasses, + #includeImplementers: includeImplementers, + #idZoneId: idZoneId, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( + this, + Invocation.method( + #getInstancesAsList, + [ + isolateId, + objectId, + ], + { + #includeSubclasses: includeSubclasses, + #includeImplementers: includeImplementers, + #idZoneId: idZoneId, + }, + ), + )), + ) as _i4.Future<_i1.InstanceRef>); + + @override + _i4.Future<_i1.Isolate> getIsolate(String? isolateId) => (super.noSuchMethod( + Invocation.method( + #getIsolate, + [isolateId], + ), + returnValue: _i4.Future<_i1.Isolate>.value(_FakeIsolate_15( + this, + Invocation.method( + #getIsolate, + [isolateId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Isolate>.value(_FakeIsolate_15( + this, + Invocation.method( + #getIsolate, + [isolateId], + ), + )), + ) as _i4.Future<_i1.Isolate>); + + @override + _i4.Future<_i1.IsolateGroup> getIsolateGroup(String? isolateGroupId) => + (super.noSuchMethod( + Invocation.method( + #getIsolateGroup, + [isolateGroupId], + ), + returnValue: _i4.Future<_i1.IsolateGroup>.value(_FakeIsolateGroup_16( + this, + Invocation.method( + #getIsolateGroup, + [isolateGroupId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.IsolateGroup>.value(_FakeIsolateGroup_16( + this, + Invocation.method( + #getIsolateGroup, + [isolateGroupId], + ), + )), + ) as _i4.Future<_i1.IsolateGroup>); + + @override + _i4.Future<_i1.Event> getIsolatePauseEvent(String? isolateId) => + (super.noSuchMethod( + Invocation.method( + #getIsolatePauseEvent, + [isolateId], + ), + returnValue: _i4.Future<_i1.Event>.value(_FakeEvent_17( + this, + Invocation.method( + #getIsolatePauseEvent, + [isolateId], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Event>.value(_FakeEvent_17( + this, + Invocation.method( + #getIsolatePauseEvent, + [isolateId], + ), + )), + ) as _i4.Future<_i1.Event>); + + @override + _i4.Future<_i1.MemoryUsage> getMemoryUsage(String? isolateId) => + (super.noSuchMethod( + Invocation.method( + #getMemoryUsage, + [isolateId], + ), + returnValue: _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( + this, + Invocation.method( + #getMemoryUsage, + [isolateId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( + this, + Invocation.method( + #getMemoryUsage, + [isolateId], + ), + )), + ) as _i4.Future<_i1.MemoryUsage>); + + @override + _i4.Future<_i1.MemoryUsage> getIsolateGroupMemoryUsage( + String? isolateGroupId) => + (super.noSuchMethod( + Invocation.method( + #getIsolateGroupMemoryUsage, + [isolateGroupId], + ), + returnValue: _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( + this, + Invocation.method( + #getIsolateGroupMemoryUsage, + [isolateGroupId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( + this, + Invocation.method( + #getIsolateGroupMemoryUsage, + [isolateGroupId], + ), + )), + ) as _i4.Future<_i1.MemoryUsage>); + + @override + _i4.Future<_i1.ScriptList> getScripts(String? isolateId) => + (super.noSuchMethod( + Invocation.method( + #getScripts, + [isolateId], + ), + returnValue: _i4.Future<_i1.ScriptList>.value(_FakeScriptList_19( + this, + Invocation.method( + #getScripts, + [isolateId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.ScriptList>.value(_FakeScriptList_19( + this, + Invocation.method( + #getScripts, + [isolateId], + ), + )), + ) as _i4.Future<_i1.ScriptList>); + + @override + _i4.Future<_i1.Obj> getObject( + String? isolateId, + String? objectId, { + int? offset, + int? count, + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #getObject, + [ + isolateId, + objectId, + ], + { + #offset: offset, + #count: count, + #idZoneId: idZoneId, + }, + ), + returnValue: _i4.Future<_i1.Obj>.value(_FakeObj_20( + this, + Invocation.method( + #getObject, + [ + isolateId, + objectId, + ], + { + #offset: offset, + #count: count, + #idZoneId: idZoneId, + }, + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Obj>.value(_FakeObj_20( + this, + Invocation.method( + #getObject, + [ + isolateId, + objectId, + ], + { + #offset: offset, + #count: count, + #idZoneId: idZoneId, + }, + ), + )), + ) as _i4.Future<_i1.Obj>); + + @override + _i4.Future<_i1.PerfettoCpuSamples> getPerfettoCpuSamples( + String? isolateId, { + int? timeOriginMicros, + int? timeExtentMicros, + }) => + (super.noSuchMethod( + Invocation.method( + #getPerfettoCpuSamples, + [isolateId], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + returnValue: + _i4.Future<_i1.PerfettoCpuSamples>.value(_FakePerfettoCpuSamples_21( + this, + Invocation.method( + #getPerfettoCpuSamples, + [isolateId], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.PerfettoCpuSamples>.value(_FakePerfettoCpuSamples_21( + this, + Invocation.method( + #getPerfettoCpuSamples, + [isolateId], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + )), + ) as _i4.Future<_i1.PerfettoCpuSamples>); + + @override + _i4.Future<_i1.PerfettoTimeline> getPerfettoVMTimeline({ + int? timeOriginMicros, + int? timeExtentMicros, + }) => + (super.noSuchMethod( + Invocation.method( + #getPerfettoVMTimeline, + [], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + returnValue: + _i4.Future<_i1.PerfettoTimeline>.value(_FakePerfettoTimeline_22( + this, + Invocation.method( + #getPerfettoVMTimeline, + [], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.PerfettoTimeline>.value(_FakePerfettoTimeline_22( + this, + Invocation.method( + #getPerfettoVMTimeline, + [], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + )), + ) as _i4.Future<_i1.PerfettoTimeline>); + + @override + _i4.Future<_i1.PortList> getPorts(String? isolateId) => (super.noSuchMethod( + Invocation.method( + #getPorts, + [isolateId], + ), + returnValue: _i4.Future<_i1.PortList>.value(_FakePortList_23( + this, + Invocation.method( + #getPorts, + [isolateId], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.PortList>.value(_FakePortList_23( + this, + Invocation.method( + #getPorts, + [isolateId], + ), + )), + ) as _i4.Future<_i1.PortList>); + + @override + _i4.Future<_i1.RetainingPath> getRetainingPath( + String? isolateId, + String? targetId, + int? limit, { + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #getRetainingPath, + [ + isolateId, + targetId, + limit, + ], + {#idZoneId: idZoneId}, + ), + returnValue: _i4.Future<_i1.RetainingPath>.value(_FakeRetainingPath_24( + this, + Invocation.method( + #getRetainingPath, + [ + isolateId, + targetId, + limit, + ], + {#idZoneId: idZoneId}, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.RetainingPath>.value(_FakeRetainingPath_24( + this, + Invocation.method( + #getRetainingPath, + [ + isolateId, + targetId, + limit, + ], + {#idZoneId: idZoneId}, + ), + )), + ) as _i4.Future<_i1.RetainingPath>); + + @override + _i4.Future<_i1.ProcessMemoryUsage> getProcessMemoryUsage() => + (super.noSuchMethod( + Invocation.method( + #getProcessMemoryUsage, + [], + ), + returnValue: + _i4.Future<_i1.ProcessMemoryUsage>.value(_FakeProcessMemoryUsage_25( + this, + Invocation.method( + #getProcessMemoryUsage, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.ProcessMemoryUsage>.value(_FakeProcessMemoryUsage_25( + this, + Invocation.method( + #getProcessMemoryUsage, + [], + ), + )), + ) as _i4.Future<_i1.ProcessMemoryUsage>); + + @override + _i4.Future<_i1.Stack> getStack( + String? isolateId, { + int? limit, + String? idZoneId, + }) => + (super.noSuchMethod( + Invocation.method( + #getStack, + [isolateId], + { + #limit: limit, + #idZoneId: idZoneId, + }, + ), + returnValue: _i4.Future<_i1.Stack>.value(_FakeStack_26( + this, + Invocation.method( + #getStack, + [isolateId], + { + #limit: limit, + #idZoneId: idZoneId, + }, + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Stack>.value(_FakeStack_26( + this, + Invocation.method( + #getStack, + [isolateId], + { + #limit: limit, + #idZoneId: idZoneId, + }, + ), + )), + ) as _i4.Future<_i1.Stack>); + + @override + _i4.Future<_i1.ProtocolList> getSupportedProtocols() => (super.noSuchMethod( + Invocation.method( + #getSupportedProtocols, + [], + ), + returnValue: _i4.Future<_i1.ProtocolList>.value(_FakeProtocolList_27( + this, + Invocation.method( + #getSupportedProtocols, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.ProtocolList>.value(_FakeProtocolList_27( + this, + Invocation.method( + #getSupportedProtocols, + [], + ), + )), + ) as _i4.Future<_i1.ProtocolList>); + + @override + _i4.Future<_i1.SourceReport> getSourceReport( + String? isolateId, + List? reports, { + String? scriptId, + int? tokenPos, + int? endTokenPos, + bool? forceCompile, + bool? reportLines, + List? libraryFilters, + List? librariesAlreadyCompiled, + }) => + (super.noSuchMethod( + Invocation.method( + #getSourceReport, + [ + isolateId, + reports, + ], + { + #scriptId: scriptId, + #tokenPos: tokenPos, + #endTokenPos: endTokenPos, + #forceCompile: forceCompile, + #reportLines: reportLines, + #libraryFilters: libraryFilters, + #librariesAlreadyCompiled: librariesAlreadyCompiled, + }, + ), + returnValue: _i4.Future<_i1.SourceReport>.value(_FakeSourceReport_28( + this, + Invocation.method( + #getSourceReport, + [ + isolateId, + reports, + ], + { + #scriptId: scriptId, + #tokenPos: tokenPos, + #endTokenPos: endTokenPos, + #forceCompile: forceCompile, + #reportLines: reportLines, + #libraryFilters: libraryFilters, + #librariesAlreadyCompiled: librariesAlreadyCompiled, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.SourceReport>.value(_FakeSourceReport_28( + this, + Invocation.method( + #getSourceReport, + [ + isolateId, + reports, + ], + { + #scriptId: scriptId, + #tokenPos: tokenPos, + #endTokenPos: endTokenPos, + #forceCompile: forceCompile, + #reportLines: reportLines, + #libraryFilters: libraryFilters, + #librariesAlreadyCompiled: librariesAlreadyCompiled, + }, + ), + )), + ) as _i4.Future<_i1.SourceReport>); + + @override + _i4.Future<_i1.Version> getVersion() => (super.noSuchMethod( + Invocation.method( + #getVersion, + [], + ), + returnValue: _i4.Future<_i1.Version>.value(_FakeVersion_29( + this, + Invocation.method( + #getVersion, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Version>.value(_FakeVersion_29( + this, + Invocation.method( + #getVersion, + [], + ), + )), + ) as _i4.Future<_i1.Version>); + + @override + _i4.Future<_i1.VM> getVM() => (super.noSuchMethod( + Invocation.method( + #getVM, + [], + ), + returnValue: _i4.Future<_i1.VM>.value(_FakeVM_30( + this, + Invocation.method( + #getVM, + [], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.VM>.value(_FakeVM_30( + this, + Invocation.method( + #getVM, + [], + ), + )), + ) as _i4.Future<_i1.VM>); + + @override + _i4.Future<_i1.Timeline> getVMTimeline({ + int? timeOriginMicros, + int? timeExtentMicros, + }) => + (super.noSuchMethod( + Invocation.method( + #getVMTimeline, + [], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + returnValue: _i4.Future<_i1.Timeline>.value(_FakeTimeline_31( + this, + Invocation.method( + #getVMTimeline, + [], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Timeline>.value(_FakeTimeline_31( + this, + Invocation.method( + #getVMTimeline, + [], + { + #timeOriginMicros: timeOriginMicros, + #timeExtentMicros: timeExtentMicros, + }, + ), + )), + ) as _i4.Future<_i1.Timeline>); + + @override + _i4.Future<_i1.TimelineFlags> getVMTimelineFlags() => (super.noSuchMethod( + Invocation.method( + #getVMTimelineFlags, + [], + ), + returnValue: _i4.Future<_i1.TimelineFlags>.value(_FakeTimelineFlags_32( + this, + Invocation.method( + #getVMTimelineFlags, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.TimelineFlags>.value(_FakeTimelineFlags_32( + this, + Invocation.method( + #getVMTimelineFlags, + [], + ), + )), + ) as _i4.Future<_i1.TimelineFlags>); + + @override + _i4.Future<_i1.Timestamp> getVMTimelineMicros() => (super.noSuchMethod( + Invocation.method( + #getVMTimelineMicros, + [], + ), + returnValue: _i4.Future<_i1.Timestamp>.value(_FakeTimestamp_33( + this, + Invocation.method( + #getVMTimelineMicros, + [], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Timestamp>.value(_FakeTimestamp_33( + this, + Invocation.method( + #getVMTimelineMicros, + [], + ), + )), + ) as _i4.Future<_i1.Timestamp>); + + @override + _i4.Future<_i1.Success> pause(String? isolateId) => (super.noSuchMethod( + Invocation.method( + #pause, + [isolateId], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #pause, + [isolateId], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #pause, + [isolateId], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> kill(String? isolateId) => (super.noSuchMethod( + Invocation.method( + #kill, + [isolateId], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #kill, + [isolateId], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #kill, + [isolateId], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.UriList> lookupResolvedPackageUris( + String? isolateId, + List? uris, { + bool? local, + }) => + (super.noSuchMethod( + Invocation.method( + #lookupResolvedPackageUris, + [ + isolateId, + uris, + ], + {#local: local}, + ), + returnValue: _i4.Future<_i1.UriList>.value(_FakeUriList_34( + this, + Invocation.method( + #lookupResolvedPackageUris, + [ + isolateId, + uris, + ], + {#local: local}, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.UriList>.value(_FakeUriList_34( + this, + Invocation.method( + #lookupResolvedPackageUris, + [ + isolateId, + uris, + ], + {#local: local}, + ), + )), + ) as _i4.Future<_i1.UriList>); + + @override + _i4.Future<_i1.UriList> lookupPackageUris( + String? isolateId, + List? uris, + ) => + (super.noSuchMethod( + Invocation.method( + #lookupPackageUris, + [ + isolateId, + uris, + ], + ), + returnValue: _i4.Future<_i1.UriList>.value(_FakeUriList_34( + this, + Invocation.method( + #lookupPackageUris, + [ + isolateId, + uris, + ], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.UriList>.value(_FakeUriList_34( + this, + Invocation.method( + #lookupPackageUris, + [ + isolateId, + uris, + ], + ), + )), + ) as _i4.Future<_i1.UriList>); + + @override + _i4.Future<_i1.Success> registerService( + String? service, + String? alias, + ) => + (super.noSuchMethod( + Invocation.method( + #registerService, + [ + service, + alias, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #registerService, + [ + service, + alias, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #registerService, + [ + service, + alias, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.ReloadReport> reloadSources( + String? isolateId, { + bool? force, + bool? pause, + String? rootLibUri, + String? packagesUri, + }) => + (super.noSuchMethod( + Invocation.method( + #reloadSources, + [isolateId], + { + #force: force, + #pause: pause, + #rootLibUri: rootLibUri, + #packagesUri: packagesUri, + }, + ), + returnValue: _i4.Future<_i1.ReloadReport>.value(_FakeReloadReport_35( + this, + Invocation.method( + #reloadSources, + [isolateId], + { + #force: force, + #pause: pause, + #rootLibUri: rootLibUri, + #packagesUri: packagesUri, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.ReloadReport>.value(_FakeReloadReport_35( + this, + Invocation.method( + #reloadSources, + [isolateId], + { + #force: force, + #pause: pause, + #rootLibUri: rootLibUri, + #packagesUri: packagesUri, + }, + ), + )), + ) as _i4.Future<_i1.ReloadReport>); + + @override + _i4.Future<_i1.Success> removeBreakpoint( + String? isolateId, + String? breakpointId, + ) => + (super.noSuchMethod( + Invocation.method( + #removeBreakpoint, + [ + isolateId, + breakpointId, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #removeBreakpoint, + [ + isolateId, + breakpointId, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #removeBreakpoint, + [ + isolateId, + breakpointId, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> requestHeapSnapshot(String? isolateId) => + (super.noSuchMethod( + Invocation.method( + #requestHeapSnapshot, + [isolateId], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #requestHeapSnapshot, + [isolateId], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #requestHeapSnapshot, + [isolateId], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> resume( + String? isolateId, { + String? step, + int? frameIndex, + }) => + (super.noSuchMethod( + Invocation.method( + #resume, + [isolateId], + { + #step: step, + #frameIndex: frameIndex, + }, + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #resume, + [isolateId], + { + #step: step, + #frameIndex: frameIndex, + }, + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #resume, + [isolateId], + { + #step: step, + #frameIndex: frameIndex, + }, + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Breakpoint> setBreakpointState( + String? isolateId, + String? breakpointId, + bool? enable, + ) => + (super.noSuchMethod( + Invocation.method( + #setBreakpointState, + [ + isolateId, + breakpointId, + enable, + ], + ), + returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #setBreakpointState, + [ + isolateId, + breakpointId, + enable, + ], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( + this, + Invocation.method( + #setBreakpointState, + [ + isolateId, + breakpointId, + enable, + ], + ), + )), + ) as _i4.Future<_i1.Breakpoint>); + + @override + _i4.Future<_i1.Success> setExceptionPauseMode( + String? isolateId, + String? mode, + ) => + (super.noSuchMethod( + Invocation.method( + #setExceptionPauseMode, + [ + isolateId, + mode, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setExceptionPauseMode, + [ + isolateId, + mode, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setExceptionPauseMode, + [ + isolateId, + mode, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> setIsolatePauseMode( + String? isolateId, { + String? exceptionPauseMode, + bool? shouldPauseOnExit, + }) => + (super.noSuchMethod( + Invocation.method( + #setIsolatePauseMode, + [isolateId], + { + #exceptionPauseMode: exceptionPauseMode, + #shouldPauseOnExit: shouldPauseOnExit, + }, + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setIsolatePauseMode, + [isolateId], + { + #exceptionPauseMode: exceptionPauseMode, + #shouldPauseOnExit: shouldPauseOnExit, + }, + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setIsolatePauseMode, + [isolateId], + { + #exceptionPauseMode: exceptionPauseMode, + #shouldPauseOnExit: shouldPauseOnExit, + }, + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Response> setFlag( + String? name, + String? value, + ) => + (super.noSuchMethod( + Invocation.method( + #setFlag, + [ + name, + value, + ], + ), + returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #setFlag, + [ + name, + value, + ], + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #setFlag, + [ + name, + value, + ], + ), + )), + ) as _i4.Future<_i1.Response>); + + @override + _i4.Future<_i1.Success> setLibraryDebuggable( + String? isolateId, + String? libraryId, + bool? isDebuggable, + ) => + (super.noSuchMethod( + Invocation.method( + #setLibraryDebuggable, + [ + isolateId, + libraryId, + isDebuggable, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setLibraryDebuggable, + [ + isolateId, + libraryId, + isDebuggable, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setLibraryDebuggable, + [ + isolateId, + libraryId, + isDebuggable, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> setName( + String? isolateId, + String? name, + ) => + (super.noSuchMethod( + Invocation.method( + #setName, + [ + isolateId, + name, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setName, + [ + isolateId, + name, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setName, + [ + isolateId, + name, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> setTraceClassAllocation( + String? isolateId, + String? classId, + bool? enable, + ) => + (super.noSuchMethod( + Invocation.method( + #setTraceClassAllocation, + [ + isolateId, + classId, + enable, + ], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setTraceClassAllocation, + [ + isolateId, + classId, + enable, + ], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setTraceClassAllocation, + [ + isolateId, + classId, + enable, + ], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> setVMName(String? name) => (super.noSuchMethod( + Invocation.method( + #setVMName, + [name], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setVMName, + [name], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setVMName, + [name], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> setVMTimelineFlags(List? recordedStreams) => + (super.noSuchMethod( + Invocation.method( + #setVMTimelineFlags, + [recordedStreams], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setVMTimelineFlags, + [recordedStreams], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #setVMTimelineFlags, + [recordedStreams], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> streamCancel(String? streamId) => (super.noSuchMethod( + Invocation.method( + #streamCancel, + [streamId], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #streamCancel, + [streamId], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #streamCancel, + [streamId], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> streamCpuSamplesWithUserTag(List? userTags) => + (super.noSuchMethod( + Invocation.method( + #streamCpuSamplesWithUserTag, + [userTags], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #streamCpuSamplesWithUserTag, + [userTags], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #streamCpuSamplesWithUserTag, + [userTags], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Success> streamListen(String? streamId) => (super.noSuchMethod( + Invocation.method( + #streamListen, + [streamId], + ), + returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #streamListen, + [streamId], + ), + )), + returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( + this, + Invocation.method( + #streamListen, + [streamId], + ), + )), + ) as _i4.Future<_i1.Success>); + + @override + _i4.Future<_i1.Response> callMethod( + String? method, { + String? isolateId, + Map? args, + }) => + (super.noSuchMethod( + Invocation.method( + #callMethod, + [method], + { + #isolateId: isolateId, + #args: args, + }, + ), + returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #callMethod, + [method], + { + #isolateId: isolateId, + #args: args, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #callMethod, + [method], + { + #isolateId: isolateId, + #args: args, + }, + ), + )), + ) as _i4.Future<_i1.Response>); + + @override + _i4.Future<_i1.Response> callServiceExtension( + String? method, { + String? isolateId, + Map? args, + }) => + (super.noSuchMethod( + Invocation.method( + #callServiceExtension, + [method], + { + #isolateId: isolateId, + #args: args, + }, + ), + returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #callServiceExtension, + [method], + { + #isolateId: isolateId, + #args: args, + }, + ), + )), + returnValueForMissingStub: + _i4.Future<_i1.Response>.value(_FakeResponse_8( + this, + Invocation.method( + #callServiceExtension, + [method], + { + #isolateId: isolateId, + #args: args, + }, + ), + )), + ) as _i4.Future<_i1.Response>); + + @override + _i4.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future wrapFuture( + String? name, + _i4.Future? future, + ) => + (super.noSuchMethod( + Invocation.method( + #wrapFuture, + [ + name, + future, + ], + ), + returnValue: _i6.ifNotNull( + _i6.dummyValueOrNull( + this, + Invocation.method( + #wrapFuture, + [ + name, + future, + ], + ), + ), + (T v) => _i4.Future.value(v), + ) ?? + _FakeFuture_36( + this, + Invocation.method( + #wrapFuture, + [ + name, + future, + ], + ), + ), + returnValueForMissingStub: _i6.ifNotNull( + _i6.dummyValueOrNull( + this, + Invocation.method( + #wrapFuture, + [ + name, + future, + ], + ), + ), + (T v) => _i4.Future.value(v), + ) ?? + _FakeFuture_36( + this, + Invocation.method( + #wrapFuture, + [ + name, + future, + ], + ), + ), + ) as _i4.Future); + + @override + void registerServiceCallback( + String? service, + _i1.ServiceCallback? cb, + ) => + super.noSuchMethod( + Invocation.method( + #registerServiceCallback, + [ + service, + cb, + ], + ), + returnValueForMissingStub: null, + ); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/ui/data_panel_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/ui/data_panel_test.dart new file mode 100644 index 00000000000..fdcce9d37da --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/ui/data_panel_test.dart @@ -0,0 +1,390 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@TestOn('browser') +library; + +import 'package:devtools_extensions/devtools_extensions.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:shared_preferences_tool/src/async_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state_provider.dart'; +import 'package:shared_preferences_tool/src/ui/data_panel.dart'; +import 'package:shared_preferences_tool/src/ui/error_panel.dart'; + +import '../../test_helpers/notifier_mocking_helpers.dart'; +import '../../test_helpers/notifier_mocking_helpers.mocks.dart'; + +void main() { + group('DataPanel', () { + setupDummies(); + + late MockSharedPreferencesStateNotifier notifierMock; + + setUp(() { + notifierMock = MockSharedPreferencesStateNotifier(); + }); + + Future pumpDataPanel(WidgetTester tester) { + return tester.pumpWidget( + DevToolsExtension( + requiresRunningApplication: false, + child: InnerSharedPreferencesStateProvider( + notifier: notifierMock, + child: const DataPanel(), + ), + ), + ); + } + + void stubAsyncState( + AsyncState? state, { + bool editing = false, + }) { + const String selectedKey = 'selectedTestKey'; + when(notifierMock.value).thenReturn( + SharedPreferencesState( + allKeys: const AsyncState>.data([selectedKey]), + editing: editing, + selectedKey: state == null + ? null + : SelectedSharedPreferencesKey( + key: selectedKey, + value: state, + ), + ), + ); + } + + void stubDataState(SharedPreferencesData state, {bool editing = false}) { + stubAsyncState( + AsyncState.data(state), + editing: editing, + ); + } + + testWidgets('should show select key state', (WidgetTester tester) async { + stubAsyncState(null); + await pumpDataPanel(tester); + + expect(find.text('Select a key to view its data.'), findsOneWidget); + }); + + testWidgets('should show loading state', (WidgetTester tester) async { + stubAsyncState(const AsyncState.loading()); + await pumpDataPanel(tester); + + expect(find.byType(CircularProgressIndicator), findsOneWidget); + }); + + testWidgets('should show error state', (WidgetTester tester) async { + stubAsyncState( + const AsyncState.error( + 'error', + StackTrace.empty, + ), + ); + await pumpDataPanel(tester); + + expect(find.byType(ErrorPanel), findsOneWidget); + }); + + testWidgets('should show string value', (WidgetTester tester) async { + const String value = 'testValue'; + stubDataState(const SharedPreferencesData.string(value: value)); + await pumpDataPanel(tester); + + expect(find.text('Type: String'), findsOneWidget); + expect(find.text('Value: $value'), findsOneWidget); + }); + + testWidgets('should show int value', (WidgetTester tester) async { + const int value = 42; + stubDataState(const SharedPreferencesData.int(value: value)); + await pumpDataPanel(tester); + + expect(find.text('Type: int'), findsOneWidget); + expect(find.text('Value: $value'), findsOneWidget); + }); + + testWidgets('should show double value', (WidgetTester tester) async { + const double value = 42.0; + stubDataState(const SharedPreferencesData.double(value: value)); + await pumpDataPanel(tester); + + expect(find.text('Type: double'), findsOneWidget); + expect(find.text('Value: $value'), findsOneWidget); + }); + + testWidgets('should show boolean value', (WidgetTester tester) async { + const bool value = true; + stubDataState(const SharedPreferencesData.bool(value: value)); + await pumpDataPanel(tester); + + expect(find.text('Type: bool'), findsOneWidget); + expect(find.text('Value: $value'), findsOneWidget); + }); + + testWidgets('should show string list value', (WidgetTester tester) async { + stubDataState(const SharedPreferencesData.stringList( + value: ['value1', 'value2'])); + await pumpDataPanel(tester); + + expect(find.text('Type: List'), findsOneWidget); + expect(find.textContaining('0 -> value1'), findsOneWidget); + expect(find.textContaining('1 -> value2'), findsOneWidget); + }); + + testWidgets('should show viewing state', (WidgetTester tester) async { + stubDataState(const SharedPreferencesData.string(value: 'value')); + await pumpDataPanel(tester); + + expect(find.text('Remove'), findsOneWidget); + expect(find.text('Edit'), findsOneWidget); + }); + + testWidgets('on edit should start editing', (WidgetTester tester) async { + stubDataState(const SharedPreferencesData.string(value: 'value')); + await pumpDataPanel(tester); + + await tester.tap(find.text('Edit')); + verify(notifierMock.startEditing()).called(1); + }); + + testWidgets( + 'on remove should show confirmation modal', + (WidgetTester tester) async { + stubDataState(const SharedPreferencesData.string(value: 'value')); + await pumpDataPanel(tester); + + await tester.tap(find.text('Remove')); + await tester.pumpAndSettle(); + + expect( + find.text('Are you sure you want to remove selectedTestKey?'), + findsOneWidget, + ); + expect(find.text('CANCEL'), findsOneWidget); + expect(find.text('REMOVE'), findsOneWidget); + }, + ); + + testWidgets( + 'on removed confirmed should remove key', + (WidgetTester tester) async { + const SharedPreferencesData value = SharedPreferencesData.string( + value: 'value', + ); + stubDataState(value); + await pumpDataPanel(tester); + await tester.tap(find.text('Remove')); + await tester.pumpAndSettle(); + + await tester.tap(find.text('REMOVE')); + + verify( + notifierMock.deleteSelectedKey(), + ).called(1); + }, + ); + + testWidgets( + 'on remove canceled should cancel remove', + (WidgetTester tester) async { + stubDataState(const SharedPreferencesData.string(value: 'value')); + await pumpDataPanel(tester); + await tester.tap(find.text('Remove')); + await tester.pumpAndSettle(); + + await tester.tap(find.text('CANCEL')); + await tester.pumpAndSettle(); + + expect( + find.text('Are you sure you want to remove selectedTestKey?'), + findsNothing, + ); + }, + ); + + testWidgets('should show editing state', (WidgetTester tester) async { + stubDataState( + const SharedPreferencesData.string(value: 'value'), + editing: true, + ); + await pumpDataPanel(tester); + + expect(find.text('Cancel'), findsOneWidget); + }); + + testWidgets( + 'should show string editing state', + (WidgetTester tester) async { + const String value = 'value'; + stubDataState( + const SharedPreferencesData.string(value: value), + editing: true, + ); + await pumpDataPanel(tester); + + expect(find.text('Type: String'), findsOneWidget); + expect(find.text('Value:'), findsOneWidget); + expect(find.text(value), findsOneWidget); + expect(find.byType(TextField), findsOneWidget); + }, + ); + + testWidgets( + 'should show int editing state', + (WidgetTester tester) async { + const int value = 42; + stubDataState( + const SharedPreferencesData.int(value: value), + editing: true, + ); + await pumpDataPanel(tester); + + expect(find.text('Type: int'), findsOneWidget); + expect(find.text('Value:'), findsOneWidget); + expect(find.text('$value'), findsOneWidget); + expect(find.byType(TextField), findsOneWidget); + expect( + tester.textInputFormatterPattern, + equals(RegExp(r'^-?\d*').toString()), + ); + }, + ); + + testWidgets( + 'should show double editing state', + (WidgetTester tester) async { + const double value = 42.0; + stubDataState( + const SharedPreferencesData.double(value: value), + editing: true, + ); + await pumpDataPanel(tester); + + expect(find.text('Type: double'), findsOneWidget); + expect(find.text('Value:'), findsOneWidget); + expect(find.text('$value'), findsOneWidget); + expect(find.byType(TextField), findsOneWidget); + expect( + tester.textInputFormatterPattern, + equals(RegExp(r'^-?\d*\.?\d*').toString()), + ); + }, + ); + + testWidgets( + 'should show boolean editing state', + (WidgetTester tester) async { + const bool value = true; + stubDataState( + const SharedPreferencesData.bool(value: value), + editing: true, + ); + await pumpDataPanel(tester); + + expect(find.text('Type: bool'), findsOneWidget); + expect(find.text('Value:'), findsOneWidget); + expect(find.byType(DropdownMenu), findsOneWidget); + }, + ); + + testWidgets( + 'should show string list editing state', + (WidgetTester tester) async { + stubDataState( + const SharedPreferencesData.stringList( + value: ['value1', 'value2'], + ), + editing: true, + ); + await pumpDataPanel(tester); + + expect(find.text('Type: List'), findsOneWidget); + expect(find.text('Value:'), findsOneWidget); + expect(find.text('value1'), findsOneWidget); + expect(find.text('value2'), findsOneWidget); + expect(find.byType(TextField), findsNWidgets(2)); + // Finds 3 add buttons: + // + + // value1 + // + + // value2 + // + + expect(find.byIcon(Icons.add), findsNWidgets(3)); + }, + ); + + testWidgets( + 'should show apply changes button on value changed', + (WidgetTester tester) async { + stubDataState( + const SharedPreferencesData.string(value: 'value'), + editing: true, + ); + await pumpDataPanel(tester); + + await tester.enterText(find.byType(TextField), 'newValue'); + await tester.pumpAndSettle(); + + expect(find.text('Apply changes'), findsOneWidget); + }, + ); + + testWidgets( + 'pressing an add button on the string list editing state ' + 'should add element in the right index', + (WidgetTester tester) async { + stubDataState( + const SharedPreferencesData.stringList( + value: ['value1', 'value2'], + ), + editing: true, + ); + await pumpDataPanel(tester); + + for (int i = 0; i < 3; i++) { + await tester.tap(find.byIcon(Icons.add).at(i)); + await tester.pumpAndSettle(); + await tester.enterText(find.byType(TextField).at(i), '$i'); + await tester.pumpAndSettle(); + await tester.tap(find.text('Apply changes')); + await tester.pumpAndSettle(); + } + + verifyInOrder(>[ + notifierMock.changeValue( + const SharedPreferencesData.stringList( + value: ['0', 'value1', 'value2'], + ), + ), + notifierMock.changeValue( + const SharedPreferencesData.stringList( + value: ['0', '1', 'value1', 'value2'], + ), + ), + notifierMock.changeValue( + const SharedPreferencesData.stringList( + value: ['0', '1', '2', 'value1', 'value2'], + ), + ), + ]); + }, + ); + }); +} + +extension on WidgetTester { + Pattern get textInputFormatterPattern { + final TextField textField = widget(find.byType(TextField)); + return (textField.inputFormatters!.first as FilteringTextInputFormatter) + .filterPattern + .toString(); + } +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/ui/error_panel_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/ui/error_panel_test.dart new file mode 100644 index 00000000000..69b3748ecf5 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/ui/error_panel_test.dart @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@TestOn('browser') +library; + +import 'package:devtools_extensions/devtools_extensions.dart'; +import 'package:flutter/widgets.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences_tool/src/ui/error_panel.dart'; + +void main() { + group('ErrorPanel', () { + testWidgets( + 'should show error and stacktrace', + (WidgetTester tester) async { + const String error = 'error'; + final StackTrace stackTrace = StackTrace.current; + + await tester.pumpWidget( + DevToolsExtension( + requiresRunningApplication: false, + child: Directionality( + textDirection: TextDirection.ltr, + child: ErrorPanel( + error: error, + stackTrace: stackTrace, + ), + ), + ), + ); + + expect(find.text('Error:\n$error\n\n$stackTrace'), findsOneWidget); + }, + ); + }); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/ui/keys_panel_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/ui/keys_panel_test.dart new file mode 100644 index 00000000000..5ce79d7bca8 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/ui/keys_panel_test.dart @@ -0,0 +1,205 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@TestOn('browser') +library; + +import 'package:devtools_app_shared/ui.dart'; +import 'package:devtools_extensions/devtools_extensions.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:shared_preferences_tool/src/async_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state_provider.dart'; +import 'package:shared_preferences_tool/src/ui/error_panel.dart'; +import 'package:shared_preferences_tool/src/ui/keys_panel.dart'; + +import '../../test_helpers/notifier_mocking_helpers.dart'; +import '../../test_helpers/notifier_mocking_helpers.mocks.dart'; + +void main() { + group('KeysPanel', () { + setupDummies(); + + late MockSharedPreferencesStateNotifier notifierMock; + + setUp(() { + notifierMock = MockSharedPreferencesStateNotifier(); + }); + + Future pumpKeysPanel(WidgetTester tester) { + return tester.pumpWidget( + DevToolsExtension( + requiresRunningApplication: false, + child: InnerSharedPreferencesStateProvider( + notifier: notifierMock, + child: const KeysPanel(), + ), + ), + ); + } + + void stubDataState({ + AsyncState> allKeys = + const AsyncState>.data([]), + SelectedSharedPreferencesKey? selectedKey, + bool editing = false, + }) { + when(notifierMock.value).thenReturn( + SharedPreferencesState( + allKeys: allKeys, + selectedKey: selectedKey, + editing: editing, + ), + ); + } + + testWidgets('should show loading state', (WidgetTester tester) async { + stubDataState( + allKeys: const AsyncState>.loading(), + ); + await pumpKeysPanel(tester); + + expect(find.byType(CircularProgressIndicator), findsOneWidget); + }); + + testWidgets('should show error state', (WidgetTester tester) async { + stubDataState( + allKeys: const AsyncState>.error( + 'error', + StackTrace.empty, + ), + ); + await pumpKeysPanel(tester); + + expect(find.byType(ErrorPanel), findsOneWidget); + }); + + testWidgets('should show keys list with all keys', + (WidgetTester tester) async { + const List allKeys = ['key1', 'key2']; + stubDataState( + allKeys: const AsyncState>.data(allKeys), + ); + + await pumpKeysPanel(tester); + + for (final String key in allKeys) { + expect(find.text(key), findsOneWidget); + } + }); + + testWidgets( + 'only selected key should be highlighted', + (WidgetTester tester) async { + const String selectedKey = 'selectedKey'; + const List keys = ['key1', selectedKey, 'key2']; + + stubDataState( + allKeys: const AsyncState>.data(keys), + selectedKey: const SelectedSharedPreferencesKey( + key: selectedKey, + value: AsyncState.loading(), + ), + ); + + await pumpKeysPanel(tester); + + final Element selectedKeyElement = + tester.element(find.text(selectedKey)); + final ColorScheme colorScheme = + Theme.of(selectedKeyElement).colorScheme; + + Color? bgColorFor(String key) { + final Container? container = tester + .element(find.text(key)) + .findAncestorWidgetOfExactType(); + return container?.color; + } + + for (final String key in [...keys]..remove(selectedKey)) { + expect( + bgColorFor(key), + isNot(equals(colorScheme.selectedRowBackgroundColor)), + ); + } + expect( + bgColorFor(selectedKey), + equals(colorScheme.selectedRowBackgroundColor), + ); + }, + ); + + testWidgets( + 'should start searching when clicking the search icon', + (WidgetTester tester) async { + stubDataState(); + await pumpKeysPanel(tester); + + await tester.tap(find.byIcon(Icons.search)); + await tester.pumpAndSettle(); + + expect(find.byType(TextField), findsOneWidget); + }, + ); + + testWidgets( + 'should stop searching when clicking the close icon', + (WidgetTester tester) async { + stubDataState(); + await pumpKeysPanel(tester); + await tester.tap(find.byIcon(Icons.search)); + await tester.pumpAndSettle(); + + await tester.tap(find.byIcon(Icons.close)); + await tester.pumpAndSettle(); + + expect(find.byType(TextField), findsNothing); + }, + ); + + testWidgets( + 'should filter keys when searching', + (WidgetTester tester) async { + stubDataState(); + await pumpKeysPanel(tester); + await tester.tap(find.byIcon(Icons.search)); + await tester.pumpAndSettle(); + + await tester.enterText(find.byType(TextField), 'key2'); + + verify(notifierMock.filter('key2')).called(1); + }, + ); + + testWidgets( + 'should refresh on refresh icon clicked', + (WidgetTester tester) async { + stubDataState(); + await pumpKeysPanel(tester); + + await tester.tap(find.byIcon(Icons.refresh)); + await tester.pumpAndSettle(); + + verify(notifierMock.fetchAllKeys()).called(1); + }, + ); + + testWidgets( + 'should select key on key clicked', + (WidgetTester tester) async { + const String keyToSelect = 'keyToSelect'; + stubDataState( + allKeys: const AsyncState>.data([keyToSelect]), + ); + await pumpKeysPanel(tester); + + await tester.tap(find.text(keyToSelect)); + + verify(notifierMock.selectKey(keyToSelect)).called(1); + }, + ); + }); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/ui/shared_preferences_body_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/ui/shared_preferences_body_test.dart new file mode 100644 index 00000000000..d59563fa469 --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/src/ui/shared_preferences_body_test.dart @@ -0,0 +1,46 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +@TestOn('browser') +library; + +import 'package:devtools_extensions/devtools_extensions.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state_provider.dart'; +import 'package:shared_preferences_tool/src/ui/data_panel.dart'; +import 'package:shared_preferences_tool/src/ui/keys_panel.dart'; +import 'package:shared_preferences_tool/src/ui/shared_preferences_body.dart'; + +import '../../test_helpers/notifier_mocking_helpers.dart'; +import '../../test_helpers/notifier_mocking_helpers.mocks.dart'; + +void main() { + group('group name', () { + setupDummies(); + + testWidgets( + 'should show keys and data panels', + (WidgetTester tester) async { + final MockSharedPreferencesStateNotifier notifier = + MockSharedPreferencesStateNotifier(); + when(notifier.value).thenReturn(const SharedPreferencesState()); + + await tester.pumpWidget( + DevToolsExtension( + requiresRunningApplication: false, + child: InnerSharedPreferencesStateProvider( + notifier: notifier, + child: const SharedPreferencesBody(), + ), + ), + ); + + expect(find.byType(KeysPanel), findsOneWidget); + expect(find.byType(DataPanel), findsOneWidget); + }, + ); + }); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.dart b/packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.dart new file mode 100644 index 00000000000..3993f3d3aaa --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.dart @@ -0,0 +1,31 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/annotations.dart'; +import 'package:mockito/mockito.dart'; +import 'package:shared_preferences_tool/src/async_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; +import 'package:shared_preferences_tool/src/shared_preferences_state_notifier.dart'; + +@GenerateNiceMocks(>[ + MockSpec(), +]) +// ignore: unused_import +import 'notifier_mocking_helpers.mocks.dart'; + +void setupDummies() { + setUpAll(() { + provideDummy( + const AsyncState.data( + SharedPreferencesData.int(value: 42), + ), + ); + provideDummy( + const AsyncState.data( + SharedPreferencesState(), + ), + ); + }); +} diff --git a/packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.mocks.dart b/packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.mocks.dart new file mode 100644 index 00000000000..25e4389403c --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.mocks.dart @@ -0,0 +1,186 @@ +// Mocks generated by Mockito 5.4.4 from annotations +// in shared_preferences_tool/test/test_helpers/notifier_mocking_helpers.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i4; +import 'dart:ui' as _i5; + +import 'package:mockito/mockito.dart' as _i1; +import 'package:shared_preferences_tool/src/shared_preferences_state.dart' + as _i2; +import 'package:shared_preferences_tool/src/shared_preferences_state_notifier.dart' + as _i3; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: deprecated_member_use +// ignore_for_file: deprecated_member_use_from_same_package +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeSharedPreferencesState_0 extends _i1.SmartFake + implements _i2.SharedPreferencesState { + _FakeSharedPreferencesState_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [SharedPreferencesStateNotifier]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockSharedPreferencesStateNotifier extends _i1.Mock + implements _i3.SharedPreferencesStateNotifier { + @override + _i2.SharedPreferencesState get value => (super.noSuchMethod( + Invocation.getter(#value), + returnValue: _FakeSharedPreferencesState_0( + this, + Invocation.getter(#value), + ), + returnValueForMissingStub: _FakeSharedPreferencesState_0( + this, + Invocation.getter(#value), + ), + ) as _i2.SharedPreferencesState); + + @override + set value(_i2.SharedPreferencesState? newValue) => super.noSuchMethod( + Invocation.setter( + #value, + newValue, + ), + returnValueForMissingStub: null, + ); + + @override + bool get hasListeners => (super.noSuchMethod( + Invocation.getter(#hasListeners), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + _i4.Future fetchAllKeys() => (super.noSuchMethod( + Invocation.method( + #fetchAllKeys, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future selectKey(String? key) => (super.noSuchMethod( + Invocation.method( + #selectKey, + [key], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + void filter(String? token) => super.noSuchMethod( + Invocation.method( + #filter, + [token], + ), + returnValueForMissingStub: null, + ); + + @override + _i4.Future changeValue(_i2.SharedPreferencesData? newValue) => + (super.noSuchMethod( + Invocation.method( + #changeValue, + [newValue], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + _i4.Future deleteSelectedKey() => (super.noSuchMethod( + Invocation.method( + #deleteSelectedKey, + [], + ), + returnValue: _i4.Future.value(), + returnValueForMissingStub: _i4.Future.value(), + ) as _i4.Future); + + @override + void startEditing() => super.noSuchMethod( + Invocation.method( + #startEditing, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void stopEditing() => super.noSuchMethod( + Invocation.method( + #stopEditing, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void selectApi({required bool? legacyApi}) => super.noSuchMethod( + Invocation.method( + #selectApi, + [], + {#legacyApi: legacyApi}, + ), + returnValueForMissingStub: null, + ); + + @override + void addListener(_i5.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #addListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void removeListener(_i5.VoidCallback? listener) => super.noSuchMethod( + Invocation.method( + #removeListener, + [listener], + ), + returnValueForMissingStub: null, + ); + + @override + void dispose() => super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void notifyListeners() => super.noSuchMethod( + Invocation.method( + #notifyListeners, + [], + ), + returnValueForMissingStub: null, + ); +} diff --git a/packages/shared_preferences/shared_preferences_tool/web/index.html b/packages/shared_preferences/shared_preferences_tool/web/index.html new file mode 100644 index 00000000000..9e3773f06dd --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/web/index.html @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + shared_preferences_tool + + + + + + + + + + diff --git a/packages/shared_preferences/shared_preferences_tool/web/manifest.json b/packages/shared_preferences/shared_preferences_tool/web/manifest.json new file mode 100644 index 00000000000..f2fa39ab9af --- /dev/null +++ b/packages/shared_preferences/shared_preferences_tool/web/manifest.json @@ -0,0 +1,11 @@ +{ + "name": "shared_preferences_tool", + "short_name": "shared_preferences_tool", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false +} diff --git a/script/configs/allowed_unpinned_deps.yaml b/script/configs/allowed_unpinned_deps.yaml index 9aa33fd59f8..2ac8f474003 100644 --- a/script/configs/allowed_unpinned_deps.yaml +++ b/script/configs/allowed_unpinned_deps.yaml @@ -35,6 +35,8 @@ - convert - crypto - dart_style +- devtools_app_shared +- devtools_extensions - fake_async - ffi - gcloud From f3c6981d22a471c0c26ae9538258b981aa9806d1 Mon Sep 17 00:00:00 2001 From: adsonpleal Date: Tue, 17 Dec 2024 18:05:25 -0300 Subject: [PATCH 2/3] remove mockito from shared_preferences_tool_eval_test --- .../shared_preferences_tool_eval_test.dart | 96 +- ...ared_preferences_tool_eval_test.mocks.dart | 3305 ----------------- 2 files changed, 65 insertions(+), 3336 deletions(-) delete mode 100644 packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart index 3220526a37d..26621a477e0 100644 --- a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart +++ b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart @@ -6,22 +6,57 @@ import 'dart:async'; import 'package:devtools_app_shared/service.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; import 'package:shared_preferences_tool/src/shared_preferences_state.dart'; import 'package:shared_preferences_tool/src/shared_preferences_tool_eval.dart'; import 'package:vm_service/vm_service.dart'; -@GenerateNiceMocks(>[ - MockSpec(), - MockSpec(), -]) -import 'shared_preferences_tool_eval_test.mocks.dart'; +typedef _Event = (String eventKind, Map eventData); + +// ignore: subtype_of_sealed_class +class _FakeEvalOnDartLibrary extends EvalOnDartLibrary { + _FakeEvalOnDartLibrary(VmService vmService) + : super( + 'fake_library', + vmService, + serviceManager: ServiceManager(), + ); + + final List<_Event> eventLog = <_Event>[]; + + late Future Function() onEval; + + @override + Future eval( + String expression, { + required Disposable? isAlive, + Map? scope, + bool shouldLogError = true, + }) async { + eventLog.add( + ( + 'eval', + { + 'expression': expression, + }, + ), + ); + return onEval(); + } +} + +class _FakeVmService extends VmService { + _FakeVmService() : super(const Stream.empty(), (String _) {}); + + final List<_Event> eventLog = <_Event>[]; + + @override + late Stream onExtensionEvent; +} void main() { group('SharedPreferencesToolEval', () { - late MockEvalOnDartLibrary eval; - late MockVmService vmService; + late _FakeEvalOnDartLibrary eval; + late _FakeVmService vmService; late SharedPreferencesToolEval sharedPreferencesToolEval; void stubEvalMethod({ @@ -30,13 +65,8 @@ void main() { required Map response, }) { final StreamController eventStream = StreamController(); - when(vmService.onExtensionEvent).thenAnswer((_) => eventStream.stream); - when( - eval.eval( - 'SharedPreferencesDevToolsExtensionData().$method', - isAlive: anyNamed('isAlive'), - ), - ).thenAnswer((_) async { + vmService.onExtensionEvent = eventStream.stream; + eval.onEval = () async { eventStream.add( Event( extensionKind: 'shared_preferences.$eventKind', @@ -44,12 +74,12 @@ void main() { ), ); return null; - }); + }; } setUp(() { - eval = MockEvalOnDartLibrary(); - vmService = MockVmService(); + vmService = _FakeVmService(); + eval = _FakeEvalOnDartLibrary(vmService); sharedPreferencesToolEval = SharedPreferencesToolEval(vmService, eval); }); @@ -234,12 +264,21 @@ void main() { false, ); - verify( - eval.eval( - 'SharedPreferencesDevToolsExtensionData().$method', - isAlive: anyNamed('isAlive'), - ), - ).called(1); + expect(eval.eventLog.length, equals(1)); + final ( + String eventKind, + Map eventData, + ) = eval.eventLog.first; + expect( + eventKind, + equals('eval'), + ); + expect( + eventData, + equals({ + 'expression': 'SharedPreferencesDevToolsExtensionData().$method', + }), + ); }); test('should delete key', () async { @@ -256,12 +295,7 @@ void main() { false, ); - verify( - eval.eval( - 'SharedPreferencesDevToolsExtensionData().$method', - isAlive: anyNamed('isAlive'), - ), - ).called(1); + expect(eval.eventLog.length, equals(1)); }); }); } diff --git a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart b/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart deleted file mode 100644 index c76289b2cc8..00000000000 --- a/packages/shared_preferences/shared_preferences_tool/test/src/shared_preferences_tool_eval_test.mocks.dart +++ /dev/null @@ -1,3305 +0,0 @@ -// Mocks generated by Mockito 5.4.4 from annotations -// in shared_preferences_tool/test/src/shared_preferences_tool_eval_test.dart. -// Do not manually edit this file. - -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i4; -import 'dart:ui' as _i8; - -import 'package:devtools_app_shared/src/service/eval_on_dart_library.dart' - as _i5; -import 'package:devtools_app_shared/src/service/service_manager.dart' as _i3; -import 'package:flutter/foundation.dart' as _i7; -import 'package:flutter/widgets.dart' as _i9; -import 'package:mockito/mockito.dart' as _i2; -import 'package:mockito/src/dummies.dart' as _i6; -import 'package:vm_service/vm_service.dart' as _i1; - -// ignore_for_file: type=lint -// ignore_for_file: avoid_redundant_argument_values -// ignore_for_file: avoid_setters_without_getters -// ignore_for_file: comment_references -// ignore_for_file: deprecated_member_use -// ignore_for_file: deprecated_member_use_from_same_package -// ignore_for_file: implementation_imports -// ignore_for_file: invalid_use_of_visible_for_testing_member -// ignore_for_file: prefer_const_constructors -// ignore_for_file: unnecessary_parenthesis -// ignore_for_file: camel_case_types -// ignore_for_file: subtype_of_sealed_class - -class _FakeServiceManager_0 extends _i2.SmartFake - implements _i3.ServiceManager { - _FakeServiceManager_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeVmService_1 extends _i2.SmartFake implements _i1.VmService { - _FakeVmService_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeClass_2 extends _i2.SmartFake implements _i1.Class { - _FakeClass_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeInstance_3 extends _i2.SmartFake implements _i1.Instance { - _FakeInstance_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeInstanceRef_4 extends _i2.SmartFake implements _i1.InstanceRef { - _FakeInstanceRef_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeBreakpoint_5 extends _i2.SmartFake implements _i1.Breakpoint { - _FakeBreakpoint_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeSuccess_6 extends _i2.SmartFake implements _i1.Success { - _FakeSuccess_6( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeIdZone_7 extends _i2.SmartFake implements _i1.IdZone { - _FakeIdZone_7( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeResponse_8 extends _i2.SmartFake implements _i1.Response { - _FakeResponse_8( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeAllocationProfile_9 extends _i2.SmartFake - implements _i1.AllocationProfile { - _FakeAllocationProfile_9( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeCpuSamples_10 extends _i2.SmartFake implements _i1.CpuSamples { - _FakeCpuSamples_10( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeClassList_11 extends _i2.SmartFake implements _i1.ClassList { - _FakeClassList_11( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeFlagList_12 extends _i2.SmartFake implements _i1.FlagList { - _FakeFlagList_12( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeInboundReferences_13 extends _i2.SmartFake - implements _i1.InboundReferences { - _FakeInboundReferences_13( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeInstanceSet_14 extends _i2.SmartFake implements _i1.InstanceSet { - _FakeInstanceSet_14( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeIsolate_15 extends _i2.SmartFake implements _i1.Isolate { - _FakeIsolate_15( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeIsolateGroup_16 extends _i2.SmartFake implements _i1.IsolateGroup { - _FakeIsolateGroup_16( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeEvent_17 extends _i2.SmartFake implements _i1.Event { - _FakeEvent_17( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeMemoryUsage_18 extends _i2.SmartFake implements _i1.MemoryUsage { - _FakeMemoryUsage_18( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeScriptList_19 extends _i2.SmartFake implements _i1.ScriptList { - _FakeScriptList_19( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeObj_20 extends _i2.SmartFake implements _i1.Obj { - _FakeObj_20( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakePerfettoCpuSamples_21 extends _i2.SmartFake - implements _i1.PerfettoCpuSamples { - _FakePerfettoCpuSamples_21( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakePerfettoTimeline_22 extends _i2.SmartFake - implements _i1.PerfettoTimeline { - _FakePerfettoTimeline_22( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakePortList_23 extends _i2.SmartFake implements _i1.PortList { - _FakePortList_23( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeRetainingPath_24 extends _i2.SmartFake implements _i1.RetainingPath { - _FakeRetainingPath_24( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeProcessMemoryUsage_25 extends _i2.SmartFake - implements _i1.ProcessMemoryUsage { - _FakeProcessMemoryUsage_25( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeStack_26 extends _i2.SmartFake implements _i1.Stack { - _FakeStack_26( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeProtocolList_27 extends _i2.SmartFake implements _i1.ProtocolList { - _FakeProtocolList_27( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeSourceReport_28 extends _i2.SmartFake implements _i1.SourceReport { - _FakeSourceReport_28( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeVersion_29 extends _i2.SmartFake implements _i1.Version { - _FakeVersion_29( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeVM_30 extends _i2.SmartFake implements _i1.VM { - _FakeVM_30( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeTimeline_31 extends _i2.SmartFake implements _i1.Timeline { - _FakeTimeline_31( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeTimelineFlags_32 extends _i2.SmartFake implements _i1.TimelineFlags { - _FakeTimelineFlags_32( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeTimestamp_33 extends _i2.SmartFake implements _i1.Timestamp { - _FakeTimestamp_33( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeUriList_34 extends _i2.SmartFake implements _i1.UriList { - _FakeUriList_34( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeReloadReport_35 extends _i2.SmartFake implements _i1.ReloadReport { - _FakeReloadReport_35( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeFuture_36 extends _i2.SmartFake implements _i4.Future { - _FakeFuture_36( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -/// A class which mocks [EvalOnDartLibrary]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockEvalOnDartLibrary extends _i2.Mock implements _i5.EvalOnDartLibrary { - @override - bool get oneRequestAtATime => (super.noSuchMethod( - Invocation.getter(#oneRequestAtATime), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); - - @override - bool get disableBreakpoints => (super.noSuchMethod( - Invocation.getter(#disableBreakpoints), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); - - @override - bool get logExceptions => (super.noSuchMethod( - Invocation.getter(#logExceptions), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); - - @override - _i3.ServiceManager<_i1.VmService> get serviceManager => (super.noSuchMethod( - Invocation.getter(#serviceManager), - returnValue: _FakeServiceManager_0<_i1.VmService>( - this, - Invocation.getter(#serviceManager), - ), - returnValueForMissingStub: _FakeServiceManager_0<_i1.VmService>( - this, - Invocation.getter(#serviceManager), - ), - ) as _i3.ServiceManager<_i1.VmService>); - - @override - String get libraryName => (super.noSuchMethod( - Invocation.getter(#libraryName), - returnValue: _i6.dummyValue( - this, - Invocation.getter(#libraryName), - ), - returnValueForMissingStub: _i6.dummyValue( - this, - Invocation.getter(#libraryName), - ), - ) as String); - - @override - _i1.VmService get service => (super.noSuchMethod( - Invocation.getter(#service), - returnValue: _FakeVmService_1( - this, - Invocation.getter(#service), - ), - returnValueForMissingStub: _FakeVmService_1( - this, - Invocation.getter(#service), - ), - ) as _i1.VmService); - - @override - set allPendingRequestsDone(_i4.Completer? _allPendingRequestsDone) => - super.noSuchMethod( - Invocation.setter( - #allPendingRequestsDone, - _allPendingRequestsDone, - ), - returnValueForMissingStub: null, - ); - - @override - bool get disposed => (super.noSuchMethod( - Invocation.getter(#disposed), - returnValue: false, - returnValueForMissingStub: false, - ) as bool); - - @override - List<_i7.Listenable> get listenables => (super.noSuchMethod( - Invocation.getter(#listenables), - returnValue: <_i7.Listenable>[], - returnValueForMissingStub: <_i7.Listenable>[], - ) as List<_i7.Listenable>); - - @override - List get listeners => (super.noSuchMethod( - Invocation.getter(#listeners), - returnValue: [], - returnValueForMissingStub: [], - ) as List); - - @override - void dispose() => super.noSuchMethod( - Invocation.method( - #dispose, - [], - ), - returnValueForMissingStub: null, - ); - - @override - _i4.Future<_i1.InstanceRef?> eval( - String? expression, { - required _i5.Disposable? isAlive, - Map? scope, - bool? shouldLogError = true, - }) => - (super.noSuchMethod( - Invocation.method( - #eval, - [expression], - { - #isAlive: isAlive, - #scope: scope, - #shouldLogError: shouldLogError, - }, - ), - returnValue: _i4.Future<_i1.InstanceRef?>.value(), - returnValueForMissingStub: _i4.Future<_i1.InstanceRef?>.value(), - ) as _i4.Future<_i1.InstanceRef?>); - - @override - _i4.Future<_i1.InstanceRef?> invoke( - _i1.InstanceRef? instanceRef, - String? name, - List? argRefs, { - required _i5.Disposable? isAlive, - bool? shouldLogError = true, - }) => - (super.noSuchMethod( - Invocation.method( - #invoke, - [ - instanceRef, - name, - argRefs, - ], - { - #isAlive: isAlive, - #shouldLogError: shouldLogError, - }, - ), - returnValue: _i4.Future<_i1.InstanceRef?>.value(), - returnValueForMissingStub: _i4.Future<_i1.InstanceRef?>.value(), - ) as _i4.Future<_i1.InstanceRef?>); - - @override - _i4.Future<_i1.Class?> getClass( - _i1.ClassRef? instance, - _i5.Disposable? isAlive, - ) => - (super.noSuchMethod( - Invocation.method( - #getClass, - [ - instance, - isAlive, - ], - ), - returnValue: _i4.Future<_i1.Class?>.value(), - returnValueForMissingStub: _i4.Future<_i1.Class?>.value(), - ) as _i4.Future<_i1.Class?>); - - @override - _i4.Future<_i1.Class> safeGetClass( - _i1.ClassRef? instance, - _i5.Disposable? isAlive, - ) => - (super.noSuchMethod( - Invocation.method( - #safeGetClass, - [ - instance, - isAlive, - ], - ), - returnValue: _i4.Future<_i1.Class>.value(_FakeClass_2( - this, - Invocation.method( - #safeGetClass, - [ - instance, - isAlive, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Class>.value(_FakeClass_2( - this, - Invocation.method( - #safeGetClass, - [ - instance, - isAlive, - ], - ), - )), - ) as _i4.Future<_i1.Class>); - - @override - _i4.Future<_i1.Func?> getFunc( - _i1.FuncRef? instance, - _i5.Disposable? isAlive, - ) => - (super.noSuchMethod( - Invocation.method( - #getFunc, - [ - instance, - isAlive, - ], - ), - returnValue: _i4.Future<_i1.Func?>.value(), - returnValueForMissingStub: _i4.Future<_i1.Func?>.value(), - ) as _i4.Future<_i1.Func?>); - - @override - _i4.Future<_i1.Instance?> getInstance( - _i4.FutureOr<_i1.InstanceRef>? instanceRefFuture, - _i5.Disposable? isAlive, - ) => - (super.noSuchMethod( - Invocation.method( - #getInstance, - [ - instanceRefFuture, - isAlive, - ], - ), - returnValue: _i4.Future<_i1.Instance?>.value(), - returnValueForMissingStub: _i4.Future<_i1.Instance?>.value(), - ) as _i4.Future<_i1.Instance?>); - - @override - _i4.Future<_i1.Instance> safeGetInstance( - _i4.FutureOr<_i1.InstanceRef>? instanceRefFuture, - _i5.Disposable? isAlive, - ) => - (super.noSuchMethod( - Invocation.method( - #safeGetInstance, - [ - instanceRefFuture, - isAlive, - ], - ), - returnValue: _i4.Future<_i1.Instance>.value(_FakeInstance_3( - this, - Invocation.method( - #safeGetInstance, - [ - instanceRefFuture, - isAlive, - ], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Instance>.value(_FakeInstance_3( - this, - Invocation.method( - #safeGetInstance, - [ - instanceRefFuture, - isAlive, - ], - ), - )), - ) as _i4.Future<_i1.Instance>); - - @override - _i4.Future getHashCode( - _i1.InstanceRef? instance, { - required _i5.Disposable? isAlive, - }) => - (super.noSuchMethod( - Invocation.method( - #getHashCode, - [instance], - {#isAlive: isAlive}, - ), - returnValue: _i4.Future.value(0), - returnValueForMissingStub: _i4.Future.value(0), - ) as _i4.Future); - - @override - _i4.Future<_i1.Instance> evalInstance( - String? expression, { - required _i5.Disposable? isAlive, - Map? scope, - }) => - (super.noSuchMethod( - Invocation.method( - #evalInstance, - [expression], - { - #isAlive: isAlive, - #scope: scope, - }, - ), - returnValue: _i4.Future<_i1.Instance>.value(_FakeInstance_3( - this, - Invocation.method( - #evalInstance, - [expression], - { - #isAlive: isAlive, - #scope: scope, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Instance>.value(_FakeInstance_3( - this, - Invocation.method( - #evalInstance, - [expression], - { - #isAlive: isAlive, - #scope: scope, - }, - ), - )), - ) as _i4.Future<_i1.Instance>); - - @override - _i4.Future<_i1.InstanceRef?> asyncEval( - String? expression, { - required _i5.Disposable? isAlive, - Map? scope, - }) => - (super.noSuchMethod( - Invocation.method( - #asyncEval, - [expression], - { - #isAlive: isAlive, - #scope: scope, - }, - ), - returnValue: _i4.Future<_i1.InstanceRef?>.value(), - returnValueForMissingStub: _i4.Future<_i1.InstanceRef?>.value(), - ) as _i4.Future<_i1.InstanceRef?>); - - @override - _i4.Future<_i1.InstanceRef> safeEval( - String? expression, { - required _i5.Disposable? isAlive, - Map? scope, - }) => - (super.noSuchMethod( - Invocation.method( - #safeEval, - [expression], - { - #isAlive: isAlive, - #scope: scope, - }, - ), - returnValue: _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( - this, - Invocation.method( - #safeEval, - [expression], - { - #isAlive: isAlive, - #scope: scope, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( - this, - Invocation.method( - #safeEval, - [expression], - { - #isAlive: isAlive, - #scope: scope, - }, - ), - )), - ) as _i4.Future<_i1.InstanceRef>); - - @override - _i4.Future addRequest( - _i5.Disposable? isAlive, - _i4.Future Function()? request, - ) => - (super.noSuchMethod( - Invocation.method( - #addRequest, - [ - isAlive, - request, - ], - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); - - @override - _i4.Future getObjHelper( - _i1.ObjRef? instance, - _i5.Disposable? isAlive, { - int? offset, - int? count, - }) => - (super.noSuchMethod( - Invocation.method( - #getObjHelper, - [ - instance, - isAlive, - ], - { - #offset: offset, - #count: count, - }, - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); - - @override - void addAutoDisposeListener( - _i7.Listenable? listenable, [ - _i8.VoidCallback? listener, - String? id, - ]) => - super.noSuchMethod( - Invocation.method( - #addAutoDisposeListener, - [ - listenable, - listener, - id, - ], - ), - returnValueForMissingStub: null, - ); - - @override - void autoDisposeStreamSubscription( - _i4.StreamSubscription? subscription) => - super.noSuchMethod( - Invocation.method( - #autoDisposeStreamSubscription, - [subscription], - ), - returnValueForMissingStub: null, - ); - - @override - void autoDisposeFocusNode(_i9.FocusNode? node) => super.noSuchMethod( - Invocation.method( - #autoDisposeFocusNode, - [node], - ), - returnValueForMissingStub: null, - ); - - @override - void cancelStreamSubscriptions() => super.noSuchMethod( - Invocation.method( - #cancelStreamSubscriptions, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void cancelListeners({List? excludeIds = const []}) => - super.noSuchMethod( - Invocation.method( - #cancelListeners, - [], - {#excludeIds: excludeIds}, - ), - returnValueForMissingStub: null, - ); - - @override - void cancelListener(_i8.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #cancelListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void cancelFocusNodes() => super.noSuchMethod( - Invocation.method( - #cancelFocusNodes, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void callOnceWhenReady({ - required _i8.VoidCallback? callback, - required _i7.ValueListenable? trigger, - required bool Function(T)? readyWhen, - }) => - super.noSuchMethod( - Invocation.method( - #callOnceWhenReady, - [], - { - #callback: callback, - #trigger: trigger, - #readyWhen: readyWhen, - }, - ), - returnValueForMissingStub: null, - ); -} - -/// A class which mocks [VmService]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockVmService extends _i2.Mock implements _i1.VmService { - @override - _i4.Stream get onSend => (super.noSuchMethod( - Invocation.getter(#onSend), - returnValue: _i4.Stream.empty(), - returnValueForMissingStub: _i4.Stream.empty(), - ) as _i4.Stream); - - @override - _i4.Stream get onReceive => (super.noSuchMethod( - Invocation.getter(#onReceive), - returnValue: _i4.Stream.empty(), - returnValueForMissingStub: _i4.Stream.empty(), - ) as _i4.Stream); - - @override - _i4.Future get onDone => (super.noSuchMethod( - Invocation.getter(#onDone), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); - - @override - _i4.Stream<_i1.Event> get onVMEvent => (super.noSuchMethod( - Invocation.getter(#onVMEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onIsolateEvent => (super.noSuchMethod( - Invocation.getter(#onIsolateEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onDebugEvent => (super.noSuchMethod( - Invocation.getter(#onDebugEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onProfilerEvent => (super.noSuchMethod( - Invocation.getter(#onProfilerEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onGCEvent => (super.noSuchMethod( - Invocation.getter(#onGCEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onExtensionEvent => (super.noSuchMethod( - Invocation.getter(#onExtensionEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onTimelineEvent => (super.noSuchMethod( - Invocation.getter(#onTimelineEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onLoggingEvent => (super.noSuchMethod( - Invocation.getter(#onLoggingEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onServiceEvent => (super.noSuchMethod( - Invocation.getter(#onServiceEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onHeapSnapshotEvent => (super.noSuchMethod( - Invocation.getter(#onHeapSnapshotEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onStdoutEvent => (super.noSuchMethod( - Invocation.getter(#onStdoutEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> get onStderrEvent => (super.noSuchMethod( - Invocation.getter(#onStderrEvent), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Stream<_i1.Event> onEvent(String? streamId) => (super.noSuchMethod( - Invocation.method( - #onEvent, - [streamId], - ), - returnValue: _i4.Stream<_i1.Event>.empty(), - returnValueForMissingStub: _i4.Stream<_i1.Event>.empty(), - ) as _i4.Stream<_i1.Event>); - - @override - _i4.Future<_i1.Breakpoint> addBreakpoint( - String? isolateId, - String? scriptId, - int? line, { - int? column, - }) => - (super.noSuchMethod( - Invocation.method( - #addBreakpoint, - [ - isolateId, - scriptId, - line, - ], - {#column: column}, - ), - returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #addBreakpoint, - [ - isolateId, - scriptId, - line, - ], - {#column: column}, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #addBreakpoint, - [ - isolateId, - scriptId, - line, - ], - {#column: column}, - ), - )), - ) as _i4.Future<_i1.Breakpoint>); - - @override - _i4.Future<_i1.Breakpoint> addBreakpointWithScriptUri( - String? isolateId, - String? scriptUri, - int? line, { - int? column, - }) => - (super.noSuchMethod( - Invocation.method( - #addBreakpointWithScriptUri, - [ - isolateId, - scriptUri, - line, - ], - {#column: column}, - ), - returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #addBreakpointWithScriptUri, - [ - isolateId, - scriptUri, - line, - ], - {#column: column}, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #addBreakpointWithScriptUri, - [ - isolateId, - scriptUri, - line, - ], - {#column: column}, - ), - )), - ) as _i4.Future<_i1.Breakpoint>); - - @override - _i4.Future<_i1.Breakpoint> addBreakpointAtEntry( - String? isolateId, - String? functionId, - ) => - (super.noSuchMethod( - Invocation.method( - #addBreakpointAtEntry, - [ - isolateId, - functionId, - ], - ), - returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #addBreakpointAtEntry, - [ - isolateId, - functionId, - ], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #addBreakpointAtEntry, - [ - isolateId, - functionId, - ], - ), - )), - ) as _i4.Future<_i1.Breakpoint>); - - @override - _i4.Future<_i1.Success> clearCpuSamples(String? isolateId) => - (super.noSuchMethod( - Invocation.method( - #clearCpuSamples, - [isolateId], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #clearCpuSamples, - [isolateId], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #clearCpuSamples, - [isolateId], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> clearVMTimeline() => (super.noSuchMethod( - Invocation.method( - #clearVMTimeline, - [], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #clearVMTimeline, - [], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #clearVMTimeline, - [], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.IdZone> createIdZone( - String? isolateId, - String? backingBufferKind, - String? idAssignmentPolicy, { - int? capacity, - }) => - (super.noSuchMethod( - Invocation.method( - #createIdZone, - [ - isolateId, - backingBufferKind, - idAssignmentPolicy, - ], - {#capacity: capacity}, - ), - returnValue: _i4.Future<_i1.IdZone>.value(_FakeIdZone_7( - this, - Invocation.method( - #createIdZone, - [ - isolateId, - backingBufferKind, - idAssignmentPolicy, - ], - {#capacity: capacity}, - ), - )), - returnValueForMissingStub: _i4.Future<_i1.IdZone>.value(_FakeIdZone_7( - this, - Invocation.method( - #createIdZone, - [ - isolateId, - backingBufferKind, - idAssignmentPolicy, - ], - {#capacity: capacity}, - ), - )), - ) as _i4.Future<_i1.IdZone>); - - @override - _i4.Future<_i1.Success> deleteIdZone( - String? isolateId, - String? idZoneId, - ) => - (super.noSuchMethod( - Invocation.method( - #deleteIdZone, - [ - isolateId, - idZoneId, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #deleteIdZone, - [ - isolateId, - idZoneId, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #deleteIdZone, - [ - isolateId, - idZoneId, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> invalidateIdZone( - String? isolateId, - String? idZoneId, - ) => - (super.noSuchMethod( - Invocation.method( - #invalidateIdZone, - [ - isolateId, - idZoneId, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #invalidateIdZone, - [ - isolateId, - idZoneId, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #invalidateIdZone, - [ - isolateId, - idZoneId, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Response> invoke( - String? isolateId, - String? targetId, - String? selector, - List? argumentIds, { - bool? disableBreakpoints, - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #invoke, - [ - isolateId, - targetId, - selector, - argumentIds, - ], - { - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #invoke, - [ - isolateId, - targetId, - selector, - argumentIds, - ], - { - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #invoke, - [ - isolateId, - targetId, - selector, - argumentIds, - ], - { - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - )), - ) as _i4.Future<_i1.Response>); - - @override - _i4.Future<_i1.Response> evaluate( - String? isolateId, - String? targetId, - String? expression, { - Map? scope, - bool? disableBreakpoints, - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #evaluate, - [ - isolateId, - targetId, - expression, - ], - { - #scope: scope, - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #evaluate, - [ - isolateId, - targetId, - expression, - ], - { - #scope: scope, - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #evaluate, - [ - isolateId, - targetId, - expression, - ], - { - #scope: scope, - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - )), - ) as _i4.Future<_i1.Response>); - - @override - _i4.Future<_i1.Response> evaluateInFrame( - String? isolateId, - int? frameIndex, - String? expression, { - Map? scope, - bool? disableBreakpoints, - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #evaluateInFrame, - [ - isolateId, - frameIndex, - expression, - ], - { - #scope: scope, - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #evaluateInFrame, - [ - isolateId, - frameIndex, - expression, - ], - { - #scope: scope, - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #evaluateInFrame, - [ - isolateId, - frameIndex, - expression, - ], - { - #scope: scope, - #disableBreakpoints: disableBreakpoints, - #idZoneId: idZoneId, - }, - ), - )), - ) as _i4.Future<_i1.Response>); - - @override - _i4.Future<_i1.AllocationProfile> getAllocationProfile( - String? isolateId, { - bool? reset, - bool? gc, - }) => - (super.noSuchMethod( - Invocation.method( - #getAllocationProfile, - [isolateId], - { - #reset: reset, - #gc: gc, - }, - ), - returnValue: - _i4.Future<_i1.AllocationProfile>.value(_FakeAllocationProfile_9( - this, - Invocation.method( - #getAllocationProfile, - [isolateId], - { - #reset: reset, - #gc: gc, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.AllocationProfile>.value(_FakeAllocationProfile_9( - this, - Invocation.method( - #getAllocationProfile, - [isolateId], - { - #reset: reset, - #gc: gc, - }, - ), - )), - ) as _i4.Future<_i1.AllocationProfile>); - - @override - _i4.Future<_i1.CpuSamples> getAllocationTraces( - String? isolateId, { - int? timeOriginMicros, - int? timeExtentMicros, - String? classId, - }) => - (super.noSuchMethod( - Invocation.method( - #getAllocationTraces, - [isolateId], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - #classId: classId, - }, - ), - returnValue: _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( - this, - Invocation.method( - #getAllocationTraces, - [isolateId], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - #classId: classId, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( - this, - Invocation.method( - #getAllocationTraces, - [isolateId], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - #classId: classId, - }, - ), - )), - ) as _i4.Future<_i1.CpuSamples>); - - @override - _i4.Future<_i1.ClassList> getClassList(String? isolateId) => - (super.noSuchMethod( - Invocation.method( - #getClassList, - [isolateId], - ), - returnValue: _i4.Future<_i1.ClassList>.value(_FakeClassList_11( - this, - Invocation.method( - #getClassList, - [isolateId], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.ClassList>.value(_FakeClassList_11( - this, - Invocation.method( - #getClassList, - [isolateId], - ), - )), - ) as _i4.Future<_i1.ClassList>); - - @override - _i4.Future<_i1.CpuSamples> getCpuSamples( - String? isolateId, - int? timeOriginMicros, - int? timeExtentMicros, - ) => - (super.noSuchMethod( - Invocation.method( - #getCpuSamples, - [ - isolateId, - timeOriginMicros, - timeExtentMicros, - ], - ), - returnValue: _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( - this, - Invocation.method( - #getCpuSamples, - [ - isolateId, - timeOriginMicros, - timeExtentMicros, - ], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.CpuSamples>.value(_FakeCpuSamples_10( - this, - Invocation.method( - #getCpuSamples, - [ - isolateId, - timeOriginMicros, - timeExtentMicros, - ], - ), - )), - ) as _i4.Future<_i1.CpuSamples>); - - @override - _i4.Future<_i1.FlagList> getFlagList() => (super.noSuchMethod( - Invocation.method( - #getFlagList, - [], - ), - returnValue: _i4.Future<_i1.FlagList>.value(_FakeFlagList_12( - this, - Invocation.method( - #getFlagList, - [], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.FlagList>.value(_FakeFlagList_12( - this, - Invocation.method( - #getFlagList, - [], - ), - )), - ) as _i4.Future<_i1.FlagList>); - - @override - _i4.Future<_i1.InboundReferences> getInboundReferences( - String? isolateId, - String? targetId, - int? limit, { - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #getInboundReferences, - [ - isolateId, - targetId, - limit, - ], - {#idZoneId: idZoneId}, - ), - returnValue: - _i4.Future<_i1.InboundReferences>.value(_FakeInboundReferences_13( - this, - Invocation.method( - #getInboundReferences, - [ - isolateId, - targetId, - limit, - ], - {#idZoneId: idZoneId}, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.InboundReferences>.value(_FakeInboundReferences_13( - this, - Invocation.method( - #getInboundReferences, - [ - isolateId, - targetId, - limit, - ], - {#idZoneId: idZoneId}, - ), - )), - ) as _i4.Future<_i1.InboundReferences>); - - @override - _i4.Future<_i1.InstanceSet> getInstances( - String? isolateId, - String? objectId, - int? limit, { - bool? includeSubclasses, - bool? includeImplementers, - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #getInstances, - [ - isolateId, - objectId, - limit, - ], - { - #includeSubclasses: includeSubclasses, - #includeImplementers: includeImplementers, - #idZoneId: idZoneId, - }, - ), - returnValue: _i4.Future<_i1.InstanceSet>.value(_FakeInstanceSet_14( - this, - Invocation.method( - #getInstances, - [ - isolateId, - objectId, - limit, - ], - { - #includeSubclasses: includeSubclasses, - #includeImplementers: includeImplementers, - #idZoneId: idZoneId, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.InstanceSet>.value(_FakeInstanceSet_14( - this, - Invocation.method( - #getInstances, - [ - isolateId, - objectId, - limit, - ], - { - #includeSubclasses: includeSubclasses, - #includeImplementers: includeImplementers, - #idZoneId: idZoneId, - }, - ), - )), - ) as _i4.Future<_i1.InstanceSet>); - - @override - _i4.Future<_i1.InstanceRef> getInstancesAsList( - String? isolateId, - String? objectId, { - bool? includeSubclasses, - bool? includeImplementers, - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #getInstancesAsList, - [ - isolateId, - objectId, - ], - { - #includeSubclasses: includeSubclasses, - #includeImplementers: includeImplementers, - #idZoneId: idZoneId, - }, - ), - returnValue: _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( - this, - Invocation.method( - #getInstancesAsList, - [ - isolateId, - objectId, - ], - { - #includeSubclasses: includeSubclasses, - #includeImplementers: includeImplementers, - #idZoneId: idZoneId, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.InstanceRef>.value(_FakeInstanceRef_4( - this, - Invocation.method( - #getInstancesAsList, - [ - isolateId, - objectId, - ], - { - #includeSubclasses: includeSubclasses, - #includeImplementers: includeImplementers, - #idZoneId: idZoneId, - }, - ), - )), - ) as _i4.Future<_i1.InstanceRef>); - - @override - _i4.Future<_i1.Isolate> getIsolate(String? isolateId) => (super.noSuchMethod( - Invocation.method( - #getIsolate, - [isolateId], - ), - returnValue: _i4.Future<_i1.Isolate>.value(_FakeIsolate_15( - this, - Invocation.method( - #getIsolate, - [isolateId], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Isolate>.value(_FakeIsolate_15( - this, - Invocation.method( - #getIsolate, - [isolateId], - ), - )), - ) as _i4.Future<_i1.Isolate>); - - @override - _i4.Future<_i1.IsolateGroup> getIsolateGroup(String? isolateGroupId) => - (super.noSuchMethod( - Invocation.method( - #getIsolateGroup, - [isolateGroupId], - ), - returnValue: _i4.Future<_i1.IsolateGroup>.value(_FakeIsolateGroup_16( - this, - Invocation.method( - #getIsolateGroup, - [isolateGroupId], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.IsolateGroup>.value(_FakeIsolateGroup_16( - this, - Invocation.method( - #getIsolateGroup, - [isolateGroupId], - ), - )), - ) as _i4.Future<_i1.IsolateGroup>); - - @override - _i4.Future<_i1.Event> getIsolatePauseEvent(String? isolateId) => - (super.noSuchMethod( - Invocation.method( - #getIsolatePauseEvent, - [isolateId], - ), - returnValue: _i4.Future<_i1.Event>.value(_FakeEvent_17( - this, - Invocation.method( - #getIsolatePauseEvent, - [isolateId], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Event>.value(_FakeEvent_17( - this, - Invocation.method( - #getIsolatePauseEvent, - [isolateId], - ), - )), - ) as _i4.Future<_i1.Event>); - - @override - _i4.Future<_i1.MemoryUsage> getMemoryUsage(String? isolateId) => - (super.noSuchMethod( - Invocation.method( - #getMemoryUsage, - [isolateId], - ), - returnValue: _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( - this, - Invocation.method( - #getMemoryUsage, - [isolateId], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( - this, - Invocation.method( - #getMemoryUsage, - [isolateId], - ), - )), - ) as _i4.Future<_i1.MemoryUsage>); - - @override - _i4.Future<_i1.MemoryUsage> getIsolateGroupMemoryUsage( - String? isolateGroupId) => - (super.noSuchMethod( - Invocation.method( - #getIsolateGroupMemoryUsage, - [isolateGroupId], - ), - returnValue: _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( - this, - Invocation.method( - #getIsolateGroupMemoryUsage, - [isolateGroupId], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.MemoryUsage>.value(_FakeMemoryUsage_18( - this, - Invocation.method( - #getIsolateGroupMemoryUsage, - [isolateGroupId], - ), - )), - ) as _i4.Future<_i1.MemoryUsage>); - - @override - _i4.Future<_i1.ScriptList> getScripts(String? isolateId) => - (super.noSuchMethod( - Invocation.method( - #getScripts, - [isolateId], - ), - returnValue: _i4.Future<_i1.ScriptList>.value(_FakeScriptList_19( - this, - Invocation.method( - #getScripts, - [isolateId], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.ScriptList>.value(_FakeScriptList_19( - this, - Invocation.method( - #getScripts, - [isolateId], - ), - )), - ) as _i4.Future<_i1.ScriptList>); - - @override - _i4.Future<_i1.Obj> getObject( - String? isolateId, - String? objectId, { - int? offset, - int? count, - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #getObject, - [ - isolateId, - objectId, - ], - { - #offset: offset, - #count: count, - #idZoneId: idZoneId, - }, - ), - returnValue: _i4.Future<_i1.Obj>.value(_FakeObj_20( - this, - Invocation.method( - #getObject, - [ - isolateId, - objectId, - ], - { - #offset: offset, - #count: count, - #idZoneId: idZoneId, - }, - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Obj>.value(_FakeObj_20( - this, - Invocation.method( - #getObject, - [ - isolateId, - objectId, - ], - { - #offset: offset, - #count: count, - #idZoneId: idZoneId, - }, - ), - )), - ) as _i4.Future<_i1.Obj>); - - @override - _i4.Future<_i1.PerfettoCpuSamples> getPerfettoCpuSamples( - String? isolateId, { - int? timeOriginMicros, - int? timeExtentMicros, - }) => - (super.noSuchMethod( - Invocation.method( - #getPerfettoCpuSamples, - [isolateId], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - returnValue: - _i4.Future<_i1.PerfettoCpuSamples>.value(_FakePerfettoCpuSamples_21( - this, - Invocation.method( - #getPerfettoCpuSamples, - [isolateId], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.PerfettoCpuSamples>.value(_FakePerfettoCpuSamples_21( - this, - Invocation.method( - #getPerfettoCpuSamples, - [isolateId], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - )), - ) as _i4.Future<_i1.PerfettoCpuSamples>); - - @override - _i4.Future<_i1.PerfettoTimeline> getPerfettoVMTimeline({ - int? timeOriginMicros, - int? timeExtentMicros, - }) => - (super.noSuchMethod( - Invocation.method( - #getPerfettoVMTimeline, - [], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - returnValue: - _i4.Future<_i1.PerfettoTimeline>.value(_FakePerfettoTimeline_22( - this, - Invocation.method( - #getPerfettoVMTimeline, - [], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.PerfettoTimeline>.value(_FakePerfettoTimeline_22( - this, - Invocation.method( - #getPerfettoVMTimeline, - [], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - )), - ) as _i4.Future<_i1.PerfettoTimeline>); - - @override - _i4.Future<_i1.PortList> getPorts(String? isolateId) => (super.noSuchMethod( - Invocation.method( - #getPorts, - [isolateId], - ), - returnValue: _i4.Future<_i1.PortList>.value(_FakePortList_23( - this, - Invocation.method( - #getPorts, - [isolateId], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.PortList>.value(_FakePortList_23( - this, - Invocation.method( - #getPorts, - [isolateId], - ), - )), - ) as _i4.Future<_i1.PortList>); - - @override - _i4.Future<_i1.RetainingPath> getRetainingPath( - String? isolateId, - String? targetId, - int? limit, { - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #getRetainingPath, - [ - isolateId, - targetId, - limit, - ], - {#idZoneId: idZoneId}, - ), - returnValue: _i4.Future<_i1.RetainingPath>.value(_FakeRetainingPath_24( - this, - Invocation.method( - #getRetainingPath, - [ - isolateId, - targetId, - limit, - ], - {#idZoneId: idZoneId}, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.RetainingPath>.value(_FakeRetainingPath_24( - this, - Invocation.method( - #getRetainingPath, - [ - isolateId, - targetId, - limit, - ], - {#idZoneId: idZoneId}, - ), - )), - ) as _i4.Future<_i1.RetainingPath>); - - @override - _i4.Future<_i1.ProcessMemoryUsage> getProcessMemoryUsage() => - (super.noSuchMethod( - Invocation.method( - #getProcessMemoryUsage, - [], - ), - returnValue: - _i4.Future<_i1.ProcessMemoryUsage>.value(_FakeProcessMemoryUsage_25( - this, - Invocation.method( - #getProcessMemoryUsage, - [], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.ProcessMemoryUsage>.value(_FakeProcessMemoryUsage_25( - this, - Invocation.method( - #getProcessMemoryUsage, - [], - ), - )), - ) as _i4.Future<_i1.ProcessMemoryUsage>); - - @override - _i4.Future<_i1.Stack> getStack( - String? isolateId, { - int? limit, - String? idZoneId, - }) => - (super.noSuchMethod( - Invocation.method( - #getStack, - [isolateId], - { - #limit: limit, - #idZoneId: idZoneId, - }, - ), - returnValue: _i4.Future<_i1.Stack>.value(_FakeStack_26( - this, - Invocation.method( - #getStack, - [isolateId], - { - #limit: limit, - #idZoneId: idZoneId, - }, - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Stack>.value(_FakeStack_26( - this, - Invocation.method( - #getStack, - [isolateId], - { - #limit: limit, - #idZoneId: idZoneId, - }, - ), - )), - ) as _i4.Future<_i1.Stack>); - - @override - _i4.Future<_i1.ProtocolList> getSupportedProtocols() => (super.noSuchMethod( - Invocation.method( - #getSupportedProtocols, - [], - ), - returnValue: _i4.Future<_i1.ProtocolList>.value(_FakeProtocolList_27( - this, - Invocation.method( - #getSupportedProtocols, - [], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.ProtocolList>.value(_FakeProtocolList_27( - this, - Invocation.method( - #getSupportedProtocols, - [], - ), - )), - ) as _i4.Future<_i1.ProtocolList>); - - @override - _i4.Future<_i1.SourceReport> getSourceReport( - String? isolateId, - List? reports, { - String? scriptId, - int? tokenPos, - int? endTokenPos, - bool? forceCompile, - bool? reportLines, - List? libraryFilters, - List? librariesAlreadyCompiled, - }) => - (super.noSuchMethod( - Invocation.method( - #getSourceReport, - [ - isolateId, - reports, - ], - { - #scriptId: scriptId, - #tokenPos: tokenPos, - #endTokenPos: endTokenPos, - #forceCompile: forceCompile, - #reportLines: reportLines, - #libraryFilters: libraryFilters, - #librariesAlreadyCompiled: librariesAlreadyCompiled, - }, - ), - returnValue: _i4.Future<_i1.SourceReport>.value(_FakeSourceReport_28( - this, - Invocation.method( - #getSourceReport, - [ - isolateId, - reports, - ], - { - #scriptId: scriptId, - #tokenPos: tokenPos, - #endTokenPos: endTokenPos, - #forceCompile: forceCompile, - #reportLines: reportLines, - #libraryFilters: libraryFilters, - #librariesAlreadyCompiled: librariesAlreadyCompiled, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.SourceReport>.value(_FakeSourceReport_28( - this, - Invocation.method( - #getSourceReport, - [ - isolateId, - reports, - ], - { - #scriptId: scriptId, - #tokenPos: tokenPos, - #endTokenPos: endTokenPos, - #forceCompile: forceCompile, - #reportLines: reportLines, - #libraryFilters: libraryFilters, - #librariesAlreadyCompiled: librariesAlreadyCompiled, - }, - ), - )), - ) as _i4.Future<_i1.SourceReport>); - - @override - _i4.Future<_i1.Version> getVersion() => (super.noSuchMethod( - Invocation.method( - #getVersion, - [], - ), - returnValue: _i4.Future<_i1.Version>.value(_FakeVersion_29( - this, - Invocation.method( - #getVersion, - [], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Version>.value(_FakeVersion_29( - this, - Invocation.method( - #getVersion, - [], - ), - )), - ) as _i4.Future<_i1.Version>); - - @override - _i4.Future<_i1.VM> getVM() => (super.noSuchMethod( - Invocation.method( - #getVM, - [], - ), - returnValue: _i4.Future<_i1.VM>.value(_FakeVM_30( - this, - Invocation.method( - #getVM, - [], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.VM>.value(_FakeVM_30( - this, - Invocation.method( - #getVM, - [], - ), - )), - ) as _i4.Future<_i1.VM>); - - @override - _i4.Future<_i1.Timeline> getVMTimeline({ - int? timeOriginMicros, - int? timeExtentMicros, - }) => - (super.noSuchMethod( - Invocation.method( - #getVMTimeline, - [], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - returnValue: _i4.Future<_i1.Timeline>.value(_FakeTimeline_31( - this, - Invocation.method( - #getVMTimeline, - [], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Timeline>.value(_FakeTimeline_31( - this, - Invocation.method( - #getVMTimeline, - [], - { - #timeOriginMicros: timeOriginMicros, - #timeExtentMicros: timeExtentMicros, - }, - ), - )), - ) as _i4.Future<_i1.Timeline>); - - @override - _i4.Future<_i1.TimelineFlags> getVMTimelineFlags() => (super.noSuchMethod( - Invocation.method( - #getVMTimelineFlags, - [], - ), - returnValue: _i4.Future<_i1.TimelineFlags>.value(_FakeTimelineFlags_32( - this, - Invocation.method( - #getVMTimelineFlags, - [], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.TimelineFlags>.value(_FakeTimelineFlags_32( - this, - Invocation.method( - #getVMTimelineFlags, - [], - ), - )), - ) as _i4.Future<_i1.TimelineFlags>); - - @override - _i4.Future<_i1.Timestamp> getVMTimelineMicros() => (super.noSuchMethod( - Invocation.method( - #getVMTimelineMicros, - [], - ), - returnValue: _i4.Future<_i1.Timestamp>.value(_FakeTimestamp_33( - this, - Invocation.method( - #getVMTimelineMicros, - [], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Timestamp>.value(_FakeTimestamp_33( - this, - Invocation.method( - #getVMTimelineMicros, - [], - ), - )), - ) as _i4.Future<_i1.Timestamp>); - - @override - _i4.Future<_i1.Success> pause(String? isolateId) => (super.noSuchMethod( - Invocation.method( - #pause, - [isolateId], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #pause, - [isolateId], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #pause, - [isolateId], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> kill(String? isolateId) => (super.noSuchMethod( - Invocation.method( - #kill, - [isolateId], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #kill, - [isolateId], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #kill, - [isolateId], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.UriList> lookupResolvedPackageUris( - String? isolateId, - List? uris, { - bool? local, - }) => - (super.noSuchMethod( - Invocation.method( - #lookupResolvedPackageUris, - [ - isolateId, - uris, - ], - {#local: local}, - ), - returnValue: _i4.Future<_i1.UriList>.value(_FakeUriList_34( - this, - Invocation.method( - #lookupResolvedPackageUris, - [ - isolateId, - uris, - ], - {#local: local}, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.UriList>.value(_FakeUriList_34( - this, - Invocation.method( - #lookupResolvedPackageUris, - [ - isolateId, - uris, - ], - {#local: local}, - ), - )), - ) as _i4.Future<_i1.UriList>); - - @override - _i4.Future<_i1.UriList> lookupPackageUris( - String? isolateId, - List? uris, - ) => - (super.noSuchMethod( - Invocation.method( - #lookupPackageUris, - [ - isolateId, - uris, - ], - ), - returnValue: _i4.Future<_i1.UriList>.value(_FakeUriList_34( - this, - Invocation.method( - #lookupPackageUris, - [ - isolateId, - uris, - ], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.UriList>.value(_FakeUriList_34( - this, - Invocation.method( - #lookupPackageUris, - [ - isolateId, - uris, - ], - ), - )), - ) as _i4.Future<_i1.UriList>); - - @override - _i4.Future<_i1.Success> registerService( - String? service, - String? alias, - ) => - (super.noSuchMethod( - Invocation.method( - #registerService, - [ - service, - alias, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #registerService, - [ - service, - alias, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #registerService, - [ - service, - alias, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.ReloadReport> reloadSources( - String? isolateId, { - bool? force, - bool? pause, - String? rootLibUri, - String? packagesUri, - }) => - (super.noSuchMethod( - Invocation.method( - #reloadSources, - [isolateId], - { - #force: force, - #pause: pause, - #rootLibUri: rootLibUri, - #packagesUri: packagesUri, - }, - ), - returnValue: _i4.Future<_i1.ReloadReport>.value(_FakeReloadReport_35( - this, - Invocation.method( - #reloadSources, - [isolateId], - { - #force: force, - #pause: pause, - #rootLibUri: rootLibUri, - #packagesUri: packagesUri, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.ReloadReport>.value(_FakeReloadReport_35( - this, - Invocation.method( - #reloadSources, - [isolateId], - { - #force: force, - #pause: pause, - #rootLibUri: rootLibUri, - #packagesUri: packagesUri, - }, - ), - )), - ) as _i4.Future<_i1.ReloadReport>); - - @override - _i4.Future<_i1.Success> removeBreakpoint( - String? isolateId, - String? breakpointId, - ) => - (super.noSuchMethod( - Invocation.method( - #removeBreakpoint, - [ - isolateId, - breakpointId, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #removeBreakpoint, - [ - isolateId, - breakpointId, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #removeBreakpoint, - [ - isolateId, - breakpointId, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> requestHeapSnapshot(String? isolateId) => - (super.noSuchMethod( - Invocation.method( - #requestHeapSnapshot, - [isolateId], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #requestHeapSnapshot, - [isolateId], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #requestHeapSnapshot, - [isolateId], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> resume( - String? isolateId, { - String? step, - int? frameIndex, - }) => - (super.noSuchMethod( - Invocation.method( - #resume, - [isolateId], - { - #step: step, - #frameIndex: frameIndex, - }, - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #resume, - [isolateId], - { - #step: step, - #frameIndex: frameIndex, - }, - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #resume, - [isolateId], - { - #step: step, - #frameIndex: frameIndex, - }, - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Breakpoint> setBreakpointState( - String? isolateId, - String? breakpointId, - bool? enable, - ) => - (super.noSuchMethod( - Invocation.method( - #setBreakpointState, - [ - isolateId, - breakpointId, - enable, - ], - ), - returnValue: _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #setBreakpointState, - [ - isolateId, - breakpointId, - enable, - ], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Breakpoint>.value(_FakeBreakpoint_5( - this, - Invocation.method( - #setBreakpointState, - [ - isolateId, - breakpointId, - enable, - ], - ), - )), - ) as _i4.Future<_i1.Breakpoint>); - - @override - _i4.Future<_i1.Success> setExceptionPauseMode( - String? isolateId, - String? mode, - ) => - (super.noSuchMethod( - Invocation.method( - #setExceptionPauseMode, - [ - isolateId, - mode, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setExceptionPauseMode, - [ - isolateId, - mode, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setExceptionPauseMode, - [ - isolateId, - mode, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> setIsolatePauseMode( - String? isolateId, { - String? exceptionPauseMode, - bool? shouldPauseOnExit, - }) => - (super.noSuchMethod( - Invocation.method( - #setIsolatePauseMode, - [isolateId], - { - #exceptionPauseMode: exceptionPauseMode, - #shouldPauseOnExit: shouldPauseOnExit, - }, - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setIsolatePauseMode, - [isolateId], - { - #exceptionPauseMode: exceptionPauseMode, - #shouldPauseOnExit: shouldPauseOnExit, - }, - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setIsolatePauseMode, - [isolateId], - { - #exceptionPauseMode: exceptionPauseMode, - #shouldPauseOnExit: shouldPauseOnExit, - }, - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Response> setFlag( - String? name, - String? value, - ) => - (super.noSuchMethod( - Invocation.method( - #setFlag, - [ - name, - value, - ], - ), - returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #setFlag, - [ - name, - value, - ], - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #setFlag, - [ - name, - value, - ], - ), - )), - ) as _i4.Future<_i1.Response>); - - @override - _i4.Future<_i1.Success> setLibraryDebuggable( - String? isolateId, - String? libraryId, - bool? isDebuggable, - ) => - (super.noSuchMethod( - Invocation.method( - #setLibraryDebuggable, - [ - isolateId, - libraryId, - isDebuggable, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setLibraryDebuggable, - [ - isolateId, - libraryId, - isDebuggable, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setLibraryDebuggable, - [ - isolateId, - libraryId, - isDebuggable, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> setName( - String? isolateId, - String? name, - ) => - (super.noSuchMethod( - Invocation.method( - #setName, - [ - isolateId, - name, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setName, - [ - isolateId, - name, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setName, - [ - isolateId, - name, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> setTraceClassAllocation( - String? isolateId, - String? classId, - bool? enable, - ) => - (super.noSuchMethod( - Invocation.method( - #setTraceClassAllocation, - [ - isolateId, - classId, - enable, - ], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setTraceClassAllocation, - [ - isolateId, - classId, - enable, - ], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setTraceClassAllocation, - [ - isolateId, - classId, - enable, - ], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> setVMName(String? name) => (super.noSuchMethod( - Invocation.method( - #setVMName, - [name], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setVMName, - [name], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setVMName, - [name], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> setVMTimelineFlags(List? recordedStreams) => - (super.noSuchMethod( - Invocation.method( - #setVMTimelineFlags, - [recordedStreams], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setVMTimelineFlags, - [recordedStreams], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #setVMTimelineFlags, - [recordedStreams], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> streamCancel(String? streamId) => (super.noSuchMethod( - Invocation.method( - #streamCancel, - [streamId], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #streamCancel, - [streamId], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #streamCancel, - [streamId], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> streamCpuSamplesWithUserTag(List? userTags) => - (super.noSuchMethod( - Invocation.method( - #streamCpuSamplesWithUserTag, - [userTags], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #streamCpuSamplesWithUserTag, - [userTags], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #streamCpuSamplesWithUserTag, - [userTags], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Success> streamListen(String? streamId) => (super.noSuchMethod( - Invocation.method( - #streamListen, - [streamId], - ), - returnValue: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #streamListen, - [streamId], - ), - )), - returnValueForMissingStub: _i4.Future<_i1.Success>.value(_FakeSuccess_6( - this, - Invocation.method( - #streamListen, - [streamId], - ), - )), - ) as _i4.Future<_i1.Success>); - - @override - _i4.Future<_i1.Response> callMethod( - String? method, { - String? isolateId, - Map? args, - }) => - (super.noSuchMethod( - Invocation.method( - #callMethod, - [method], - { - #isolateId: isolateId, - #args: args, - }, - ), - returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #callMethod, - [method], - { - #isolateId: isolateId, - #args: args, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #callMethod, - [method], - { - #isolateId: isolateId, - #args: args, - }, - ), - )), - ) as _i4.Future<_i1.Response>); - - @override - _i4.Future<_i1.Response> callServiceExtension( - String? method, { - String? isolateId, - Map? args, - }) => - (super.noSuchMethod( - Invocation.method( - #callServiceExtension, - [method], - { - #isolateId: isolateId, - #args: args, - }, - ), - returnValue: _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #callServiceExtension, - [method], - { - #isolateId: isolateId, - #args: args, - }, - ), - )), - returnValueForMissingStub: - _i4.Future<_i1.Response>.value(_FakeResponse_8( - this, - Invocation.method( - #callServiceExtension, - [method], - { - #isolateId: isolateId, - #args: args, - }, - ), - )), - ) as _i4.Future<_i1.Response>); - - @override - _i4.Future dispose() => (super.noSuchMethod( - Invocation.method( - #dispose, - [], - ), - returnValue: _i4.Future.value(), - returnValueForMissingStub: _i4.Future.value(), - ) as _i4.Future); - - @override - _i4.Future wrapFuture( - String? name, - _i4.Future? future, - ) => - (super.noSuchMethod( - Invocation.method( - #wrapFuture, - [ - name, - future, - ], - ), - returnValue: _i6.ifNotNull( - _i6.dummyValueOrNull( - this, - Invocation.method( - #wrapFuture, - [ - name, - future, - ], - ), - ), - (T v) => _i4.Future.value(v), - ) ?? - _FakeFuture_36( - this, - Invocation.method( - #wrapFuture, - [ - name, - future, - ], - ), - ), - returnValueForMissingStub: _i6.ifNotNull( - _i6.dummyValueOrNull( - this, - Invocation.method( - #wrapFuture, - [ - name, - future, - ], - ), - ), - (T v) => _i4.Future.value(v), - ) ?? - _FakeFuture_36( - this, - Invocation.method( - #wrapFuture, - [ - name, - future, - ], - ), - ), - ) as _i4.Future); - - @override - void registerServiceCallback( - String? service, - _i1.ServiceCallback? cb, - ) => - super.noSuchMethod( - Invocation.method( - #registerServiceCallback, - [ - service, - cb, - ], - ), - returnValueForMissingStub: null, - ); -} From 1875caa301bd41461ee25f3a5de8960f42e96d55 Mon Sep 17 00:00:00 2001 From: adsonpleal Date: Thu, 16 Jan 2025 14:09:25 -0300 Subject: [PATCH 3/3] update SDK constraints --- .../shared_preferences/shared_preferences_tool/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/shared_preferences/shared_preferences_tool/pubspec.yaml b/packages/shared_preferences/shared_preferences_tool/pubspec.yaml index 3f06964acec..c3f2f5d3036 100644 --- a/packages/shared_preferences/shared_preferences_tool/pubspec.yaml +++ b/packages/shared_preferences/shared_preferences_tool/pubspec.yaml @@ -5,7 +5,7 @@ publish_to: 'none' version: 1.0.0+1 environment: - sdk: '>=3.4.0 <4.0.0' + sdk: '>=3.6.0 <4.0.0' dependencies: devtools_app_shared: ^0.3.0