-
Notifications
You must be signed in to change notification settings - Fork 9.7k
[in_app_purchase] platform interface improvement #3821
Changes from 8 commits
674bddd
875d3f1
06daea2
7f1653f
0f3d0b9
899bafb
8a7341d
a697f09
b8774b6
2d9c2ae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,18 +2,33 @@ | |
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'package:in_app_purchase_platform_interface/in_app_purchase_platform_interface.dart'; | ||
|
|
||
| // ignore: avoid_classes_with_only_static_members | ||
| /// The interface that platform implementations must implement when they want to | ||
| /// provide platform specific in_app_purchase features. | ||
| /// provide platform-specific in_app_purchase features. | ||
| /// | ||
| /// Platforms that wants to introduce platform-specific public APIs should create | ||
| /// a class that either extend or implements [InAppPurchasePlatformAddition]. Then replace | ||
| /// the [InAppPurchasePlatformAddition.instance] with an instance of that class. | ||
| /// | ||
| /// All the APIs added by [InAppPurchasePlatformAddition] implementers will be accessed from | ||
|
||
| /// [InAppPurchasePlatformAdditionProvider.getPlatformAddition] by the client APPs. | ||
| /// To avoid client APPs to directly call the [InAppPurchasePlatform] APIs, an [InAppPurchasePlatformAddition] implementation must not | ||
|
||
| /// be a type of [InAppPurchasePlatform]. | ||
| abstract class InAppPurchasePlatformAddition { | ||
| static InAppPurchasePlatformAddition? _instance; | ||
|
|
||
| /// The instance containing the platform-specific in_app_purchase | ||
| /// functionality. | ||
| /// | ||
| /// Returns `null` by default. | ||
| /// | ||
| /// To implement additional functionality extend | ||
| /// [`InAppPurchasePlatformAddition`][3] with the platform-specific | ||
| /// functionality, and when the plugin is registered, set the | ||
| /// `InAppPurchasePlatformAddition.instance` with the new addition | ||
| /// implementationinstance. | ||
| /// implementation instance. | ||
| /// | ||
| /// Example implementation might look like this: | ||
| /// ```dart | ||
|
|
@@ -22,7 +37,7 @@ abstract class InAppPurchasePlatformAddition { | |
| /// } | ||
| /// ``` | ||
| /// | ||
| /// The following snippit shows how to register the `InAppPurchaseMyPlatformAddition`: | ||
| /// The following snippet shows how to register the `InAppPurchaseMyPlatformAddition`: | ||
| /// ```dart | ||
| /// class InAppPurchaseMyPlatformPlugin { | ||
| /// static void registerWith(Registrar registrar) { | ||
|
|
@@ -36,5 +51,13 @@ abstract class InAppPurchasePlatformAddition { | |
| /// } | ||
| /// } | ||
| /// ``` | ||
| static InAppPurchasePlatformAddition? instance; | ||
| static InAppPurchasePlatformAddition? get instance => _instance; | ||
|
|
||
| /// Set the instance to a desired [InAppPurchasePlatformAddition] implementation. | ||
|
||
| /// | ||
| /// The `instance` must not be a type of [InAppPurchasePlatform]. | ||
|
||
| static set instance(InAppPurchasePlatformAddition? instance) { | ||
| assert(instance is! InAppPurchasePlatform); | ||
| _instance = instance; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -18,7 +18,7 @@ class ProductDetailsResponse { | |
|
|
||
| /// The list of identifiers that are in the `identifiers` of [InAppPurchasePlatform.queryProductDetails] but failed to be fetched. | ||
| /// | ||
| /// There's multiple platform specific reasons that product information could fail to be fetched, | ||
| /// There's multiple platform-specific reasons that product information could fail to be fetched, | ||
|
||
| /// ranging from products not being correctly configured in the storefront to the queried IDs not existing. | ||
| final List<String> notFoundIDs; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,22 +11,18 @@ void main() { | |
| TestWidgetsFlutterBinding.ensureInitialized(); | ||
|
|
||
| group('$InAppPurchasePlatform', () { | ||
| test('Default instance should return null', () { | ||
| expect(InAppPurchasePlatform.instance, null); | ||
| }); | ||
|
|
||
| test('Cannot be implemented with `implements`', () { | ||
| expect(() { | ||
| InAppPurchasePlatform.setInstance(ImplementsInAppPurchasePlatform()); | ||
| InAppPurchasePlatform.instance = ImplementsInAppPurchasePlatform(); | ||
| }, throwsNoSuchMethodError); | ||
| }); | ||
|
|
||
| test('Can be extended', () { | ||
| InAppPurchasePlatform.setInstance(ExtendsInAppPurchasePlatform()); | ||
| InAppPurchasePlatform.instance = ExtendsInAppPurchasePlatform(); | ||
| }); | ||
|
|
||
| test('Can be mocked with `implements`', () { | ||
| InAppPurchasePlatform.setInstance(MockInAppPurchasePlatform()); | ||
| InAppPurchasePlatform.instance = MockInAppPurchasePlatform(); | ||
| }); | ||
|
|
||
| test( | ||
|
|
@@ -124,6 +120,55 @@ void main() { | |
| ); | ||
| }); | ||
| }); | ||
|
|
||
| group('$InAppPurchasePlatformAddition', () { | ||
| setUp(() { | ||
| InAppPurchasePlatformAddition.instance = null; | ||
| }); | ||
|
|
||
| test('Cannot be implemented with `implements`', () { | ||
| expect(InAppPurchasePlatformAddition.instance, isNull); | ||
| }); | ||
|
|
||
| test('Can be implemented.', () { | ||
| InAppPurchasePlatformAddition.instance = | ||
| ImplementsInAppPurchasePlatformAddition(); | ||
| }); | ||
|
|
||
| test('InAppPurchasePlatformAddition Can be extended', () { | ||
| InAppPurchasePlatformAddition.instance = | ||
| ExtendsInAppPurchasePlatformAddition(); | ||
| }); | ||
|
|
||
| test('Can be mocked with `implements`', () { | ||
| InAppPurchasePlatformAddition.instance = | ||
| MockInAppPurchasePlatformAddition(); | ||
| }); | ||
|
|
||
| test('Can not be a `InAppPurchasePlatform`', () { | ||
| expect( | ||
| () => InAppPurchasePlatformAddition.instance = | ||
| ExtendsInAppPurchasePlatformAdditionIsPlatformInterface(), | ||
| throwsAssertionError); | ||
| }); | ||
|
|
||
| test('Provider can provide', () { | ||
| ImplementsInAppPurchasePlatformAdditionProvider.register(); | ||
| final ImplementsInAppPurchasePlatformAdditionProvider provider = | ||
| ImplementsInAppPurchasePlatformAdditionProvider(); | ||
| final InAppPurchasePlatformAddition? addition = | ||
| provider.getPlatformAddition(); | ||
| expect(addition.runtimeType, ExtendsInAppPurchasePlatformAddition); | ||
| }); | ||
|
|
||
| test('Provider can provide `null`', () { | ||
| final ImplementsInAppPurchasePlatformAdditionProvider provider = | ||
| ImplementsInAppPurchasePlatformAdditionProvider(); | ||
| final InAppPurchasePlatformAddition? addition = | ||
| provider.getPlatformAddition(); | ||
| expect(addition, isNull); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| class ImplementsInAppPurchasePlatform implements InAppPurchasePlatform { | ||
|
|
@@ -143,3 +188,36 @@ class ExtendsInAppPurchasePlatform extends InAppPurchasePlatform {} | |
| class MockPurchaseParam extends Mock implements PurchaseParam {} | ||
|
|
||
| class MockPurchaseDetails extends Mock implements PurchaseDetails {} | ||
|
|
||
| class ImplementsInAppPurchasePlatformAddition | ||
| implements InAppPurchasePlatformAddition { | ||
| @override | ||
| dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation); | ||
| } | ||
|
|
||
| class MockInAppPurchasePlatformAddition extends Mock | ||
| with | ||
| // ignore: prefer_mixin | ||
| MockPlatformInterfaceMixin | ||
|
||
| implements | ||
| InAppPurchasePlatformAddition {} | ||
|
|
||
| class ExtendsInAppPurchasePlatformAddition | ||
| extends InAppPurchasePlatformAddition {} | ||
|
|
||
| class ImplementsInAppPurchasePlatformAdditionProvider | ||
| implements InAppPurchasePlatformAdditionProvider { | ||
| static void register() { | ||
| InAppPurchasePlatformAddition.instance = | ||
| ExtendsInAppPurchasePlatformAddition(); | ||
| } | ||
|
|
||
| @override | ||
| T getPlatformAddition<T extends InAppPurchasePlatformAddition?>() { | ||
| return InAppPurchasePlatformAddition.instance as T; | ||
| } | ||
| } | ||
|
|
||
| class ExtendsInAppPurchasePlatformAdditionIsPlatformInterface | ||
| extends InAppPurchasePlatform | ||
| implements ExtendsInAppPurchasePlatformAddition {} | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/replace ... with/set ... to/ (by default there's no instance, so there's nothing to replace)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done