[various] Adopt `plugin_platform_interface` (#6332)
diff --git a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md
index 591f36e..cc88c07 100644
--- a/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md
+++ b/packages/google_sign_in/google_sign_in_platform_interface/CHANGELOG.md
@@ -1,3 +1,8 @@
+## 2.3.0
+
+* Adopts `plugin_platform_interface`. As a result, `isMock` is deprecated in
+ favor of the now-standard `MockPlatformInterfaceMixin`.
+
## 2.2.0
* Adds support for the `serverClientId` parameter.
diff --git a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart
index 69d8455..64fc88d 100644
--- a/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart
+++ b/packages/google_sign_in/google_sign_in_platform_interface/lib/google_sign_in_platform_interface.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import 'package:flutter/foundation.dart' show visibleForTesting;
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'src/method_channel_google_sign_in.dart';
import 'src/types.dart';
@@ -20,13 +21,19 @@
/// ensures that the subclass will get the default implementation, while
/// platform implementations that `implements` this interface will be broken by
/// newly added [GoogleSignInPlatform] methods.
-abstract class GoogleSignInPlatform {
+abstract class GoogleSignInPlatform extends PlatformInterface {
+ /// Constructs a GoogleSignInPlatform.
+ GoogleSignInPlatform() : super(token: _token);
+
+ static final Object _token = Object();
+
/// Only mock implementations should set this to `true`.
///
/// Mockito mocks implement this class with `implements` which is forbidden
/// (see class docs). This property provides a backdoor for mocks to skip the
/// verification that the class isn't implemented with `implements`.
@visibleForTesting
+ @Deprecated('Use MockPlatformInterfaceMixin instead')
bool get isMock => false;
/// The default instance of [GoogleSignInPlatform] to use.
@@ -44,25 +51,11 @@
// https://github.com/flutter/flutter/issues/43368
static set instance(GoogleSignInPlatform instance) {
if (!instance.isMock) {
- try {
- instance._verifyProvidesDefaultImplementations();
- } on NoSuchMethodError catch (_) {
- throw AssertionError(
- 'Platform interfaces must not be implemented with `implements`');
- }
+ PlatformInterface.verify(instance, _token);
}
_instance = instance;
}
- /// This method ensures that [GoogleSignInPlatform] isn't implemented with `implements`.
- ///
- /// See class docs for more details on why using `implements` to implement
- /// [GoogleSignInPlatform] is forbidden.
- ///
- /// This private method is called by the [instance] setter, which should fail
- /// if the provided instance is a class implemented with `implements`.
- void _verifyProvidesDefaultImplementations() {}
-
/// Initializes the plugin. Deprecated: call [initWithParams] instead.
///
/// The [hostedDomain] argument specifies a hosted domain restriction. By
diff --git a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml
index 9ad3e1c..aa9c8f6 100644
--- a/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml
+++ b/packages/google_sign_in/google_sign_in_platform_interface/pubspec.yaml
@@ -4,7 +4,7 @@
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+google_sign_in%22
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
-version: 2.2.0
+version: 2.3.0
environment:
sdk: ">=2.12.0 <3.0.0"
@@ -13,6 +13,7 @@
dependencies:
flutter:
sdk: flutter
+ plugin_platform_interface: ^2.1.0
quiver: ^3.0.0
dev_dependencies:
diff --git a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart
index 6ffa85f..057f13c 100644
--- a/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart
+++ b/packages/google_sign_in/google_sign_in_platform_interface/test/google_sign_in_platform_interface_test.dart
@@ -5,6 +5,7 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:google_sign_in_platform_interface/google_sign_in_platform_interface.dart';
import 'package:mockito/mockito.dart';
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
void main() {
// Store the initial instance before any tests change it.
@@ -33,7 +34,11 @@
});
test('Can be mocked with `implements`', () {
- GoogleSignInPlatform.instance = ImplementsWithIsMock();
+ GoogleSignInPlatform.instance = ModernMockImplementation();
+ });
+
+ test('still supports legacy isMock', () {
+ GoogleSignInPlatform.instance = LegacyIsMockImplementation();
});
});
@@ -76,11 +81,18 @@
});
}
-class ImplementsWithIsMock extends Mock implements GoogleSignInPlatform {
+class LegacyIsMockImplementation extends Mock implements GoogleSignInPlatform {
@override
bool get isMock => true;
}
+class ModernMockImplementation extends Mock
+ with MockPlatformInterfaceMixin
+ implements GoogleSignInPlatform {
+ @override
+ bool get isMock => false;
+}
+
class ImplementsGoogleSignInPlatform extends Mock
implements GoogleSignInPlatform {}
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md
index 51b5965..12d6132 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md
+++ b/packages/shared_preferences/shared_preferences_platform_interface/CHANGELOG.md
@@ -1,6 +1,7 @@
-## NEXT
+## 2.1.0
-* Fixes newly enabled analyzer options.
+* Adopts `plugin_platform_interface`. As a result, `isMock` is deprecated in
+ favor of the now-standard `MockPlatformInterfaceMixin`.
## 2.0.0
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart
index 8023c86..ced6aa5 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart
+++ b/packages/shared_preferences/shared_preferences_platform_interface/lib/shared_preferences_platform_interface.dart
@@ -5,6 +5,7 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'method_channel_shared_preferences.dart';
@@ -15,7 +16,12 @@
/// (using `extends`) ensures that the subclass will get the default implementation, while
/// platform implementations that `implements` this interface will be broken by newly added
/// [SharedPreferencesStorePlatform] methods.
-abstract class SharedPreferencesStorePlatform {
+abstract class SharedPreferencesStorePlatform extends PlatformInterface {
+ /// Constructs a SharedPreferencesStorePlatform.
+ SharedPreferencesStorePlatform() : super(token: _token);
+
+ static final Object _token = Object();
+
/// The default instance of [SharedPreferencesStorePlatform] to use.
///
/// Defaults to [MethodChannelSharedPreferencesStore].
@@ -23,16 +29,11 @@
/// Platform-specific plugins should set this with their own platform-specific
/// class that extends [SharedPreferencesStorePlatform] when they register themselves.
- static set instance(SharedPreferencesStorePlatform value) {
- if (!value.isMock) {
- try {
- value._verifyProvidesDefaultImplementations();
- } on NoSuchMethodError catch (_) {
- throw AssertionError(
- 'Platform interfaces must not be implemented with `implements`');
- }
+ static set instance(SharedPreferencesStorePlatform instance) {
+ if (!instance.isMock) {
+ PlatformInterface.verify(instance, _token);
}
- _instance = value;
+ _instance = instance;
}
static SharedPreferencesStorePlatform _instance =
@@ -44,6 +45,7 @@
/// other than mocks (see class docs). This property provides a backdoor for mockito mocks to
/// skip the verification that the class isn't implemented with `implements`.
@visibleForTesting
+ @Deprecated('Use MockPlatformInterfaceMixin instead')
bool get isMock => false;
/// Removes the value associated with the [key].
@@ -65,14 +67,6 @@
/// Returns all key/value pairs persisted in this store.
Future<Map<String, Object>> getAll();
-
- // This method makes sure that SharedPreferencesStorePlatform isn't implemented with `implements`.
- //
- // See class doc for more details on why implementing this class is forbidden.
- //
- // This private method is called by the instance setter, which fails if the class is
- // implemented with `implements`.
- void _verifyProvidesDefaultImplementations() {}
}
/// Stores data in memory.
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml
index 9dce94c..7e4b9f0 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml
+++ b/packages/shared_preferences/shared_preferences_platform_interface/pubspec.yaml
@@ -2,7 +2,7 @@
description: A common platform interface for the shared_preferences plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/shared_preferences/shared_preferences_platform_interface
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+shared_preferences%22
-version: 2.0.0
+version: 2.1.0
environment:
sdk: ">=2.12.0 <3.0.0"
@@ -11,6 +11,7 @@
dependencies:
flutter:
sdk: flutter
+ plugin_platform_interface: ^2.1.0
dev_dependencies:
flutter_test:
diff --git a/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart b/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart
index 8efe885..ed078e8 100644
--- a/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart
+++ b/packages/shared_preferences/shared_preferences_platform_interface/test/shared_preferences_platform_interface_test.dart
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import 'package:flutter_test/flutter_test.dart';
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_platform_interface.dart';
void main() {
@@ -10,16 +11,30 @@
group(SharedPreferencesStorePlatform, () {
test('disallows implementing interface', () {
- expect(
- () {
- SharedPreferencesStorePlatform.instance = IllegalImplementation();
- },
- throwsAssertionError,
- );
+ expect(() {
+ SharedPreferencesStorePlatform.instance = IllegalImplementation();
+ },
+ // In versions of `package:plugin_platform_interface` prior to fixing
+ // https://github.com/flutter/flutter/issues/109339, an attempt to
+ // implement a platform interface using `implements` would sometimes
+ // throw a `NoSuchMethodError` and other times throw an
+ // `AssertionError`. After the issue is fixed, an `AssertionError` will
+ // always be thrown. For the purpose of this test, we don't really care
+ // what exception is thrown, so just allow any exception.
+ throwsA(anything));
+ });
+
+ test('supports MockPlatformInterfaceMixin', () {
+ SharedPreferencesStorePlatform.instance = ModernMockImplementation();
+ });
+
+ test('still supports legacy isMock', () {
+ SharedPreferencesStorePlatform.instance = LegacyIsMockImplementation();
});
});
}
+/// An implementation using `implements` that isn't a mock, which isn't allowed.
class IllegalImplementation implements SharedPreferencesStorePlatform {
// Intentionally declare self as not a mock to trigger the
// compliance check.
@@ -46,3 +61,55 @@
throw UnimplementedError();
}
}
+
+class LegacyIsMockImplementation implements SharedPreferencesStorePlatform {
+ @override
+ bool get isMock => true;
+
+ @override
+ Future<bool> clear() {
+ throw UnimplementedError();
+ }
+
+ @override
+ Future<Map<String, Object>> getAll() {
+ throw UnimplementedError();
+ }
+
+ @override
+ Future<bool> remove(String key) {
+ throw UnimplementedError();
+ }
+
+ @override
+ Future<bool> setValue(String valueType, String key, Object value) {
+ throw UnimplementedError();
+ }
+}
+
+class ModernMockImplementation
+ with MockPlatformInterfaceMixin
+ implements SharedPreferencesStorePlatform {
+ @override
+ bool get isMock => false;
+
+ @override
+ Future<bool> clear() {
+ throw UnimplementedError();
+ }
+
+ @override
+ Future<Map<String, Object>> getAll() {
+ throw UnimplementedError();
+ }
+
+ @override
+ Future<bool> remove(String key) {
+ throw UnimplementedError();
+ }
+
+ @override
+ Future<bool> setValue(String valueType, String key, Object value) {
+ throw UnimplementedError();
+ }
+}