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) 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