Skip to content

Commit

Permalink
Add e2e tests skeleton for generated cpp code (facebook#25673)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebook#25673

This diff add e2e code generator validation. I added proper buck rule which compiles cpp code and test if it really compiles.

While testing I faced few minor issues:

- `getBool` and `getNumber` shouldn't have `rt` param.

- Generators now start considering whole module name instead of sliced part of their name.

- Fixed import structure in generated cpp.

- renamed `jsireact` to `ReactCommon` following D16231697

Reviewed By: rickhanlonii

Differential Revision: D16221277

fbshipit-source-id: aff4011ad52dd5e16546ffdb709d6a751ebfaced
  • Loading branch information
osdnk authored and facebook-github-bot committed Jul 17, 2019
1 parent 83969c2 commit d672247
Show file tree
Hide file tree
Showing 11 changed files with 206 additions and 125 deletions.
3 changes: 3 additions & 0 deletions packages/react-native-codegen/BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ fb_native.genrule(
srcs = glob(
[
"**/e2e/__test_fixtures__/*NativeComponent.js",
"**/e2e/__test_fixtures__/Native*.js",
],
),
cmd = "$(exe fbsource//xplat/js/react-native-github/packages/react-native-codegen:write_to_json) $OUT $SRCS",
Expand Down Expand Up @@ -66,6 +67,7 @@ fb_xplat_cxx_binary(
visibility = ["PUBLIC"],
deps = [
":generated_components-codegen_tests",
":generated_modules-codegen_tests",
],
)

Expand All @@ -89,6 +91,7 @@ rn_xplat_cxx_library(
],
deps = [
":generated_components-codegen_tests",
":generated_modules-codegen_tests",
],
)

Expand Down
48 changes: 48 additions & 0 deletions packages/react-native-codegen/DEFS.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ def rn_codegen(
generate_props_h_name = "generated_props_h-{}".format(name)
generate_shadow_node_cpp_name = "generated_shadow_node_cpp-{}".format(name)
generate_shadow_node_h_name = "generated_shadow_node_h-{}".format(name)
generate_module_h_name = "generate_module_h-{}".format(name)
generate_module_cpp_name = "generate_module_cpp-{}".format(name)

fb_native.genrule(
name = generate_fixtures_rule_name,
Expand Down Expand Up @@ -82,6 +84,18 @@ def rn_codegen(
out = "ShadowNodes.h",
)

fb_native.genrule(
name = generate_module_h_name,
cmd = "cp $(location :{})/NativeModules.h $OUT".format(generate_fixtures_rule_name),
out = "NativeModules.h",
)

fb_native.genrule(
name = generate_module_cpp_name,
cmd = "cp $(location :{})/NativeModules.cpp $OUT".format(generate_fixtures_rule_name),
out = "NativeModules.cpp",
)

# libs
rn_xplat_cxx_library(
name = "generated_components-{}".format(name),
Expand Down Expand Up @@ -134,6 +148,40 @@ def rn_codegen(
],
)

# libs
rn_xplat_cxx_library(
name = "generated_modules-{}".format(name),
tests = [":generated_tests-{}".format(name)],
srcs = [
":{}".format(generate_module_cpp_name),
],
headers = [
":{}".format(generate_module_h_name),
],
exported_headers = {
"NativeModules.cpp": ":{}".format(generate_module_cpp_name),
"NativeModules.h": ":{}".format(generate_module_h_name),
},
header_namespace = "react/modules/{}".format(name),
compiler_flags = [
"-fexceptions",
"-frtti",
"-std=c++14",
"-Wall",
],
fbobjc_compiler_flags = get_apple_compiler_flags(),
fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(),
platforms = (ANDROID, APPLE),
preprocessor_flags = [
"-DLOG_TAG=\"ReactNative\"",
"-DWITH_FBSYSTRACE=1",
],
visibility = ["PUBLIC"],
exported_deps = [
react_native_xplat_target("turbomodule/core:core"),
],
)

# Tests
fb_xplat_cxx_test(
name = "generated_tests-{}".format(name),
Expand Down
2 changes: 2 additions & 0 deletions packages/react-native-codegen/buck_tests/emptyFile.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#import <react/components/codegen_tests/ComponentDescriptors.h>
#import <react/modules/codegen_tests/NativeModules.h>
#import <react/modules/codegen_tests/NativeModules.cpp>

// TODO: Import every prop and event to asset they're generated

Expand Down
11 changes: 10 additions & 1 deletion packages/react-native-codegen/buck_tests/generate-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,14 @@ try {

RNCodegen.generate(
{libraryName, schema, outputDirectory},
{generators: ['descriptors', 'events', 'props', 'tests', 'shadow-nodes']},
{
generators: [
'descriptors',
'events',
'props',
'tests',
'shadow-nodes',
'modules',
],
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
* @format
*/

'use strict';

import type {TurboModule} from 'react-native/Libraries/TurboModule/RCTExport';
import * as TurboModuleRegistry from 'react-native/Libraries/TurboModule/TurboModuleRegistry';

export interface Spec extends TurboModule {
// Exported methods.
+getConstants: () => {|
const1: boolean,
const2: number,
const3: string,
|};
+voidFunc: () => void;
+getBool: (arg: boolean) => boolean;
+getNumber: (arg: number) => number;
+getString: (arg: string) => string;
+getArray: (arg: Array<any>) => Array<any>;
+getObject: (arg: Object) => Object;
+getValue: (x: number, y: string, z: Object) => Object;
+getValueWithCallback: (callback: (value: string) => void) => void;
+getValueWithPromise: (error: boolean) => Promise<string>;
}

export default TurboModuleRegistry.getEnforcing<Spec>('SampleTurboModule');
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ function combineSchemas(files: Array<string>): SchemaType {
const contents = fs.readFileSync(filename, 'utf8');
if (
contents &&
/export\s+default\s+codegenNativeComponent</.test(contents)
(/export\s+default\s+codegenNativeComponent</.test(contents) ||
/extends TurboModule/.test(contents))
) {
const schema = FlowParser.parseFile(filename);

Expand Down
4 changes: 4 additions & 0 deletions packages/react-native-codegen/src/generators/RNCodegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ const generateEventEmitterCpp = require('./components/GenerateEventEmitterCpp.js
const generateEventEmitterH = require('./components/GenerateEventEmitterH.js');
const generatePropsCpp = require('./components/GeneratePropsCpp.js');
const generatePropsH = require('./components/GeneratePropsH.js');
const generateModuleH = require('./modules/GenerateModuleH.js');
const generateModuleCpp = require('./modules/GenerateModuleCpp.js');
const generateTests = require('./components/GenerateTests.js');
const generateShadowNodeCpp = require('./components/GenerateShadowNodeCpp.js');
const generateShadowNodeH = require('./components/GenerateShadowNodeH.js');
Expand All @@ -43,6 +45,7 @@ type Generators =
| 'props'
| 'tests'
| 'shadow-nodes'
| 'modules'
| 'view-configs';

type Config = $ReadOnly<{|
Expand All @@ -54,6 +57,7 @@ const GENERATORS = {
descriptors: [generateComponentDescriptorH.generate],
events: [generateEventEmitterCpp.generate, generateEventEmitterH.generate],
props: [generatePropsCpp.generate, generatePropsH.generate],
modules: [generateModuleCpp.generate, generateModuleH.generate],
tests: [generateTests.generate],
'shadow-nodes': [
generateShadowNodeCpp.generate,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ import type {SchemaType} from '../../CodegenSchema';
type FilesOutput = Map<string, string>;

const propertyHeaderTemplate =
'static jsi::Value __hostFunction_Native::_MODULE_NAME_::TurboCxxModuleSpecJSI_::_PROPERTY_NAME_::(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {';
'static jsi::Value __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) {';

const propertyCastTemplate =
'static_cast<Native::_MODULE_NAME_::TurboCxxModuleSpecJSI *>(&turboModule)->::_PROPERTY_NAME_::(rt::_ARGS_::);';
'static_cast<Native::_MODULE_NAME_::SpecJSI *>(&turboModule)->::_PROPERTY_NAME_::(rt::_ARGS_::);';

const nonvoidPropertyTemplate = `
${propertyHeaderTemplate}
return ${propertyCastTemplate}
}`;
}`.trim();

const voidPropertyTemplate = `
${propertyHeaderTemplate}
Expand All @@ -32,16 +32,15 @@ ${propertyHeaderTemplate}
}`;

const proprertyDefTemplate =
' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_Native::_MODULE_NAME_::TurboCxxModuleSpecJSI_::_PROPERTY_NAME_::};';
' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::};';

const moduleTemplate = `
::_MODULE_PROPERTIES_::
::_MODULE_PROPERTIES_::
Native::_MODULE_NAME_::TurboCxxModuleSpecJSI::Native::_MODULE_NAME_::TurboCxxModuleSpecJSI(std::shared_ptr<JSCallInvoker> jsInvoker)
: TurboModule("::_MODULE_NAME_::TurboCxxModule", jsInvoker) {
Native::_MODULE_NAME_::SpecJSI::Native::_MODULE_NAME_::SpecJSI(std::shared_ptr<JSCallInvoker> jsInvoker)
: TurboModule("::_MODULE_NAME_::", jsInvoker) {
::_PROPERTIES_MAP_::
}
`;
}`.trim();

const template = `
/**
Expand All @@ -51,7 +50,7 @@ const template = `
* LICENSE file in the root directory of this source tree.
*/
#include "Native::_MODULE_NAME_::TurboCxxModuleSpecJSI.h"
#include <react/modules/::_LIBRARY_NAME_::/NativeModules.h>
namespace facebook {
namespace react {
Expand All @@ -72,11 +71,11 @@ function traverseArg(arg, index): string {
case 'StringTypeAnnotation':
return wrap('.getString(rt)');
case 'BooleanTypeAnnotation':
return wrap('.getBool(rt)');
return wrap('.getBool()');
case 'NumberTypeAnnotation':
case 'FloatTypeAnnotation':
case 'Int32TypeAnnotation':
return wrap('.getNumber(rt)');
return wrap('.getNumber()');
case 'ArrayTypeAnnotation':
return wrap('.getObject(rt).getArray(rt)');
case 'FunctionTypeAnnotation':
Expand Down Expand Up @@ -138,13 +137,14 @@ module.exports = {
)
.join('\n'),
)
.replace(/::_MODULE_NAME_::/g, name.slice(0, -11)); // FIXME
.replace(/::_MODULE_NAME_::/g, name);
})
.join('\n');

const fileName = 'NativeModules.h';
const replacedTemplate = template.replace(/::_MODULES_::/g, modules);

const fileName = 'NativeModules.cpp';
const replacedTemplate = template
.replace(/::_MODULES_::/g, modules)
.replace(/::_LIBRARY_NAME_::/g, libraryName);
return new Map([[fileName, replacedTemplate]]);
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import type {
type FilesOutput = Map<string, string>;

const moduleTemplate = `
class JSI_EXPORT Native::_MODULE_NAME_::TurboCxxModuleSpecJSI : public TurboModule {
class JSI_EXPORT Native::_MODULE_NAME_::SpecJSI : public TurboModule {
protected:
Native::_MODULE_NAME_::TurboCxxModuleSpecJSI(std::shared_ptr<JSCallInvoker> jsInvoker);
Native::_MODULE_NAME_::SpecJSI(std::shared_ptr<JSCallInvoker> jsInvoker);
public:
::_MODULE_PROPERTIES_::
Expand All @@ -38,7 +38,7 @@ const template = `
#pragma once
#include <jsireact/TurboModule.h>
#include <ReactCommon/TurboModule.h>
namespace facebook {
namespace react {
Expand Down Expand Up @@ -137,7 +137,7 @@ module.exports = {
.join('\n');
return moduleTemplate
.replace(/::_MODULE_PROPERTIES_::/g, traversedProperties)
.replace(/::_MODULE_NAME_::/g, name.slice(0, -11)) // FIXME
.replace(/::_MODULE_NAME_::/g, name)
.replace('::_PROPERTIES_MAP_::', '');
})
.join('\n');
Expand Down
Loading

0 comments on commit d672247

Please sign in to comment.