-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Windows unit tests no longer use the Windows SDK #2696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
746a7c2
5a6b816
79a32ba
badf079
26c6de7
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 |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| // Just a mock, doesn't need real types or safety. | ||
| // ignore_for_file: type_annotate_public_apis, always_specify_types | ||
|
|
||
| import 'dart:ffi'; | ||
|
|
||
| import 'package:ffi/ffi.dart'; | ||
|
|
||
| import 'bindings.dart'; | ||
|
|
||
| /// Mocked FFI bindings. | ||
| class MockBindings implements NotificationsPluginBindings { | ||
| @override | ||
| void cancelAll(_) {} | ||
|
|
||
| @override | ||
| void cancelNotification(_, int id) {} | ||
|
|
||
| @override | ||
| Pointer<NativePlugin> createPlugin() => malloc<Int>().cast(); | ||
|
|
||
| @override | ||
| void disposePlugin(_) {} | ||
|
|
||
| @override | ||
| void freeLaunchDetails(_) {} | ||
|
|
||
| @override | ||
| void freeDetailsArray(ptr) => malloc.free(ptr); | ||
|
|
||
| @override | ||
| Pointer<NativeNotificationDetails> getActiveNotifications(_, __) => | ||
| malloc<NativeNotificationDetails>(); | ||
|
|
||
| @override | ||
| Pointer<NativeNotificationDetails> getPendingNotifications(_, __) => | ||
| malloc<NativeNotificationDetails>(); | ||
|
|
||
| @override | ||
| bool hasPackageIdentity() => false; | ||
|
|
||
| @override | ||
| bool init(_, __, ___, ____, _____, ______) => true; | ||
|
|
||
| @override | ||
| bool isValidXml(ptr) => true; | ||
|
|
||
| @override | ||
| bool scheduleNotification(a, b, c, d) => true; | ||
|
|
||
| @override | ||
| bool showNotification(a, b, c, d) => true; | ||
|
|
||
| @override | ||
| NativeUpdateResult updateNotification(a, b, c) => NativeUpdateResult.success; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| import 'dart:ffi'; | ||
|
|
||
| import 'package:ffi/ffi.dart'; | ||
| import 'package:meta/meta.dart'; | ||
| import 'package:xml/xml.dart'; | ||
|
|
||
| import '../details.dart'; | ||
| import '../details/notification_to_xml.dart'; | ||
|
|
@@ -22,10 +24,28 @@ extension on String { | |
| this[23] == '-'; | ||
| } | ||
|
|
||
| /// Does a basic syntax check on XML. | ||
| bool _checkXml(String xml) { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's file private but look this could have been private within the Note: on a related note and not that it has to be done in this PR but I believe I missed picking this up when it comes to |
||
| try { | ||
| XmlDocument.parse(xml); | ||
| return true; | ||
| } on XmlFormatException { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| /// The Windows implementation of `package:flutter_local_notifications`. | ||
| class FlutterLocalNotificationsWindows extends WindowsNotificationsBase { | ||
| /// Creates an instance of the native plugin. | ||
| FlutterLocalNotificationsWindows(); | ||
| FlutterLocalNotificationsWindows() | ||
| : _bindings = NotificationsPluginBindings( | ||
| DynamicLibrary.open('flutter_local_notifications_windows.dll')); | ||
|
|
||
| /// Creates an instance of this plugin with the given (mocked) bindings. | ||
| @visibleForTesting | ||
| FlutterLocalNotificationsWindows.withBindings( | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I was about to mention perhaps to rename it to Rather than taking this approach, I noticed first-party plugins are taking an optional, nullable argument with the |
||
| this._bindings, | ||
| ); | ||
|
|
||
| /// Registers the Windows implementation with Flutter. | ||
| static void registerWith() { | ||
|
|
@@ -37,11 +57,7 @@ class FlutterLocalNotificationsWindows extends WindowsNotificationsBase { | |
| static FlutterLocalNotificationsWindows? instance; | ||
|
|
||
| /// The FFI generated bindings to the native code. | ||
| late final NotificationsPluginBindings _bindings = | ||
| NotificationsPluginBindings(_library); | ||
|
|
||
| final DynamicLibrary _library = | ||
| DynamicLibrary.open('flutter_local_notifications_windows.dll'); | ||
| final NotificationsPluginBindings _bindings; | ||
|
|
||
| /// A pointer to the C++ handler class. | ||
| late final Pointer<NativePlugin> _plugin; | ||
|
|
@@ -281,6 +297,9 @@ class FlutterLocalNotificationsWindows extends WindowsNotificationsBase { | |
|
|
||
| @override | ||
| bool isValidXml(String xml) => using((Arena arena) { | ||
| if (!_checkXml(xml)) { | ||
| return false; | ||
| } | ||
| final Pointer<Utf8> nativeXml = xml.toNativeUtf8(allocator: arena); | ||
| return _bindings.isValidXml(nativeXml); | ||
| }); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,22 @@ | ||
| import 'package:meta/meta.dart'; | ||
|
|
||
| import '../details.dart'; | ||
| import '../ffi/bindings.dart'; | ||
| import 'base.dart'; | ||
|
|
||
| /// The Windows implementation of `package:flutter_local_notifications`. | ||
| class FlutterLocalNotificationsWindows extends WindowsNotificationsBase { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With the comment I left that allows the FFI implementation to take an argument for the bindings used behind the scenes, does this perhaps render the stub redundant now? Based on my own knowledge and testing, it would be redundant but let me know if I've missed anything |
||
| /// Creates an instance of this plugin. | ||
| FlutterLocalNotificationsWindows(); | ||
|
|
||
| /// Creates an instance of this plugin with the given (mocked) bindings. | ||
| @visibleForTesting | ||
| FlutterLocalNotificationsWindows.withBindings( | ||
| // Needed in this file due to conditional imports | ||
| // ignore: avoid_unused_constructor_parameters | ||
| NotificationsPluginBindings bindings, | ||
| ); | ||
|
|
||
| @override | ||
| Future<bool> initialize( | ||
| WindowsInitializationSettings settings, { | ||
|
|
||
This file was deleted.
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.
Can you place this in the test folder? It's purely test related and is the approach taken when creating mocks via mocktail or mockito or hand crafted ones. Note this is also currently a stub not a mock. A mock provides the ability to record the interactions that can then be used to verify what took place. Can you also rename the class and adjust the docs accordingly to reflect this?