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