[quick_actions] 2/3 Quick actions federated platform interface (#3735)
* Moved quickactions to a subfolder
* Added platform interface with tests
* Added exports
* Formatted, made initialize return Future<void> instead of void
* Fixed formatting
* formatting
* Fixed analyze issue with import
* Fixed formatting
* Fixed formatting
* Added license in files
* Removed accidental \\\
* changed license to Flutter 2017
* Moved quickactions to a subfolder
* Added platform interface with tests
* Added exports
* Formatted, made initialize return Future<void> instead of void
* Fixed formatting
* formatting
* Fixed analyze issue with import
* Fixed formatting
* Fixed formatting
* Added license in files
* Removed accidental \\\
* changed license to Flutter 2017
* Implemented feedback
* Changed 2017 to 2013
* Changed 2017 to 2013
* Implemented feedback.
diff --git a/packages/quick_actions/AUTHORS b/packages/quick_actions/AUTHORS
deleted file mode 100644
index 493a0b4..0000000
--- a/packages/quick_actions/AUTHORS
+++ /dev/null
@@ -1,66 +0,0 @@
-# Below is a list of people and organizations that have contributed
-# to the Flutter project. Names should be added to the list like so:
-#
-# Name/Organization <email address>
-
-Google Inc.
-The Chromium Authors
-German Saprykin <saprykin.h@gmail.com>
-Benjamin Sauer <sauer.benjamin@gmail.com>
-larsenthomasj@gmail.com
-Ali Bitek <alibitek@protonmail.ch>
-Pol Batlló <pol.batllo@gmail.com>
-Anatoly Pulyaevskiy
-Hayden Flinner <haydenflinner@gmail.com>
-Stefano Rodriguez <hlsroddy@gmail.com>
-Salvatore Giordano <salvatoregiordanoo@gmail.com>
-Brian Armstrong <brian@flutter.institute>
-Paul DeMarco <paulmdemarco@gmail.com>
-Fabricio Nogueira <feufeu@gmail.com>
-Simon Lightfoot <simon@devangels.london>
-Ashton Thomas <ashton@acrinta.com>
-Thomas Danner <thmsdnnr@gmail.com>
-Diego Velásquez <diego.velasquez.lopez@gmail.com>
-Hajime Nakamura <nkmrhj@gmail.com>
-Tuyển Vũ Xuân <netsoft1985@gmail.com>
-Miguel Ruivo <miguel@miguelruivo.com>
-Sarthak Verma <sarthak@artiosys.com>
-Mike Diarmid <mike@invertase.io>
-Invertase <oss@invertase.io>
-Elliot Hesp <elliot@invertase.io>
-Vince Varga <vince.varga@smaho.com>
-Aawaz Gyawali <awazgyawali@gmail.com>
-EUI Limited <ian.evans3@admiralgroup.co.uk>
-Katarina Sheremet <katarina@sheremet.ch>
-Thomas Stockx <thomas@stockxit.com>
-Sarbagya Dhaubanjar <sarbagyastha@gmail.com>
-Ozkan Eksi <ozeksi@gmail.com>
-Rishab Nayak <rishab@bu.edu>
-ko2ic <ko2ic.dev@gmail.com>
-Jonathan Younger <jonathan@daikini.com>
-Jose Sanchez <josesm82@gmail.com>
-Debkanchan Samadder <debu.samadder@gmail.com>
-Audrius Karosevicius <audrius.karosevicius@gmail.com>
-Lukasz Piliszczuk <lukasz@intheloup.io>
-SoundReply Solutions GmbH <ch@soundreply.com>
-Rafal Wachol <rwachol@gmail.com>
-Pau Picas <pau.picas@gmail.com>
-Christian Weder <chrstian.weder@yapeal.ch>
-Alexandru Tuca <salexandru.tuca@outlook.com>
-Christian Weder <chrstian.weder@yapeal.ch>
-Rhodes Davis Jr. <rody.davis.jr@gmail.com>
-Luigi Agosti <luigi@tengio.com>
-Quentin Le Guennec <quentin@tengio.com>
-Koushik Ravikumar <koushik@tengio.com>
-Nissim Dsilva <nissim@tengio.com>
-Giancarlo Rocha <giancarloiff@gmail.com>
-Ryo Miyake <ryo@miyake.id>
-Théo Champion <contact.theochampion@gmail.com>
-Kazuki Yamaguchi <y.kazuki0614n@gmail.com>
-Eitan Schwartz <eshvartz@gmail.com>
-Chris Rutkowski <chrisrutkowski89@gmail.com>
-Juan Alvarez <juan.alvarez@resideo.com>
-Aleksandr Yurkovskiy <sanekyy@gmail.com>
-Anton Borries <mail@antonborri.es>
-Alex Li <google@alexv525.com>
-Rahul Raj <64.rahulraj@gmail.com>
diff --git a/packages/quick_actions/quick_actions/test/quick_actions_test.dart b/packages/quick_actions/quick_actions/test/quick_actions_test.dart
index f2b9a9a..ccb593f 100644
--- a/packages/quick_actions/quick_actions/test/quick_actions_test.dart
+++ b/packages/quick_actions/quick_actions/test/quick_actions_test.dart
@@ -1,6 +1,7 @@
// 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:flutter/services.dart';
diff --git a/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md b/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md
new file mode 100644
index 0000000..4b63991
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/CHANGELOG.md
@@ -0,0 +1,3 @@
+# 1.0.0
+
+* Initial release of quick_actions_platform_interface
diff --git a/packages/quick_actions/quick_actions_platform_interface/LICENSE b/packages/quick_actions/quick_actions_platform_interface/LICENSE
new file mode 100644
index 0000000..4c99d1d
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/LICENSE
@@ -0,0 +1,25 @@
+Copyright 2013 The Chromium 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/quick_actions/quick_actions_platform_interface/README.md b/packages/quick_actions/quick_actions_platform_interface/README.md
new file mode 100644
index 0000000..ce8136e
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/README.md
@@ -0,0 +1,26 @@
+# quick_actions_platform_interface
+
+A common platform interface for the [`quick_actions`][1] plugin.
+
+This interface allows platform-specific implementations of the `quick_actions`
+plugin, as well as the plugin itself, to ensure they are supporting the
+same interface.
+
+# Usage
+
+To implement a new platform-specific implementation of `quick_actions`, extend
+[`QuickActionsPlatform`][2] with an implementation that performs the
+platform-specific behavior, and when you register your plugin, set the default
+`QuickActionsPlatform` by calling
+`QuickActionsPlatform.instance = MyPlatformQuickActions()`.
+
+# Note on breaking changes
+
+Strongly prefer non-breaking changes (such as adding a method to the interface)
+over breaking changes for this package.
+
+See https://flutter.dev/go/platform-interface-breaking-changes for a discussion
+on why a less-clean interface is preferable to a breaking change.
+
+[1]: ../quick_actions
+[2]: lib/quick_actions_platform_interface.dart
diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/method_channel/method_channel_quick_actions.dart b/packages/quick_actions/quick_actions_platform_interface/lib/method_channel/method_channel_quick_actions.dart
new file mode 100644
index 0000000..8172fe0
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/lib/method_channel/method_channel_quick_actions.dart
@@ -0,0 +1,52 @@
+// 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';
+import 'package:flutter/services.dart';
+import 'package:meta/meta.dart' show visibleForTesting;
+import 'package:quick_actions_platform_interface/types/types.dart';
+
+import '../platform_interface/quick_actions_platform.dart';
+
+final MethodChannel _channel =
+ MethodChannel('plugins.flutter.io/quick_actions');
+
+/// An implementation of [QuickActionsPlatform] that uses method channels.
+class MethodChannelQuickActions extends QuickActionsPlatform {
+ /// The MethodChannel that is being used by this implementation of the plugin.
+ @visibleForTesting
+ MethodChannel get channel => _channel;
+
+ @override
+ Future<void> initialize(QuickActionHandler handler) async {
+ channel.setMethodCallHandler((MethodCall call) async {
+ assert(call.method == 'launch');
+ handler(call.arguments);
+ });
+ final String? action =
+ await channel.invokeMethod<String?>('getLaunchAction');
+ if (action != null) {
+ handler(action);
+ }
+ }
+
+ @override
+ Future<void> setShortcutItems(List<ShortcutItem> items) async {
+ final List<Map<String, String?>> itemsList =
+ items.map(_serializeItem).toList();
+ await channel.invokeMethod<void>('setShortcutItems', itemsList);
+ }
+
+ @override
+ Future<void> clearShortcutItems() =>
+ channel.invokeMethod<void>('clearShortcutItems');
+
+ Map<String, String?> _serializeItem(ShortcutItem item) {
+ return <String, String?>{
+ 'type': item.type,
+ 'localizedTitle': item.localizedTitle,
+ 'icon': item.icon,
+ };
+ }
+}
diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/platform_interface/quick_actions_platform.dart b/packages/quick_actions/quick_actions_platform_interface/lib/platform_interface/quick_actions_platform.dart
new file mode 100644
index 0000000..b15fb8b
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/lib/platform_interface/quick_actions_platform.dart
@@ -0,0 +1,55 @@
+// 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:plugin_platform_interface/plugin_platform_interface.dart';
+import 'package:quick_actions_platform_interface/types/types.dart';
+
+import '../method_channel/method_channel_quick_actions.dart';
+
+/// The interface that implementations of quick_actions must implement.
+///
+/// Platform implementations should extend this class rather than implement it as `quick_actions`
+/// does not consider newly added methods to be breaking changes. Extending this class
+/// (using `extends`) ensures that the subclass will get the default implementation, while
+/// platform implementations that `implements` this interface will be broken by newly added
+/// [QuickActionsPlatform] methods.
+abstract class QuickActionsPlatform extends PlatformInterface {
+ /// Constructs a QuickActionsPlatform.
+ QuickActionsPlatform() : super(token: _token);
+
+ static final Object _token = Object();
+
+ static QuickActionsPlatform _instance = MethodChannelQuickActions();
+
+ /// The default instance of [QuickActionsPlatform] to use.
+ ///
+ /// Defaults to [MethodChannelQuickActions].
+ static QuickActionsPlatform get instance => _instance;
+
+ /// Platform-specific plugins should set this with their own platform-specific
+ /// class that extends [QuickActionsPlatform] when they register themselves.
+ // TODO(amirh): Extract common platform interface logic.
+ // https://github.com/flutter/flutter/issues/43368
+ static set instance(QuickActionsPlatform instance) {
+ PlatformInterface.verifyToken(instance, _token);
+ _instance = instance;
+ }
+
+ /// Initializes this plugin.
+ ///
+ /// Call this once before any further interaction with the the plugin.
+ Future<void> initialize(QuickActionHandler handler) async {
+ throw UnimplementedError("initialize() has not been implemented.");
+ }
+
+ /// Sets the [ShortcutItem]s to become the app's quick actions.
+ Future<void> setShortcutItems(List<ShortcutItem> items) async {
+ throw UnimplementedError("setShortcutItems() has not been implemented.");
+ }
+
+ /// Removes all [ShortcutItem]s registered for the app.
+ Future<void> clearShortcutItems() {
+ throw UnimplementedError("clearShortcutItems() has not been implemented.");
+ }
+}
diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/quick_actions_platform_interface.dart b/packages/quick_actions/quick_actions_platform_interface/lib/quick_actions_platform_interface.dart
new file mode 100644
index 0000000..51bed8f
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/lib/quick_actions_platform_interface.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export 'package:quick_actions_platform_interface/platform_interface/quick_actions_platform.dart';
+export 'package:quick_actions_platform_interface/types/types.dart';
diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/types/quick_action_handler.dart b/packages/quick_actions/quick_actions_platform_interface/lib/types/quick_action_handler.dart
new file mode 100644
index 0000000..27c6bb4
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/lib/types/quick_action_handler.dart
@@ -0,0 +1,8 @@
+// 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.
+
+/// Handler for a quick action launch event.
+///
+/// The argument [type] corresponds to the [ShortcutItem]'s field.
+typedef void QuickActionHandler(String type);
diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/types/shortcut_item.dart b/packages/quick_actions/quick_actions_platform_interface/lib/types/shortcut_item.dart
new file mode 100644
index 0000000..1d84e16
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/lib/types/shortcut_item.dart
@@ -0,0 +1,26 @@
+// 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.
+
+/// Home screen quick-action shortcut item.
+class ShortcutItem {
+ /// Constructs an instance with the given [type], [localizedTitle], and
+ /// [icon].
+ ///
+ /// Only [icon] should be nullable. It will remain `null` if unset.
+ const ShortcutItem({
+ required this.type,
+ required this.localizedTitle,
+ this.icon,
+ });
+
+ /// The identifier of this item; should be unique within the app.
+ final String type;
+
+ /// Localized title of the item.
+ final String localizedTitle;
+
+ /// Name of native resource (xcassets etc; NOT a Flutter asset) to be
+ /// displayed as the icon for this item.
+ final String? icon;
+}
diff --git a/packages/quick_actions/quick_actions_platform_interface/lib/types/types.dart b/packages/quick_actions/quick_actions_platform_interface/lib/types/types.dart
new file mode 100644
index 0000000..ab85ca8
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/lib/types/types.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export 'quick_action_handler.dart';
+export 'shortcut_item.dart';
diff --git a/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml b/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml
new file mode 100644
index 0000000..eb1ff40
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/pubspec.yaml
@@ -0,0 +1,22 @@
+name: quick_actions_platform_interface
+description: A common platform interface for the quick_actions plugin.
+homepage: https://github.com/flutter/plugins/tree/master/packages/quick_actions/quick_actions_platform_interface
+# 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: 1.0.0
+
+dependencies:
+ flutter:
+ sdk: flutter
+ meta: ^1.3.0
+ plugin_platform_interface: ^2.0.0
+
+dev_dependencies:
+ flutter_test:
+ sdk: flutter
+ mockito: ^5.0.1
+ pedantic: ^1.11.0
+
+environment:
+ sdk: ">=2.12.0-259.9.beta <3.0.0"
+ flutter: ">=1.22.0"
diff --git a/packages/quick_actions/quick_actions_platform_interface/test/method_channel_quick_actions_test.dart b/packages/quick_actions/quick_actions_platform_interface/test/method_channel_quick_actions_test.dart
new file mode 100644
index 0000000..f3e172e
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/test/method_channel_quick_actions_test.dart
@@ -0,0 +1,155 @@
+// 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:flutter/services.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:quick_actions_platform_interface/method_channel/method_channel_quick_actions.dart';
+import 'package:quick_actions_platform_interface/types/shortcut_item.dart';
+
+void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+
+ group('$MethodChannelQuickActions', () {
+ MethodChannelQuickActions quickActions = MethodChannelQuickActions();
+
+ final List<MethodCall> log = <MethodCall>[];
+
+ setUp(() {
+ quickActions.channel
+ .setMockMethodCallHandler((MethodCall methodCall) async {
+ log.add(methodCall);
+ return '';
+ });
+
+ log.clear();
+ });
+
+ group('#initialize', () {
+ test('passes getLaunchAction on launch method', () {
+ quickActions.initialize((type) {
+ 'launch';
+ });
+
+ expect(
+ log,
+ <Matcher>[
+ isMethodCall('getLaunchAction', arguments: null),
+ ],
+ );
+ });
+
+ test('initialize', () async {
+ final Completer<bool> quickActionsHandler = Completer<bool>();
+ await quickActions
+ .initialize((_) => quickActionsHandler.complete(true));
+ expect(
+ log,
+ <Matcher>[
+ isMethodCall('getLaunchAction', arguments: null),
+ ],
+ );
+ log.clear();
+
+ expect(quickActionsHandler.future, completion(isTrue));
+ });
+ });
+
+ group('#setShortCutItems', () {
+ test('passes shortcutItem through channel', () {
+ quickActions.initialize((type) {
+ 'launch';
+ });
+ quickActions.setShortcutItems([
+ ShortcutItem(type: 'test', localizedTitle: 'title', icon: 'icon.svg')
+ ]);
+
+ expect(
+ log,
+ <Matcher>[
+ isMethodCall('getLaunchAction', arguments: null),
+ isMethodCall('setShortcutItems', arguments: [
+ {
+ 'type': 'test',
+ 'localizedTitle': 'title',
+ 'icon': 'icon.svg',
+ }
+ ]),
+ ],
+ );
+ });
+
+ test('setShortcutItems with demo data', () async {
+ const String type = 'type';
+ const String localizedTitle = 'localizedTitle';
+ const String icon = 'icon';
+ await quickActions.setShortcutItems(
+ const <ShortcutItem>[
+ ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon)
+ ],
+ );
+ expect(
+ log,
+ <Matcher>[
+ isMethodCall(
+ 'setShortcutItems',
+ arguments: <Map<String, String>>[
+ <String, String>{
+ 'type': type,
+ 'localizedTitle': localizedTitle,
+ 'icon': icon,
+ }
+ ],
+ ),
+ ],
+ );
+ log.clear();
+ });
+ });
+
+ group('#clearShortCutItems', () {
+ test('send clearShortcutItems through channel', () {
+ quickActions.initialize((type) {
+ 'launch';
+ });
+ quickActions.clearShortcutItems();
+
+ expect(
+ log,
+ <Matcher>[
+ isMethodCall('getLaunchAction', arguments: null),
+ isMethodCall('clearShortcutItems', arguments: null),
+ ],
+ );
+ });
+
+ test('clearShortcutItems', () {
+ quickActions.clearShortcutItems();
+ expect(
+ log,
+ <Matcher>[
+ isMethodCall('clearShortcutItems', arguments: null),
+ ],
+ );
+ log.clear();
+ });
+ });
+ });
+
+ group('$ShortcutItem', () {
+ test('Shortcut item can be constructed', () {
+ const String type = 'type';
+ const String localizedTitle = 'title';
+ const String icon = 'foo';
+
+ const ShortcutItem item =
+ ShortcutItem(type: type, localizedTitle: localizedTitle, icon: icon);
+
+ expect(item.type, type);
+ expect(item.localizedTitle, localizedTitle);
+ expect(item.icon, icon);
+ });
+ });
+}
diff --git a/packages/quick_actions/quick_actions_platform_interface/test/quick_actions_platform_interface_test.dart b/packages/quick_actions/quick_actions_platform_interface/test/quick_actions_platform_interface_test.dart
new file mode 100644
index 0000000..8ce4081
--- /dev/null
+++ b/packages/quick_actions/quick_actions_platform_interface/test/quick_actions_platform_interface_test.dart
@@ -0,0 +1,73 @@
+// 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:quick_actions_platform_interface/method_channel/method_channel_quick_actions.dart';
+import 'package:quick_actions_platform_interface/platform_interface/quick_actions_platform.dart';
+
+void main() {
+ TestWidgetsFlutterBinding.ensureInitialized();
+
+ group('$QuickActionsPlatform', () {
+ test('$MethodChannelQuickActions is the default instance', () {
+ expect(QuickActionsPlatform.instance, isA<MethodChannelQuickActions>());
+ });
+
+ test('Cannot be implemented with `implements`', () {
+ expect(() {
+ QuickActionsPlatform.instance = ImplementsQuickActionsPlatform();
+ }, throwsNoSuchMethodError);
+ });
+
+ test('Can be extended', () {
+ QuickActionsPlatform.instance = ExtendsQuickActionsPlatform();
+ });
+
+ test(
+ 'Default implementation of initialize() should throw unimplemented error',
+ () {
+ // Arrange
+ final QuickActionsPlatform = ExtendsQuickActionsPlatform();
+
+ // Act & Assert
+ expect(
+ () => QuickActionsPlatform.initialize((type) {}),
+ throwsUnimplementedError,
+ );
+ });
+
+ test(
+ 'Default implementation of setShortcutItems() should throw unimplemented error',
+ () {
+ // Arrange
+ final QuickActionsPlatform = ExtendsQuickActionsPlatform();
+
+ // Act & Assert
+ expect(
+ () => QuickActionsPlatform.setShortcutItems([]),
+ throwsUnimplementedError,
+ );
+ });
+
+ test(
+ 'Default implementation of clearShortcutItems() should throw unimplemented error',
+ () {
+ // Arrange
+ final QuickActionsPlatform = ExtendsQuickActionsPlatform();
+
+ // Act & Assert
+ expect(
+ () => QuickActionsPlatform.clearShortcutItems(),
+ throwsUnimplementedError,
+ );
+ });
+ });
+}
+
+class ImplementsQuickActionsPlatform implements QuickActionsPlatform {
+ @override
+ dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class ExtendsQuickActionsPlatform extends QuickActionsPlatform {}