Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[various] Adopt plugin_platform_interface #6332

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -20,13 +21,19 @@ export 'src/types.dart';
/// 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.
Expand All @@ -44,25 +51,11 @@ abstract class GoogleSignInPlatform {
// 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ repository: https://github.com/flutter/plugins/tree/main/packages/google_sign_in
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"
Expand All @@ -13,6 +13,7 @@ environment:
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.1.0
quiver: ^3.0.0

dev_dependencies:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -33,7 +34,11 @@ void main() {
});

test('Can be mocked with `implements`', () {
GoogleSignInPlatform.instance = ImplementsWithIsMock();
GoogleSignInPlatform.instance = ModernMockImplementation();
});

test('still supports legacy isMock', () {
GoogleSignInPlatform.instance = LegacyIsMockImplementation();
});
});

Expand Down Expand Up @@ -76,11 +81,18 @@ void main() {
});
}

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 {}

Expand Down
Original file line number Diff line number Diff line change
@@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -15,24 +16,24 @@ import 'method_channel_shared_preferences.dart';
/// (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].
static SharedPreferencesStorePlatform get instance => _instance;

/// 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 =
Expand All @@ -44,6 +45,7 @@ abstract class SharedPreferencesStorePlatform {
/// 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].
Expand All @@ -65,14 +67,6 @@ abstract class SharedPreferencesStorePlatform {

/// 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: shared_preferences_platform_interface
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"
Expand All @@ -11,6 +11,7 @@ environment:
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.1.0

dev_dependencies:
flutter_test:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,38 @@
// 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() {
TestWidgetsFlutterBinding.ensureInitialized();

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.
Expand All @@ -46,3 +61,55 @@ class IllegalImplementation implements SharedPreferencesStorePlatform {
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();
}
}