diff --git a/.github/ISSUE_TEMPLATE/react-native-windows--vnext--bug-report.md b/.github/ISSUE_TEMPLATE/react-native-windows--vnext--bug-report.md
index 9eec9ad1661..e04f2dbda25 100644
--- a/.github/ISSUE_TEMPLATE/react-native-windows--vnext--bug-report.md
+++ b/.github/ISSUE_TEMPLATE/react-native-windows--vnext--bug-report.md
@@ -15,6 +15,7 @@ assignees: ''
If you are using latest version:
1. `react-native -v`:
2. `react-native run-windows --info`:
+3. `reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock"`
Otherwise if `--info` doesn't exist:
1. `react-native -v`:
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-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/change/react-native-windows-2020-04-16-17-40-26-removeAccessibilityStates.json b/change/react-native-windows-2020-04-22-16-22-32-direction-rtl.json
similarity index 63%
rename from change/react-native-windows-2020-04-16-17-40-26-removeAccessibilityStates.json
rename to change/react-native-windows-2020-04-22-16-22-32-direction-rtl.json
index 5339bf2015e..344797ea32a 100644
--- a/change/react-native-windows-2020-04-16-17-40-26-removeAccessibilityStates.json
+++ b/change/react-native-windows-2020-04-22-16-22-32-direction-rtl.json
@@ -1,8 +1,8 @@
{
"type": "prerelease",
- "comment": "remove AccessibilityStates",
+ "comment": "fix RTL",
"packageName": "react-native-windows",
"email": "kmelmon@microsoft.com",
"dependentChangeType": "patch",
- "date": "2020-04-17T00:40:26.842Z"
+ "date": "2020-04-22T23:22:32.344Z"
}
\ No newline at end of file
diff --git a/packages/E2ETest/package.json b/packages/E2ETest/package.json
index f4901d96b96..46062c996ec 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.46",
"rnpm-plugin-windows": "^0.6.1"
},
"devDependencies": {
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..863452d52a0 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
@@ -174,11 +174,9 @@
16.0
+
-
- echo WorkingDir %CD%
- npx --no-install yarn run bundle
-
+ dist/app/index.js
+## 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/packages/react-native-windows-codegen/.gitignore b/packages/react-native-windows-codegen/.gitignore
new file mode 100644
index 00000000000..f42efbb9f7c
--- /dev/null
+++ b/packages/react-native-windows-codegen/.gitignore
@@ -0,0 +1,2 @@
+lib/
+lib-commonjs/
diff --git a/packages/react-native-windows-codegen/CHANGELOG.json b/packages/react-native-windows-codegen/CHANGELOG.json
new file mode 100644
index 00000000000..c708783e949
--- /dev/null
+++ b/packages/react-native-windows-codegen/CHANGELOG.json
@@ -0,0 +1,20 @@
+{
+ "name": "react-native-windows-codegen",
+ "entries": [
+ {
+ "date": "Thu, 23 Apr 2020 00:04:37 GMT",
+ "tag": "react-native-windows-codegen_v0.0.2",
+ "version": "0.0.2",
+ "comments": {
+ "patch": [
+ {
+ "comment": "Initial react-native-windows-codegen",
+ "author": "acoates@microsoft.com",
+ "commit": "dcccb2c4d84ff530de5a80ac7e947c3287dff5ab",
+ "package": "react-native-windows-codegen"
+ }
+ ]
+ }
+ }
+ ]
+}
diff --git a/packages/react-native-windows-codegen/CHANGELOG.md b/packages/react-native-windows-codegen/CHANGELOG.md
new file mode 100644
index 00000000000..2ca2fe760aa
--- /dev/null
+++ b/packages/react-native-windows-codegen/CHANGELOG.md
@@ -0,0 +1,13 @@
+# Change Log - react-native-windows-codegen
+
+This log was last generated on Thu, 23 Apr 2020 00:04:37 GMT and should not be manually modified.
+
+
+
+## 0.0.2
+
+Thu, 23 Apr 2020 00:04:37 GMT
+
+### Patches
+
+- Initial react-native-windows-codegen (acoates@microsoft.com)
diff --git a/packages/react-native-windows-codegen/README.md b/packages/react-native-windows-codegen/README.md
new file mode 100644
index 00000000000..2950bcd0969
--- /dev/null
+++ b/packages/react-native-windows-codegen/README.md
@@ -0,0 +1,7 @@
+# react-native-windows-codegen
+
+Generators for react-native-codegen targeting react-native-windows
+
+## Usage
+
+Coming soon..
diff --git a/packages/react-native-windows-codegen/bin.js b/packages/react-native-windows-codegen/bin.js
new file mode 100644
index 00000000000..24e308197b6
--- /dev/null
+++ b/packages/react-native-windows-codegen/bin.js
@@ -0,0 +1,12 @@
+#!/usr/bin/env node
+
+/**
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * @format
+ */
+
+// Yarn will fail to link workspace binaries if they haven't been built yet. Add
+// a simple JS file to forward to the CLI which is built after install.
+require('./lib-commonjs/Cli');
diff --git a/packages/react-native-windows-codegen/just-task.js b/packages/react-native-windows-codegen/just-task.js
new file mode 100644
index 00000000000..f5fac08c7f8
--- /dev/null
+++ b/packages/react-native-windows-codegen/just-task.js
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * @format
+ * @ts-check
+ */
+
+const {eslintTask, series, task, taskPresets} = require('just-scripts');
+
+taskPresets.lib();
+
+task('eslint', () => {
+ return eslintTask();
+});
+task('eslint:fix', () => {
+ return eslintTask({fix: true});
+});
+task('lint', series('eslint'));
+task('lint:fix', series('eslint:fix'));
diff --git a/packages/react-native-windows-codegen/package.json b/packages/react-native-windows-codegen/package.json
new file mode 100644
index 00000000000..bc8ee786b23
--- /dev/null
+++ b/packages/react-native-windows-codegen/package.json
@@ -0,0 +1,29 @@
+{
+ "name": "react-native-windows-codegen",
+ "version": "0.0.2",
+ "description": "Generators for react-native-codegen targeting react-native-windows",
+ "main": "index.js",
+ "repository": "https://github.com/microsoft/react-native-windows",
+ "license": "MIT",
+ "private": false,
+ "scripts": {
+ "build": "just-scripts build",
+ "clean": "just-scripts clean",
+ "lint": "just-scripts lint",
+ "lint:fix": "just-scripts lint:fix"
+ },
+ "bin": {
+ "react-native-windows-codegen": "./bin.js"
+ },
+ "dependencies": {
+ "chalk": "^3",
+ "react-native-tscodegen": "0.0.10",
+ "react-native-codegen": "0.0.2",
+ "yargs": "^15.1.0"
+ },
+ "devDependencies": {
+ "@types/chalk": "^2.2.0",
+ "@types/yargs": "^15.0.3",
+ "just-scripts": "^0.36.1"
+ }
+}
diff --git a/packages/react-native-windows-codegen/src/Cli.ts b/packages/react-native-windows-codegen/src/Cli.ts
new file mode 100644
index 00000000000..d8ea11a57dd
--- /dev/null
+++ b/packages/react-native-windows-codegen/src/Cli.ts
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ *
+ * @format
+ */
+
+import * as yargs from 'yargs';
+import * as path from 'path';
+import * as fs from 'fs';
+import {createNM2Generator} from './generators/GenerateNM2';
+// @ts-ignore
+import {parseFile} from 'react-native-tscodegen/lib/rncodegen/src/parsers/flow';
+// @ts-ignore
+import * as schemaValidator from 'react-native-tscodegen/lib/rncodegen/src/schemaValidator';
+
+const argv = yargs.options({
+ file: {
+ type: 'string',
+ describe: 'file which contains spec',
+ },
+ test: {
+ type: 'boolean',
+ describe: 'Verify that the generated output is unchanged',
+ },
+ namespace: {
+ type: 'string',
+ describe: 'C++/C# Namespace to put generated native modules in',
+ default: 'MyNamespace',
+ },
+}).argv;
+
+import {SchemaType} from 'react-native-tscodegen';
+
+interface Options {
+ libraryName: string;
+ schema: SchemaType;
+ outputDirectory: string;
+ moduleSpecName: string;
+}
+
+interface Config {
+ generators: any[] /*Generators[]*/;
+ test?: boolean;
+}
+
+/*
+const GENERATORS = {
+ descriptors: [generateComponentDescriptorH.generate],
+ events: [
+ generateEventEmitterCpp.generate,
+ generateEventEmitterH.generate,
+ generateModuleHObjCpp.generate,
+ generateModuleMm.generate,
+ ],
+ props: [
+ generateComponentHObjCpp.generate,
+ generatePropsCpp.generate,
+ generatePropsH.generate,
+ generatePropsJavaInterface.generate,
+ generatePropsJavaDelegate.generate,
+ ],
+ modules: [generateModuleCpp.generate, generateModuleH.generate],
+ tests: [generateTests.generate],
+ 'shadow-nodes': [
+ generateShadowNodeCpp.generate,
+ generateShadowNodeH.generate,
+ ],
+};
+*/
+
+function checkFilesForChanges(
+ map: Map,
+ outputDir: string,
+): boolean {
+ map.forEach((contents: string, fileName: string) => {
+ const location = path.join(outputDir, fileName);
+ if (!fs.existsSync(location)) {
+ return true;
+ }
+
+ const currentContents = fs.readFileSync(location, 'utf8');
+ if (currentContents !== contents) {
+ console.error(`- ${fileName} has changed`);
+ return true;
+ }
+ });
+
+ return false;
+}
+
+function writeMapToFiles(map: Map, outputDir: string) {
+ let success = true;
+ map.forEach((contents: string, fileName: string) => {
+ try {
+ const location = path.join(outputDir, fileName);
+ fs.writeFileSync(location, contents);
+ } catch (error) {
+ success = false;
+ console.error(`Failed to write ${fileName} to ${outputDir}`, error);
+ }
+ });
+
+ return success;
+}
+
+function generate(
+ {libraryName, schema, outputDirectory, moduleSpecName}: Options,
+ {/*generators,*/ test}: Config,
+): boolean {
+ schemaValidator.validate(schema);
+
+ const generatedFiles = [];
+ /*
+ for (const name of generators) {
+ for (const generator of GENERATORS[name]) {
+ generatedFiles.push(...generator(libraryName, schema, moduleSpecName));
+ }
+ }
+*/
+
+ const generateNM2 = createNM2Generator({namespace: argv.namespace});
+
+ generatedFiles.push(...generateNM2(libraryName, schema, moduleSpecName));
+
+ const filesToUpdate = new Map([...generatedFiles]);
+
+ if (test === true) {
+ return checkFilesForChanges(filesToUpdate, outputDirectory);
+ }
+
+ return writeMapToFiles(filesToUpdate, outputDirectory);
+}
+
+const schema: SchemaType = parseFile(argv.file);
+const libraryName = 'libraryName';
+const moduleSpecName = 'moduleSpecName';
+const outputDirectory = 'codegen';
+generate(
+ {libraryName, schema, outputDirectory, moduleSpecName},
+ {generators: [], test: false},
+);
diff --git a/packages/react-native-windows-codegen/src/generators/GenerateNM2.ts b/packages/react-native-windows-codegen/src/generators/GenerateNM2.ts
new file mode 100644
index 00000000000..190e09c6821
--- /dev/null
+++ b/packages/react-native-windows-codegen/src/generators/GenerateNM2.ts
@@ -0,0 +1,305 @@
+/**
+ * Copyright (c) Microsoft Corporation.
+ * Licensed under the MIT License.
+ * @format
+ */
+
+'use strict';
+
+import {
+ SchemaType,
+ MethodTypeShape,
+ // FunctionTypeAnnotation,
+ FunctionTypeAnnotationParam,
+ FunctionTypeAnnotationParamTypeAnnotation,
+ FunctionTypeAnnotationReturn,
+} from 'react-native-tscodegen';
+
+type FilesOutput = Map;
+
+const moduleTemplate = `
+/*
+ * This is a C++ Spec class that should be used with MakeTurboModuleProvider to register native modules
+ * in a way that also verifies at compile time that the native module matches the interface required
+ * by the TurboModule JS spec.
+ */
+struct ::_MODULE_NAME_::Spec : winrt::Microsoft::ReactNative::TurboModuleSpec {
+ static constexpr auto methods = std::tuple{
+::_MODULE_PROPERTIES_TUPLE_::
+ };
+
+ template
+ static constexpr void ValidateModule() noexcept {
+ constexpr auto methodCheckResults = CheckMethods();
+
+::_MODULE_PROPERTIES_SPEC_ERRORS_::
+ }
+};`;
+
+const template = `
+/**
+ * This file is auto-generated from a NativeModule spec file in js.
+ */
+
+#pragma once
+
+#include "NativeModules.h"
+#include
+
+namespace ::_NAMESPACE_:: {
+::_MODULES_::
+
+} // namespace ::_NAMESPACE_::
+`;
+
+function translateSpecFunctionParam(
+ param: FunctionTypeAnnotationParam,
+): string {
+ switch (param.typeAnnotation.type) {
+ case 'StringTypeAnnotation':
+ return 'std::string';
+ case 'NumberTypeAnnotation':
+ case 'FloatTypeAnnotation':
+ return 'double';
+ case 'Int32TypeAnnotation':
+ return 'int';
+ case 'BooleanTypeAnnotation':
+ return 'bool';
+ case 'FunctionTypeAnnotation': {
+ // Ideally we'd get more information about the expected parameters of the callback
+ // But the current schema doesn't seem to provide the necessary information.
+ return 'Callback';
+ }
+ case 'ArrayTypeAnnotation':
+ // Ideally we'd get more information about the expected type of the array
+ // But the current schema doesn't seem to provide the necessary information.
+ return 'JSValueArray';
+ case 'GenericObjectTypeAnnotation':
+ return 'JSValueObject';
+ default:
+ throw new Error(`Unhandled type: ${param.typeAnnotation.type}`);
+ }
+}
+
+function translateFunctionParam(param: FunctionTypeAnnotationParam): string {
+ switch (param.typeAnnotation.type) {
+ case 'StringTypeAnnotation':
+ return 'std::string';
+ case 'NumberTypeAnnotation':
+ case 'FloatTypeAnnotation':
+ return 'double';
+ case 'Int32TypeAnnotation':
+ return 'int';
+ case 'BooleanTypeAnnotation':
+ return 'bool';
+ case 'FunctionTypeAnnotation': {
+ // Ideally we'd get more information about the expected parameters of the callback
+ // But the current schema doesn't seem to provide the necessary information.
+ return 'std::function const &';
+ }
+ case 'ArrayTypeAnnotation':
+ // Ideally we'd get more information about the expected type of the array
+ // But the current schema doesn't seem to provide the necessary information.
+ return 'React::JSValueArray &&';
+ case 'GenericObjectTypeAnnotation':
+ return 'React::JSValueObject &&';
+ default:
+ throw new Error(`Unhandled type: ${param.typeAnnotation.type}`);
+ }
+}
+
+function translateSpecReturnType(
+ type:
+ | FunctionTypeAnnotationParamTypeAnnotation
+ | FunctionTypeAnnotationReturn,
+) {
+ switch (type.type) {
+ case 'VoidTypeAnnotation':
+ return 'void';
+ case 'StringTypeAnnotation':
+ return 'std::string';
+ case 'NumberTypeAnnotation':
+ case 'FloatTypeAnnotation':
+ return 'double';
+ case 'Int32TypeAnnotation':
+ return 'int';
+ case 'BooleanTypeAnnotation':
+ return 'bool';
+ case 'GenericPromiseTypeAnnotation':
+ return 'void';
+ case 'ArrayTypeAnnotation':
+ // Ideally we'd get more information about the expected type of the array
+ // But the current schema doesn't seem to provide the necessary information.
+ return 'JSValueArray';
+ case 'GenericObjectTypeAnnotation':
+ return 'JSValueObject';
+ default:
+ throw new Error(`Unhandled type: ${type.type}`);
+ }
+}
+
+function translateImplReturnType(
+ type:
+ | FunctionTypeAnnotationParamTypeAnnotation
+ | FunctionTypeAnnotationReturn,
+) {
+ switch (type.type) {
+ case 'VoidTypeAnnotation':
+ return 'void';
+ case 'StringTypeAnnotation':
+ return 'std::string';
+ case 'NumberTypeAnnotation':
+ case 'FloatTypeAnnotation':
+ return 'double';
+ case 'Int32TypeAnnotation':
+ return 'int';
+ case 'BooleanTypeAnnotation':
+ return 'bool';
+ case 'GenericPromiseTypeAnnotation':
+ return 'void';
+ case 'ArrayTypeAnnotation':
+ // Ideally we'd get more information about the expected type of the array
+ // But the current schema doesn't seem to provide the necessary information.
+ return 'React::JSValueArray';
+ case 'GenericObjectTypeAnnotation':
+ return 'React::JSValueObject';
+ default:
+ throw new Error(`Unhandled type: ${type.type}`);
+ }
+}
+
+function translateSpecArgs(params: ReadonlyArray) {
+ return params.map(param => {
+ const translatedParam = translateSpecFunctionParam(param);
+ return `${translatedParam}`;
+ });
+}
+
+function translateArgs(params: ReadonlyArray) {
+ return params.map(param => {
+ const translatedParam = translateFunctionParam(param);
+ return `${translatedParam} ${param.name}`;
+ });
+}
+
+function isMethodSync(prop: MethodTypeShape) {
+ return (
+ prop.typeAnnotation.returnTypeAnnotation.type !== 'VoidTypeAnnotation' &&
+ prop.typeAnnotation.returnTypeAnnotation.type !==
+ 'GenericPromiseTypeAnnotation'
+ );
+}
+
+function isPromise(prop: MethodTypeShape) {
+ return (
+ prop.typeAnnotation.returnTypeAnnotation.type ===
+ 'GenericPromiseTypeAnnotation'
+ );
+}
+
+function getPossibleMethodSignatures(prop: MethodTypeShape): string[] {
+ let args = translateArgs(prop.typeAnnotation.params);
+ if (isPromise(prop)) {
+ // Sadly, currently, the schema doesn't currently provide us information on the type of the promise.
+ args.push('React::ReactPromise &&result');
+ }
+
+ // TODO be much more exhastive on the possible method signatures that can be used..
+ let sig = `REACT_${isMethodSync(prop) ? 'SYNC_' : ''}METHOD(${
+ prop.name
+ }) ${translateImplReturnType(prop.typeAnnotation.returnTypeAnnotation)} ${
+ prop.name
+ }(${args.join(', ')}) noexcept { /* implementation */ }}`;
+ let staticsig = `REACT_${isMethodSync(prop) ? 'SYNC_' : ''}METHOD(${
+ prop.name
+ }) static ${translateImplReturnType(
+ prop.typeAnnotation.returnTypeAnnotation,
+ )} ${prop.name}(${args.join(', ')}) noexcept { /* implementation */ }}`;
+
+ return [sig, staticsig];
+}
+
+function translatePossibleMethodSignatures(prop: MethodTypeShape): string {
+ return getPossibleMethodSignatures(prop)
+ .map(sig => `" ${sig}"`)
+ .join(',\n ');
+}
+
+function renderProperties(
+ properties: ReadonlyArray,
+ tuple: boolean,
+): string {
+ // We skip the constants for now, since we dont have Spec file validation of them.
+ return properties
+ .filter(prop => prop.name !== 'getConstants')
+ .map((prop, index) => {
+ let params = prop.typeAnnotation.params;
+
+ const traversedArgs = translateSpecArgs(params);
+
+ const translatedReturnParam = translateSpecReturnType(
+ prop.typeAnnotation.returnTypeAnnotation,
+ );
+
+ if (isPromise(prop)) {
+ // Sadly, currently, the schema doesn't currently provide us information on the type of the promise.
+ traversedArgs.push('Promise');
+ }
+
+ if (tuple) {
+ return ` ${
+ isMethodSync(prop) ? 'Sync' : ''
+ }Method<${translatedReturnParam}(${traversedArgs.join(
+ ',',
+ )}) noexcept>{${index}, L"${prop.name}"},`;
+ } else {
+ return ` REACT_SHOW_METHOD_SPEC_ERRORS(
+ ${index},
+ "${prop.name}",
+ ${translatePossibleMethodSignatures(prop)});`;
+ }
+ })
+ .join('\n');
+}
+
+export function createNM2Generator({namespace}: {namespace: string}) {
+ return (
+ _libraryName: string,
+ schema: SchemaType,
+ _moduleSpecName: string,
+ ): FilesOutput => {
+ // console.log(JSON.stringify(schema, null, 2));
+
+ const nativeModules = Object.keys(schema.modules)
+ .map(moduleName => {
+ const modules = schema.modules[moduleName].nativeModules;
+ if (modules == null) {
+ return null;
+ }
+
+ return modules;
+ })
+ .filter(Boolean)
+ .reduce((acc, components) => Object.assign(acc, components), {});
+
+ const modules = Object.keys(nativeModules)
+ .map(name => {
+ const {properties} = nativeModules[name];
+ const traversedProperties = renderProperties(properties, false);
+ const traversedPropertyTuples = renderProperties(properties, true);
+
+ return moduleTemplate
+ .replace(/::_MODULE_PROPERTIES_TUPLE_::/g, traversedPropertyTuples)
+ .replace(/::_MODULE_PROPERTIES_SPEC_ERRORS_::/g, traversedProperties)
+ .replace(/::_MODULE_NAME_::/g, name);
+ })
+ .join('\n');
+
+ const fileName = 'NativeModules.g.h';
+ const replacedTemplate = template
+ .replace(/::_NAMESPACE_::/g, namespace)
+ .replace(/::_MODULES_::/g, modules);
+
+ return new Map([[fileName, replacedTemplate]]);
+ };
+}
diff --git a/packages/react-native-windows-codegen/tsconfig.json b/packages/react-native-windows-codegen/tsconfig.json
new file mode 100644
index 00000000000..955be039942
--- /dev/null
+++ b/packages/react-native-windows-codegen/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "compilerOptions": {
+ "baseUrl": ".",
+ "target": "es6",
+ "sourceMap": true,
+ "noImplicitAny": true,
+ "preserveConstEnums": true,
+ "moduleResolution": "node",
+ "noUnusedLocals": true,
+ "skipLibCheck": true,
+ "rootDirs": ["src"],
+ },
+ "include": ["src"],
+ "exclude": ["node_modules"]
+}
diff --git a/packages/react-native-windows-init/CHANGELOG.json b/packages/react-native-windows-init/CHANGELOG.json
index 86d5d71e492..779d63823f0 100644
--- a/packages/react-native-windows-init/CHANGELOG.json
+++ b/packages/react-native-windows-init/CHANGELOG.json
@@ -1,6 +1,21 @@
{
"name": "react-native-windows-init",
"entries": [
+ {
+ "date": "Wed, 22 Apr 2020 00:04:29 GMT",
+ "tag": "react-native-windows-init_v0.1.5",
+ "version": "0.1.5",
+ "comments": {
+ "patch": [
+ {
+ "comment": "Fix react-native-windows-init to work with tags (@master)",
+ "author": "acoates@microsoft.com",
+ "commit": "a34e2169b7a0224cd2486fab5bd224077234d5d5",
+ "package": "react-native-windows-init"
+ }
+ ]
+ }
+ },
{
"date": "Tue, 07 Apr 2020 18:46:38 GMT",
"tag": "react-native-windows-init_v0.1.4",
diff --git a/packages/react-native-windows-init/CHANGELOG.md b/packages/react-native-windows-init/CHANGELOG.md
index 27c98ceb7fa..4858be37ae3 100644
--- a/packages/react-native-windows-init/CHANGELOG.md
+++ b/packages/react-native-windows-init/CHANGELOG.md
@@ -1,9 +1,17 @@
# Change Log - react-native-windows-init
-This log was last generated on Tue, 07 Apr 2020 18:46:38 GMT and should not be manually modified.
+This log was last generated on Wed, 22 Apr 2020 00:04:29 GMT and should not be manually modified.
+## 0.1.5
+
+Wed, 22 Apr 2020 00:04:29 GMT
+
+### Patches
+
+- Fix react-native-windows-init to work with tags (@master) (acoates@microsoft.com)
+
## 0.1.4
Tue, 07 Apr 2020 18:46:38 GMT
diff --git a/packages/react-native-windows-init/package.json b/packages/react-native-windows-init/package.json
index b036c590e4c..362c27f21be 100644
--- a/packages/react-native-windows-init/package.json
+++ b/packages/react-native-windows-init/package.json
@@ -1,6 +1,6 @@
{
"name": "react-native-windows-init",
- "version": "0.1.4",
+ "version": "0.1.5",
"description": "CLI to add react-native-windows to an existing react-native project",
"main": "index.js",
"repository": "https://github.com/microsoft/react-native-windows",
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`),
+ );
+ }
}
});
}
diff --git a/vnext/CHANGELOG.json b/vnext/CHANGELOG.json
index aaa03fcc7b3..c709b9e000e 100644
--- a/vnext/CHANGELOG.json
+++ b/vnext/CHANGELOG.json
@@ -1,6 +1,126 @@
{
"name": "react-native-windows",
"entries": [
+ {
+ "date": "Thu, 23 Apr 2020 00:04:37 GMT",
+ "tag": "react-native-windows_v0.0.0-master.46",
+ "version": "0.0.0-master.46",
+ "comments": {
+ "prerelease": [
+ {
+ "comment": "Hook up to packager websocket to allow 'r' to reload instance",
+ "author": "acoates@microsoft.com",
+ "commit": "2fad67bf25bc6eff90417cff91493d9479db5076",
+ "package": "react-native-windows"
+ },
+ {
+ "comment": "Handle syntax errors in RedBox",
+ "author": "asklar@microsoft.com",
+ "commit": "16a4ede863a147bf2b473b1eb3b85e6b19c3cb72",
+ "package": "react-native-windows"
+ },
+ {
+ "comment": "Publish ship and debug bits in the nuget",
+ "author": "acoates@microsoft.com",
+ "commit": "b35cc97adef395d7b9886425ef3b12ccd5cec6ee",
+ "package": "react-native-windows"
+ },
+ {
+ "comment": "Implement String ViewManager Command IDs",
+ "author": "ngerlem@microsoft.com",
+ "commit": "509b9e5a57f6d032f2422ead1e09207f10855cbd",
+ "package": "react-native-windows"
+ }
+ ]
+ }
+ },
+ {
+ "date": "Wed, 22 Apr 2020 00:04:29 GMT",
+ "tag": "react-native-windows_v0.0.0-master.45",
+ "version": "0.0.0-master.45",
+ "comments": {
+ "prerelease": [
+ {
+ "comment": "Make default template build non-dev bundle when not using debug configuration",
+ "author": "acoates@microsoft.com",
+ "commit": "5c98e236066ced8eb314fae9995c288cb2eee798",
+ "package": "react-native-windows"
+ },
+ {
+ "comment": "Implemented C++ TurboModule compile time spec validation",
+ "author": "vmorozov@microsoft.com",
+ "commit": "21dea64efa55d0cc23d0ad0e33a058b0e3981800",
+ "package": "react-native-windows"
+ },
+ {
+ "comment": "Fix devtools connection to match RN0.62",
+ "author": "acoates@microsoft.com",
+ "commit": "c779043f0dd5e57f66b7609a8a09270aa78ad1b7",
+ "package": "react-native-windows"
+ }
+ ]
+ }
+ },
+ {
+ "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",
+ "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..aced2707bc0 100644
--- a/vnext/CHANGELOG.md
+++ b/vnext/CHANGELOG.md
@@ -1,9 +1,51 @@
# 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 Thu, 23 Apr 2020 00:04:37 GMT and should not be manually modified.
+## 0.0.0-master.46
+
+Thu, 23 Apr 2020 00:04:37 GMT
+
+### Changes
+
+- Hook up to packager websocket to allow 'r' to reload instance (acoates@microsoft.com)
+- Handle syntax errors in RedBox (asklar@microsoft.com)
+- Publish ship and debug bits in the nuget (acoates@microsoft.com)
+- Implement String ViewManager Command IDs (ngerlem@microsoft.com)
+
+## 0.0.0-master.45
+
+Wed, 22 Apr 2020 00:04:29 GMT
+
+### Changes
+
+- Make default template build non-dev bundle when not using debug configuration (acoates@microsoft.com)
+- Implemented C++ TurboModule compile time spec validation (vmorozov@microsoft.com)
+- Fix devtools connection to match RN0.62 (acoates@microsoft.com)
+
+## 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
+
+### 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/Desktop.DLL/react-native-win32.x64.def b/vnext/Desktop.DLL/react-native-win32.x64.def
index 280de54d461..253bc9d1dfa 100644
--- a/vnext/Desktop.DLL/react-native-win32.x64.def
+++ b/vnext/Desktop.DLL/react-native-win32.x64.def
@@ -34,7 +34,7 @@ EXPORTS
?createIUIManager@react@facebook@@YA?AV?$shared_ptr@VIUIManager@react@facebook@@@std@@$$QEAV?$vector@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@V?$allocator@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@@2@@4@PEAUINativeUIManager@12@@Z
?createUIManagerModule@react@facebook@@YA?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z
?destroy@dynamic@folly@@AEAAXXZ
-?dispatchCommand@ShadowNode@react@facebook@@UEAAX_JAEBUdynamic@folly@@@Z
+?dispatchCommand@ShadowNode@react@facebook@@UEAAXAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@AEBUdynamic@folly@@@Z
?getModuleRegistry@Instance@react@facebook@@QEAAAEAVModuleRegistry@23@XZ
?get_ptr@dynamic@folly@@QEGBAPEBU12@V?$Range@PEBD@2@@Z
?get_ptrImpl@dynamic@folly@@AEGBAPEBU12@AEBU12@@Z
diff --git a/vnext/Desktop.DLL/react-native-win32.x86.def b/vnext/Desktop.DLL/react-native-win32.x86.def
index 9ae703e4de2..8a299514bc9 100644
--- a/vnext/Desktop.DLL/react-native-win32.x86.def
+++ b/vnext/Desktop.DLL/react-native-win32.x86.def
@@ -35,7 +35,7 @@ EXPORTS
?createIUIManager@react@facebook@@YG?AV?$shared_ptr@VIUIManager@react@facebook@@@std@@$$QAV?$vector@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@V?$allocator@V?$unique_ptr@VIViewManager@react@facebook@@U?$default_delete@VIViewManager@react@facebook@@@std@@@std@@@2@@4@PAUINativeUIManager@12@@Z
?createUIManagerModule@react@facebook@@YG?AV?$unique_ptr@VCxxModule@module@xplat@facebook@@U?$default_delete@VCxxModule@module@xplat@facebook@@@std@@@std@@V?$shared_ptr@VIUIManager@react@facebook@@@4@@Z
?destroy@dynamic@folly@@AAEXXZ
-?dispatchCommand@ShadowNode@react@facebook@@UAEX_JABUdynamic@folly@@@Z
+?dispatchCommand@ShadowNode@react@facebook@@UAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABUdynamic@folly@@@Z
?getModuleRegistry@Instance@react@facebook@@QAEAAVModuleRegistry@23@XZ
?get_ptr@dynamic@folly@@QGBEPBU12@V?$Range@PBD@2@@Z
?get_ptrImpl@dynamic@folly@@AGBEPBU12@ABU12@@Z
diff --git a/vnext/Desktop.UnitTests/EmptyUIManagerModule.h b/vnext/Desktop.UnitTests/EmptyUIManagerModule.h
index 6006bb2ca44..f8e333ea0bb 100644
--- a/vnext/Desktop.UnitTests/EmptyUIManagerModule.h
+++ b/vnext/Desktop.UnitTests/EmptyUIManagerModule.h
@@ -63,7 +63,10 @@ class EmptyUIManager {
std::function /*final Callback*/ callback);
void setJSResponder(int64_t reactTag, bool blockNativeResponder);
void clearJSResponder();
- void dispatchViewManagerCommand(int64_t reactTag, int64_t commandId, folly::dynamic /*ReadableMap*/ commandArgs);
+ void dispatchViewManagerCommand(
+ int64_t reactTag,
+ const std::string &commandId,
+ folly::dynamic /*ReadableMap*/ commandArgs);
void showPopupMenu(
int64_t reactTag,
folly::dynamic /*ReadableMap*/ items,
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