From f0b905bb7044e497a5a275cda0d755f9aa78d8b1 Mon Sep 17 00:00:00 2001 From: "Jon Thysell (JAUNTY)" Date: Fri, 10 Nov 2023 11:20:27 -0800 Subject: [PATCH] Fabric: Enable react-test-renderer tests in the new cpp-app template The upstream RN app template includes a jest test suite (run with `yarn test`) with a default test to render your app JS using the `react-test-renderer`. However, this only tests the iOS version of your app (it forces platform === 'ios') and therefore won't catch if there are issues in your `windows` platform files. Using `@rnx-kit/jest-preset`, you can run jest tests against any platform via a custom jest config. This PR adds `@rnx-kit/jest-preset` as a dev dependency to the new `cpp-app` template, as well as a `jest.config.windows.js` to use it. Furthermore it adds a script so users can run these tests for windows via `yarn test:windows`. To support this, I've extended the templateUtils added in #12374 to include functionality to run `npm i` / `yarn` to install any new dependencies added. Closes #11939 --- .ado/templates/react-native-init-windows.yml | 6 ++++++ ...-20088f72-5201-4d7b-96c9-2b522fed786b.json | 7 +++++++ .../templates/cpp-app/jest.config.windows.js | 3 +++ vnext/templates/cpp-app/template.config.js | 13 ++++++++++-- vnext/templates/templateUtils.js | 20 ++++++++++++++++++- 5 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 change/react-native-windows-20088f72-5201-4d7b-96c9-2b522fed786b.json create mode 100644 vnext/templates/cpp-app/jest.config.windows.js diff --git a/.ado/templates/react-native-init-windows.yml b/.ado/templates/react-native-init-windows.yml index 69ee0b100a8..7d977a95082 100644 --- a/.ado/templates/react-native-init-windows.yml +++ b/.ado/templates/react-native-init-windows.yml @@ -112,6 +112,12 @@ steps: parameters: buildLogDirectory: '$(Build.BinariesDirectory)\${{ parameters.platform }}\${{ parameters.configuration }}\BuildLogs' + # Only run the following on apps + - ${{ if endsWith(parameters.template, '-app') }}: + - script: call yarn test:windows + displayName: Run jest tests with react-test-renderer + workingDirectory: $(Agent.BuildDirectory)\testcli + # Only test bundling in debug since we already bundle as part of release builds - ${{ if and(endsWith(parameters.template, '-app'), eq(parameters.configuration, 'Debug')) }}: - script: npx react-native bundle --entry-file index.js --platform windows --bundle-output test.bundle diff --git a/change/react-native-windows-20088f72-5201-4d7b-96c9-2b522fed786b.json b/change/react-native-windows-20088f72-5201-4d7b-96c9-2b522fed786b.json new file mode 100644 index 00000000000..3116abda09c --- /dev/null +++ b/change/react-native-windows-20088f72-5201-4d7b-96c9-2b522fed786b.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Fabric: Enable react-test-renderer tests in the new cpp-app template", + "packageName": "react-native-windows", + "email": "jthysell@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/vnext/templates/cpp-app/jest.config.windows.js b/vnext/templates/cpp-app/jest.config.windows.js new file mode 100644 index 00000000000..4ae04e8b489 --- /dev/null +++ b/vnext/templates/cpp-app/jest.config.windows.js @@ -0,0 +1,3 @@ +const config = {}; + +module.exports = require('@rnx-kit/jest-preset')('windows', config); diff --git a/vnext/templates/cpp-app/template.config.js b/vnext/templates/cpp-app/template.config.js index 2e0db4ce69c..4627b7c6488 100644 --- a/vnext/templates/cpp-app/template.config.js +++ b/vnext/templates/cpp-app/template.config.js @@ -107,11 +107,20 @@ async function getFileMappings(config = {}, options = {}) { } async function postInstall(config = {}, options = {}) { - // Update package.json with new scripts + // Update package.json with new scripts and dependencies await templateUtils.updateProjectPackageJson(config, options, { - scripts: {windows: 'react-native run-windows'}, + scripts: { + windows: 'react-native run-windows', + 'test:windows': 'jest --config jest.config.windows.js', + }, + devDependencies: { + '@rnx-kit/jest-preset': '^0.1.16', + }, }); + // Install recently added dependencies + await templateUtils.runNpmInstall(config, options); + console.log(chalk.white.bold('To run your new windows app:')); console.log(chalk.white(' npx react-native run-windows')); } diff --git a/vnext/templates/templateUtils.js b/vnext/templates/templateUtils.js index 0d6238484e8..e9f2bb7174b 100644 --- a/vnext/templates/templateUtils.js +++ b/vnext/templates/templateUtils.js @@ -6,8 +6,26 @@ * @format */ +const existsSync = require('fs').existsSync; +const path = require('path'); +const util = require('util'); +const exec = util.promisify(require('child_process').exec); + const pkgUtils = require('@react-native-windows/package-utils'); +async function runNpmInstall(config = {}, options = {}) { + const projectPath = config?.root ?? process.cwd(); + + if (options?.logging) { + console.log('Installing dependencies...'); + } + const isYarn = existsSync(path.join(projectPath, 'yarn.lock')); + await exec( + isYarn ? 'yarn' : 'npm i', + options?.logging ? {stdio: 'inherit'} : {}, + ); +} + async function updateProjectPackageJson(config = {}, options = {}, props = {}) { const projectPath = config?.root ?? process.cwd(); const projectPackage = await pkgUtils.WritableNpmPackage.fromPath( @@ -26,4 +44,4 @@ async function updateProjectPackageJson(config = {}, options = {}, props = {}) { await projectPackage.mergeProps(props); } -module.exports = {updateProjectPackageJson}; +module.exports = {runNpmInstall, updateProjectPackageJson};