// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for details.
import * as path from "path";
import * as fs from "fs";
import assert = require("assert");
import { Node } from "../../src/common/node/node";
import { ReactNativeProjectHelper } from "../../src/common/reactNativeProjectHelper";
suite("ReactNativeProjectHelper", function () {
const fsHelper = new Node.FileSystem();
const sampleReactNativeProjectDir = path.join(
__dirname,
"..",
"resources",
"sampleReactNativeProject",
);
suite("isAndroidHermesEnabled", () => {
const buildGradleFilePath = path.join(
sampleReactNativeProjectDir,
"android",
"app",
"build.gradle",
);
suiteSetup(() => {
fsHelper.makeDirectoryRecursiveSync(path.dirname(buildGradleFilePath));
});
suiteTeardown(() => {
fsHelper.removePathRecursivelySync(path.join(sampleReactNativeProjectDir, "android"));
});
test("isAndroidHermesEnabled should return 'true' if Hermes engine is enabled in the build.gradle file", () => {
const buildGradleFileContent =
"project.ext.react = [\nenableHermes: true, // clean and rebuild if changing\n]";
fs.writeFileSync(buildGradleFilePath, buildGradleFileContent);
const androidHermesEnabled = ReactNativeProjectHelper.isAndroidHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(androidHermesEnabled, true);
});
test("isAndroidHermesEnabled should return 'false' if Hermes engine is disabled in the build.gradle file", () => {
const buildGradleFileContent =
"project.ext.react = [\nenableHermes: false, // clean and rebuild if changing\n]";
fs.writeFileSync(buildGradleFilePath, buildGradleFileContent);
const androidHermesEnabled = ReactNativeProjectHelper.isAndroidHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(androidHermesEnabled, false);
});
test("isAndroidHermesEnabled should return 'false' if the Hermes engine parameter is absent in the build.gradle file", () => {
const buildGradleFileContent = "project.ext.react = [\n]";
fs.writeFileSync(buildGradleFilePath, buildGradleFileContent);
const androidHermesEnabled = ReactNativeProjectHelper.isAndroidHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(androidHermesEnabled, false);
});
});
suite("isIOSHermesEnabled", () => {
const podfileFilePath = path.join(sampleReactNativeProjectDir, "ios", "Podfile");
suiteSetup(() => {
fsHelper.makeDirectoryRecursiveSync(path.dirname(podfileFilePath));
});
suiteTeardown(() => {
fsHelper.removePathRecursivelySync(path.join(sampleReactNativeProjectDir, "ios"));
});
test("isIOSHermesEnabled should return 'true' if Hermes engine is enabled in the Podfile file", () => {
const podfileFileContent =
" use_react_native!(\n" +
" :path => config[:reactNativePath],\n" +
" # to enable hermes on iOS, change `false` to `true` and then install pods\n" +
" :hermes_enabled => true\n" +
" )";
fs.writeFileSync(podfileFilePath, podfileFileContent);
const iOSHermesEnabled = ReactNativeProjectHelper.isIOSHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(iOSHermesEnabled, true);
});
test("isIOSHermesEnabled should return 'false' if Hermes engine is disabled in the Podfile file", () => {
const podfileFileContent =
" use_react_native!(\n" +
" :path => config[:reactNativePath],\n" +
" # to enable hermes on iOS, change `false` to `true` and then install pods\n" +
" :hermes_enabled => false\n" +
" )";
fs.writeFileSync(podfileFilePath, podfileFileContent);
const iOSHermesEnabled = ReactNativeProjectHelper.isIOSHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(iOSHermesEnabled, false);
});
test("isIOSHermesEnabled should return 'false' if the Hermes engine parameter is absent in the Podfile file", () => {
const podfileFileContent =
" use_react_native!(\n" + " :path => config[:reactNativePath],\n" + " )";
fs.writeFileSync(podfileFilePath, podfileFileContent);
const iOSHermesEnabled = ReactNativeProjectHelper.isIOSHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(iOSHermesEnabled, false);
});
});
suite("isMacOSHermesEnabled", () => {
const podfileFilePath = path.join(sampleReactNativeProjectDir, "macos", "Podfile");
suiteSetup(() => {
fsHelper.makeDirectoryRecursiveSync(path.dirname(podfileFilePath));
});
suiteTeardown(() => {
fsHelper.removePathRecursivelySync(path.join(sampleReactNativeProjectDir, "macos"));
});
test("isMacOSHermesEnabled should return 'true' if the 'hermes_enabled' parameter in the Podfile file is uncommented and equal to 'true'", () => {
const podfileFileContent =
" use_react_native!(\n" +
" :path => '../node_modules/react-native-macos',\n" +
" # To use Hermes, install the `hermes-engine-darwin` npm package, e.g.:\n" +
" # $ yarn add 'hermes-engine-darwin@~0.5.3'\n" +
" #\n" +
" # Then enable this option:\n" +
" :hermes_enabled => true\n" +
" )";
fs.writeFileSync(podfileFilePath, podfileFileContent);
const macOSHermesEnabled = ReactNativeProjectHelper.isMacOSHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(macOSHermesEnabled, true);
});
test("isMacOSHermesEnabled should return 'true' if the \"pod 'hermes'\" parameter in the Podfile file is uncommented", () => {
const podfileFileContent =
" target 'rnmacos62-macOS' do\n" +
" platform :macos, '10.13'\n" +
" use_native_modules!\n" +
" # Enables Hermes\n" +
" #\n" +
" # Be sure to first install the `hermes-engine-darwin` npm package, e.g.:\n" +
" #\n" +
" # $ yarn add 'hermes-engine-darwin@^0.4.3'\n" +
" #\n" +
" pod 'React-Core/Hermes', :path => '../node_modules/react-native-macos/'\n" +
" pod 'hermes', :path => '../node_modules/hermes-engine-darwin'\n" +
" pod 'libevent', :podspec => '../node_modules/react-native-macos/third-party-podspecs/libevent.podspec'\n" +
" # Pods specifically for macOS target\n" +
" end\n";
fs.writeFileSync(podfileFilePath, podfileFileContent);
const macOSHermesEnabled = ReactNativeProjectHelper.isMacOSHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(macOSHermesEnabled, true);
});
test("isMacOSHermesEnabled should return 'false' if the 'hermes_enabled' parameter in the Podfile file is commented and equal to 'true'", () => {
const podfileFileContent =
" use_react_native!(\n" +
" :path => '../node_modules/react-native-macos',\n" +
" # To use Hermes, install the `hermes-engine-darwin` npm package, e.g.:\n" +
" # $ yarn add 'hermes-engine-darwin@~0.5.3'\n" +
" #\n" +
" # Then enable this option:\n" +
" # :hermes_enabled => true\n" +
" )";
fs.writeFileSync(podfileFilePath, podfileFileContent);
const macOSHermesEnabled = ReactNativeProjectHelper.isMacOSHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(macOSHermesEnabled, false);
});
test("isMacOSHermesEnabled should return 'false' if the Hermes engine parameter is absent in the Podfile file", () => {
const podfileFileContent =
" use_react_native!(\n" +
" :path => '../node_modules/react-native-macos',\n" +
" )";
fs.writeFileSync(podfileFilePath, podfileFileContent);
const macOSHermesEnabled = ReactNativeProjectHelper.isMacOSHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(macOSHermesEnabled, false);
});
});
suite("isWindowsHermesEnabled", () => {
const experimentalFeaturesFilePath = path.join(
sampleReactNativeProjectDir,
"windows",
"ExperimentalFeatures.props",
);
suiteSetup(() => {
fsHelper.makeDirectoryRecursiveSync(path.dirname(experimentalFeaturesFilePath));
});
suiteTeardown(() => {
fsHelper.removePathRecursivelySync(path.join(sampleReactNativeProjectDir, "windows"));
});
test("isWindowsHermesEnabled should return 'true' if Hermes engine is enabled in the ExperimentalFeatures.props file", () => {
const experimentalFeaturesFileContent =
' \n' +
" \n" +
" true\n" +
" false\n" +
" ";
fs.writeFileSync(experimentalFeaturesFilePath, experimentalFeaturesFileContent);
const windowsHermesEnabled = ReactNativeProjectHelper.isWindowsHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(windowsHermesEnabled, true);
});
test("isWindowsHermesEnabled should return 'fasle' if Hermes engine is disabled in the ExperimentalFeatures.props file", () => {
const experimentalFeaturesFileContent =
' \n' +
" \n" +
" false\n" +
" false\n" +
" ";
fs.writeFileSync(experimentalFeaturesFilePath, experimentalFeaturesFileContent);
const windowsHermesEnabled = ReactNativeProjectHelper.isWindowsHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(windowsHermesEnabled, false);
});
test("isWindowsHermesEnabled should return 'fasle' if there is no the ExperimentalFeatures.props file", () => {
fsHelper.removePathRecursivelySync(path.join(sampleReactNativeProjectDir, "windows"));
const windowsHermesEnabled = ReactNativeProjectHelper.isWindowsHermesEnabled(
sampleReactNativeProjectDir,
);
assert.strictEqual(windowsHermesEnabled, false);
});
});
suite("verifyMetroConfigFile", () => {
test("Should not throw an error for verifyMetroConfigFile function", async () => {
try {
ReactNativeProjectHelper.verifyMetroConfigFile(sampleReactNativeProjectDir);
} catch (err) {
assert.fail(err as any);
}
});
});
});