From 783410677774bcac2b7ada5900e2cec8675e5b2c Mon Sep 17 00:00:00 2001 From: Drew Higgins Date: Fri, 17 Apr 2020 14:04:57 -0700 Subject: [PATCH 01/21] Add support for React Native BackHandler API on Windows (#4623) * Added initial implementation * Add backrequested listener * Add handlers for other back actions Also remove debug code * Change files * Remove TODO * Responding to PR comments * Copied in Android BackHandler code from upstream * Changed the base file for the BackHandler override * Fixed weak ptr check * Removed unnecessary validation after casting XamlView to UIElement * Call JS with legacyPointer * More PR feedback * Use weak pointers to this in event handlers * Fix safety issue in query_cast * Revoke handlers on Uninit * Remove added binary file * use weak ptr for BackRequested too * Fix override hash verification --- ...0-04-16-11-09-41-jahiggin-backHandler.json | 8 +++ packages/override-tools/src/Manifest.ts | 3 +- packages/playground/Samples/mouse.tsx | 9 +++ .../Views/ReactRootControl.cpp | 70 ++++++++++++++++++ .../Views/ReactRootControl.h | 6 ++ vnext/ReactUWP/Views/TouchEventHandler.cpp | 17 +++++ vnext/ReactUWP/Views/TouchEventHandler.h | 1 + .../Utilities/BackHandler.windows.js | 71 +++++++++++++++---- vnext/src/overrides.json | 8 +-- 9 files changed, 175 insertions(+), 18 deletions(-) create mode 100644 change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json diff --git a/change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json b/change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json new file mode 100644 index 00000000000..b7b3e0c8d40 --- /dev/null +++ b/change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Add support for React Native BackHandler API", + "packageName": "react-native-windows", + "email": "jahiggin@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-04-16T18:09:41.547Z" +} \ No newline at end of file diff --git a/packages/override-tools/src/Manifest.ts b/packages/override-tools/src/Manifest.ts index 78e872cf3d3..3c362767642 100644 --- a/packages/override-tools/src/Manifest.ts +++ b/packages/override-tools/src/Manifest.ts @@ -242,7 +242,8 @@ export default class Manifest { */ static hashContent(str: string) { const hasher = crypto.createHash('sha1'); - hasher.update(str); + const normalizedStr = str.replace(/(? { + console.log('hardwareBackPress'); + return true; + }; } const styles = StyleSheet.create({ diff --git a/vnext/Microsoft.ReactNative/Views/ReactRootControl.cpp b/vnext/Microsoft.ReactNative/Views/ReactRootControl.cpp index 0574a0762d3..bd5a340f130 100644 --- a/vnext/Microsoft.ReactNative/Views/ReactRootControl.cpp +++ b/vnext/Microsoft.ReactNative/Views/ReactRootControl.cpp @@ -184,6 +184,7 @@ void ReactRootControl::InitRootView( m_SIPEventHandler->AttachView(xamlRootView, /*fireKeyboradEvents:*/ true); UpdateRootViewInternal(); + AttachBackHandlers(xamlRootView); m_isInitialized = true; } @@ -232,6 +233,8 @@ void ReactRootControl::UninitRootView() noexcept { m_previewKeyboardEventHandlerOnRoot->unhook(); } + RemoveBackHandlers(); + // If the redbox error UI is shown we need to remove it, otherwise let the // natural teardown process do this if (m_redBoxGrid) { @@ -607,6 +610,73 @@ void ReactRootControl::ReloadViewHost() noexcept { } } +void ReactRootControl::AttachBackHandlers(XamlView const &rootView) noexcept { + auto weakThis = weak_from_this(); + m_backRequestedRevoker = winrt::Windows::UI::Core::SystemNavigationManager::GetForCurrentView().BackRequested( + winrt::auto_revoke, + [weakThis](winrt::IInspectable const & /*sender*/, winrt::BackRequestedEventArgs const &args) { + if (auto self = weakThis.lock()) { + args.Handled(self->OnBackRequested()); + } + }); + + // In addition to handling the BackRequested event, UWP suggests that we listen for other user inputs that should + // trigger back navigation that don't fire that event: + // https://docs.microsoft.com/en-us/windows/uwp/design/basics/navigation-history-and-backwards-navigation + auto rootElement(rootView.try_as()); + if (rootElement == nullptr) { + assert(false); + return; + } + + // Handle keyboard "back" button press + winrt::KeyboardAccelerator goBack{}; + goBack.Key(winrt::VirtualKey::GoBack); + goBack.Invoked( + [weakThis]( + winrt::KeyboardAccelerator const & /*sender*/, winrt::KeyboardAcceleratorInvokedEventArgs const &args) { + if (auto self = weakThis.lock()) { + args.Handled(self->OnBackRequested()); + } + }); + rootElement.KeyboardAccelerators().Append(goBack); + + // Handle Alt+Left keyboard shortcut + winrt::KeyboardAccelerator altLeft{}; + altLeft.Key(winrt::VirtualKey::Left); + altLeft.Invoked( + [weakThis]( + winrt::KeyboardAccelerator const & /*sender*/, winrt::KeyboardAcceleratorInvokedEventArgs const &args) { + if (auto self = weakThis.lock()) { + args.Handled(self->OnBackRequested()); + } + }); + rootElement.KeyboardAccelerators().Append(altLeft); + altLeft.Modifiers(winrt::VirtualKeyModifiers::Menu); + + // Hide keyboard accelerator tooltips + rootElement.KeyboardAcceleratorPlacementMode(winrt::KeyboardAcceleratorPlacementMode::Hidden); +} + +void ReactRootControl::RemoveBackHandlers() noexcept { + m_backRequestedRevoker.revoke(); + if (auto rootView = m_weakRootView.get()) { + if (auto element = rootView.try_as()) { + element.KeyboardAccelerators().Clear(); + } + } +} + +bool ReactRootControl::OnBackRequested() noexcept { + if (auto reactInstance = m_weakReactInstance.GetStrongPtr()) { + query_cast(*reactInstance) + .CallJsFunction("RCTDeviceEventEmitter", "emit", folly::dynamic::array("hardwareBackPress")); + return true; + } + + return false; +} + Mso::React::IReactViewHost *ReactRootControl::ReactViewHost() noexcept { return m_reactViewHost.Get(); } diff --git a/vnext/Microsoft.ReactNative/Views/ReactRootControl.h b/vnext/Microsoft.ReactNative/Views/ReactRootControl.h index 3166195164b..26bb5948cc2 100644 --- a/vnext/Microsoft.ReactNative/Views/ReactRootControl.h +++ b/vnext/Microsoft.ReactNative/Views/ReactRootControl.h @@ -15,6 +15,7 @@ namespace winrt { using namespace Windows::UI; +using namespace Windows::UI::Core; using namespace Windows::UI::Xaml; using namespace Windows::UI::Xaml::Controls; using namespace Windows::UI::Xaml::Input; @@ -83,6 +84,10 @@ struct ReactRootControl final : std::enable_shared_from_this, void ReloadHost() noexcept; void ReloadViewHost() noexcept; + void AttachBackHandlers(XamlView const &rootView) noexcept; + void RemoveBackHandlers() noexcept; + bool OnBackRequested() noexcept; + private: int64_t m_rootTag{-1}; @@ -130,6 +135,7 @@ struct ReactRootControl final : std::enable_shared_from_this, winrt::Button::Click_revoker m_directDebuggingRevoker{}; winrt::Button::Click_revoker m_breakOnNextLineRevoker{}; winrt::CoreDispatcher::AcceleratorKeyActivated_revoker m_coreDispatcherAKARevoker{}; + winrt::SystemNavigationManager::BackRequested_revoker m_backRequestedRevoker{}; }; //! This class ensures that we access ReactRootView from UI thread. diff --git a/vnext/ReactUWP/Views/TouchEventHandler.cpp b/vnext/ReactUWP/Views/TouchEventHandler.cpp index cdcd9de40a8..d08300864ca 100644 --- a/vnext/ReactUWP/Views/TouchEventHandler.cpp +++ b/vnext/ReactUWP/Views/TouchEventHandler.cpp @@ -78,6 +78,13 @@ void TouchEventHandler::OnPointerPressed( if (!TagFromOriginalSource(args, &tag, &sourceElement)) return; + // If this was caused by the user pressing the "back" hardware button, fire that event instead + if (args.GetCurrentPoint(sourceElement).Properties().PointerUpdateKind() == + winrt::Windows::UI::Input::PointerUpdateKind::XButton1Pressed) { + args.Handled(DispatchBackEvent()); + return; + } + if (m_xamlView.as().CapturePointer(args.Pointer())) { // Pointer pressing updates the enter/leave state UpdatePointersInViews(args, tag, sourceElement); @@ -341,6 +348,16 @@ void TouchEventHandler::DispatchTouchEvent(TouchEventType eventType, size_t poin instance->CallJsFunction("RCTEventEmitter", "receiveTouches", std::move(params)); } +bool TouchEventHandler::DispatchBackEvent() { + auto instance = m_wkReactInstance.lock(); + if (instance != nullptr && !instance->IsInError()) { + instance->CallJsFunction("RCTDeviceEventEmitter", "emit", folly::dynamic::array("hardwareBackPress")); + return true; + } + + return false; +} + const char *TouchEventHandler::GetPointerDeviceTypeName( winrt::Windows::Devices::Input::PointerDeviceType deviceType) noexcept { const char *deviceTypeName = "unknown"; diff --git a/vnext/ReactUWP/Views/TouchEventHandler.h b/vnext/ReactUWP/Views/TouchEventHandler.h index 62488bc7e4f..df26eaf2c19 100644 --- a/vnext/ReactUWP/Views/TouchEventHandler.h +++ b/vnext/ReactUWP/Views/TouchEventHandler.h @@ -78,6 +78,7 @@ class TouchEventHandler { enum class TouchEventType { Start = 0, End, Move, Cancel, PointerEntered, PointerExited, PointerMove }; void OnPointerConcluded(TouchEventType eventType, const winrt::PointerRoutedEventArgs &args); void DispatchTouchEvent(TouchEventType eventType, size_t pointerIndex); + bool DispatchBackEvent(); const char *GetPointerDeviceTypeName(winrt::Windows::Devices::Input::PointerDeviceType deviceType) noexcept; const char *GetTouchEventTypeName(TouchEventType eventType) noexcept; diff --git a/vnext/src/Libraries/Utilities/BackHandler.windows.js b/vnext/src/Libraries/Utilities/BackHandler.windows.js index 8a57351da63..e6e3d035295 100644 --- a/vnext/src/Libraries/Utilities/BackHandler.windows.js +++ b/vnext/src/Libraries/Utilities/BackHandler.windows.js @@ -4,16 +4,30 @@ * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * - * @format * @flow + * @format */ -// On Apple TV, this implements back navigation using the TV remote's menu button. -// On iOS, this just implements a stub. - 'use strict'; -// TODO Hx: Implement. +import NativeDeviceEventManager from '../../Libraries/NativeModules/specs/NativeDeviceEventManager'; +import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter'; + +const DEVICE_BACK_EVENT = 'hardwareBackPress'; + +type BackPressEventName = 'backPress' | 'hardwareBackPress'; + +const _backPressSubscriptions = []; + +RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function() { + for (let i = _backPressSubscriptions.length - 1; i >= 0; i--) { + if (_backPressSubscriptions[i]()) { + return; + } + } + + BackHandler.exitApp(); +}); /** * Detect hardware button presses for back navigation. @@ -45,9 +59,6 @@ * }); * ``` */ - -type BackPressEventName = 'backPress' | 'hardwareBackPress'; - type TBackHandler = {| +exitApp: () => void, +addEventListener: ( @@ -59,13 +70,47 @@ type TBackHandler = {| handler: Function, ) => void, |}; - const BackHandler: TBackHandler = { - exitApp: () => {}, - addEventListener: (eventName: BackPressEventName, handler: Function) => { - return {remove: () => {}}; + exitApp: function(): void { + if (!NativeDeviceEventManager) { + return; + } + + NativeDeviceEventManager.invokeDefaultBackPressHandler(); + }, + + /** + * Adds an event handler. Supported events: + * + * - `hardwareBackPress`: Fires when the Android hardware back button is pressed or when the + * tvOS menu button is pressed. + */ + addEventListener: function( + eventName: BackPressEventName, + handler: Function, + ): {remove: () => void, ...} { + if (_backPressSubscriptions.indexOf(handler) === -1) { + _backPressSubscriptions.push(handler); + } + return { + remove: (): void => BackHandler.removeEventListener(eventName, handler), + }; + }, + + /** + * Removes the event handler. + */ + removeEventListener: function( + eventName: BackPressEventName, + handler: Function, + ): void { + if (_backPressSubscriptions.indexOf(handler) !== -1) { + _backPressSubscriptions.splice( + _backPressSubscriptions.indexOf(handler), + 1, + ); + } }, - removeEventListener: (eventName: BackPressEventName, handler: Function) => {}, }; module.exports = BackHandler; diff --git a/vnext/src/overrides.json b/vnext/src/overrides.json index c08977e63fd..e904a57504e 100644 --- a/vnext/src/overrides.json +++ b/vnext/src/overrides.json @@ -683,10 +683,10 @@ { "type": "derived", "file": "Libraries\\Utilities\\BackHandler.windows.js", - "baseFile": "Libraries\\Utilities\\BackHandler.ios.js", - "baseVersion": "0.62.0-rc.3", - "baseHash": "aa2d482b80ae66104d632c75c24646fdcbe916af", - "issue": "LEGACY_FIXME" + "baseFile": "Libraries\\Utilities\\BackHandler.android.js", + "baseVersion": "0.62.2", + "baseHash": "b1633b6bb5e3dc842011b09f778626c39bf6b654", + "issue": 4629 }, { "type": "derived", From 18d54be2f6fb6a95f055ab65792cbad22dcdfc97 Mon Sep 17 00:00:00 2001 From: React-Native-Windows Bot <53619745+rnbot@users.noreply.github.com> Date: Sat, 18 Apr 2020 00:04:35 +0000 Subject: [PATCH 02/21] applying package updates ***NO_CI*** --- ...-2020-04-15-05-17-49-statusbarmanager.json | 8 ---- ...0-04-08-09-04-34-direct_debugging_cli.json | 8 ---- ...-2020-04-15-05-17-49-statusbarmanager.json | 8 ---- ...2020-04-16-08-41-54-appearance-module.json | 8 ---- ...0-04-16-11-09-41-jahiggin-backHandler.json | 8 ---- ...16-17-40-26-removeAccessibilityStates.json | 8 ---- ...ws-2020-04-17-10-57-52-x64releaseyoga.json | 8 ---- packages/E2ETest/package.json | 2 +- .../package.json | 2 +- packages/playground/package.json | 2 +- packages/react-native-win32/CHANGELOG.json | 15 +++++++ packages/react-native-win32/CHANGELOG.md | 10 ++++- packages/react-native-win32/package.json | 2 +- vnext/CHANGELOG.json | 45 +++++++++++++++++++ vnext/CHANGELOG.md | 15 ++++++- vnext/package.json | 2 +- 16 files changed, 88 insertions(+), 63 deletions(-) delete mode 100644 change/@office-iss-react-native-win32-2020-04-15-05-17-49-statusbarmanager.json delete mode 100644 change/react-native-windows-2020-04-08-09-04-34-direct_debugging_cli.json delete mode 100644 change/react-native-windows-2020-04-15-05-17-49-statusbarmanager.json delete mode 100644 change/react-native-windows-2020-04-16-08-41-54-appearance-module.json delete mode 100644 change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json delete mode 100644 change/react-native-windows-2020-04-16-17-40-26-removeAccessibilityStates.json delete mode 100644 change/react-native-windows-2020-04-17-10-57-52-x64releaseyoga.json diff --git a/change/@office-iss-react-native-win32-2020-04-15-05-17-49-statusbarmanager.json b/change/@office-iss-react-native-win32-2020-04-15-05-17-49-statusbarmanager.json deleted file mode 100644 index 12f05680cb6..00000000000 --- a/change/@office-iss-react-native-win32-2020-04-15-05-17-49-statusbarmanager.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Implelent Shared StatusBarManagerModule and Do Module Cleanup", - "packageName": "@office-iss/react-native-win32", - "email": "ngerlem@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-04-15T12:17:45.965Z" -} \ No newline at end of file diff --git a/change/react-native-windows-2020-04-08-09-04-34-direct_debugging_cli.json b/change/react-native-windows-2020-04-08-09-04-34-direct_debugging_cli.json deleted file mode 100644 index 6e190fdc286..00000000000 --- a/change/react-native-windows-2020-04-08-09-04-34-direct_debugging_cli.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Allow enabling of direct debugging through the CLI.", - "packageName": "react-native-windows", - "email": "12337821+nasadigital@users.noreply.github.com", - "dependentChangeType": "patch", - "date": "2020-04-08T16:04:34.634Z" -} \ No newline at end of file diff --git a/change/react-native-windows-2020-04-15-05-17-49-statusbarmanager.json b/change/react-native-windows-2020-04-15-05-17-49-statusbarmanager.json deleted file mode 100644 index b480b1da114..00000000000 --- a/change/react-native-windows-2020-04-15-05-17-49-statusbarmanager.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Implelent Shared StatusBarManagerModule and Do Module Cleanup", - "packageName": "react-native-windows", - "email": "ngerlem@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-04-15T12:17:49.517Z" -} \ No newline at end of file diff --git a/change/react-native-windows-2020-04-16-08-41-54-appearance-module.json b/change/react-native-windows-2020-04-16-08-41-54-appearance-module.json deleted file mode 100644 index fe356c2fdee..00000000000 --- a/change/react-native-windows-2020-04-16-08-41-54-appearance-module.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Implement AppearanceModule", - "packageName": "react-native-windows", - "email": "ngerlem@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-04-16T15:41:54.563Z" -} \ No newline at end of file diff --git a/change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json b/change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json deleted file mode 100644 index b7b3e0c8d40..00000000000 --- a/change/react-native-windows-2020-04-16-11-09-41-jahiggin-backHandler.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Add support for React Native BackHandler API", - "packageName": "react-native-windows", - "email": "jahiggin@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-04-16T18:09:41.547Z" -} \ No newline at end of file diff --git a/change/react-native-windows-2020-04-16-17-40-26-removeAccessibilityStates.json b/change/react-native-windows-2020-04-16-17-40-26-removeAccessibilityStates.json deleted file mode 100644 index 5339bf2015e..00000000000 --- a/change/react-native-windows-2020-04-16-17-40-26-removeAccessibilityStates.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "remove AccessibilityStates", - "packageName": "react-native-windows", - "email": "kmelmon@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-04-17T00:40:26.842Z" -} \ No newline at end of file diff --git a/change/react-native-windows-2020-04-17-10-57-52-x64releaseyoga.json b/change/react-native-windows-2020-04-17-10-57-52-x64releaseyoga.json deleted file mode 100644 index 06de46f36b9..00000000000 --- a/change/react-native-windows-2020-04-17-10-57-52-x64releaseyoga.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "Fix issue with yoga layout in x64 release", - "packageName": "react-native-windows", - "email": "acoates@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-04-17T17:57:52.347Z" -} \ No newline at end of file diff --git a/packages/E2ETest/package.json b/packages/E2ETest/package.json index f4901d96b96..235b472e0b8 100644 --- a/packages/E2ETest/package.json +++ b/packages/E2ETest/package.json @@ -25,7 +25,7 @@ "prompt-sync": "^4.2.0", "react": "16.9.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.42", + "react-native-windows": "0.0.0-master.43", "rnpm-plugin-windows": "^0.6.1" }, "devDependencies": { diff --git a/packages/microsoft-reactnative-sampleapps/package.json b/packages/microsoft-reactnative-sampleapps/package.json index 8b3b95431bc..154d787b143 100644 --- a/packages/microsoft-reactnative-sampleapps/package.json +++ b/packages/microsoft-reactnative-sampleapps/package.json @@ -16,7 +16,7 @@ "dependencies": { "react": "16.9.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.42", + "react-native-windows": "0.0.0-master.43", "rnpm-plugin-windows": "^0.6.1" }, "devDependencies": { diff --git a/packages/playground/package.json b/packages/playground/package.json index 67ec25b6364..d369d05a3db 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -11,7 +11,7 @@ "dependencies": { "react": "16.9.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.42" + "react-native-windows": "0.0.0-master.43" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/packages/react-native-win32/CHANGELOG.json b/packages/react-native-win32/CHANGELOG.json index ff298ee9b21..3c83cf0780f 100644 --- a/packages/react-native-win32/CHANGELOG.json +++ b/packages/react-native-win32/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "@office-iss/react-native-win32", "entries": [ + { + "date": "Sat, 18 Apr 2020 00:04:34 GMT", + "tag": "@office-iss/react-native-win32_v0.0.0-master.6", + "version": "0.0.0-master.6", + "comments": { + "prerelease": [ + { + "comment": "Implelent Shared StatusBarManagerModule and Do Module Cleanup", + "author": "ngerlem@microsoft.com", + "commit": "609c18ca016e9e4b5831890bad56309f02280566", + "package": "@office-iss/react-native-win32" + } + ] + } + }, { "date": "Wed, 15 Apr 2020 22:26:36 GMT", "tag": "@office-iss/react-native-win32_v0.0.0-master.5", diff --git a/packages/react-native-win32/CHANGELOG.md b/packages/react-native-win32/CHANGELOG.md index 31e1fdfcde8..15432ae1647 100644 --- a/packages/react-native-win32/CHANGELOG.md +++ b/packages/react-native-win32/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - @office-iss/react-native-win32 -This log was last generated on Wed, 15 Apr 2020 22:26:36 GMT and should not be manually modified. +This log was last generated on Sat, 18 Apr 2020 00:04:34 GMT and should not be manually modified. +## 0.0.0-master.6 + +Sat, 18 Apr 2020 00:04:34 GMT + +### Changes + +- Implelent Shared StatusBarManagerModule and Do Module Cleanup (ngerlem@microsoft.com) + ## 0.0.0-master.5 Wed, 15 Apr 2020 22:26:36 GMT diff --git a/packages/react-native-win32/package.json b/packages/react-native-win32/package.json index 663285b48d4..9f18e975354 100644 --- a/packages/react-native-win32/package.json +++ b/packages/react-native-win32/package.json @@ -1,6 +1,6 @@ { "name": "@office-iss/react-native-win32", - "version": "0.0.0-master.5", + "version": "0.0.0-master.6", "description": "Implementation of react native on top of Office's Win32 platform.", "license": "MIT", "main": "./index.win32.js", diff --git a/vnext/CHANGELOG.json b/vnext/CHANGELOG.json index aaa03fcc7b3..5a174bb64bb 100644 --- a/vnext/CHANGELOG.json +++ b/vnext/CHANGELOG.json @@ -1,6 +1,51 @@ { "name": "react-native-windows", "entries": [ + { + "date": "Sat, 18 Apr 2020 00:04:34 GMT", + "tag": "react-native-windows_v0.0.0-master.43", + "version": "0.0.0-master.43", + "comments": { + "prerelease": [ + { + "comment": "Allow enabling of direct debugging through the CLI.", + "author": "12337821+nasadigital@users.noreply.github.com", + "commit": "c1a2140928b37d9c761c41bfa0fcc38704a14099", + "package": "react-native-windows" + }, + { + "comment": "Implelent Shared StatusBarManagerModule and Do Module Cleanup", + "author": "ngerlem@microsoft.com", + "commit": "609c18ca016e9e4b5831890bad56309f02280566", + "package": "react-native-windows" + }, + { + "comment": "Implement AppearanceModule", + "author": "ngerlem@microsoft.com", + "commit": "317d9fc1474930ef56c869706707126a78834c8b", + "package": "react-native-windows" + }, + { + "comment": "Add support for React Native BackHandler API", + "author": "jahiggin@microsoft.com", + "commit": "783410677774bcac2b7ada5900e2cec8675e5b2c", + "package": "react-native-windows" + }, + { + "comment": "remove AccessibilityStates", + "author": "kmelmon@microsoft.com", + "commit": "f3d983eff16d81b60127b67ff8f056d4c6f20e29", + "package": "react-native-windows" + }, + { + "comment": "Fix issue with yoga layout in x64 release", + "author": "acoates@microsoft.com", + "commit": "a67124cbd122bc9f90f7a9d5f328c94c504fe283", + "package": "react-native-windows" + } + ] + } + }, { "date": "Fri, 17 Apr 2020 00:04:27 GMT", "tag": "react-native-windows_v0.0.0-master.42", diff --git a/vnext/CHANGELOG.md b/vnext/CHANGELOG.md index cb8eebf1c71..f4d88cc8bff 100644 --- a/vnext/CHANGELOG.md +++ b/vnext/CHANGELOG.md @@ -1,9 +1,22 @@ # Change Log - react-native-windows -This log was last generated on Fri, 17 Apr 2020 00:04:27 GMT and should not be manually modified. +This log was last generated on Sat, 18 Apr 2020 00:04:34 GMT and should not be manually modified. +## 0.0.0-master.43 + +Sat, 18 Apr 2020 00:04:34 GMT + +### Changes + +- Allow enabling of direct debugging through the CLI. (12337821+nasadigital@users.noreply.github.com) +- Implelent Shared StatusBarManagerModule and Do Module Cleanup (ngerlem@microsoft.com) +- Implement AppearanceModule (ngerlem@microsoft.com) +- Add support for React Native BackHandler API (jahiggin@microsoft.com) +- remove AccessibilityStates (kmelmon@microsoft.com) +- Fix issue with yoga layout in x64 release (acoates@microsoft.com) + ## 0.0.0-master.42 Fri, 17 Apr 2020 00:04:27 GMT diff --git a/vnext/package.json b/vnext/package.json index 366f2127156..115ae4f285d 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -1,6 +1,6 @@ { "name": "react-native-windows", - "version": "0.0.0-master.42", + "version": "0.0.0-master.43", "license": "MIT", "repository": { "type": "git", From 52bf9690a1e48d18f8d36c3f8de8aaa95fdd174a Mon Sep 17 00:00:00 2001 From: kmelmon <33470154+kmelmon@users.noreply.github.com> Date: Sat, 18 Apr 2020 14:59:42 -0700 Subject: [PATCH 03/21] Fix include paths (#4634) * fix include paths * Change files * fix include paths --- ...ndows-2020-04-18-14-07-46-fix-includes.json | 8 ++++++++ .../Microsoft.ReactNative.vcxproj | 18 +++++++++--------- .../Microsoft.ReactNative.vcxproj.filters | 18 +++++++++--------- 3 files changed, 26 insertions(+), 18 deletions(-) create mode 100644 change/react-native-windows-2020-04-18-14-07-46-fix-includes.json diff --git a/change/react-native-windows-2020-04-18-14-07-46-fix-includes.json b/change/react-native-windows-2020-04-18-14-07-46-fix-includes.json new file mode 100644 index 00000000000..4f86a406153 --- /dev/null +++ b/change/react-native-windows-2020-04-18-14-07-46-fix-includes.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "fix include paths", + "packageName": "react-native-windows", + "email": "kmelmon@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-04-18T21:07:46.779Z" +} \ No newline at end of file diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj index 2ba8b5f70d5..50a4e0e8f53 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj @@ -223,15 +223,15 @@ - - - - - - - - - + + + + + + + + + diff --git a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters index 3fe649bb226..3b221e531d0 100644 --- a/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters +++ b/vnext/Microsoft.ReactNative/Microsoft.ReactNative.vcxproj.filters @@ -458,31 +458,31 @@ Polyester - + Utils - + Utils - + Utils - + Utils - + Utils - + Utils - + Utils - + Utils - + Utils From 6dae6e7c78853722f3cd2f3c13c1f6d1aa20035c Mon Sep 17 00:00:00 2001 From: React-Native-Windows Bot <53619745+rnbot@users.noreply.github.com> Date: Sun, 19 Apr 2020 00:04:29 +0000 Subject: [PATCH 04/21] applying package updates ***NO_CI*** --- ...-windows-2020-04-18-14-07-46-fix-includes.json | 8 -------- packages/E2ETest/package.json | 2 +- .../microsoft-reactnative-sampleapps/package.json | 2 +- packages/playground/package.json | 2 +- vnext/CHANGELOG.json | 15 +++++++++++++++ vnext/CHANGELOG.md | 10 +++++++++- vnext/package.json | 2 +- 7 files changed, 28 insertions(+), 13 deletions(-) delete mode 100644 change/react-native-windows-2020-04-18-14-07-46-fix-includes.json diff --git a/change/react-native-windows-2020-04-18-14-07-46-fix-includes.json b/change/react-native-windows-2020-04-18-14-07-46-fix-includes.json deleted file mode 100644 index 4f86a406153..00000000000 --- a/change/react-native-windows-2020-04-18-14-07-46-fix-includes.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "prerelease", - "comment": "fix include paths", - "packageName": "react-native-windows", - "email": "kmelmon@microsoft.com", - "dependentChangeType": "patch", - "date": "2020-04-18T21:07:46.779Z" -} \ No newline at end of file diff --git a/packages/E2ETest/package.json b/packages/E2ETest/package.json index 235b472e0b8..f86695a3402 100644 --- a/packages/E2ETest/package.json +++ b/packages/E2ETest/package.json @@ -25,7 +25,7 @@ "prompt-sync": "^4.2.0", "react": "16.9.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.43", + "react-native-windows": "0.0.0-master.44", "rnpm-plugin-windows": "^0.6.1" }, "devDependencies": { diff --git a/packages/microsoft-reactnative-sampleapps/package.json b/packages/microsoft-reactnative-sampleapps/package.json index 154d787b143..27afe30cf3b 100644 --- a/packages/microsoft-reactnative-sampleapps/package.json +++ b/packages/microsoft-reactnative-sampleapps/package.json @@ -16,7 +16,7 @@ "dependencies": { "react": "16.9.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.43", + "react-native-windows": "0.0.0-master.44", "rnpm-plugin-windows": "^0.6.1" }, "devDependencies": { diff --git a/packages/playground/package.json b/packages/playground/package.json index d369d05a3db..0eb37b69c06 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -11,7 +11,7 @@ "dependencies": { "react": "16.9.0", "react-native": "0.62.2", - "react-native-windows": "0.0.0-master.43" + "react-native-windows": "0.0.0-master.44" }, "devDependencies": { "@babel/core": "^7.8.4", diff --git a/vnext/CHANGELOG.json b/vnext/CHANGELOG.json index 5a174bb64bb..33aba5c3498 100644 --- a/vnext/CHANGELOG.json +++ b/vnext/CHANGELOG.json @@ -1,6 +1,21 @@ { "name": "react-native-windows", "entries": [ + { + "date": "Sun, 19 Apr 2020 00:04:29 GMT", + "tag": "react-native-windows_v0.0.0-master.44", + "version": "0.0.0-master.44", + "comments": { + "prerelease": [ + { + "comment": "fix include paths", + "author": "kmelmon@microsoft.com", + "commit": "52bf9690a1e48d18f8d36c3f8de8aaa95fdd174a", + "package": "react-native-windows" + } + ] + } + }, { "date": "Sat, 18 Apr 2020 00:04:34 GMT", "tag": "react-native-windows_v0.0.0-master.43", diff --git a/vnext/CHANGELOG.md b/vnext/CHANGELOG.md index f4d88cc8bff..af70ecde804 100644 --- a/vnext/CHANGELOG.md +++ b/vnext/CHANGELOG.md @@ -1,9 +1,17 @@ # Change Log - react-native-windows -This log was last generated on Sat, 18 Apr 2020 00:04:34 GMT and should not be manually modified. +This log was last generated on Sun, 19 Apr 2020 00:04:29 GMT and should not be manually modified. +## 0.0.0-master.44 + +Sun, 19 Apr 2020 00:04:29 GMT + +### Changes + +- fix include paths (kmelmon@microsoft.com) + ## 0.0.0-master.43 Sat, 18 Apr 2020 00:04:34 GMT diff --git a/vnext/package.json b/vnext/package.json index 115ae4f285d..9ddeeb8ebeb 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -1,6 +1,6 @@ { "name": "react-native-windows", - "version": "0.0.0-master.43", + "version": "0.0.0-master.44", "license": "MIT", "repository": { "type": "git", From 97a2fda638eea575d57e5e792b5b47f037333b6b Mon Sep 17 00:00:00 2001 From: Alexander Sklar Date: Sun, 19 Apr 2020 16:17:19 -0700 Subject: [PATCH 05/21] Remove break for 4122 and reenable DManip test (#4636) * remove 4122 guard rail * re-enable dmanip test --- packages/E2ETest/wdio/test/DirectManipulation.spec.ts | 5 +---- packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs | 6 ------ .../E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj | 2 +- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/E2ETest/wdio/test/DirectManipulation.spec.ts b/packages/E2ETest/wdio/test/DirectManipulation.spec.ts index 6e97bb96599..bc609af6a41 100644 --- a/packages/E2ETest/wdio/test/DirectManipulation.spec.ts +++ b/packages/E2ETest/wdio/test/DirectManipulation.spec.ts @@ -28,9 +28,6 @@ describe('DirectManipulationTest', () => { result.includes('width=50'), 'measureLayout response has correct width' ); - // https://github.com/microsoft/react-native-windows/issues/4122 - // Un-comment this when bug 4122 is fixed - // E2ETEST_OVERRIDE_4122 - // assert.ok(result.includes('x=20;'), 'measureLayout response x=20'); + assert.ok(result.includes('x=20;'), 'measureLayout response x=20'); }); }); diff --git a/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs b/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs index 0a6a8c61fd0..d813eb85f37 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs +++ b/packages/E2ETest/windows/ReactUWPTestApp/App.xaml.cs @@ -56,12 +56,6 @@ protected override void OnLaunched(LaunchActivatedEventArgs e) base.OnLaunched(e); SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Collapsed; ApplicationView.GetForCurrentView().TryResizeView(new Size(800, 600)); -#if !E2ETEST_OVERRIDE_4122 -#error [E2ETest] - There is a bug in Yoga with v142/VS2019 that makes the masters for this app different in Release|x64 than in other platforms. -#error However we want to test what people will be shipping. As a result, the tree dump output won't match the masters (which have the bug). -#error You can disable this warning by defining the constant E2ETEST_OVERRIDE_4122 in the project properties page under "Define Constants" -#error For more information see https://github.com/microsoft/react-native-windows/issues/4122 -#endif if (DisplayInformation.GetForCurrentView().ResolutionScale != ResolutionScale.Scale100Percent) { throw new Exception("A bug requires this app to run at 100% for accurate results - See https://github.com/microsoft/react-native-windows/issues/4619"); diff --git a/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj b/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj index 6611c1e40c4..07275254969 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj +++ b/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj @@ -81,7 +81,7 @@ bin\x64\Release\ - TRACE;NETFX_CORE;WINDOWS_UWP;E2ETEST_OVERRIDE_4122 + TRACE;NETFX_CORE;WINDOWS_UWP; true ;2008 pdbonly From 8a730a15ef2a2addb5b47b6eb2fabee5d54e4bbf Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 13:04:30 -0700 Subject: [PATCH 06/21] Bump io-ts from 2.2.0 to 2.2.1 (#4644) Bumps [io-ts](https://github.com/gcanti/io-ts) from 2.2.0 to 2.2.1. - [Release notes](https://github.com/gcanti/io-ts/releases) - [Changelog](https://github.com/gcanti/io-ts/blob/master/CHANGELOG.md) - [Commits](https://github.com/gcanti/io-ts/compare/2.2.0...2.2.1) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 363d82f3a04..6f1e6011465 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7704,9 +7704,9 @@ invert-kv@^2.0.0: integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== io-ts@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-2.2.0.tgz#e01ee2031098f05ab2ef17d137b8bebc928644e2" - integrity sha512-BIZkC9IJ1ix8v3ttSWb5CWVzbEbMkGwjl0dMBGCXVT921/4f/9wAngsqA8VLXFe5JjLJ3INxBufz3BaQVf2zKw== + version "2.2.1" + resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-2.2.1.tgz#d8cb21a23cf8fbe697d78445a65bab42c0eb467f" + integrity sha512-RufppkTV58MfDKF2gXlHVBvi+WIyL7nUcAQMkJ1O3SiQcqwlxf6dBOJP/LV19UxHRkGKJZ6ImSj7LqYcELIejQ== io.appium.settings@^2.10.0: version "2.14.1" From 854fd9d0b1f8b41203396697342d30c965d32f14 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 20 Apr 2020 13:04:48 -0700 Subject: [PATCH 07/21] Bump @types/lodash from 4.14.149 to 4.14.150 (#4642) Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.14.149 to 4.14.150. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) Signed-off-by: dependabot-preview[bot] Co-authored-by: dependabot-preview[bot] <27856297+dependabot-preview[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6f1e6011465..5b78372ccac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2807,9 +2807,9 @@ integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= "@types/lodash@^4.14.149": - version "4.14.149" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" - integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== + version "4.14.150" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.150.tgz#649fe44684c3f1fcb6164d943c5a61977e8cf0bd" + integrity sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w== "@types/minimatch@*": version "3.0.3" From 5c98e236066ced8eb314fae9995c288cb2eee798 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Mon, 20 Apr 2020 20:20:22 -0700 Subject: [PATCH 08/21] Release bundle builds should have --dev false flag (#4603) * Make default template build non-dev bundle when not using debug configuration * Change files * review feedback * ReactNativeWindows location shouldn't be hard coded in template project, since RNW could be hoisted * Align bundle props with gradle build options * Fix playground app * minor change * Change how we find the packageroot --- ...ows-2020-04-14-11-43-18-releasebundle.json | 8 ++++ .../ReactUWPTestApp/ReactUWPTestApp.csproj | 6 +-- .../TreeDumpLibrary/TreeDumpLibrary.csproj | 2 +- .../windows/SampleAppCPP/SampleAppCpp.vcxproj | 6 +-- .../windows/SampleAppCS/SampleAppCS.csproj | 8 +--- packages/playground/windows/.gitignore | 1 + .../windows/playground/Bundle/.gitignore | 2 - .../windows/playground/Playground.vcxproj | 8 ++-- vnext/PropertySheets/Bundle.Common.targets | 10 ++--- vnext/PropertySheets/Bundle.Cpp.targets | 2 +- vnext/PropertySheets/Bundle.props | 43 ++++++++++++++++++- vnext/local-cli/generator-windows/index.js | 2 +- .../generator-windows/templates/b_gitignore | 3 +- .../cpp/proj-experimental/MyApp.vcxproj | 14 +++--- .../templates/cpp/proj/MyApp.vcxproj | 16 +++---- .../templates/cs/proj/MyApp.csproj | 15 +++---- 16 files changed, 87 insertions(+), 59 deletions(-) create mode 100644 change/react-native-windows-2020-04-14-11-43-18-releasebundle.json delete mode 100644 packages/playground/windows/playground/Bundle/.gitignore diff --git a/change/react-native-windows-2020-04-14-11-43-18-releasebundle.json b/change/react-native-windows-2020-04-14-11-43-18-releasebundle.json new file mode 100644 index 00000000000..cddc40b0588 --- /dev/null +++ b/change/react-native-windows-2020-04-14-11-43-18-releasebundle.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Make default template build non-dev bundle when not using debug configuration", + "packageName": "react-native-windows", + "email": "acoates@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-04-14T18:43:18.289Z" +} \ No newline at end of file diff --git a/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj b/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj index 07275254969..863452d52a0 100644 --- a/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj +++ b/packages/E2ETest/windows/ReactUWPTestApp/ReactUWPTestApp.csproj @@ -174,11 +174,9 @@ 16.0 + - - echo WorkingDir %CD% - npx --no-install yarn run bundle - + dist/app/index.js - - - - - + + + + + \ No newline at end of file diff --git a/vnext/PropertySheets/Bundle.Cpp.targets b/vnext/PropertySheets/Bundle.Cpp.targets index 1ad7e09acf6..ef11a97b368 100644 --- a/vnext/PropertySheets/Bundle.Cpp.targets +++ b/vnext/PropertySheets/Bundle.Cpp.targets @@ -10,7 +10,7 @@ - $(BundleContentRoot)\%(RecursiveDir)%(Filename)%(Extension) + $([MSBuild]::MakeRelative($(ProjectDir),'$(BundleContentRoot)\%(RecursiveDir)%(Filename)%(Extension)')) true diff --git a/vnext/PropertySheets/Bundle.props b/vnext/PropertySheets/Bundle.props index 64f7c7eb244..883379ace3d 100644 --- a/vnext/PropertySheets/Bundle.props +++ b/vnext/PropertySheets/Bundle.props @@ -6,10 +6,49 @@ + + false true - Bundle - $(BundleContentRoot)\**\* + + + $([MSBuild]::NormalizePath('$(ProjectDir)\Bundle')) + + + $(BundleContentRoot)\**\* + + + index.windows.bundle + + + $([MSBuild]::NormalizePath('$(ProjectDir)\Bundle')) + + + true + false + + + + + + npx --no-install react-native bundle + + + $([MSBuild]::GetDirectoryNameOfFileAbove($(ProjectDir), 'package.json')) + + + index.windows.js + index.js + + + + + + $(OutDir)\sourcemaps\react + diff --git a/vnext/local-cli/generator-windows/index.js b/vnext/local-cli/generator-windows/index.js index 13b2e476bf0..7387048d3dd 100644 --- a/vnext/local-cli/generator-windows/index.js +++ b/vnext/local-cli/generator-windows/index.js @@ -97,7 +97,7 @@ function copyProjectTemplateAndReplace( [ { from: path.join(srcRootPath, 'metro.config.js'), to: 'metro.config.js' }, { from: path.join(srcRootPath, '_gitignore'), to: path.join(windowsDir, '.gitignore') }, - { from: path.join(srcRootPath, 'b_gitignore'), to: path.join(windowsDir, newProjectName, bundleDir, '.gitignore') }, + { from: path.join(srcRootPath, 'b_gitignore'), to: path.join(windowsDir, newProjectName, '.gitignore') }, { from: path.join(srcRootPath, 'index.windows.bundle'), to: path.join(windowsDir, newProjectName, bundleDir, 'index.windows.bundle') }, { from: path.join(srcPath, projDir, 'MyApp.sln'), to: path.join(windowsDir, newProjectName + '.sln') }, ].forEach((mapping) => copyAndReplaceWithChangedCallback(mapping.from, destPath, mapping.to, templateVars, options.overwrite)); diff --git a/vnext/local-cli/generator-windows/templates/b_gitignore b/vnext/local-cli/generator-windows/templates/b_gitignore index d6b7ef32c84..917243bd7ae 100644 --- a/vnext/local-cli/generator-windows/templates/b_gitignore +++ b/vnext/local-cli/generator-windows/templates/b_gitignore @@ -1,2 +1 @@ -* -!.gitignore +/Bundle diff --git a/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj b/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj index 3e6ccd65be1..f6a21a959da 100644 --- a/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj +++ b/vnext/local-cli/generator-windows/templates/cpp/proj-experimental/MyApp.vcxproj @@ -19,6 +19,9 @@ <%=certificateThumbprint%> password + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ + @@ -71,7 +74,7 @@ - + @@ -150,13 +153,8 @@ - - - - npx --no-install react-native bundle --platform windows --entry-file index.js --bundle-output $(MSBuildThisFileDirectory)/Bundle/index.windows.bundle --assets-dest $(MSBuildThisFileDirectory)/Bundle - - - + + diff --git a/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj b/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj index da48fb3cb65..d6970f786da 100644 --- a/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj +++ b/vnext/local-cli/generator-windows/templates/cpp/proj/MyApp.vcxproj @@ -19,6 +19,9 @@ <%=certificateThumbprint%> password + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ + @@ -71,7 +74,7 @@ - + @@ -149,19 +152,14 @@ - + {f7d32bd0-2749-483e-9a0d-1635ef7e3136} - - - - npx --no-install react-native bundle --platform windows --entry-file index.js --bundle-output $(MSBuildThisFileDirectory)/Bundle/index.windows.bundle --assets-dest $(MSBuildThisFileDirectory)/Bundle - - - + + diff --git a/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj b/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj index 2b598cbc339..e7010aff763 100644 --- a/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj +++ b/vnext/local-cli/generator-windows/templates/cs/proj/MyApp.csproj @@ -22,6 +22,9 @@ password false + + $([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), 'node_modules\react-native-windows\package.json'))\node_modules\react-native-windows\ + true bin\x86\Debug\ @@ -151,7 +154,7 @@ - + {f7d32bd0-2749-483e-9a0d-1635ef7e3136} Microsoft.ReactNative @@ -159,17 +162,13 @@ 2.3.191129002 - + 16.0 - - - npx --no-install react-native bundle --platform windows --entry-file index.js --bundle-output $(MSBuildThisFileDirectory)/Bundle/index.windows.bundle --assets-dest $(MSBuildThisFileDirectory)/Bundle - - - + + From a34e2169b7a0224cd2486fab5bd224077234d5d5 Mon Sep 17 00:00:00 2001 From: Andrew Coates <30809111+acoates-ms@users.noreply.github.com> Date: Mon, 20 Apr 2020 21:42:37 -0700 Subject: [PATCH 09/21] react-native-windows-init should support npm tags for --version parameter (#4647) * Fix react-native-windows-init to work with tags (@master) * Change files --- ...ws-init-2020-04-20-13-55-48-tagininit.json | 8 +++ packages/react-native-windows-init/src/Cli.ts | 50 ++++++++++++------- 2 files changed, 41 insertions(+), 17 deletions(-) create mode 100644 change/react-native-windows-init-2020-04-20-13-55-48-tagininit.json diff --git a/change/react-native-windows-init-2020-04-20-13-55-48-tagininit.json b/change/react-native-windows-init-2020-04-20-13-55-48-tagininit.json new file mode 100644 index 00000000000..6bf0f618f2f --- /dev/null +++ b/change/react-native-windows-init-2020-04-20-13-55-48-tagininit.json @@ -0,0 +1,8 @@ +{ + "type": "patch", + "comment": "Fix react-native-windows-init to work with tags (@master)", + "packageName": "react-native-windows-init", + "email": "acoates@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-04-20T20:55:48.747Z" +} \ No newline at end of file diff --git a/packages/react-native-windows-init/src/Cli.ts b/packages/react-native-windows-init/src/Cli.ts index 42c4bd320a4..512a797113a 100644 --- a/packages/react-native-windows-init/src/Cli.ts +++ b/packages/react-native-windows-init/src/Cli.ts @@ -8,7 +8,7 @@ import * as yargs from 'yargs'; import * as fs from 'fs'; import * as semver from 'semver'; -import {execSync} from 'child_process'; +import {exec, execSync} from 'child_process'; import * as validUrl from 'valid-url'; import * as prompts from 'prompts'; import * as findUp from 'find-up'; @@ -171,22 +171,38 @@ function getLatestMatchingVersion( }, ); } else { - // Assume that versionSemVer is actually a tag - npm.packages.release( - pkg, - versionSemVer, - (err: any, details: {version: string}[]) => { - if (err) { - reject(err); - } else if (details && details.length > 0) { - resolve(details[0].version); - return; - } - reject( - new Error(`No matching version of ${pkg}@${versionSemVer} found`), - ); - }, - ); + try { + exec( + `npm info ${pkg}@${versionSemVer} version --json`, + (err, stdout, _stderr) => { + try { + if (!err) { + let candidates = JSON.parse(stdout); + if (typeof candidates === 'string') { + resolve(candidates); + return; + } + candidates = candidates.sort(semver.rcompare); + if (candidates && candidates.length > 0) { + resolve(candidates[0]); + return; + } + } + reject( + new Error( + `No matching version of ${pkg}@${versionSemVer} found`, + ), + ); + } catch (e) { + reject(e); + } + }, + ); + } catch (err) { + reject( + new Error(`No matching version of ${pkg}@${versionSemVer} found`), + ); + } } }); } From 21dea64efa55d0cc23d0ad0e33a058b0e3981800 Mon Sep 17 00:00:00 2001 From: Vladimir Morozov Date: Tue, 21 Apr 2020 08:52:53 -0700 Subject: [PATCH 10/21] Implemented C++ TurboModule compile time spec validation (#4656) * Implemented C++ TurboModule compile time spec validation * Change files --- ...020-04-21-06-23-19-MS_CppTurboModules.json | 8 + ...icrosoft.ReactNative.Cxx.UnitTests.vcxproj | 4 +- .../NativeModuleTest.cpp | 264 +-- .../NoAttributeNativeModuleTest.cpp | 6 +- .../Point.h | 15 + .../ReactModuleBuilderMock.h | 4 +- .../TurboModuleTest.cpp | 2050 +++++++++++++++++ .../ModuleRegistration.h | 31 +- .../Microsoft.ReactNative.Cxx/NativeModules.h | 1176 ++++++---- vnext/Microsoft.ReactNative.Cxx/StructInfo.h | 2 +- 10 files changed, 2956 insertions(+), 604 deletions(-) create mode 100644 change/react-native-windows-2020-04-21-06-23-19-MS_CppTurboModules.json create mode 100644 vnext/Microsoft.ReactNative.Cxx.UnitTests/Point.h create mode 100644 vnext/Microsoft.ReactNative.Cxx.UnitTests/TurboModuleTest.cpp diff --git a/change/react-native-windows-2020-04-21-06-23-19-MS_CppTurboModules.json b/change/react-native-windows-2020-04-21-06-23-19-MS_CppTurboModules.json new file mode 100644 index 00000000000..80fe2a4b0ef --- /dev/null +++ b/change/react-native-windows-2020-04-21-06-23-19-MS_CppTurboModules.json @@ -0,0 +1,8 @@ +{ + "type": "prerelease", + "comment": "Implemented C++ TurboModule compile time spec validation", + "packageName": "react-native-windows", + "email": "vmorozov@microsoft.com", + "dependentChangeType": "patch", + "date": "2020-04-21T13:23:19.348Z" +} \ No newline at end of file diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj b/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj index 7959860f16f..352c770761e 100644 --- a/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/Microsoft.ReactNative.Cxx.UnitTests.vcxproj @@ -112,6 +112,7 @@ + @@ -126,6 +127,7 @@ Create + @@ -157,4 +159,4 @@ - + \ No newline at end of file diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/NativeModuleTest.cpp b/vnext/Microsoft.ReactNative.Cxx.UnitTests/NativeModuleTest.cpp index 8edd3933795..84eb534ceda 100644 --- a/vnext/Microsoft.ReactNative.Cxx.UnitTests/NativeModuleTest.cpp +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/NativeModuleTest.cpp @@ -5,24 +5,15 @@ #include "ReactModuleBuilderMock.h" #include -#include "NativeModules.h" +#include "Point.h" #include "future/futureWait.h" -namespace winrt::Microsoft::ReactNative { - -REACT_STRUCT(Point) -struct Point { - REACT_FIELD(X) - int X; - - REACT_FIELD(Y) - int Y; -}; +namespace ReactNativeTests { REACT_MODULE(SimpleNativeModule) struct SimpleNativeModule { REACT_INIT(Initialize) - void Initialize(IReactContext const &context) noexcept { + void Initialize(React::IReactContext const &context) noexcept { IsInitialized = true; TestCheck(context != nullptr); @@ -322,46 +313,46 @@ struct SimpleNativeModule { } REACT_METHOD(DividePromise) - void DividePromise(int x, int y, ReactPromise const &result) noexcept { + void DividePromise(int x, int y, React::ReactPromise const &result) noexcept { if (y != 0) { result.Resolve(x / y); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Division by 0"; result.Reject(std::move(error)); } } REACT_METHOD(NegatePromise) - void NegatePromise(int x, ReactPromise const &result) noexcept { + void NegatePromise(int x, React::ReactPromise const &result) noexcept { if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } } REACT_METHOD(NegateAsyncPromise) - fire_and_forget NegateAsyncPromise(int x, ReactPromise result) noexcept { + fire_and_forget NegateAsyncPromise(int x, React::ReactPromise result) noexcept { co_await winrt::resume_background(); if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } } REACT_METHOD(NegateDispatchQueuePromise) - void NegateDispatchQueuePromise(int x, ReactPromise const &result) noexcept { + void NegateDispatchQueuePromise(int x, React::ReactPromise const &result) noexcept { Mso::DispatchQueue::ConcurrentQueue().Post([ x, result ]() noexcept { if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } @@ -369,12 +360,12 @@ struct SimpleNativeModule { } REACT_METHOD(NegateFuturePromise) - void NegateFuturePromise(int x, ReactPromise const &result) noexcept { + void NegateFuturePromise(int x, React::ReactPromise const &result) noexcept { Mso::PostFuture([ x, result ]() noexcept { if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } @@ -383,7 +374,7 @@ struct SimpleNativeModule { // Each macro has second optional parameter: JS name. REACT_METHOD(VoidPromise, L"voidPromise") - void VoidPromise(int x, ReactPromise const &result) noexcept { + void VoidPromise(int x, React::ReactPromise const &result) noexcept { if (x % 2 == 0) { result.Resolve(); } else { @@ -392,58 +383,58 @@ struct SimpleNativeModule { } REACT_METHOD(ResolveSayHelloPromise) - void ResolveSayHelloPromise(ReactPromise const &result) noexcept { + void ResolveSayHelloPromise(React::ReactPromise const &result) noexcept { result.Resolve("Hello_4"); } REACT_METHOD(RejectSayHelloPromise) - void RejectSayHelloPromise(ReactPromise const &result) noexcept { - ReactError error{}; + void RejectSayHelloPromise(React::ReactPromise const &result) noexcept { + React::ReactError error{}; error.Message = "Promise rejected"; result.Reject(std::move(error)); } REACT_METHOD(StaticDividePromise) - static void StaticDividePromise(int x, int y, ReactPromise const &result) noexcept { + static void StaticDividePromise(int x, int y, React::ReactPromise const &result) noexcept { if (y != 0) { result.Resolve(x / y); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Division by 0"; result.Reject(std::move(error)); } } REACT_METHOD(StaticNegatePromise) - static void StaticNegatePromise(int x, ReactPromise const &result) noexcept { + static void StaticNegatePromise(int x, React::ReactPromise const &result) noexcept { if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } } REACT_METHOD(StaticNegateAsyncPromise) - static fire_and_forget StaticNegateAsyncPromise(int x, ReactPromise result) noexcept { + static fire_and_forget StaticNegateAsyncPromise(int x, React::ReactPromise result) noexcept { co_await winrt::resume_background(); if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } } REACT_METHOD(StaticNegateDispatchQueuePromise) - static void StaticNegateDispatchQueuePromise(int x, ReactPromise const &result) noexcept { + static void StaticNegateDispatchQueuePromise(int x, React::ReactPromise const &result) noexcept { Mso::DispatchQueue::ConcurrentQueue().Post([ x, result ]() noexcept { if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } @@ -451,12 +442,12 @@ struct SimpleNativeModule { } REACT_METHOD(StaticNegateFuturePromise) - static void StaticNegateFuturePromise(int x, ReactPromise const &result) noexcept { + static void StaticNegateFuturePromise(int x, React::ReactPromise const &result) noexcept { Mso::PostFuture([ x, result ]() noexcept { if (x >= 0) { result.Resolve(-x); } else { - ReactError error{}; + React::ReactError error{}; error.Message = "Already negative"; result.Reject(std::move(error)); } @@ -465,7 +456,7 @@ struct SimpleNativeModule { // Each macro has second optional parameter: JS name. REACT_METHOD(StaticVoidPromise, L"staticVoidPromise") - void StaticVoidPromise(int x, ReactPromise const &result) noexcept { + void StaticVoidPromise(int x, React::ReactPromise const &result) noexcept { if (x % 2 == 0) { result.Resolve(); } else { @@ -474,13 +465,13 @@ struct SimpleNativeModule { } REACT_METHOD(StaticResolveSayHelloPromise) - static void StaticResolveSayHelloPromise(ReactPromise const &result) noexcept { + static void StaticResolveSayHelloPromise(React::ReactPromise const &result) noexcept { result.Resolve("Hello_4"); } REACT_METHOD(StaticRejectSayHelloPromise) - static void StaticRejectSayHelloPromise(ReactPromise const &result) noexcept { - ReactError error{}; + static void StaticRejectSayHelloPromise(React::ReactPromise const &result) noexcept { + React::ReactError error{}; error.Message = "Promise rejected"; result.Reject(std::move(error)); } @@ -528,13 +519,13 @@ struct SimpleNativeModule { static constexpr Point Constant4{/*X =*/3, /*Y =*/4}; REACT_CONSTANT_PROVIDER(Constant5) - void Constant5(ReactConstantProvider &provider) noexcept { + void Constant5(React::ReactConstantProvider &provider) noexcept { provider.Add(L"const51", Point{/*X =*/12, /*Y =*/14}); provider.Add(L"const52", "MyConstant52"); } REACT_CONSTANT_PROVIDER(Constant6) - static void Constant6(ReactConstantProvider &provider) noexcept { + static void Constant6(React::ReactConstantProvider &provider) noexcept { provider.Add(L"const61", Point{/*X =*/15, /*Y =*/17}); provider.Add(L"const62", "MyConstant62"); } @@ -560,9 +551,9 @@ struct SimpleNativeModule { REACT_EVENT(OnStringEvent, L"onStringEvent", L"MyEventEmitter") std::function OnStringEvent; - // Use JSValue which is an immutable JSON-like data representation. + // Use React::JSValue which is an immutable JSON-like data representation. REACT_EVENT(OnJSValueEvent) - std::function OnJSValueEvent; + std::function OnJSValueEvent; // Allows to call JS functions. REACT_FUNCTION(JSIntFunction) @@ -585,9 +576,9 @@ struct SimpleNativeModule { REACT_FUNCTION(JSStringFunction, L"stringFunc", L"MyModule") std::function JSStringFunction; - // Use JSValue which is an immutable JSON-like data representation. + // Use React::JSValue which is an immutable JSON-like data representation. REACT_FUNCTION(JSValueFunction) - std::function JSValueFunction; + std::function JSValueFunction; public: // Used to report some test messages bool IsInitialized{false}; @@ -598,17 +589,17 @@ struct SimpleNativeModule { /*static*/ std::string SimpleNativeModule::StaticMessage; TEST_CLASS (NativeModuleTest) { - ReactModuleBuilderMock m_builderMock{}; - IReactModuleBuilder m_moduleBuilder; + React::ReactModuleBuilderMock m_builderMock{}; + React::IReactModuleBuilder m_moduleBuilder; Windows::Foundation::IInspectable m_moduleObject{nullptr}; SimpleNativeModule *m_module; NativeModuleTest() { - m_moduleBuilder = make(m_builderMock); - auto provider = MakeModuleProvider(); + m_moduleBuilder = winrt::make(m_builderMock); + auto provider = React::MakeModuleProvider(); m_moduleObject = m_builderMock.CreateModule(provider, m_moduleBuilder); - auto reactModule = m_moduleObject.as(); - m_module = &BoxedValue::GetImpl(reactModule); + auto reactModule = m_moduleObject.as(); + m_module = &React::BoxedValue::GetImpl(reactModule); } TEST_METHOD(TestMethodCall_Add) { @@ -644,7 +635,6 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call1(L"StaticSayHello", std::function([ ](const std::string &result) noexcept { TestCheck(result == "Hello"); })); TestCheck(m_builderMock.IsResolveCallbackCalled()); - TestCheck(m_builderMock.IsResolveCallbackCalled()); } TEST_METHOD(TestMethodCall_SayHello0) { @@ -1005,8 +995,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"DividePromise", std::function([](int result) noexcept { TestCheck(result == 3); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), 6, 2); TestCheck(m_builderMock.IsResolveCallbackCalled()); @@ -1016,8 +1006,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"DividePromise", std::function([](int result) noexcept { TestCheck(result == 3); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), 6, 0); TestCheck(m_builderMock.IsRejectCallbackCalled()); @@ -1027,8 +1017,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"NegatePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1037,8 +1027,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"NegatePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1047,8 +1037,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"NegateAsyncPromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5)); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1057,8 +1047,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"NegateAsyncPromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5)); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1067,8 +1057,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"NegateDispatchQueuePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5)); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1077,8 +1067,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"NegateDispatchQueuePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5)); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1087,8 +1077,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"NegateFuturePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5)); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1097,8 +1087,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"NegateFuturePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5)); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1107,8 +1097,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"voidPromise", std::function([]() noexcept {}), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), 2); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1117,8 +1107,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"voidPromise", std::function([]() noexcept {}), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), 3); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1128,8 +1118,8 @@ TEST_CLASS (NativeModuleTest) { L"ResolveSayHelloPromise", std::function( [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1138,8 +1128,8 @@ TEST_CLASS (NativeModuleTest) { L"RejectSayHelloPromise", std::function( [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1147,8 +1137,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"StaticDividePromise", std::function([](int result) noexcept { TestCheck(result == 3); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), 6, 2); TestCheck(m_builderMock.IsResolveCallbackCalled()); @@ -1158,8 +1148,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"StaticDividePromise", std::function([](int result) noexcept { TestCheck(result == 3); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), 6, 0); TestCheck(m_builderMock.IsRejectCallbackCalled()); @@ -1169,8 +1159,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"StaticNegatePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1179,8 +1169,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"StaticNegateAsyncPromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5)); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1189,8 +1179,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"StaticNegateAsyncPromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5)); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1199,8 +1189,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"StaticNegatePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1209,8 +1199,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"StaticNegateDispatchQueuePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5)); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1219,8 +1209,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"StaticNegateDispatchQueuePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5)); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1229,8 +1219,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"StaticNegateFuturePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), 5)); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1239,8 +1229,8 @@ TEST_CLASS (NativeModuleTest) { Mso::FutureWait(m_builderMock.Call2( L"StaticNegateFuturePromise", std::function([](int result) noexcept { TestCheck(result == -5); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), -5)); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1249,8 +1239,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"staticVoidPromise", std::function([]() noexcept {}), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), 2); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1259,8 +1249,8 @@ TEST_CLASS (NativeModuleTest) { m_builderMock.Call2( L"staticVoidPromise", std::function([]() noexcept {}), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), 3); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1270,8 +1260,8 @@ TEST_CLASS (NativeModuleTest) { L"StaticResolveSayHelloPromise", std::function( [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); TestCheck(m_builderMock.IsResolveCallbackCalled()); } @@ -1280,8 +1270,8 @@ TEST_CLASS (NativeModuleTest) { L"StaticRejectSayHelloPromise", std::function( [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), - std::function( - [](JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); TestCheck(m_builderMock.IsRejectCallbackCalled()); } @@ -1340,7 +1330,7 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestEvent_IntEventField) { bool eventRaised = false; m_builderMock.ExpectEvent( - L"RCTDeviceEventEmitter", L"OnIntEvent", [&eventRaised](JSValueArray const &args) noexcept { + L"RCTDeviceEventEmitter", L"OnIntEvent", [&eventRaised](React::JSValueArray const &args) noexcept { TestCheck(args[0] == 42); eventRaised = true; }); @@ -1352,7 +1342,7 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestEvent_OnNoArgEventField) { bool eventRaised = false; m_builderMock.ExpectEvent( - L"RCTDeviceEventEmitter", L"OnNoArgEvent", [&eventRaised](JSValueArray const &args) noexcept { + L"RCTDeviceEventEmitter", L"OnNoArgEvent", [&eventRaised](React::JSValueArray const &args) noexcept { TestCheckEqual(0, args.size()); eventRaised = true; }); @@ -1364,7 +1354,7 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestEvent_TwoArgsEventField) { bool eventRaised = false; m_builderMock.ExpectEvent( - L"RCTDeviceEventEmitter", L"OnTwoArgsEvent", [&eventRaised](JSValueArray const &args) noexcept { + L"RCTDeviceEventEmitter", L"OnTwoArgsEvent", [&eventRaised](React::JSValueArray const &args) noexcept { TestCheckEqual(4, args[0]["X"]); TestCheckEqual(2, args[0]["Y"]); TestCheckEqual(12, args[1]["X"]); @@ -1379,7 +1369,7 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestEvent_JSNameEventField) { bool eventRaised = false; m_builderMock.ExpectEvent( - L"RCTDeviceEventEmitter", L"onPointEvent", [&eventRaised](JSValueArray const &args) noexcept { + L"RCTDeviceEventEmitter", L"onPointEvent", [&eventRaised](React::JSValueArray const &args) noexcept { TestCheck(args[0]["X"] == 4); TestCheck(args[0]["Y"] == 2); eventRaised = true; @@ -1391,10 +1381,11 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestEvent_JSEventEmitterEventField) { bool eventRaised = false; - m_builderMock.ExpectEvent(L"MyEventEmitter", L"onStringEvent", [&eventRaised](JSValueArray const &args) noexcept { - TestCheckEqual("Hello World!", args[0]); - eventRaised = true; - }); + m_builderMock.ExpectEvent( + L"MyEventEmitter", L"onStringEvent", [&eventRaised](React::JSValueArray const &args) noexcept { + TestCheckEqual("Hello World!", args[0]); + eventRaised = true; + }); m_module->OnStringEvent("Hello World!"); TestCheck(eventRaised == true); @@ -1403,20 +1394,20 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestEvent_JSValueObjectEventField) { bool eventRaised = false; m_builderMock.ExpectEvent( - L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](JSValueArray const &args) noexcept { + L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](React::JSValueArray const &args) noexcept { TestCheck(args[0]["X"] == 4); TestCheck(args[0]["Y"] == 2); eventRaised = true; })); - m_module->OnJSValueEvent(JSValueObject{{"X", 4}, {"Y", 2}}); + m_module->OnJSValueEvent(React::JSValueObject{{"X", 4}, {"Y", 2}}); TestCheck(eventRaised == true); } TEST_METHOD(TestEvent_JSValueArrayEventField) { bool eventRaised = false; m_builderMock.ExpectEvent( - L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](JSValueArray const &args) noexcept { + L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](React::JSValueArray const &args) noexcept { TestCheck(args[0][0] == "X"); TestCheck(args[0][1] == 4); TestCheck(args[0][2] == true); @@ -1424,26 +1415,26 @@ TEST_CLASS (NativeModuleTest) { eventRaised = true; })); - m_module->OnJSValueEvent(JSValueArray{"X", 4, true, JSValueObject{{"Id", 42}}}); + m_module->OnJSValueEvent(React::JSValueArray{"X", 4, true, React::JSValueObject{{"Id", 42}}}); TestCheck(eventRaised == true); } TEST_METHOD(TestEvent_JSValueArray1EventField) { bool eventRaised = false; m_builderMock.ExpectEvent( - L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](JSValueArray const &args) noexcept { + L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](React::JSValueArray const &args) noexcept { TestCheck(args[0][0] == 4); eventRaised = true; })); - m_module->OnJSValueEvent(JSValueArray{4}); + m_module->OnJSValueEvent(React::JSValueArray{4}); TestCheck(eventRaised == true); } TEST_METHOD(TestFunction_JSIntFunctionField) { bool functionCalled = false; m_builderMock.ExpectFunction( - L"SimpleNativeModule", L"JSIntFunction", [&functionCalled](JSValueArray const &args) noexcept { + L"SimpleNativeModule", L"JSIntFunction", [&functionCalled](React::JSValueArray const &args) noexcept { TestCheck(args[0] == 42); functionCalled = true; }); @@ -1455,7 +1446,7 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestFunction_JSNameFunctionField) { bool functionCalled = false; m_builderMock.ExpectFunction( - L"SimpleNativeModule", L"pointFunc", [&functionCalled](JSValueArray const &args) noexcept { + L"SimpleNativeModule", L"pointFunc", [&functionCalled](React::JSValueArray const &args) noexcept { TestCheck(args[0]["X"] == 4); TestCheck(args[0]["Y"] == 2); functionCalled = true; @@ -1468,7 +1459,7 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestFunction_TwoArgFunctionField) { bool functionCalled = false; m_builderMock.ExpectFunction( - L"SimpleNativeModule", L"lineFunc", [&functionCalled](JSValueArray const &args) noexcept { + L"SimpleNativeModule", L"lineFunc", [&functionCalled](React::JSValueArray const &args) noexcept { TestCheck(args[0]["X"] == 4); TestCheck(args[0]["Y"] == 2); TestCheck(args[1]["X"] == 12); @@ -1483,7 +1474,7 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestFunction_NoArgFunctionField) { bool functionCalled = false; m_builderMock.ExpectFunction( - L"SimpleNativeModule", L"JSNoArgFunction", [&functionCalled](JSValueArray const &args) noexcept { + L"SimpleNativeModule", L"JSNoArgFunction", [&functionCalled](React::JSValueArray const &args) noexcept { TestCheckEqual(0, args.size()); functionCalled = true; }); @@ -1494,10 +1485,11 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestFunction_JSModuleNameFunctionField) { bool functionCalled = false; - m_builderMock.ExpectFunction(L"MyModule", L"stringFunc", [&functionCalled](JSValueArray const &args) noexcept { - TestCheck(args[0] == "Hello World!"); - functionCalled = true; - }); + m_builderMock.ExpectFunction( + L"MyModule", L"stringFunc", [&functionCalled](React::JSValueArray const &args) noexcept { + TestCheck(args[0] == "Hello World!"); + functionCalled = true; + }); m_module->JSStringFunction("Hello World!"); TestCheck(functionCalled == true); @@ -1506,20 +1498,20 @@ TEST_CLASS (NativeModuleTest) { TEST_METHOD(TestFunction_JSValueObjectFunctionField) { bool functionCalled = false; m_builderMock.ExpectFunction( - L"SimpleNativeModule", L"JSValueFunction", ([&functionCalled](JSValueArray const &args) noexcept { + L"SimpleNativeModule", L"JSValueFunction", ([&functionCalled](React::JSValueArray const &args) noexcept { TestCheck(args[0]["X"] == 4); TestCheck(args[0]["Y"] == 2); functionCalled = true; })); - m_module->JSValueFunction(JSValueObject{{"X", 4}, {"Y", 2}}); + m_module->JSValueFunction(React::JSValueObject{{"X", 4}, {"Y", 2}}); TestCheck(functionCalled == true); } TEST_METHOD(TestFunction_JSValueArrayFunctionField) { bool functionCalled = false; m_builderMock.ExpectFunction( - L"SimpleNativeModule", L"JSValueFunction", ([&functionCalled](JSValueArray const &args) noexcept { + L"SimpleNativeModule", L"JSValueFunction", ([&functionCalled](React::JSValueArray const &args) noexcept { TestCheck(args[0][0] == "X"); TestCheck(args[0][1] == 4); TestCheck(args[0][2] == true); @@ -1527,7 +1519,7 @@ TEST_CLASS (NativeModuleTest) { functionCalled = true; })); - m_module->JSValueFunction(JSValueArray{"X", 4, true, JSValueObject{{"Id", 42}}}); + m_module->JSValueFunction(React::JSValueArray{"X", 4, true, React::JSValueObject{{"Id", 42}}}); TestCheck(functionCalled == true); } @@ -1536,4 +1528,4 @@ TEST_CLASS (NativeModuleTest) { } }; -} // namespace winrt::Microsoft::ReactNative +} // namespace ReactNativeTests diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/NoAttributeNativeModuleTest.cpp b/vnext/Microsoft.ReactNative.Cxx.UnitTests/NoAttributeNativeModuleTest.cpp index 149e39eec87..35c2af283aa 100644 --- a/vnext/Microsoft.ReactNative.Cxx.UnitTests/NoAttributeNativeModuleTest.cpp +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/NoAttributeNativeModuleTest.cpp @@ -507,7 +507,7 @@ struct SimpleNativeModule2 { /*static*/ std::string SimpleNativeModule2::StaticMessage; -void RegisterModule(ReactModuleBuilder &moduleBuilder) noexcept { +void GetReactModuleInfo(SimpleNativeModule2 *, ReactModuleBuilder &moduleBuilder) noexcept { moduleBuilder.RegisterModuleName(L"SimpleNativeModule2"); moduleBuilder.RegisterInitMethod(&SimpleNativeModule2::Initialize); moduleBuilder.RegisterMethod(&SimpleNativeModule2::Add, L"Add"); @@ -577,8 +577,8 @@ void RegisterModule(ReactModuleBuilder &moduleBuilder) noex moduleBuilder.RegisterConstantField(&SimpleNativeModule2::Constant2, L"const2"); moduleBuilder.RegisterConstantField(&SimpleNativeModule2::Constant3, L"const3"); moduleBuilder.RegisterConstantField(&SimpleNativeModule2::Constant4, L"Constant4"); - moduleBuilder.RegisterConstantMethod(&SimpleNativeModule2::Constant5, L"Constant5"); - moduleBuilder.RegisterConstantMethod(&SimpleNativeModule2::Constant6, L"Constant6"); + moduleBuilder.RegisterConstantMethod(&SimpleNativeModule2::Constant5); + moduleBuilder.RegisterConstantMethod(&SimpleNativeModule2::Constant6); moduleBuilder.RegisterEventField(&SimpleNativeModule2::OnIntEvent, L"OnIntEvent"); moduleBuilder.RegisterEventField(&SimpleNativeModule2::OnNoArgEvent, L"OnNoArgEvent"); moduleBuilder.RegisterEventField(&SimpleNativeModule2::OnTwoArgsEvent, L"OnTwoArgsEvent"); diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/Point.h b/vnext/Microsoft.ReactNative.Cxx.UnitTests/Point.h new file mode 100644 index 00000000000..d711b247c33 --- /dev/null +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/Point.h @@ -0,0 +1,15 @@ +#pragma once +#include "NativeModules.h" + +namespace ReactNativeTests { + +REACT_STRUCT(Point) +struct Point { + REACT_FIELD(X) + int X; + + REACT_FIELD(Y) + int Y; +}; + +} // namespace ReactNativeTests diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactModuleBuilderMock.h b/vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactModuleBuilderMock.h index ded81090484..88ec6935f02 100644 --- a/vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactModuleBuilderMock.h +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/ReactModuleBuilderMock.h @@ -112,8 +112,8 @@ struct ReactModuleBuilderMock { std::vector m_constantProviders; std::map> m_methods; std::map m_syncMethods; - bool m_isResolveCallbackCalled; - bool m_isRejectCallbackCalled; + bool m_isResolveCallbackCalled{false}; + bool m_isRejectCallbackCalled{false}; Mso::Functor m_jsFunctionHandler; Mso::Functor m_jsEventHandler; }; diff --git a/vnext/Microsoft.ReactNative.Cxx.UnitTests/TurboModuleTest.cpp b/vnext/Microsoft.ReactNative.Cxx.UnitTests/TurboModuleTest.cpp new file mode 100644 index 00000000000..7564168c4dd --- /dev/null +++ b/vnext/Microsoft.ReactNative.Cxx.UnitTests/TurboModuleTest.cpp @@ -0,0 +1,2050 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +#include "pch.h" +#include "ReactModuleBuilderMock.h" + +#include +#include "Point.h" +#include "future/futureWait.h" + +namespace ReactNativeTests { +REACT_MODULE(MyTurboModule) +struct MyTurboModule { + REACT_INIT(Initialize) + void Initialize(React::IReactContext const &context) noexcept { + IsInitialized = true; + TestCheck(context != nullptr); + + // Event and Function fields are initialized before REACT_INIT method call. + TestCheck(this->OnIntEvent != nullptr); + TestCheck(this->JSIntFunction != nullptr); + } + + REACT_METHOD(Add) + int Add(int x, int y) noexcept { + return x + y; + } + + REACT_METHOD(Negate) + int Negate(int x) noexcept { + return -x; + } + + REACT_METHOD(SayHello) + std::string SayHello() noexcept { + return "Hello"; + } + + REACT_METHOD(StaticAdd) + static int StaticAdd(int x, int y) noexcept { + return x + y; + } + + REACT_METHOD(StaticNegate) + static int StaticNegate(int x) noexcept { + return -x; + } + + REACT_METHOD(StaticSayHello) + static std::string StaticSayHello() noexcept { + return "Hello"; + } + + REACT_METHOD(SayHello0) + void SayHello0() noexcept { + Message = "Hello_0"; + } + + REACT_METHOD(PrintPoint) + void PrintPoint(Point pt) noexcept { + std::stringstream ss; + ss << "Point: (" << pt.X << ", " << pt.Y << ")"; + Message = ss.str(); + } + + REACT_METHOD(PrintLine) + void PrintLine(Point start, Point end) noexcept { + std::stringstream ss; + ss << "Line: (" << start.X << ", " << start.Y << ")-(" << end.X << ", " << end.Y << ")"; + Message = ss.str(); + } + + REACT_METHOD(StaticSayHello0) + static void StaticSayHello0() noexcept { + StaticMessage = "Hello_0"; + } + + REACT_METHOD(StaticPrintPoint) + static void StaticPrintPoint(Point pt) noexcept { + std::stringstream ss; + ss << "Static Point: (" << pt.X << ", " << pt.Y << ")"; + StaticMessage = ss.str(); + } + + REACT_METHOD(StaticPrintLine) + static void StaticPrintLine(Point start, Point end) noexcept { + std::stringstream ss; + ss << "Static Line: (" << start.X << ", " << start.Y << ")-(" << end.X << ", " << end.Y << ")"; + StaticMessage = ss.str(); + } + + REACT_METHOD(AddCallback) + void AddCallback(int x, int y, std::function const &resolve) noexcept { + resolve(x + y); + } + + REACT_METHOD(NegateCallback) + void NegateCallback(int x, std::function const &resolve) noexcept { + resolve(-x); + } + + REACT_METHOD(NegateAsyncCallback) + fire_and_forget NegateAsyncCallback(int x, std::function resolve) noexcept { + co_await winrt::resume_background(); + resolve(-x); + } + + REACT_METHOD(NegateDispatchQueueCallback) + void NegateDispatchQueueCallback(int x, std::function const &resolve) noexcept { + Mso::DispatchQueue::ConcurrentQueue().Post([ x, resolve ]() noexcept { resolve(-x); }); + } + + REACT_METHOD(NegateFutureCallback) + void NegateFutureCallback(int x, std::function const &resolve) noexcept { + Mso::PostFuture([ x, resolve ]() noexcept { resolve(-x); }); + } + + REACT_METHOD(SayHelloCallback) + void SayHelloCallback(std::function const &resolve) noexcept { + resolve("Hello_2"); + } + + REACT_METHOD(StaticAddCallback) + static void StaticAddCallback(int x, int y, std::function const &resolve) noexcept { + resolve(x + y); + } + + REACT_METHOD(StaticNegateCallback) + static void StaticNegateCallback(int x, std::function const &resolve) noexcept { + resolve(-x); + } + + REACT_METHOD(StaticNegateAsyncCallback) + static fire_and_forget StaticNegateAsyncCallback(int x, std::function resolve) noexcept { + co_await winrt::resume_background(); + resolve(-x); + } + + REACT_METHOD(StaticNegateDispatchQueueCallback) + static void StaticNegateDispatchQueueCallback(int x, std::function const &resolve) noexcept { + Mso::DispatchQueue::ConcurrentQueue().Post([ x, resolve ]() noexcept { resolve(-x); }); + } + + REACT_METHOD(StaticNegateFutureCallback) + static void StaticNegateFutureCallback(int x, std::function const &resolve) noexcept { + Mso::PostFuture([ x, resolve ]() noexcept { resolve(-x); }); + } + + REACT_METHOD(StaticSayHelloCallback) + static void StaticSayHelloCallback(std::function const &resolve) noexcept { + resolve("Static Hello_2"); + } + + REACT_METHOD(DivideCallbacks) + void DivideCallbacks( + int x, + int y, + std::function const &resolve, + std::function const &reject) noexcept { + if (y != 0) { + resolve(x / y); + } else { + reject("Division by 0"); + } + } + + REACT_METHOD(NegateCallbacks) + void NegateCallbacks( + int x, + std::function const &resolve, + std::function const &reject) noexcept { + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + } + + REACT_METHOD(NegateAsyncCallbacks) + fire_and_forget NegateAsyncCallbacks( + int x, + std::function resolve, + std::function reject) noexcept { + co_await winrt::resume_background(); + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + } + + REACT_METHOD(NegateDispatchQueueCallbacks) + void NegateDispatchQueueCallbacks( + int x, + std::function const &resolve, + std::function const &reject) noexcept { + Mso::DispatchQueue::ConcurrentQueue().Post([ x, resolve, reject ]() noexcept { + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + }); + } + + REACT_METHOD(NegateFutureCallbacks) + void NegateFutureCallbacks( + int x, + std::function const &resolve, + std::function const &reject) noexcept { + Mso::PostFuture([ x, resolve, reject ]() noexcept { + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + }); + } + + REACT_METHOD(ResolveSayHelloCallbacks) + void ResolveSayHelloCallbacks( + std::function const &resolve, + std::function const & /*reject*/) noexcept { + resolve("Hello_3"); + } + + REACT_METHOD(RejectSayHelloCallbacks) + void RejectSayHelloCallbacks( + std::function const & /*resolve*/, + std::function const &reject) noexcept { + reject("Goodbye"); + } + + REACT_METHOD(StaticDivideCallbacks) + static void StaticDivideCallbacks( + int x, + int y, + std::function const &resolve, + std::function const &reject) noexcept { + if (y != 0) { + resolve(x / y); + } else { + reject("Division by 0"); + } + } + + REACT_METHOD(StaticNegateCallbacks) + static void StaticNegateCallbacks( + int x, + std::function const &resolve, + std::function const &reject) noexcept { + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + } + + REACT_METHOD(StaticNegateAsyncCallbacks) + static fire_and_forget StaticNegateAsyncCallbacks( + int x, + std::function resolve, + std::function reject) noexcept { + co_await winrt::resume_background(); + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + } + + REACT_METHOD(StaticNegateDispatchQueueCallbacks) + static void StaticNegateDispatchQueueCallbacks( + int x, + std::function const &resolve, + std::function const &reject) noexcept { + Mso::DispatchQueue::ConcurrentQueue().Post([ x, resolve, reject ]() noexcept { + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + }); + } + + REACT_METHOD(StaticNegateFutureCallbacks) + static void StaticNegateFutureCallbacks( + int x, + std::function const &resolve, + std::function const &reject) noexcept { + Mso::PostFuture([ x, resolve, reject ]() noexcept { + if (x >= 0) { + resolve(-x); + } else { + reject("Already negative"); + } + }); + } + + REACT_METHOD(StaticResolveSayHelloCallbacks) + static void StaticResolveSayHelloCallbacks( + std::function const &resolve, + std::function const & /*reject*/) noexcept { + resolve("Hello_3"); + } + + REACT_METHOD(StaticRejectSayHelloCallbacks) + static void StaticRejectSayHelloCallbacks( + std::function const & /*resolve*/, + std::function const &reject) noexcept { + reject("Goodbye"); + } + + REACT_METHOD(DividePromise) + void DividePromise(int x, int y, React::ReactPromise const &result) noexcept { + if (y != 0) { + result.Resolve(x / y); + } else { + React::ReactError error{}; + error.Message = "Division by 0"; + result.Reject(std::move(error)); + } + } + + REACT_METHOD(NegatePromise) + void NegatePromise(int x, React::ReactPromise const &result) noexcept { + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + } + + REACT_METHOD(NegateAsyncPromise) + fire_and_forget NegateAsyncPromise(int x, React::ReactPromise result) noexcept { + co_await winrt::resume_background(); + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + } + + REACT_METHOD(NegateDispatchQueuePromise) + void NegateDispatchQueuePromise(int x, React::ReactPromise const &result) noexcept { + Mso::DispatchQueue::ConcurrentQueue().Post([ x, result ]() noexcept { + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + }); + } + + REACT_METHOD(NegateFuturePromise) + void NegateFuturePromise(int x, React::ReactPromise const &result) noexcept { + Mso::PostFuture([ x, result ]() noexcept { + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + }); + } + + // Each macro has second optional parameter: JS name. + REACT_METHOD(VoidPromise, L"voidPromise") + void VoidPromise(int x, React::ReactPromise const &result) noexcept { + if (x % 2 == 0) { + result.Resolve(); + } else { + result.Reject("Odd unexpected"); + } + } + + REACT_METHOD(ResolveSayHelloPromise) + void ResolveSayHelloPromise(React::ReactPromise const &result) noexcept { + result.Resolve("Hello_4"); + } + + REACT_METHOD(RejectSayHelloPromise) + void RejectSayHelloPromise(React::ReactPromise const &result) noexcept { + React::ReactError error{}; + error.Message = "Promise rejected"; + result.Reject(std::move(error)); + } + + REACT_METHOD(StaticDividePromise) + static void StaticDividePromise(int x, int y, React::ReactPromise const &result) noexcept { + if (y != 0) { + result.Resolve(x / y); + } else { + React::ReactError error{}; + error.Message = "Division by 0"; + result.Reject(std::move(error)); + } + } + + REACT_METHOD(StaticNegatePromise) + static void StaticNegatePromise(int x, React::ReactPromise const &result) noexcept { + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + } + + REACT_METHOD(StaticNegateAsyncPromise) + static fire_and_forget StaticNegateAsyncPromise(int x, React::ReactPromise result) noexcept { + co_await winrt::resume_background(); + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + } + + REACT_METHOD(StaticNegateDispatchQueuePromise) + static void StaticNegateDispatchQueuePromise(int x, React::ReactPromise const &result) noexcept { + Mso::DispatchQueue::ConcurrentQueue().Post([ x, result ]() noexcept { + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + }); + } + + REACT_METHOD(StaticNegateFuturePromise) + static void StaticNegateFuturePromise(int x, React::ReactPromise const &result) noexcept { + Mso::PostFuture([ x, result ]() noexcept { + if (x >= 0) { + result.Resolve(-x); + } else { + React::ReactError error{}; + error.Message = "Already negative"; + result.Reject(std::move(error)); + } + }); + } + + // Each macro has second optional parameter: JS name. + REACT_METHOD(StaticVoidPromise, L"staticVoidPromise") + void StaticVoidPromise(int x, React::ReactPromise const &result) noexcept { + if (x % 2 == 0) { + result.Resolve(); + } else { + result.Reject("Odd unexpected"); + } + } + + REACT_METHOD(StaticResolveSayHelloPromise) + static void StaticResolveSayHelloPromise(React::ReactPromise const &result) noexcept { + result.Resolve("Hello_4"); + } + + REACT_METHOD(StaticRejectSayHelloPromise) + static void StaticRejectSayHelloPromise(React::ReactPromise const &result) noexcept { + React::ReactError error{}; + error.Message = "Promise rejected"; + result.Reject(std::move(error)); + } + + REACT_SYNC_METHOD(AddSync) + int AddSync(int x, int y) noexcept { + return x + y; + } + + REACT_SYNC_METHOD(NegateSync) + int NegateSync(int x) noexcept { + return -x; + } + + REACT_SYNC_METHOD(SayHelloSync) + std::string SayHelloSync() noexcept { + return "Hello"; + } + + REACT_SYNC_METHOD(StaticAddSync) + static int StaticAddSync(int x, int y) noexcept { + return x + y; + } + + REACT_SYNC_METHOD(StaticNegateSync) + static int StaticNegateSync(int x) noexcept { + return -x; + } + + REACT_SYNC_METHOD(StaticSayHelloSync) + static std::string StaticSayHelloSync() noexcept { + return "Hello"; + } + + REACT_CONSTANT(Constant1) + const std::string Constant1{"MyConstant1"}; + + REACT_CONSTANT(Constant2, L"const2") + const std::string Constant2{"MyConstant2"}; + + REACT_CONSTANT(Constant3, L"const3") + static constexpr Point Constant3{/*X =*/2, /*Y =*/3}; + + REACT_CONSTANT(Constant4) + static constexpr Point Constant4{/*X =*/3, /*Y =*/4}; + + REACT_CONSTANT_PROVIDER(Constant5) + void Constant5(React::ReactConstantProvider &provider) noexcept { + provider.Add(L"const51", Point{/*X =*/12, /*Y =*/14}); + provider.Add(L"const52", "MyConstant52"); + } + + REACT_CONSTANT_PROVIDER(Constant6) + static void Constant6(React::ReactConstantProvider &provider) noexcept { + provider.Add(L"const61", Point{/*X =*/15, /*Y =*/17}); + provider.Add(L"const62", "MyConstant62"); + } + + // Allows to emit native module events + REACT_EVENT(OnIntEvent) + std::function OnIntEvent; + + // An event without arguments + REACT_EVENT(OnNoArgEvent) + std::function OnNoArgEvent; + + // An event with two arguments + REACT_EVENT(OnTwoArgsEvent) + std::function OnTwoArgsEvent; + + // Specify event name different from the field name. + REACT_EVENT(OnPointEvent, L"onPointEvent") + std::function OnPointEvent; + + // By default we use the event emitter name from REACT_MODULE which is by default 'RCTDeviceEventEmitter'. + // Here we specify event emitter name local for this event. + REACT_EVENT(OnStringEvent, L"onStringEvent", L"MyEventEmitter") + std::function OnStringEvent; + + // Use React::JSValue which is an immutable JSON-like data representation. + REACT_EVENT(OnJSValueEvent) + std::function OnJSValueEvent; + + // Allows to call JS functions. + REACT_FUNCTION(JSIntFunction) + std::function JSIntFunction; + + // Specify JS function name different from the field name. + REACT_FUNCTION(JSPointFunction, L"pointFunc") + std::function JSPointFunction; + + // Use two arguments. Specify JS function name different from the field name. + REACT_FUNCTION(JSLineFunction, L"lineFunc") + std::function JSLineFunction; + + // Use no arguments. + REACT_FUNCTION(JSNoArgFunction) + std::function JSNoArgFunction; + + // By default we use the module name from REACT_MODULE which is by default the struct name. + // Here we specify module name local for this function. + REACT_FUNCTION(JSStringFunction, L"stringFunc", L"MyModule") + std::function JSStringFunction; + + // Use React::JSValue which is an immutable JSON-like data representation. + REACT_FUNCTION(JSValueFunction) + std::function JSValueFunction; + + public: // Used to report some test messages + bool IsInitialized{false}; + std::string Message; + static std::string StaticMessage; +}; + +/*static*/ std::string MyTurboModule::StaticMessage; + +// The TurboModule spec is going to be generated from the Flow spec file. +// It verifies that: +// - module methods names are unique; +// - method names are matching to the module spec method names; +// - method signatures match the spec method signatures. +struct MyTurboModuleSpec : winrt::Microsoft::ReactNative::TurboModuleSpec { + static constexpr auto methods = std::tuple{ + Method) noexcept>{0, L"Add"}, + Method) noexcept>{1, L"Negate"}, + Method) noexcept>{2, L"SayHello"}, + Method) noexcept>{3, L"StaticAdd"}, + Method) noexcept>{4, L"StaticNegate"}, + Method) noexcept>{5, L"StaticSayHello"}, + Method{6, L"SayHello0"}, + Method{7, L"PrintPoint"}, + Method{8, L"PrintLine"}, + Method{9, L"StaticSayHello0"}, + Method{10, L"StaticPrintPoint"}, + Method{11, L"StaticPrintLine"}, + Method) noexcept>{12, L"AddCallback"}, + Method) noexcept>{13, L"NegateCallback"}, + Method) noexcept>{14, L"NegateAsyncCallback"}, + Method) noexcept>{15, L"NegateDispatchQueueCallback"}, + Method) noexcept>{16, L"NegateFutureCallback"}, + Method) noexcept>{17, L"SayHelloCallback"}, + Method) noexcept>{18, L"StaticAddCallback"}, + Method) noexcept>{19, L"StaticNegateCallback"}, + Method) noexcept>{20, L"StaticNegateAsyncCallback"}, + Method) noexcept>{21, L"StaticNegateDispatchQueueCallback"}, + Method) noexcept>{22, L"StaticNegateFutureCallback"}, + Method) noexcept>{23, L"StaticSayHelloCallback"}, + Method, Callback) noexcept>{24, L"DivideCallbacks"}, + Method, Callback) noexcept>{25, L"NegateCallbacks"}, + Method, Callback) noexcept>{26, L"NegateAsyncCallbacks"}, + Method, Callback) noexcept>{27, L"NegateDispatchQueueCallbacks"}, + Method, Callback) noexcept>{28, L"NegateFutureCallbacks"}, + Method, Callback) noexcept>{29, L"ResolveSayHelloCallbacks"}, + Method, Callback) noexcept>{30, L"RejectSayHelloCallbacks"}, + Method, Callback) noexcept>{31, L"StaticDivideCallbacks"}, + Method, Callback) noexcept>{32, L"StaticNegateCallbacks"}, + Method, Callback) noexcept>{33, L"StaticNegateAsyncCallbacks"}, + Method, Callback) noexcept>{34, L"StaticNegateDispatchQueueCallbacks"}, + Method, Callback) noexcept>{35, L"StaticNegateFutureCallbacks"}, + Method, Callback) noexcept>{36, L"StaticResolveSayHelloCallbacks"}, + Method, Callback) noexcept>{37, L"StaticRejectSayHelloCallbacks"}, + Method) noexcept>{38, L"DividePromise"}, + Method) noexcept>{39, L"NegatePromise"}, + Method) noexcept>{40, L"NegateAsyncPromise"}, + Method) noexcept>{41, L"NegateDispatchQueuePromise"}, + Method) noexcept>{42, L"NegateFuturePromise"}, + Method) noexcept>{43, L"voidPromise"}, + Method) noexcept>{44, L"ResolveSayHelloPromise"}, + Method) noexcept>{45, L"RejectSayHelloPromise"}, + Method) noexcept>{46, L"StaticDividePromise"}, + Method) noexcept>{47, L"StaticNegatePromise"}, + Method) noexcept>{48, L"StaticNegateAsyncPromise"}, + Method) noexcept>{49, L"StaticNegateDispatchQueuePromise"}, + Method) noexcept>{50, L"StaticNegateFuturePromise"}, + Method) noexcept>{51, L"staticVoidPromise"}, + Method) noexcept>{52, L"StaticResolveSayHelloPromise"}, + Method) noexcept>{53, L"StaticRejectSayHelloPromise"}, + SyncMethod{54, L"AddSync"}, + SyncMethod{55, L"NegateSync"}, + SyncMethod{56, L"SayHelloSync"}, + SyncMethod{57, L"StaticAddSync"}, + SyncMethod{58, L"StaticNegateSync"}, + SyncMethod{59, L"StaticSayHelloSync"}, + }; + + template + static constexpr void ValidateModule() noexcept { + constexpr auto methodCheckResults = CheckMethods(); + + REACT_SHOW_METHOD_SPEC_ERRORS( + 0, + "Add", + " REACT_METHOD(Add) int Add(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(Add) void Add(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(Add) winrt::fire_and_forget Add(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(Add) static int Add(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(Add) static void Add(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(Add) static React::Coroutine Add(int, int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 1, + "Negate", + " REACT_METHOD(Negate) int Negate(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(Negate) void Negate(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(Negate) winrt::fire_and_forget Negate(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(Negate) static int Negate(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(Negate) static void Negate(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(Negate) static winrt::fire_and_forget Negate(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 2, + "SayHello", + " REACT_METHOD(SayHello) std::string SayHello() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello) void SayHello(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello) winrt::fire_and_forget SayHello(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello) static std::string SayHello() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello) static void SayHello(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello) static winrt::fire_and_forget SayHello(ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 3, + "StaticAdd", + " REACT_METHOD(StaticAdd) int StaticAdd(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAdd) void StaticAdd(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAdd) winrt::fire_and_forget StaticAdd(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAdd) static int StaticAdd(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAdd) static void StaticAdd(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAdd) static winrt::fire_and_forget StaticAdd(int, int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 4, + "StaticNegate", + " REACT_METHOD(StaticNegate) int StaticNegate(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegate) void StaticNegate(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegate) winrt::fire_and_forget StaticNegate(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegate) static int StaticNegate(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegate) static void StaticNegate(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegate) static winrt::fire_and_forget StaticNegate(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 5, + "StaticSayHello", + " REACT_METHOD(StaticSayHello) std::string StaticSayHello() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello) void StaticSayHello(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello) winrt::fire_and_forget StaticSayHello(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello) static std::string StaticSayHello() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello) static void StaticSayHello(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello) static winrt::fire_and_forget StaticSayHello(ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 6, + "SayHello0", + " REACT_METHOD(SayHello0) void SayHello0() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello0) winrt::fire_and_forget SayHello0() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello0) static void SayHello0() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHello0) static winrt::fire_and_forget SayHello0() noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 7, + "PrintPoint", + " REACT_METHOD(PrintPoint) void PrintPoint(Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(PrintPoint) winrt::fire_and_forget PrintPoint(Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(PrintPoint) static void PrintPoint(Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(PrintPoint) static winrt::fire_and_forget PrintPoint(Point) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 8, + "PrintLine", + " REACT_METHOD(PrintPoint) void PrintLine(Point, Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(PrintPoint) winrt::fire_and_forget PrintLine(Point, Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(PrintPoint) static void PrintLine(Point, Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(PrintPoint) static winrt::fire_and_forget PrintLine(Point, Point) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 9, + "StaticSayHello0", + " REACT_METHOD(StaticSayHello0) void StaticSayHello0() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello0) winrt::fire_and_forget StaticSayHello0() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello0) static void StaticSayHello0() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHello0) static winrt::fire_and_forget StaticSayHello0() noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 10, + "StaticPrintPoint", + " REACT_METHOD(StaticPrintPoint) void StaticPrintPoint(Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticPrintPoint) winrt::fire_and_forget StaticPrintPoint(Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticPrintPoint) static void StaticPrintPoint(Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticPrintPoint) static winrt::fire_and_forget StaticPrintPoint(Point) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 11, + "StaticPrintLine", + " REACT_METHOD(StaticPrintPoint) void StaticPrintLine(Point, Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticPrintPoint) winrt::fire_and_forget StaticPrintLine(Point, Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticPrintPoint) static void StaticPrintLine(Point, Point) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticPrintPoint) static winrt::fire_and_forget StaticPrintLine(Point, Point) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 12, + "AddCallback", + " REACT_METHOD(AddCallback) int AddCallback(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(AddCallback) void AddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(AddCallback) winrt::fire_and_forget AddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(AddCallback) static int AddCallback(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(AddCallback) static void AddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(AddCallback) static winrt::fire_and_forget AddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 13, + "NegateCallback", + " REACT_METHOD(NegateCallback) int NegateCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallback) void NegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallback) winrt::fire_and_forget NegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallback) static int NegateCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallback) static void NegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallback) static winrt::fire_and_forget NegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 14, + "NegateAsyncCallback", + " REACT_METHOD(NegateAsyncCallback) int NegateAsyncCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallback) void NegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallback) winrt::fire_and_forget NegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallback) static int NegateAsyncCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallback) static void NegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallback) static winrt::fire_and_forget NegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 15, + "NegateDispatchQueueCallback", + " REACT_METHOD(NegateDispatchQueueCallback) int NegateDispatchQueueCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallback) void NegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallback) winrt::fire_and_forget NegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallback) static int NegateDispatchQueueCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallback) static void NegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallback) static winrt::fire_and_forget NegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 16, + "NegateFutureCallback", + " REACT_METHOD(NegateFutureCallback) int NegateFutureCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallback) void NegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallback) winrt::fire_and_forget NegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallback) static int NegateFutureCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallback) static void NegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallback) static winrt::fire_and_forget NegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 17, + "SayHelloCallback", + " REACT_METHOD(SayHelloCallback) std::string SayHelloCallback() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHelloCallback) void SayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHelloCallback) winrt::fire_and_forget SayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHelloCallback) static std::string SayHelloCallback() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHelloCallback) static void SayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHelloCallback) static winrt::fire_and_forget SayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 18, + "StaticAddCallback", + " REACT_METHOD(StaticAddCallback) int StaticAddCallback(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAddCallback) void StaticAddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAddCallback) winrt::fire_and_forget StaticAddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAddCallback) static int StaticAddCallback(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAddCallback) static void StaticAddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAddCallback) static winrt::fire_and_forget StaticAddCallback(int, int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 19, + "StaticNegateCallback", + " REACT_METHOD(StaticNegateCallback) int StaticNegateCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallback) void StaticNegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallback) winrt::fire_and_forget StaticNegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallback) static int StaticNegateCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallback) static void StaticNegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallback) static winrt::fire_and_forget StaticNegateCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 20, + "StaticNegateAsyncCallback", + " REACT_METHOD(StaticNegateAsyncCallback) int StaticNegateAsyncCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallback) void StaticNegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallback) winrt::fire_and_forget StaticNegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallback) static int StaticNegateAsyncCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallback) static void StaticNegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallback) static winrt::fire_and_forget StaticNegateAsyncCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 21, + "StaticNegateDispatchQueueCallback", + " REACT_METHOD(StaticNegateDispatchQueueCallback) int StaticNegateDispatchQueueCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallback) void StaticNegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallback) winrt::fire_and_forget StaticNegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallback) static int StaticNegateDispatchQueueCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallback) static void StaticNegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallback) static winrt::fire_and_forget StaticNegateDispatchQueueCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 22, + "StaticNegateFutureCallback", + " REACT_METHOD(StaticNegateFutureCallback) int StaticNegateFutureCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallback) void StaticNegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallback) winrt::fire_and_forget StaticNegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallback) static int StaticNegateFutureCallback(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallback) static void StaticNegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallback) static winrt::fire_and_forget StaticNegateFutureCallback(int, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 23, + "StaticSayHelloCallback", + " REACT_METHOD(StaticSayHelloCallback) std::string StaticSayHelloCallback() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHelloCallback) void StaticSayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHelloCallback) winrt::fire_and_forget StaticSayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHelloCallback) static std::string StaticSayHelloCallback() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHelloCallback) static void StaticSayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHelloCallback) static winrt::fire_and_forget StaticSayHelloCallback(ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 24, + "DivideCallbacks", + " REACT_METHOD(DivideCallbacks) void DivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(DivideCallbacks) winrt::fire_and_forget DivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(DivideCallbacks) static void DivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(DivideCallbacks) static winrt::fire_and_forget DivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 25, + "NegateCallbacks", + " REACT_METHOD(NegateCallbacks) void NegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallbacks) winrt::fire_and_forget NegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallbacks) static void NegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateCallbacks) static winrt::fire_and_forget NegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 26, + "NegateAsyncCallbacks", + " REACT_METHOD(NegateAsyncCallbacks) void NegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallbacks) winrt::fire_and_forget NegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallbacks) static void NegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncCallbacks) static winrt::fire_and_forget NegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 27, + "NegateDispatchQueueCallbacks", + " REACT_METHOD(NegateDispatchQueueCallbacks) void NegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallbacks) winrt::fire_and_forget NegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallbacks) static void NegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueueCallbacks) static winrt::fire_and_forget NegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 28, + "NegateFutureCallbacks", + " REACT_METHOD(NegateFutureCallbacks) void NegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallbacks) winrt::fire_and_forget NegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallbacks) static void NegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFutureCallbacks) static winrt::fire_and_forget NegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 29, + "ResolveSayHelloCallbacks", + " REACT_METHOD(ResolveSayHelloCallbacks) void ResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(ResolveSayHelloCallbacks) winrt::fire_and_forget ResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(ResolveSayHelloCallbacks) static void ResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(ResolveSayHelloCallbacks) static winrt::fire_and_forget ResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 30, + "RejectSayHelloCallbacks", + " REACT_METHOD(RejectSayHelloCallbacks) void RejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(RejectSayHelloCallbacks) winrt::fire_and_forget RejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(RejectSayHelloCallbacks) static void RejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(RejectSayHelloCallbacks) static winrt::fire_and_forget RejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 31, + "StaticDivideCallbacks", + " REACT_METHOD(StaticDivideCallbacks) void StaticDivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticDivideCallbacks) winrt::fire_and_forget StaticDivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticDivideCallbacks) static void StaticDivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticDivideCallbacks) static winrt::fire_and_forget StaticDivideCallbacks(int, int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 32, + "StaticNegateCallbacks", + " REACT_METHOD(StaticNegateCallbacks) void StaticNegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallbacks) winrt::fire_and_forget StaticNegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallbacks) static void StaticNegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateCallbacks) static winrt::fire_and_forget StaticNegateCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 33, + "StaticNegateAsyncCallbacks", + " REACT_METHOD(StaticNegateAsyncCallbacks) void StaticNegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallbacks) winrt::fire_and_forget StaticNegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallbacks) static void StaticNegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncCallbacks) static winrt::fire_and_forget StaticNegateAsyncCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 34, + "StaticNegateDispatchQueueCallbacks", + " REACT_METHOD(StaticNegateDispatchQueueCallbacks) void StaticNegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallbacks) winrt::fire_and_forget StaticNegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallbacks) static void StaticNegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueueCallbacks) static winrt::fire_and_forget StaticNegateDispatchQueueCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 35, + "StaticNegateFutureCallbacks", + " REACT_METHOD(StaticNegateFutureCallbacks) void StaticNegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallbacks) winrt::fire_and_forget StaticNegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallbacks) static void StaticNegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFutureCallbacks) static winrt::fire_and_forget StaticNegateFutureCallbacks(int, ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 36, + "StaticResolveSayHelloCallbacks", + " REACT_METHOD(StaticResolveSayHelloCallbacks) void StaticResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticResolveSayHelloCallbacks) winrt::fire_and_forget StaticResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticResolveSayHelloCallbacks) static void StaticResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticResolveSayHelloCallbacks) static winrt::fire_and_forget StaticResolveSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 37, + "StaticRejectSayHelloCallbacks", + " REACT_METHOD(StaticRejectSayHelloCallbacks) void StaticRejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticRejectSayHelloCallbacks) winrt::fire_and_forget StaticRejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticRejectSayHelloCallbacks) static void StaticRejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticRejectSayHelloCallbacks) static winrt::fire_and_forget StaticRejectSayHelloCallbacks(ReactCallback, ReactCallback) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 38, + "DividePromise", + " REACT_METHOD(DividePromise) void DividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(DividePromise) winrt::fire_and_forget DividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(DividePromise) static void DividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(DividePromise) static winrt::fire_and_forget DividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 39, + "NegatePromise", + " REACT_METHOD(NegatePromise) void NegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegatePromise) winrt::fire_and_forget NegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegatePromise) static void NegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegatePromise) static winrt::fire_and_forget NegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 40, + "NegateAsyncPromise", + " REACT_METHOD(NegateAsyncPromise) void NegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncPromise) winrt::fire_and_forget NegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncPromise) static void NegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateAsyncPromise) static winrt::fire_and_forget NegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 41, + "NegateDispatchQueuePromise", + " REACT_METHOD(NegateDispatchQueuePromise) void NegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueuePromise) winrt::fire_and_forget NegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueuePromise) static void NegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateDispatchQueuePromise) static winrt::fire_and_forget NegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 42, + "NegateFuturePromise", + " REACT_METHOD(NegateFuturePromise) void NegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFuturePromise) winrt::fire_and_forget NegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFuturePromise) static void NegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateFuturePromise) static winrt::fire_and_forget NegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 43, + "voidPromise", + " REACT_METHOD(voidPromise) void voidPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(voidPromise) winrt::fire_and_forget voidPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(voidPromise) static void voidPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(voidPromise) static winrt::fire_and_forget voidPromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 44, + "ResolveSayHelloPromise", + " REACT_METHOD(ResolveSayHelloPromise) void ResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(ResolveSayHelloPromise) winrt::fire_and_forget ResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(ResolveSayHelloPromise) static void ResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(ResolveSayHelloPromise) static winrt::fire_and_forget ResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 45, + "RejectSayHelloPromise", + " REACT_METHOD(RejectSayHelloPromise) void RejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(RejectSayHelloPromise) winrt::fire_and_forget RejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(RejectSayHelloPromise) static void RejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(RejectSayHelloPromise) static winrt::fire_and_forget RejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 46, + "StaticDividePromise", + " REACT_METHOD(StaticDividePromise) void StaticDividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticDividePromise) winrt::fire_and_forget StaticDividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticDividePromise) static void StaticDividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticDividePromise) static winrt::fire_and_forget StaticDividePromise(int, int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 47, + "StaticNegatePromise", + " REACT_METHOD(StaticNegatePromise) void StaticNegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegatePromise) winrt::fire_and_forget StaticNegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegatePromise) static void StaticNegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegatePromise) static winrt::fire_and_forget StaticNegatePromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 48, + "StaticNegateAsyncPromise", + " REACT_METHOD(StaticNegateAsyncPromise) void StaticNegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncPromise) winrt::fire_and_forget StaticNegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncPromise) static void StaticNegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateAsyncPromise) static winrt::fire_and_forget StaticNegateAsyncPromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 49, + "StaticNegateDispatchQueuePromise", + " REACT_METHOD(StaticNegateDispatchQueuePromise) void StaticNegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueuePromise) winrt::fire_and_forget StaticNegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueuePromise) static void StaticNegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateDispatchQueuePromise) static winrt::fire_and_forget StaticNegateDispatchQueuePromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 50, + "StaticNegateFuturePromise", + " REACT_METHOD(StaticNegateFuturePromise) void StaticNegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFuturePromise) winrt::fire_and_forget StaticNegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFuturePromise) static void StaticNegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateFuturePromise) static winrt::fire_and_forget StaticNegateFuturePromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 51, + "staticVoidPromise", + " REACT_METHOD(staticVoidPromise) void staticVoidPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(staticVoidPromise) winrt::fire_and_forget staticVoidPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(staticVoidPromise) static void staticVoidPromise(int, ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(staticVoidPromise) static winrt::fire_and_forget staticVoidPromise(int, ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 52, + "StaticResolveSayHelloPromise", + " REACT_METHOD(StaticResolveSayHelloPromise) void StaticResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticResolveSayHelloPromise) winrt::fire_and_forget StaticResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticResolveSayHelloPromise) static void StaticResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticResolveSayHelloPromise) static winrt::fire_and_forget StaticResolveSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_METHOD_SPEC_ERRORS( + 53, + "StaticRejectSayHelloPromise", + " REACT_METHOD(StaticRejectSayHelloPromise) void StaticRejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticRejectSayHelloPromise) winrt::fire_and_forget StaticRejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticRejectSayHelloPromise) static void StaticRejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticRejectSayHelloPromise) static winrt::fire_and_forget StaticRejectSayHelloPromise(ReactPromise) noexcept {/*implementation*/}\n"); + REACT_SHOW_SYNC_METHOD_SPEC_ERRORS( + 54, + "AddSync", + " REACT_METHOD(AddSync) int AddSync(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(AddSync) static int AddSync(int, int) noexcept {/*implementation*/}\n"); + REACT_SHOW_SYNC_METHOD_SPEC_ERRORS( + 55, + "NegateSync", + " REACT_METHOD(NegateSync) int NegateSync(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(NegateSync) static int NegateSync(int) noexcept {/*implementation*/}\n"); + REACT_SHOW_SYNC_METHOD_SPEC_ERRORS( + 56, + "SayHelloSync", + " REACT_METHOD(SayHelloSync) std::string SayHelloSync() noexcept {/*implementation*/}\n" + " REACT_METHOD(SayHelloSync) static std::string SayHelloSync() noexcept {/*implementation*/}\n"); + REACT_SHOW_SYNC_METHOD_SPEC_ERRORS( + 57, + "StaticAddSync", + " REACT_METHOD(StaticAddSync) int StaticAddSync(int, int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticAddSync) static int StaticAddSync(int, int) noexcept {/*implementation*/}\n"); + REACT_SHOW_SYNC_METHOD_SPEC_ERRORS( + 58, + "StaticNegateSync", + " REACT_METHOD(StaticNegateSync) int StaticNegateSync(int) noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticNegateSync) static int StaticNegateSync(int) noexcept {/*implementation*/}\n"); + REACT_SHOW_SYNC_METHOD_SPEC_ERRORS( + 59, + "StaticSayHelloSync", + " REACT_METHOD(StaticSayHelloSync) std::string StaticSayHelloSync() noexcept {/*implementation*/}\n" + " REACT_METHOD(StaticSayHelloSync) static std::string StaticSayHelloSync() noexcept {/*implementation*/}\n"); + } +}; + +TEST_CLASS (TurboModuleTest) { + winrt::Microsoft::ReactNative::ReactModuleBuilderMock m_builderMock{}; + winrt::Microsoft::ReactNative::IReactModuleBuilder m_moduleBuilder; + Windows::Foundation::IInspectable m_moduleObject{nullptr}; + MyTurboModule *m_module; + + TurboModuleTest() { + m_moduleBuilder = winrt::make(m_builderMock); + auto provider = winrt::Microsoft::ReactNative::MakeTurboModuleProvider(); + m_moduleObject = m_builderMock.CreateModule(provider, m_moduleBuilder); + auto reactModule = m_moduleObject.as(); + m_module = &winrt::Microsoft::ReactNative::BoxedValue::GetImpl(reactModule); + } + + TEST_METHOD(TestMethodCall_Add) { + m_builderMock.Call1(L"Add", std::function([](int result) noexcept { TestCheckEqual(8, result); }), 3, 5); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_Negate) { + m_builderMock.Call1(L"Negate", std::function([](int result) noexcept { TestCheck(result == -3); }), 3); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_SayHello) { + m_builderMock.Call1(L"SayHello", std::function([](const std::string &result) noexcept { + TestCheck(result == "Hello"); + })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticAdd) { + m_builderMock.Call1( + L"StaticAdd", std::function([](int result) noexcept { TestCheck(result == 25); }), 20, 5); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegate) { + m_builderMock.Call1( + L"StaticNegate", std::function([](int result) noexcept { TestCheck(result == -7); }), 7); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticSayHello) { + m_builderMock.Call1(L"StaticSayHello", std::function([ + ](const std::string &result) noexcept { TestCheck(result == "Hello"); })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_SayHello0) { + m_builderMock.Call0(L"SayHello0"); + TestCheck(m_module->Message == "Hello_0"); + } + + TEST_METHOD(TestMethodCall_PrintPoint) { + m_builderMock.Call0(L"PrintPoint", Point{/*X =*/3, /*Y =*/5}); + TestCheck(m_module->Message == "Point: (3, 5)"); + } + + TEST_METHOD(TestMethodCall_PrintLine) { + m_builderMock.Call0(L"PrintLine", Point{/*X =*/3, /*Y =*/5}, Point{/*X =*/6, /*Y =*/8}); + TestCheck(m_module->Message == "Line: (3, 5)-(6, 8)"); + } + + TEST_METHOD(TestMethodCall_StaticSayHello0) { + m_builderMock.Call0(L"StaticSayHello0"); + TestCheck(MyTurboModule::StaticMessage == "Hello_0"); + } + + TEST_METHOD(TestMethodCall_StaticPrintPoint) { + m_builderMock.Call0(L"StaticPrintPoint", Point{/*X =*/13, /*Y =*/15}); + TestCheck(MyTurboModule::StaticMessage == "Static Point: (13, 15)"); + } + + TEST_METHOD(TestMethodCall_StaticPrintLine) { + m_builderMock.Call0(L"StaticPrintLine", Point{/*X =*/13, /*Y =*/15}, Point{/*X =*/16, /*Y =*/18}); + TestCheck(MyTurboModule::StaticMessage == "Static Line: (13, 15)-(16, 18)"); + } + + TEST_METHOD(TestMethodCall_AddCallback) { + m_builderMock.Call1( + L"AddCallback", std::function([](int result) noexcept { TestCheck(result == -1); }), 7, -8); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateCallback) { + m_builderMock.Call1( + L"NegateCallback", std::function([](int result) noexcept { TestCheck(result == -4); }), 4); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateAsyncCallback) { + Mso::FutureWait(m_builderMock.Call1( + L"NegateAsyncCallback", std::function([](int result) noexcept { TestCheck(result == -4); }), 4)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateDispatchQueueCallback) { + Mso::FutureWait(m_builderMock.Call1( + L"NegateDispatchQueueCallback", + std::function([](int result) noexcept { TestCheck(result == -4); }), + 4)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateFutureCallback) { + Mso::FutureWait(m_builderMock.Call1( + L"NegateFutureCallback", std::function([](int result) noexcept { TestCheck(result == -4); }), 4)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_SayHelloCallback) { + m_builderMock.Call1(L"SayHelloCallback", std::function([ + ](const std::string &result) noexcept { TestCheck(result == "Hello_2"); })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticAddCallback) { + m_builderMock.Call1( + L"StaticAddCallback", std::function([](int result) noexcept { TestCheck(result == 60); }), 4, 56); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateCallback) { + m_builderMock.Call1( + L"StaticNegateCallback", std::function([](int result) noexcept { TestCheck(result == -33); }), 33); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateAsyncCallback) { + Mso::FutureWait(m_builderMock.Call1( + L"StaticNegateAsyncCallback", + std::function([](int result) noexcept { TestCheck(result == -4); }), + 4)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateDispatchQueueCallback) { + Mso::FutureWait(m_builderMock.Call1( + L"StaticNegateDispatchQueueCallback", + std::function([](int result) noexcept { TestCheck(result == -4); }), + 4)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateFutureCallback) { + Mso::FutureWait(m_builderMock.Call1( + L"StaticNegateFutureCallback", + std::function([](int result) noexcept { TestCheck(result == -4); }), + 4)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticSayHelloCallback) { + m_builderMock.Call1(L"StaticSayHelloCallback", std::function([ + ](const std::string &result) noexcept { TestCheck(result == "Static Hello_2"); })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_DivideCallbacks) { + m_builderMock.Call2( + L"DivideCallbacks", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Division by 0"); }), + 6, + 2); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_DivideCallbacksError) { + m_builderMock.Call2( + L"DivideCallbacks", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Division by 0"); }), + 6, + 0); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateCallbacks) { + m_builderMock.Call2( + L"NegateCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateCallbacksError) { + m_builderMock.Call2( + L"NegateCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateAsyncCallbacks) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateAsyncCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateAsyncCallbacksError) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateAsyncCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateDispatchQueueCallbacks) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateDispatchQueueCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateDispatchQueueCallbacksError) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateDispatchQueueCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateFutureCallbacks) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateFutureCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateFutureCallbacksError) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateFutureCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_ResolveSayHelloCallbacks) { + m_builderMock.Call2( + L"ResolveSayHelloCallbacks", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_3"); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Goodbye"); })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_RejectSayHelloCallbacks) { + m_builderMock.Call2( + L"RejectSayHelloCallbacks", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_3"); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Goodbye"); })); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticDivideCallbacks) { + m_builderMock.Call2( + L"StaticDivideCallbacks", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Division by 0"); }), + 6, + 2); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticDivideCallbacksError) { + m_builderMock.Call2( + L"StaticDivideCallbacks", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Division by 0"); }), + 6, + 0); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateCallbacks) { + m_builderMock.Call2( + L"StaticNegateCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateCallbacksError) { + m_builderMock.Call2( + L"StaticNegateCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateAsyncCallbacks) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateAsyncCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateAsyncCallbacksError) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateAsyncCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateDispatchQueueCallbacks) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateDispatchQueueCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateDispatchQueueCallbacksError) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateDispatchQueueCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateFutureCallbacks) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateFutureCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateFutureCallbacksError) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateFutureCallbacks", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticResolveSayHelloCallbacks) { + m_builderMock.Call2( + L"StaticResolveSayHelloCallbacks", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_3"); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Goodbye"); })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticRejectSayHelloCallbacks) { + m_builderMock.Call2( + L"StaticRejectSayHelloCallbacks", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_3"); }), + std::function( + [](std::string const &error) noexcept { TestCheck(error == "Goodbye"); })); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_DividePromise) { + m_builderMock.Call2( + L"DividePromise", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + 6, + 2); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_DividePromiseError) { + m_builderMock.Call2( + L"DividePromise", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + 6, + 0); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegatePromise) { + m_builderMock.Call2( + L"NegatePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegatePromiseError) { + m_builderMock.Call2( + L"NegatePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateAsyncPromise) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateAsyncPromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateAsyncPromiseError) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateAsyncPromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateDispatchQueuePromise) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateDispatchQueuePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateDispatchQueuePromiseError) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateDispatchQueuePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateFuturePromise) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateFuturePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_NegateFuturePromiseError) { + Mso::FutureWait(m_builderMock.Call2( + L"NegateFuturePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_VoidPromise) { + m_builderMock.Call2( + L"voidPromise", + std::function([]() noexcept {}), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + 2); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_VoidError) { + m_builderMock.Call2( + L"voidPromise", + std::function([]() noexcept {}), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + 3); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_ResolveSayHelloPromise) { + m_builderMock.Call2( + L"ResolveSayHelloPromise", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_RejectSayHelloPromise) { + m_builderMock.Call2( + L"RejectSayHelloPromise", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticDividePromise) { + m_builderMock.Call2( + L"StaticDividePromise", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + 6, + 2); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticDividePromiseError) { + m_builderMock.Call2( + L"StaticDividePromise", + std::function([](int result) noexcept { TestCheck(result == 3); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Division by 0"); }), + 6, + 0); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegatePromise) { + m_builderMock.Call2( + L"StaticNegatePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegatePromiseError) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateAsyncPromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateAsyncPromise) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateAsyncPromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateAsyncPromiseError) { + m_builderMock.Call2( + L"StaticNegatePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateDispatchQueuePromise) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateDispatchQueuePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateDispatchQueuePromiseError) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateDispatchQueuePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateFuturePromise) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateFuturePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + 5)); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticNegateFuturePromiseError) { + Mso::FutureWait(m_builderMock.Call2( + L"StaticNegateFuturePromise", + std::function([](int result) noexcept { TestCheck(result == -5); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Already negative"); }), + -5)); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticVoidPromise) { + m_builderMock.Call2( + L"staticVoidPromise", + std::function([]() noexcept {}), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + 2); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticVoidPromiseError) { + m_builderMock.Call2( + L"staticVoidPromise", + std::function([]() noexcept {}), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Odd unexpected"); }), + 3); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticResolveSayHelloPromise) { + m_builderMock.Call2( + L"StaticResolveSayHelloPromise", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + TestCheck(m_builderMock.IsResolveCallbackCalled()); + } + + TEST_METHOD(TestMethodCall_StaticRejectSayHelloPromise) { + m_builderMock.Call2( + L"StaticRejectSayHelloPromise", + std::function( + [](const std::string &result) noexcept { TestCheck(result == "Hello_4"); }), + std::function( + [](React::JSValue const &error) noexcept { TestCheck(error["message"] == "Promise rejected"); })); + TestCheck(m_builderMock.IsRejectCallbackCalled()); + } + + TEST_METHOD(TestMethodSyncCall_AddSync) { + int result; + m_builderMock.CallSync(L"AddSync", /*out*/ result, 3, 5); + TestCheck(result == 8); + } + + TEST_METHOD(TestMethodSyncCall_NegateSync) { + int result; + m_builderMock.CallSync(L"NegateSync", /*out*/ result, 7); + TestCheck(result == -7); + } + + TEST_METHOD(TestMethodSyncCall_SayHelloSync) { + std::string result; + m_builderMock.CallSync(L"SayHelloSync", /*out*/ result); + TestCheck(result == "Hello"); + } + + TEST_METHOD(TestMethodSyncCall_StaticAddSync) { + int result; + m_builderMock.CallSync(L"StaticAddSync", /*out*/ result, 3, 5); + TestCheck(result == 8); + } + + TEST_METHOD(TestMethodSyncCall_StaticNegateSync) { + int result; + m_builderMock.CallSync(L"StaticNegateSync", /*out*/ result, 7); + TestCheck(result == -7); + } + + TEST_METHOD(TestMethodSyncCall_StaticSayHelloSync) { + std::string result; + m_builderMock.CallSync(L"StaticSayHelloSync", /*out*/ result); + TestCheck(result == "Hello"); + } + + TEST_METHOD(TestConstants) { + auto constants = m_builderMock.GetConstants(); + TestCheck(constants["Constant1"] == "MyConstant1"); + TestCheck(constants["const2"] == "MyConstant2"); + TestCheck(constants["const3"]["X"] == 2); + TestCheck(constants["const3"]["Y"] == 3); + TestCheck(constants["Constant4"]["X"] == 3); + TestCheck(constants["Constant4"]["Y"] == 4); + TestCheck(constants["const51"]["X"] == 12); + TestCheck(constants["const51"]["Y"] == 14); + TestCheck(constants["const52"] == "MyConstant52"); + TestCheck(constants["const61"]["X"] == 15); + TestCheck(constants["const61"]["Y"] == 17); + TestCheck(constants["const62"] == "MyConstant62"); + } + + TEST_METHOD(TestEvent_IntEventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"RCTDeviceEventEmitter", L"OnIntEvent", [&eventRaised](React::JSValueArray const &args) noexcept { + TestCheck(args[0] == 42); + eventRaised = true; + }); + + m_module->OnIntEvent(42); + TestCheck(eventRaised); + } + + TEST_METHOD(TestEvent_OnNoArgEventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"RCTDeviceEventEmitter", L"OnNoArgEvent", [&eventRaised](React::JSValueArray const &args) noexcept { + TestCheckEqual(0, args.size()); + eventRaised = true; + }); + + m_module->OnNoArgEvent(); + TestCheck(eventRaised); + } + + TEST_METHOD(TestEvent_TwoArgsEventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"RCTDeviceEventEmitter", L"OnTwoArgsEvent", [&eventRaised](React::JSValueArray const &args) noexcept { + TestCheckEqual(4, args[0]["X"]); + TestCheckEqual(2, args[0]["Y"]); + TestCheckEqual(12, args[1]["X"]); + TestCheckEqual(18, args[1]["Y"]); + eventRaised = true; + }); + + m_module->OnTwoArgsEvent(Point{/*X =*/4, /*Y =*/2}, Point{/*X =*/12, /*Y =*/18}); + TestCheck(eventRaised); + } + + TEST_METHOD(TestEvent_JSNameEventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"RCTDeviceEventEmitter", L"onPointEvent", [&eventRaised](React::JSValueArray const &args) noexcept { + TestCheck(args[0]["X"] == 4); + TestCheck(args[0]["Y"] == 2); + eventRaised = true; + }); + + m_module->OnPointEvent(Point{/*X =*/4, /*Y =*/2}); + TestCheck(eventRaised == true); + } + + TEST_METHOD(TestEvent_JSEventEmitterEventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"MyEventEmitter", L"onStringEvent", [&eventRaised](React::JSValueArray const &args) noexcept { + TestCheckEqual("Hello World!", args[0]); + eventRaised = true; + }); + + m_module->OnStringEvent("Hello World!"); + TestCheck(eventRaised == true); + } + + TEST_METHOD(TestEvent_JSValueObjectEventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](React::JSValueArray const &args) noexcept { + TestCheck(args[0]["X"] == 4); + TestCheck(args[0]["Y"] == 2); + eventRaised = true; + })); + + m_module->OnJSValueEvent(React::JSValueObject{{"X", 4}, {"Y", 2}}); + TestCheck(eventRaised == true); + } + + TEST_METHOD(TestEvent_JSValueArrayEventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](React::JSValueArray const &args) noexcept { + TestCheck(args[0][0] == "X"); + TestCheck(args[0][1] == 4); + TestCheck(args[0][2] == true); + TestCheck(args[0][3]["Id"] == 42); + eventRaised = true; + })); + + m_module->OnJSValueEvent(React::JSValueArray{"X", 4, true, React::JSValueObject{{"Id", 42}}}); + TestCheck(eventRaised == true); + } + + TEST_METHOD(TestEvent_JSValueArray1EventField) { + bool eventRaised = false; + m_builderMock.ExpectEvent( + L"RCTDeviceEventEmitter", L"OnJSValueEvent", ([&eventRaised](React::JSValueArray const &args) noexcept { + TestCheck(args[0][0] == 4); + eventRaised = true; + })); + + m_module->OnJSValueEvent(React::JSValueArray{4}); + TestCheck(eventRaised == true); + } + + TEST_METHOD(TestFunction_JSIntFunctionField) { + bool functionCalled = false; + m_builderMock.ExpectFunction( + L"MyTurboModule", L"JSIntFunction", [&functionCalled](React::JSValueArray const &args) noexcept { + TestCheck(args[0] == 42); + functionCalled = true; + }); + + m_module->JSIntFunction(42); + TestCheck(functionCalled); + } + + TEST_METHOD(TestFunction_JSNameFunctionField) { + bool functionCalled = false; + m_builderMock.ExpectFunction( + L"MyTurboModule", L"pointFunc", [&functionCalled](React::JSValueArray const &args) noexcept { + TestCheck(args[0]["X"] == 4); + TestCheck(args[0]["Y"] == 2); + functionCalled = true; + }); + + m_module->JSPointFunction(Point{/*X =*/4, /*Y =*/2}); + TestCheck(functionCalled == true); + } + + TEST_METHOD(TestFunction_TwoArgFunctionField) { + bool functionCalled = false; + m_builderMock.ExpectFunction( + L"MyTurboModule", L"lineFunc", [&functionCalled](React::JSValueArray const &args) noexcept { + TestCheck(args[0]["X"] == 4); + TestCheck(args[0]["Y"] == 2); + TestCheck(args[1]["X"] == 12); + TestCheck(args[1]["Y"] == 18); + functionCalled = true; + }); + + m_module->JSLineFunction(Point{/*X =*/4, /*Y =*/2}, Point{/*X =*/12, /*Y =*/18}); + TestCheck(functionCalled == true); + } + + TEST_METHOD(TestFunction_NoArgFunctionField) { + bool functionCalled = false; + m_builderMock.ExpectFunction( + L"MyTurboModule", L"JSNoArgFunction", [&functionCalled](React::JSValueArray const &args) noexcept { + TestCheckEqual(0, args.size()); + functionCalled = true; + }); + + m_module->JSNoArgFunction(); + TestCheck(functionCalled); + } + + TEST_METHOD(TestFunction_JSModuleNameFunctionField) { + bool functionCalled = false; + m_builderMock.ExpectFunction( + L"MyModule", L"stringFunc", [&functionCalled](React::JSValueArray const &args) noexcept { + TestCheck(args[0] == "Hello World!"); + functionCalled = true; + }); + + m_module->JSStringFunction("Hello World!"); + TestCheck(functionCalled == true); + } + + TEST_METHOD(TestFunction_JSValueObjectFunctionField) { + bool functionCalled = false; + m_builderMock.ExpectFunction( + L"MyTurboModule", L"JSValueFunction", ([&functionCalled](React::JSValueArray const &args) noexcept { + TestCheck(args[0]["X"] == 4); + TestCheck(args[0]["Y"] == 2); + functionCalled = true; + })); + + m_module->JSValueFunction(React::JSValueObject{{"X", 4}, {"Y", 2}}); + TestCheck(functionCalled == true); + } + + TEST_METHOD(TestFunction_JSValueArrayFunctionField) { + bool functionCalled = false; + m_builderMock.ExpectFunction( + L"MyTurboModule", L"JSValueFunction", ([&functionCalled](React::JSValueArray const &args) noexcept { + TestCheck(args[0][0] == "X"); + TestCheck(args[0][1] == 4); + TestCheck(args[0][2] == true); + TestCheck(args[0][3]["Id"] == 42); + functionCalled = true; + })); + + m_module->JSValueFunction(React::JSValueArray{"X", 4, true, React::JSValueObject{{"Id", 42}}}); + TestCheck(functionCalled == true); + } + + TEST_METHOD(TestInitialized) { + TestCheck(m_module->IsInitialized); + } +}; + +} // namespace ReactNativeTests diff --git a/vnext/Microsoft.ReactNative.Cxx/ModuleRegistration.h b/vnext/Microsoft.ReactNative.Cxx/ModuleRegistration.h index 03916ce88e4..9f8979006d0 100644 --- a/vnext/Microsoft.ReactNative.Cxx/ModuleRegistration.h +++ b/vnext/Microsoft.ReactNative.Cxx/ModuleRegistration.h @@ -34,13 +34,13 @@ template struct moduleStruct##_ModuleRegistration; \ \ template \ - constexpr void RegisterModule(TRegistry ®istry) noexcept { \ + constexpr void GetReactModuleInfo(moduleStruct *, TRegistry ®istry) noexcept { \ registry.RegisterModule( \ - moduleName, eventEmitterName, winrt::Microsoft::ReactNative::ReactMemberId<__COUNTER__>{}); \ + moduleName, eventEmitterName, winrt::Microsoft::ReactNative::ReactAttributeId<__COUNTER__>{}); \ } #define INTERNAL_REACT_MODULE_2_ARGS(moduleStruct, moduleName) \ - INTERNAL_REACT_MODULE_3_ARGS(moduleStruct, moduleName, nullptr) + INTERNAL_REACT_MODULE_3_ARGS(moduleStruct, moduleName, L"") #define INTERNAL_REACT_MODULE_1_ARG(moduleStruct) INTERNAL_REACT_MODULE_2_ARGS(moduleStruct, L## #moduleStruct) @@ -48,21 +48,24 @@ INTERNAL_REACT_RECOMPOSER_4( \ (__VA_ARGS__, INTERNAL_REACT_MODULE_3_ARGS, INTERNAL_REACT_MODULE_2_ARGS, INTERNAL_REACT_MODULE_1_ARG, )) -// Register struct member. -// For each registered member we create a static method that registers it. +// Provide meta data information about struct member. +// For each member with a 'custom attribute' macro we create a static method to provide meta data. // The member Id is generated as a ReactMemberId<__COUNTER__> type. -// To invoke the static registration methods, we increment ReactMemberId while static member exists. -#define INTERNAL_REACT_MEMBER_4_ARGS(memberType, member, memberName, moduleName) \ - template \ - constexpr static void RegisterMember( \ - TRegistry ®istry, winrt::Microsoft::ReactNative::ReactMemberId<__COUNTER__>) noexcept { \ - registry.Register##memberType(&TClass::member, memberName, moduleName); \ +// To enumerate the static methods, we can increment ReactMemberId while static member exists. +#define INTERNAL_REACT_MEMBER_4_ARGS(memberKind, member, jsMemberName, jsModuleName) \ + template \ + constexpr static void GetReactMemberAttribute( \ + TVisitor &visitor, winrt::Microsoft::ReactNative::ReactAttributeId<__COUNTER__> attributeId) noexcept { \ + visitor.Visit( \ + &TStruct::member, \ + attributeId, \ + winrt::Microsoft::ReactNative::React##memberKind##Attribute{jsMemberName, jsModuleName}); \ } -#define INTERNAL_REACT_MEMBER_3_ARGS(memberType, member, memberName) \ - INTERNAL_REACT_MEMBER_4_ARGS(memberType, member, memberName, nullptr) +#define INTERNAL_REACT_MEMBER_3_ARGS(memberKind, member, jsMemberName) \ + INTERNAL_REACT_MEMBER_4_ARGS(memberKind, member, jsMemberName, L"") -#define INTERNAL_REACT_MEMBER_2_ARGS(memberType, member) INTERNAL_REACT_MEMBER_3_ARGS(memberType, member, L## #member) +#define INTERNAL_REACT_MEMBER_2_ARGS(memberKind, member) INTERNAL_REACT_MEMBER_3_ARGS(memberKind, member, L## #member) #define INTERNAL_REACT_MEMBER(...) \ INTERNAL_REACT_RECOMPOSER_4( \ diff --git a/vnext/Microsoft.ReactNative.Cxx/NativeModules.h b/vnext/Microsoft.ReactNative.Cxx/NativeModules.h index 305709f3aa6..a7070651b62 100644 --- a/vnext/Microsoft.ReactNative.Cxx/NativeModules.h +++ b/vnext/Microsoft.ReactNative.Cxx/NativeModules.h @@ -9,6 +9,7 @@ #include "ModuleRegistration.h" #include "ReactPromise.h" +#include #include // REACT_MODULE(moduleStruct, [opt] moduleName, [opt] eventEmitterName) @@ -47,7 +48,7 @@ // - Return non-void value. In JavaScript it is treated as a method with one Callback. Return std::pair to // be able to communicate error condition. // It can be an instance or static method. -#define REACT_METHOD(/* method, [opt] methodName */...) INTERNAL_REACT_MEMBER(__VA_ARGS__)(Method, __VA_ARGS__) +#define REACT_METHOD(/* method, [opt] methodName */...) INTERNAL_REACT_MEMBER(__VA_ARGS__)(AsyncMethod, __VA_ARGS__) // REACT_SYNC_METHOD(method, [opt] methodName) // Arguments: @@ -105,39 +106,165 @@ #define REACT_FUNCTION(/* field, [opt] functionName, [opt] moduleName */...) \ INTERNAL_REACT_MEMBER(__VA_ARGS__)(FunctionField, __VA_ARGS__) +#define REACT_SHOW_METHOD_SIGNATURES(methodName, signatures) \ + " (see details below in output).\n" \ + " It must be one of the following:\n" signatures \ + " The C++ method name could be different. In that case add the L\"" methodName \ + "\" to the attribute:\n" \ + " REACT_METHOD(method, L\"" methodName "\")\n...\n" + +#define REACT_SHOW_SYNC_METHOD_SIGNATURES(methodName, signatures) \ + " (see details below in output).\n" \ + " It must be one of the following:\n" signatures \ + " The C++ method name could be different. In that case add the L\"" methodName \ + "\" to the attribute:\n" \ + " REACT_SYNC_METHOD(method, L\"" methodName "\")\n...\n" + +#define REACT_SHOW_METHOD_SPEC_ERRORS(index, methodName, signatures) \ + static_assert(methodCheckResults[index].IsUniqueName, "Name '" methodName "' used for multiple methods"); \ + static_assert( \ + methodCheckResults[index].IsMethodFound, \ + "Method '" methodName "' is not defined" REACT_SHOW_METHOD_SIGNATURES(methodName, signatures)); \ + static_assert( \ + methodCheckResults[index].IsSignatureMatching, \ + "Method '" methodName "' does not match signature" REACT_SHOW_METHOD_SIGNATURES(methodName, signatures)); + +#define REACT_SHOW_SYNC_METHOD_SPEC_ERRORS(index, methodName, signatures) \ + static_assert(methodCheckResults[index].IsUniqueName, "Name '" methodName "' used for multiple methods"); \ + static_assert( \ + methodCheckResults[index].IsMethodFound, \ + "Method '" methodName "' is not defined" REACT_SHOW_SYNC_METHOD_SIGNATURES(methodName, signatures)); \ + static_assert( \ + methodCheckResults[index].IsSignatureMatching, \ + "Method '" methodName "' does not match signature" REACT_SHOW_SYNC_METHOD_SIGNATURES(methodName, signatures)); + +// +// Code below helps to register React native modules and verify method signatures +// against specification. +// + namespace winrt::Microsoft::ReactNative { -namespace Internal { +// Often used to create a tuple with arguments or to create a method signature. +template +using RemoveConstRef = std::remove_const_t>; -// Checks if provided type has a callback-like signature TFunc struct IsCallback : std::false_type {}; -template