From 93b480ab8e06078d4e4aa2b39f2b3b5f04c509ea Mon Sep 17 00:00:00 2001 From: Tommy Nguyen <4123478+tido64@users.noreply.github.com> Date: Fri, 11 Nov 2022 08:53:04 +0100 Subject: [PATCH] feat(dep-check): add migration message (#1941) --- .changeset/kind-pillows-fix.md | 5 + packages/dep-check/README.md | 4 + packages/dep-check/package.json | 11 +- packages/dep-check/scripts/update-profile.mjs | 399 --------------- packages/dep-check/scripts/update-readme.js | 78 --- packages/dep-check/src/check.ts | 6 +- packages/dep-check/src/helpers.ts | 16 + packages/dep-check/src/initialize.ts | 4 +- .../node_modules/conan/package.json | 14 - .../node_modules/dutch/package.json | 16 - .../node_modules/john/package.json | 15 - .../node_modules/quaid/package.json | 16 - .../node_modules/react-native/package.json | 7 - .../node_modules/react/package.json | 4 - .../node_modules/t-800/package.json | 18 - .../awesome-repo-extended/package.json | 19 - .../node_modules/conan/package.json | 14 - .../node_modules/dutch/package.json | 16 - .../node_modules/john/package.json | 15 - .../node_modules/quaid/package.json | 16 - .../node_modules/react-native/package.json | 7 - .../node_modules/react/package.json | 4 - .../node_modules/t-800/package.json | 16 - .../__fixtures__/awesome-repo/package.json | 19 - .../packageSpecificProfiles.js | 22 - .../custom-profiles/local-profiles.js | 0 .../custom-profiles-package/index.js | 0 .../custom-profiles-package/package.json | 5 - .../custom-profiles/root-level-profiles.js | 26 - .../custom-profiles/valid-profiles.js | 23 - .../node_modules/conan/package.json | 17 - .../node_modules/react-native/package.json | 7 - .../node_modules/react/package.json | 4 - .../node_modules/t-800/package.json | 17 - .../no-profile-satisfying-deps/package.json | 18 - .../test/__mocks__/@rnx-kit/config.js | 13 - packages/dep-check/test/__mocks__/chalk.js | 16 - packages/dep-check/test/__mocks__/fs.js | 19 - .../test/__snapshots__/check.app.test.ts.snap | 31 -- .../test/__snapshots__/check.test.ts.snap | 37 -- .../test/__snapshots__/profiles.test.ts.snap | 112 ---- .../test/__snapshots__/vigilant.test.ts.snap | 249 --------- packages/dep-check/test/capabilities.test.ts | 276 ---------- packages/dep-check/test/check.app.test.ts | 40 -- packages/dep-check/test/check.test.ts | 359 ------------- packages/dep-check/test/dependencies.test.ts | 239 --------- .../dep-check/test/findBadPackages.test.ts | 115 ----- packages/dep-check/test/helpers.test.ts | 17 - packages/dep-check/test/helpers.ts | 20 - packages/dep-check/test/initialize.test.ts | 170 ------- packages/dep-check/test/manifest.test.ts | 312 ------------ packages/dep-check/test/profiles.test.ts | 265 ---------- packages/dep-check/test/setVersion.test.ts | 204 -------- packages/dep-check/test/vigilant.test.ts | 477 ------------------ 54 files changed, 34 insertions(+), 3815 deletions(-) create mode 100644 .changeset/kind-pillows-fix.md delete mode 100755 packages/dep-check/scripts/update-profile.mjs delete mode 100755 packages/dep-check/scripts/update-readme.js delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/conan/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/dutch/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/john/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/quaid/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react-native/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/t-800/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo-extended/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/node_modules/conan/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/node_modules/dutch/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/node_modules/john/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/node_modules/quaid/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react-native/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/node_modules/t-800/package.json delete mode 100644 packages/dep-check/test/__fixtures__/awesome-repo/package.json delete mode 100644 packages/dep-check/test/__fixtures__/config-custom-profiles-only/packageSpecificProfiles.js delete mode 100644 packages/dep-check/test/__fixtures__/custom-profiles/local-profiles.js delete mode 100644 packages/dep-check/test/__fixtures__/custom-profiles/node_modules/custom-profiles-package/index.js delete mode 100644 packages/dep-check/test/__fixtures__/custom-profiles/node_modules/custom-profiles-package/package.json delete mode 100644 packages/dep-check/test/__fixtures__/custom-profiles/root-level-profiles.js delete mode 100644 packages/dep-check/test/__fixtures__/custom-profiles/valid-profiles.js delete mode 100644 packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/conan/package.json delete mode 100644 packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react-native/package.json delete mode 100644 packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react/package.json delete mode 100644 packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/t-800/package.json delete mode 100644 packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/package.json delete mode 100644 packages/dep-check/test/__mocks__/@rnx-kit/config.js delete mode 100644 packages/dep-check/test/__mocks__/chalk.js delete mode 100644 packages/dep-check/test/__mocks__/fs.js delete mode 100644 packages/dep-check/test/__snapshots__/check.app.test.ts.snap delete mode 100644 packages/dep-check/test/__snapshots__/check.test.ts.snap delete mode 100644 packages/dep-check/test/__snapshots__/profiles.test.ts.snap delete mode 100644 packages/dep-check/test/__snapshots__/vigilant.test.ts.snap delete mode 100644 packages/dep-check/test/capabilities.test.ts delete mode 100644 packages/dep-check/test/check.app.test.ts delete mode 100644 packages/dep-check/test/check.test.ts delete mode 100644 packages/dep-check/test/dependencies.test.ts delete mode 100644 packages/dep-check/test/findBadPackages.test.ts delete mode 100644 packages/dep-check/test/helpers.test.ts delete mode 100644 packages/dep-check/test/helpers.ts delete mode 100644 packages/dep-check/test/initialize.test.ts delete mode 100644 packages/dep-check/test/manifest.test.ts delete mode 100644 packages/dep-check/test/profiles.test.ts delete mode 100644 packages/dep-check/test/setVersion.test.ts delete mode 100644 packages/dep-check/test/vigilant.test.ts diff --git a/.changeset/kind-pillows-fix.md b/.changeset/kind-pillows-fix.md new file mode 100644 index 000000000..348ebcc5c --- /dev/null +++ b/.changeset/kind-pillows-fix.md @@ -0,0 +1,5 @@ +--- +"@rnx-kit/dep-check": minor +--- + +Tell users to migrate to `@rnx-kit/align-deps` diff --git a/packages/dep-check/README.md b/packages/dep-check/README.md index 23161ad4f..a53550d51 100644 --- a/packages/dep-check/README.md +++ b/packages/dep-check/README.md @@ -1,3 +1,7 @@ +# `@rnx-kit/dep-check` has been renamed to `@rnx-kit/align-deps` + +For more details, read the RFC: https://github.com/microsoft/rnx-kit/pull/1757 + # @rnx-kit/dep-check diff --git a/packages/dep-check/package.json b/packages/dep-check/package.json index 68d671dc0..c2d93d1e9 100644 --- a/packages/dep-check/package.json +++ b/packages/dep-check/package.json @@ -21,11 +21,7 @@ "scripts": { "build": "rnx-kit-scripts build", "bundle": "rnx-kit-scripts bundle", - "format": "rnx-kit-scripts format", - "lint": "rnx-kit-scripts lint", - "test": "rnx-kit-scripts test", - "update-profile": "node scripts/update-profile.mjs", - "update-readme": "node scripts/update-readme.js" + "format": "rnx-kit-scripts format" }, "devDependencies": { "@rnx-kit/config": "*", @@ -44,8 +40,6 @@ "detect-indent": "^6.0.0", "jest-diff": "^26.0.0", "lodash": "^4.17.21", - "markdown-table": "^2.0.0", - "pacote": "^12.0.0", "prompts": "^2.4.0", "semver": "^7.0.0", "yargs": "^16.0.0" @@ -55,8 +49,5 @@ }, "eslintConfig": { "extends": "@rnx-kit/eslint-config" - }, - "jest": { - "preset": "@rnx-kit/scripts" } } diff --git a/packages/dep-check/scripts/update-profile.mjs b/packages/dep-check/scripts/update-profile.mjs deleted file mode 100755 index 6b5373a9e..000000000 --- a/packages/dep-check/scripts/update-profile.mjs +++ /dev/null @@ -1,399 +0,0 @@ -#!/usr/bin/env node -// @ts-check - -import { existsSync as fileExists } from "fs"; -import * as fs from "fs/promises"; -import markdownTable from "markdown-table"; -import pacote from "pacote"; -import * as path from "path"; -import semverCoerce from "semver/functions/coerce.js"; -import semverCompare from "semver/functions/compare.js"; -import { fileURLToPath } from "url"; -import { isMetaPackage } from "../lib/capabilities.js"; - -/** - * @typedef {import("../src/types").MetaPackage} MetaPackage - * @typedef {import("../src/types").Package} Package - * @typedef {import("../src/types").Profile} Profile - * - * @typedef {{ - * name: string; - * version: string; - * latest: string; - * homepage: string; - * dependencies?: Record; - * peerDependencies?: Record; - * }} PackageInfo - */ - -/** - * Fetches package manifest from npm. - * @param {MetaPackage | Package} pkg - * @param {string=} defaultTag - * @returns {Promise} - */ -async function fetchPackageInfo(pkg, defaultTag = "latest") { - if (isMetaPackage(pkg)) { - return Promise.resolve(); - } - - const { name, version } = pkg; - const manifest = await pacote.manifest(name, { - defaultTag, - fullMetadata: true, - }); - return { - name, - version, - latest: manifest.version, - homepage: manifest.homepage, - dependencies: manifest.dependencies, - peerDependencies: manifest.peerDependencies, - }; -} - -/** - * @param {string} packageName - * @param {Record?} dependencies - * @returns {string} - */ -function getPackageVersion(packageName, dependencies) { - const packageVersion = dependencies?.[packageName]; - if (!packageVersion) { - throw new Error(`Failed to get '${packageName}' version`); - } - return semverCoerce(packageVersion).version; -} - -/** - * Returns the path to a profile. - * @param {string} preset - * @param {string} profileVersion - * @returns {string} - */ -function getProfilePath(preset, profileVersion) { - const __dirname = path.dirname(fileURLToPath(import.meta.url)); - return path.relative( - process.cwd(), - path.join( - __dirname, - "..", - "src", - "presets", - preset, - `profile-${profileVersion}.ts` - ) - ); -} - -/** - * Generates a profile. - * @param {{ - * preset: string; - * targetVersion: string; - * reactVersion: string; - * metroVersion: string; - * }} versions - * @returns {string} - */ -function generateFromTemplate({ - preset, - targetVersion, - reactVersion, - metroVersion, -}) { - const nextVersionCoerced = semverCoerce(targetVersion); - const currentVersion = `${nextVersionCoerced.major}.${ - nextVersionCoerced.minor - 1 - }`; - - const currentProfile = getProfilePath(preset, currentVersion); - if (!fileExists(currentProfile)) { - throw new Error(`Could not find '${currentProfile}'`); - } - - const currentVersionVarName = `${nextVersionCoerced.major}_${ - nextVersionCoerced.minor - 1 - }`; - return `import type { Profile, Package } from "../../types"; -import profile_${currentVersionVarName} from "./profile-${currentVersion}"; - -const reactNative: Package = { - name: "react-native", - version: "^${targetVersion}.0", - capabilities: ["react"], -}; - -const profile: Profile = { - ...profile_${currentVersionVarName}, - react: { - name: "react", - version: "${reactVersion}", - }, - "react-dom": { - name: "react-dom", - version: "^${reactVersion}", - capabilities: ["react"], - }, - "react-test-renderer": { - name: "react-test-renderer", - version: "${reactVersion}", - capabilities: ["react"], - devOnly: true, - }, - - core: reactNative, - "core-android": reactNative, - "core-ios": reactNative, - "core-macos": { - name: "react-native-macos", - version: "^${targetVersion}.0", - capabilities: ["react"], - }, - "core-windows": { - name: "react-native-windows", - version: "^${targetVersion}.0", - capabilities: ["core"], - }, - - "babel-preset-react-native": { - name: "metro-react-native-babel-preset", - version: "^${metroVersion}", - devOnly: true, - }, - metro: { - name: "metro", - version: "^${metroVersion}", - devOnly: true, - }, - "metro-config": { - name: "metro-config", - version: "^${metroVersion}", - devOnly: true, - }, - "metro-core": { - name: "metro-core", - version: "^${metroVersion}", - devOnly: true, - }, - "metro-react-native-babel-transformer": { - name: "metro-react-native-babel-transformer", - version: "^${metroVersion}", - devOnly: true, - }, - "metro-resolver": { - name: "metro-resolver", - version: "^${metroVersion}", - devOnly: true, - }, - "metro-runtime": { - name: "metro-runtime", - version: "^${metroVersion}", - devOnly: true, - }, -}; - -export default profile; -`; -} - -/** - * Fetches package versions for specified react-native version. - * @param {string} preset - * @param {string} targetVersion - * @param {Profile} latestProfile - * @returns {Promise} - */ -async function makeProfile(preset, targetVersion, latestProfile) { - const reactNativeInfo = await fetchPackageInfo( - latestProfile["core"], - `^${targetVersion}.0-0` - ); - if (!reactNativeInfo) { - throw new Error(`Failed to get manifest of 'react-native@${targetVersion}`); - } - - const { dependencies, peerDependencies } = reactNativeInfo; - if (!dependencies) { - throw new Error( - `Failed to get dependencies of 'react-native@${targetVersion}` - ); - } - if (!peerDependencies) { - throw new Error( - `Failed to get peer dependencies of 'react-native@${targetVersion}` - ); - } - - // Fetch `metro` version from `@react-native-community/cli-plugin-metro` > `@react-native-community/cli` - const cliMetroPluginDependencies = await [ - "@react-native-community/cli", - "@react-native-community/cli-plugin-metro", - ].reduce(async (dependencies, packageName) => { - try { - const packageInfo = await pacote.manifest(packageName, { - defaultTag: getPackageVersion(packageName, await dependencies), - fullMetadata: true, - }); - return packageInfo.dependencies; - } catch (e) { - if (e.code === "ETARGET") { - // Some packages, such as `@react-native-community/cli`, are still in - // alpha or beta while react-native RCs. Try again with the `next` tag. - const packageInfo = await pacote.manifest(packageName, { - defaultTag: "next", - fullMetadata: true, - }); - return packageInfo.dependencies; - } else { - throw e; - } - } - }, Promise.resolve(dependencies)); - - return generateFromTemplate({ - preset, - targetVersion, - reactVersion: getPackageVersion("react", peerDependencies), - metroVersion: getPackageVersion("metro", cliMetroPluginDependencies), - }); -} - -/** - * Displays a table of all capabilities that resolve to a package, its current - * version, and the latest available version. - * - * If `targetVersion` is specified, also generates a profile. - * - * Note that this script spawns a new process for each capability in parallel. - * It currently does not honor throttling hints of any kind. - * - * @param {{ preset?: string; targetVersion?: string; force?: boolean; }} options - */ -async function main({ - preset: presetName = "microsoft", - targetVersion = "", - force, -}) { - const { preset } = await import(`../lib/presets/${presetName}/index.js`); - const allVersions = /** @type {import("../src/types").ProfileVersion[]} */ ( - Object.keys(preset) - .sort((lhs, rhs) => semverCompare(semverCoerce(lhs), semverCoerce(rhs))) - .reverse() - ); - - const latestProfile = preset[allVersions[0]]; - - if (targetVersion) { - if (!force && preset[targetVersion]) { - console.error( - `Profile for '${targetVersion}' already exists. To overwrite it anyway, re-run with '--force'.` - ); - process.exit(1); - } - - try { - const newProfile = await makeProfile( - presetName, - targetVersion, - latestProfile - ); - if (newProfile) { - const dst = getProfilePath(presetName, targetVersion); - fs.writeFile(dst, newProfile).then(() => { - console.log(`Wrote to '${dst}'`); - }); - } - } catch (e) { - if (e.distTags) { - console.error( - [ - e.message, - "Available tags:", - ...Object.entries(e.distTags).map( - ([tag, version]) => ` - ${tag}: ${version}` - ), - ].join("\n") - ); - } else { - console.error(e); - } - process.exit(1); - } - } - - const ignoredCapabilities = [ - "babel-preset-react-native", - "core", - "core-android", - "core-ios", - "core-macos", - "core-windows", - "hermes", - "metro", - "metro-config", - "metro-core", - "metro-react-native-babel-transformer", - "metro-resolver", - "metro-runtime", - "react", - "react-dom", - "react-test-renderer", - ]; - - /** @type {Record} */ - const delta = {}; - await Promise.all( - Object.entries(latestProfile) - .filter(([capability]) => { - return !ignoredCapabilities.includes(capability); - }) - .map(async ([capability, pkg]) => { - await fetchPackageInfo(pkg).then((info) => { - if (info) { - delta[capability] = info; - } - }); - }) - ); - - const table = markdownTable([ - ["Capability", "Name", "Version", "Latest", "Homepage"], - ...Object.keys(delta) - .sort() - .map((capability) => { - const { name, version, latest, homepage } = delta[capability]; - return [ - capability, - name, - version, - version.endsWith(latest) ? "=" : latest, - homepage, - ]; - }), - ]); - console.log(table); -} - -const options = (() => { - const options = {}; - process.argv.slice(2).forEach((arg) => { - switch (arg) { - case "--force": - options.force = true; - break; - default: - if (!/^\d+\.\d+$/.test(arg)) { - console.error( - `Expected version in the format '.', got: ${arg}` - ); - process.exit(1); - } - options.targetVersion = arg; - break; - } - }); - return options; -})(); - -main(options); diff --git a/packages/dep-check/scripts/update-readme.js b/packages/dep-check/scripts/update-readme.js deleted file mode 100755 index 903eec586..000000000 --- a/packages/dep-check/scripts/update-readme.js +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env node -// @ts-check - -const fs = require("fs"); -const markdownTable = require("markdown-table"); -const { preset } = require("../lib/presets/microsoft"); - -const README = "README.md"; -const TOKEN_START = ""; -const TOKEN_END = ""; - -/** - * Returns whether specified capability is a core capability. - * @param capability {string} - * @returns {boolean} - */ -function isCoreCapability(capability) { - return capability === "core" || capability.startsWith("core-"); -} - -/** - * Compare function that places core capabilities first. - * @param lhs {string} - * @param rhs {string} - * @returns {number} - */ -function sortCoreFirst(lhs, rhs) { - if (isCoreCapability(lhs)) { - if (!isCoreCapability(rhs)) { - return -1; - } - } else if (isCoreCapability(rhs)) { - return 1; - } - - if (lhs === rhs) { - return 0; - } - - return lhs < rhs ? -1 : 1; -} - -const allVersions = /** @type {import("../src/types").ProfileVersion[]} */ ( - Object.keys(preset).reverse() -); -const allCapabilities = /** @type {import("@rnx-kit/config").Capability[]} */ ( - Object.keys(preset[allVersions[0]]).sort(sortCoreFirst) -); - -const table = markdownTable([ - ["Capability", ...allVersions], - ...allCapabilities.map((capability) => { - return [ - capability, - ...allVersions.map((profileVersion) => { - const pkg = preset[profileVersion][capability]; - if ("version" in pkg) { - const { name, version } = pkg; - return `${name}@${version}`; - } else { - return `Meta package for installing ${pkg.capabilities - .map((name) => `\`${name}\``) - .join(", ")}`; - } - }), - ]; - }), -]); - -const readme = fs.readFileSync(README, { encoding: "utf-8" }); -const updatedReadme = readme.replace( - new RegExp(`${TOKEN_START}([^]+)${TOKEN_END}`), - `${TOKEN_START}\n\n${table}\n\n${TOKEN_END}` -); - -if (updatedReadme !== readme) { - fs.writeFileSync(README, updatedReadme); -} diff --git a/packages/dep-check/src/check.ts b/packages/dep-check/src/check.ts index 3bb07912c..8fbbeb70e 100644 --- a/packages/dep-check/src/check.ts +++ b/packages/dep-check/src/check.ts @@ -6,7 +6,7 @@ import { diffLinesUnified } from "jest-diff"; import path from "path"; import { getRequirements } from "./dependencies"; import { findBadPackages } from "./findBadPackages"; -import { modifyManifest } from "./helpers"; +import { modifyManifest, printMigrationMessage } from "./helpers"; import { updatePackageManifest } from "./manifest"; import { getProfilesFor, resolveCustomProfiles } from "./profiles"; import type { CheckConfig, CheckOptions, Command } from "./types"; @@ -144,10 +144,14 @@ export function checkPackageManifest( const url = chalk.bold("https://aka.ms/dep-check"); info(`Visit ${url} for more information about dep-check.`); + printMigrationMessage(); + return 1; } } + printMigrationMessage(); + return 0; } diff --git a/packages/dep-check/src/helpers.ts b/packages/dep-check/src/helpers.ts index 8c4e58a2d..5a006f579 100644 --- a/packages/dep-check/src/helpers.ts +++ b/packages/dep-check/src/helpers.ts @@ -1,3 +1,4 @@ +import { warn } from "@rnx-kit/console"; import type { PackageManifest } from "@rnx-kit/tools-node/package"; import { writePackage } from "@rnx-kit/tools-node/package"; import detectIndent from "detect-indent"; @@ -40,3 +41,18 @@ export function omitEmptySections(manifest: PackageManifest): PackageManifest { } return manifest; } + +export function printMigrationMessage(): void { + const banner = + "⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️ ⚠️"; + + warn(banner); + warn("'@rnx-kit/dep-check' has been renamed to '@rnx-kit/align-deps'!"); + warn( + "You can replace '@rnx-kit/dep-check' with '@rnx-kit/align-deps' in your 'package.json' and your configurations will be automatically upgraded." + ); + warn( + "For reasoning and more details, you can read the RFC: https://github.com/microsoft/rnx-kit/pull/1757" + ); + warn(banner); +} diff --git a/packages/dep-check/src/initialize.ts b/packages/dep-check/src/initialize.ts index 384a032bf..ca3204be0 100644 --- a/packages/dep-check/src/initialize.ts +++ b/packages/dep-check/src/initialize.ts @@ -1,6 +1,6 @@ import { readPackage } from "@rnx-kit/tools-node/package"; import { capabilitiesFor } from "./capabilities"; -import { modifyManifest } from "./helpers"; +import { modifyManifest, printMigrationMessage } from "./helpers"; import type { CapabilitiesOptions } from "./types"; export function initializeConfig( @@ -28,4 +28,6 @@ export function initializeConfig( }, }; modifyManifest(packageManifest, updatedManifest); + + printMigrationMessage(); } diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/conan/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/conan/package.json deleted file mode 100644 index 88bf75cc7..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/conan/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "conan", - "version": "1.0.0", - "dependencies": { - "t-800": "1.0.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/dutch/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/dutch/package.json deleted file mode 100644 index 3ff6ec40e..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/dutch/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "dutch", - "version": "1.0.0", - "peerDependencies": { - "react": "17.0.1", - "react-native": "0.64.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "netinfo" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/john/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/john/package.json deleted file mode 100644 index 2560a9602..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/john/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "john", - "version": "1.0.0", - "dependencies": { - "dutch": "1.0.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "storage" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/quaid/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/quaid/package.json deleted file mode 100644 index 7b57d84ed..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/quaid/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "quaid", - "version": "1.0.0", - "peerDependencies": { - "react": "17.0.1", - "react-native": "0.64.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "webview" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react-native/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react-native/package.json deleted file mode 100644 index 8d4fc8c2b..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react-native/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "react-native", - "version": "0.64.0", - "dependencies": { - "react": "17.0.1" - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react/package.json deleted file mode 100644 index e8ba83664..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/react/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "react", - "version": "17.0.1" -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/t-800/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/t-800/package.json deleted file mode 100644 index 38055faab..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/node_modules/t-800/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "t-800", - "version": "1.0.0", - "dependencies": { - "john": "1.0.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "animation", - "cyberdyne", - "skynet", - "test-app" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo-extended/package.json b/packages/dep-check/test/__fixtures__/awesome-repo-extended/package.json deleted file mode 100644 index c01cb6918..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo-extended/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "awesome-repo-extended", - "version": "1.0.0", - "dependencies": { - "conan": "1.0.0", - "quaid": "1.0.0", - "react": "17.0.1", - "react-native": "0.64.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "kitType": "app", - "capabilities": [ - "core-android", - "hermes", - "lazy-index" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/conan/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/conan/package.json deleted file mode 100644 index 88bf75cc7..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/conan/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "conan", - "version": "1.0.0", - "dependencies": { - "t-800": "1.0.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/dutch/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/dutch/package.json deleted file mode 100644 index 3ff6ec40e..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/dutch/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "dutch", - "version": "1.0.0", - "peerDependencies": { - "react": "17.0.1", - "react-native": "0.64.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "netinfo" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/john/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/john/package.json deleted file mode 100644 index 2560a9602..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/john/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "john", - "version": "1.0.0", - "dependencies": { - "dutch": "1.0.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "storage" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/quaid/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/quaid/package.json deleted file mode 100644 index 7b57d84ed..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/quaid/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "quaid", - "version": "1.0.0", - "peerDependencies": { - "react": "17.0.1", - "react-native": "0.64.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "webview" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react-native/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react-native/package.json deleted file mode 100644 index 8d4fc8c2b..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react-native/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "react-native", - "version": "0.64.0", - "dependencies": { - "react": "17.0.1" - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react/package.json deleted file mode 100644 index e8ba83664..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/react/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "react", - "version": "17.0.1" -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/t-800/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/t-800/package.json deleted file mode 100644 index dc1d1e888..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/node_modules/t-800/package.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "t-800", - "version": "1.0.0", - "dependencies": { - "john": "1.0.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios", - "animation", - "test-app" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/awesome-repo/package.json b/packages/dep-check/test/__fixtures__/awesome-repo/package.json deleted file mode 100644 index 1bea7cc75..000000000 --- a/packages/dep-check/test/__fixtures__/awesome-repo/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "awesome-repo", - "version": "1.0.0", - "dependencies": { - "conan": "1.0.0", - "quaid": "1.0.0", - "react": "17.0.1", - "react-native": "0.64.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "kitType": "app", - "capabilities": [ - "core-android", - "hermes", - "lazy-index" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/config-custom-profiles-only/packageSpecificProfiles.js b/packages/dep-check/test/__fixtures__/config-custom-profiles-only/packageSpecificProfiles.js deleted file mode 100644 index fd5d0635d..000000000 --- a/packages/dep-check/test/__fixtures__/config-custom-profiles-only/packageSpecificProfiles.js +++ /dev/null @@ -1,22 +0,0 @@ -module.exports = { - 0.64: { - core: { - name: "react-native", - version: "0.64.3", - }, - react: { - name: "react", - version: "17.0.2", - }, - }, - 0.65: { - core: { - name: "react-native", - version: "0.65.2", - }, - react: { - name: "react", - version: "17.0.2", - }, - }, -}; diff --git a/packages/dep-check/test/__fixtures__/custom-profiles/local-profiles.js b/packages/dep-check/test/__fixtures__/custom-profiles/local-profiles.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/dep-check/test/__fixtures__/custom-profiles/node_modules/custom-profiles-package/index.js b/packages/dep-check/test/__fixtures__/custom-profiles/node_modules/custom-profiles-package/index.js deleted file mode 100644 index e69de29bb..000000000 diff --git a/packages/dep-check/test/__fixtures__/custom-profiles/node_modules/custom-profiles-package/package.json b/packages/dep-check/test/__fixtures__/custom-profiles/node_modules/custom-profiles-package/package.json deleted file mode 100644 index b9d31bf36..000000000 --- a/packages/dep-check/test/__fixtures__/custom-profiles/node_modules/custom-profiles-package/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name": "custom-profiles-package", - "version": "1.0.0", - "main": "index.js" -} diff --git a/packages/dep-check/test/__fixtures__/custom-profiles/root-level-profiles.js b/packages/dep-check/test/__fixtures__/custom-profiles/root-level-profiles.js deleted file mode 100644 index a1fcec004..000000000 --- a/packages/dep-check/test/__fixtures__/custom-profiles/root-level-profiles.js +++ /dev/null @@ -1,26 +0,0 @@ -module.exports = { - format: { - name: "prettier", - version: "^2.5.1", - devOnly: true, - }, - 0.66: { - test: { - name: "jest", - version: "26.0", - devOnly: true, - }, - }, - 0.67: { - format: { - name: "prettier", - version: "3.0", - devOnly: true, - }, - test: { - name: "jest", - version: "27.0", - devOnly: true, - }, - }, -}; diff --git a/packages/dep-check/test/__fixtures__/custom-profiles/valid-profiles.js b/packages/dep-check/test/__fixtures__/custom-profiles/valid-profiles.js deleted file mode 100644 index 6a15a7ed9..000000000 --- a/packages/dep-check/test/__fixtures__/custom-profiles/valid-profiles.js +++ /dev/null @@ -1,23 +0,0 @@ -module.exports = { - 0.65: { - format: { - name: "prettier", - version: "^2.5.1", - devOnly: true, - }, - }, - 0.66: { - format: { - name: "prettier", - version: "^2.5.1", - devOnly: true, - }, - }, - 0.67: { - format: { - name: "prettier", - version: "^2.5.1", - devOnly: true, - }, - }, -}; diff --git a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/conan/package.json b/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/conan/package.json deleted file mode 100644 index a6d98f4c1..000000000 --- a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/conan/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "conan", - "version": "1.0.0", - "peerDependencies": { - "react-native": "^0.63.2 || ^0.64.2" - }, - "devDependencies": { - "react-native": "^0.63.2" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63 || ^0.64", - "capabilities": [ - "core-android", - "core-ios" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react-native/package.json b/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react-native/package.json deleted file mode 100644 index 3bef893a7..000000000 --- a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react-native/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "react-native", - "version": "0.64.2", - "dependencies": { - "react": "17.0.1" - } -} diff --git a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react/package.json b/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react/package.json deleted file mode 100644 index e8ba83664..000000000 --- a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/react/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "react", - "version": "17.0.1" -} diff --git a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/t-800/package.json b/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/t-800/package.json deleted file mode 100644 index 01d042190..000000000 --- a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/node_modules/t-800/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "t-800", - "version": "1.0.0", - "peerDependencies": { - "react-native": "^0.63.2" - }, - "devDependencies": { - "react-native": "^0.63.2" - }, - "rnx-kit": { - "reactNativeVersion": "^0.63", - "capabilities": [ - "core-android", - "core-ios" - ] - } -} diff --git a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/package.json b/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/package.json deleted file mode 100644 index 8810a65de..000000000 --- a/packages/dep-check/test/__fixtures__/no-profile-satisfying-deps/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "no-profile-satisfying-deps", - "version": "1.0.0", - "dependencies": { - "conan": "1.0.0", - "react": "17.0.1", - "react-native": "^0.64.2", - "t-800": "1.0.0" - }, - "rnx-kit": { - "reactNativeVersion": "^0.64", - "kitType": "app", - "capabilities": [ - "core-android", - "core-ios" - ] - } -} diff --git a/packages/dep-check/test/__mocks__/@rnx-kit/config.js b/packages/dep-check/test/__mocks__/@rnx-kit/config.js deleted file mode 100644 index 25cac233b..000000000 --- a/packages/dep-check/test/__mocks__/@rnx-kit/config.js +++ /dev/null @@ -1,13 +0,0 @@ -const rnxKitConfig = jest.createMockFromModule("@rnx-kit/config"); -const actualKitConfig = jest.requireActual("@rnx-kit/config"); - -let kitConfig = ""; - -rnxKitConfig.__setMockConfig = (config) => { - kitConfig = config; -}; - -rnxKitConfig.getKitCapabilities = actualKitConfig.getKitCapabilities; -rnxKitConfig.getKitConfig = () => kitConfig; - -module.exports = rnxKitConfig; diff --git a/packages/dep-check/test/__mocks__/chalk.js b/packages/dep-check/test/__mocks__/chalk.js deleted file mode 100644 index c07fae9cb..000000000 --- a/packages/dep-check/test/__mocks__/chalk.js +++ /dev/null @@ -1,16 +0,0 @@ -const chalk = jest.createMockFromModule("chalk"); - -function passthrough(s) { - return s; -} - -chalk.bold = passthrough; -chalk.cyan = passthrough; -chalk.cyan.bold = passthrough; -chalk.dim = passthrough; -chalk.green = passthrough; -chalk.red = passthrough; -chalk.red.bold = passthrough; -chalk.yellow = passthrough; - -module.exports = chalk; diff --git a/packages/dep-check/test/__mocks__/fs.js b/packages/dep-check/test/__mocks__/fs.js deleted file mode 100644 index 72c7bde33..000000000 --- a/packages/dep-check/test/__mocks__/fs.js +++ /dev/null @@ -1,19 +0,0 @@ -const fs = jest.createMockFromModule("fs"); -const actualFs = jest.requireActual("fs"); - -let data = ""; - -fs.__setMockContent = (content, space = 2) => { - data = JSON.stringify(content, undefined, space) + "\n"; -}; - -fs.__setMockFileWriter = (writer) => { - fs.writeFileSync = writer; -}; - -fs.lstatSync = (...args) => actualFs.lstatSync(...args); -fs.readFileSync = (...args) => data || actualFs.readFileSync(...args); -fs.statSync = actualFs.statSync; // used by cosmiconfig -fs.writeFileSync = undefined; - -module.exports = fs; diff --git a/packages/dep-check/test/__snapshots__/check.app.test.ts.snap b/packages/dep-check/test/__snapshots__/check.app.test.ts.snap deleted file mode 100644 index 6ff1cdcb1..000000000 --- a/packages/dep-check/test/__snapshots__/check.app.test.ts.snap +++ /dev/null @@ -1,31 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`checkPackageManifest({ kitType: 'app' }) adds required dependencies 1`] = ` -"{ - \\"name\\": \\"awesome-repo\\", - \\"version\\": \\"1.0.0\\", - \\"dependencies\\": { - \\"@react-native-async-storage/async-storage\\": \\"^1.15.8\\", - \\"@react-native-community/async-storage\\": \\"^1.12.1\\", - \\"@react-native-community/netinfo\\": \\"^6.0.2\\", - \\"conan\\": \\"1.0.0\\", - \\"hermes-engine\\": \\"~0.7.0\\", - \\"quaid\\": \\"1.0.0\\", - \\"react\\": \\"17.0.1\\", - \\"react-native\\": \\"^0.64.2\\", - \\"react-native-lazy-index\\": \\"^2.1.1\\", - \\"react-native-reanimated\\": \\"^2.1.0\\", - \\"react-native-webview\\": \\"^11.4.2\\" - }, - \\"rnx-kit\\": { - \\"reactNativeVersion\\": \\"^0.63 || ^0.64\\", - \\"kitType\\": \\"app\\", - \\"capabilities\\": [ - \\"core-android\\", - \\"hermes\\", - \\"lazy-index\\" - ] - } -} -" -`; diff --git a/packages/dep-check/test/__snapshots__/check.test.ts.snap b/packages/dep-check/test/__snapshots__/check.test.ts.snap deleted file mode 100644 index c79c98ba0..000000000 --- a/packages/dep-check/test/__snapshots__/check.test.ts.snap +++ /dev/null @@ -1,37 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`checkPackageManifest({ kitType: 'library' }) preserves indentation in 'package.json' 1`] = ` -"{ - \\"name\\": \\"@rnx-kit/dep-check\\", - \\"version\\": \\"0.0.1\\", - \\"peerDependencies\\": { - \\"react\\": \\"17.0.1\\", - \\"react-native\\": \\"^0.64.2\\" - }, - \\"devDependencies\\": { - \\"react\\": \\"17.0.1\\", - \\"react-native\\": \\"^0.64.2\\" - } -} -" -`; - -exports[`checkPackageManifest({ kitType: 'library' }) prints warnings when detecting bad packages (with version range) 1`] = ` -Array [ - Array [ - "warn", - "Known bad packages are found in '@rnx-kit/dep-check': - react-native-linear-gradient@<2.6.0: This package causes significant degradation in app start up time prior to 2.6.0.", - ], -] -`; - -exports[`checkPackageManifest({ kitType: 'library' }) prints warnings when detecting bad packages 1`] = ` -Array [ - Array [ - "warn", - "Known bad packages are found in '@rnx-kit/dep-check': - react-native-linear-gradient@<2.6.0: This package causes significant degradation in app start up time prior to 2.6.0.", - ], -] -`; diff --git a/packages/dep-check/test/__snapshots__/profiles.test.ts.snap b/packages/dep-check/test/__snapshots__/profiles.test.ts.snap deleted file mode 100644 index f1575a48f..000000000 --- a/packages/dep-check/test/__snapshots__/profiles.test.ts.snap +++ /dev/null @@ -1,112 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`loadCustomProfiles() loads valid custom profiles 1`] = ` -Object { - "0.65": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.66": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.67": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, -} -`; - -exports[`loadCustomProfiles() prepends root-level capabilities to all profiles 1`] = ` -Object { - "0.61": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.62": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.63": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.64": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.65": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.66": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - "test": Object { - "devOnly": true, - "name": "jest", - "version": "26.0", - }, - }, - "0.67": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "3.0", - }, - "test": Object { - "devOnly": true, - "name": "jest", - "version": "27.0", - }, - }, - "0.68": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.69": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, - "0.70": Object { - "format": Object { - "devOnly": true, - "name": "prettier", - "version": "^2.5.1", - }, - }, -} -`; diff --git a/packages/dep-check/test/__snapshots__/vigilant.test.ts.snap b/packages/dep-check/test/__snapshots__/vigilant.test.ts.snap deleted file mode 100644 index d45385ae7..000000000 --- a/packages/dep-check/test/__snapshots__/vigilant.test.ts.snap +++ /dev/null @@ -1,249 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`buildManifestProfile() builds a package manifest for a single profile version 1`] = ` -Object { - "dependencies": Object { - "@react-native-async-storage/async-storage": "^1.15.8", - "@react-native-clipboard/clipboard": "^1.8.3", - "@react-native-community/checkbox": "^0.5.8", - "@react-native-community/datetimepicker": "^3.4.6", - "@react-native-community/hooks": "^2.6.0", - "@react-native-community/netinfo": "^6.0.2", - "@react-native-masked-view/masked-view": "^0.2.4", - "@react-navigation/native": "^5.9.8", - "@react-navigation/stack": "^5.14.9", - "hermes-engine": "~0.7.0", - "jest": "^26.5.2", - "metro": "^0.64.0", - "metro-config": "^0.64.0", - "metro-core": "^0.64.0", - "metro-react-native-babel-preset": "^0.64.0", - "metro-react-native-babel-transformer": "^0.64.0", - "metro-resolver": "^0.64.0", - "metro-runtime": "^0.64.0", - "react": "17.0.1", - "react-dom": "17.0.1", - "react-native": "^0.64.2", - "react-native-base64": "^0.2.1", - "react-native-floating-action": "^1.21.0", - "react-native-fs": "^2.17.0", - "react-native-gesture-handler": "^1.10.3", - "react-native-lazy-index": "^2.1.1", - "react-native-macos": "^0.64.0", - "react-native-modal": "^11.10.0", - "react-native-popover-view": "^4.0.3", - "react-native-reanimated": "^2.1.0", - "react-native-render-html": "^5.1.1", - "react-native-safe-area-context": "^3.2.0", - "react-native-screens": "^3.1.1", - "react-native-shimmer": "^0.5.0", - "react-native-sqlite-storage": "^5.0.0", - "react-native-svg": "^12.1.1", - "react-native-test-app": "^0.11.4", - "react-native-webview": "^11.4.2", - "react-native-windows": "^0.64.0", - "react-test-renderer": "17.0.1", - }, - "devDependencies": Object { - "@react-native-async-storage/async-storage": "^1.15.8", - "@react-native-clipboard/clipboard": "^1.8.3", - "@react-native-community/checkbox": "^0.5.8", - "@react-native-community/datetimepicker": "^3.4.6", - "@react-native-community/hooks": "^2.6.0", - "@react-native-community/netinfo": "^6.0.2", - "@react-native-masked-view/masked-view": "^0.2.4", - "@react-navigation/native": "^5.9.8", - "@react-navigation/stack": "^5.14.9", - "hermes-engine": "~0.7.0", - "jest": "^26.5.2", - "metro": "^0.64.0", - "metro-config": "^0.64.0", - "metro-core": "^0.64.0", - "metro-react-native-babel-preset": "^0.64.0", - "metro-react-native-babel-transformer": "^0.64.0", - "metro-resolver": "^0.64.0", - "metro-runtime": "^0.64.0", - "react": "17.0.1", - "react-dom": "17.0.1", - "react-native": "^0.64.2", - "react-native-base64": "^0.2.1", - "react-native-floating-action": "^1.21.0", - "react-native-fs": "^2.17.0", - "react-native-gesture-handler": "^1.10.3", - "react-native-lazy-index": "^2.1.1", - "react-native-macos": "^0.64.0", - "react-native-modal": "^11.10.0", - "react-native-popover-view": "^4.0.3", - "react-native-reanimated": "^2.1.0", - "react-native-render-html": "^5.1.1", - "react-native-safe-area-context": "^3.2.0", - "react-native-screens": "^3.1.1", - "react-native-shimmer": "^0.5.0", - "react-native-sqlite-storage": "^5.0.0", - "react-native-svg": "^12.1.1", - "react-native-test-app": "^0.11.4", - "react-native-webview": "^11.4.2", - "react-native-windows": "^0.64.0", - "react-test-renderer": "17.0.1", - }, - "name": "@rnx-kit/dep-check", - "peerDependencies": Object { - "@react-native-async-storage/async-storage": "^1.15.8", - "@react-native-clipboard/clipboard": "^1.8.3", - "@react-native-community/checkbox": "^0.5.8", - "@react-native-community/datetimepicker": "^3.4.6", - "@react-native-community/hooks": "^2.6.0", - "@react-native-community/netinfo": "^6.0.2", - "@react-native-masked-view/masked-view": "^0.2.4", - "@react-navigation/native": "^5.9.8", - "@react-navigation/stack": "^5.14.9", - "hermes-engine": "~0.7.0", - "react": "17.0.1", - "react-dom": "17.0.1", - "react-native": "^0.64.2", - "react-native-base64": "^0.2.1", - "react-native-floating-action": "^1.21.0", - "react-native-fs": "^2.17.0", - "react-native-gesture-handler": "^1.10.3", - "react-native-lazy-index": "^2.1.1", - "react-native-macos": "^0.64.0", - "react-native-modal": "^11.10.0", - "react-native-popover-view": "^4.0.3", - "react-native-reanimated": "^2.1.0", - "react-native-render-html": "^5.1.1", - "react-native-safe-area-context": "^3.2.0", - "react-native-screens": "^3.1.1", - "react-native-shimmer": "^0.5.0", - "react-native-sqlite-storage": "^5.0.0", - "react-native-svg": "^12.1.1", - "react-native-webview": "^11.4.2", - "react-native-windows": "^0.64.0", - }, - "version": "1.0.0-test", -} -`; - -exports[`buildManifestProfile() builds a package manifest for multiple profile versions 1`] = ` -Object { - "dependencies": Object { - "@react-native-async-storage/async-storage": "^1.15.8", - "@react-native-clipboard/clipboard": "^1.8.3", - "@react-native-community/checkbox": "^0.5.8", - "@react-native-community/datetimepicker": "^3.4.6", - "@react-native-community/hooks": "^2.6.0", - "@react-native-community/netinfo": "^6.0.2", - "@react-native-masked-view/masked-view": "^0.2.4", - "@react-navigation/native": "^5.9.8", - "@react-navigation/stack": "^5.14.9", - "hermes-engine": "~0.7.0", - "jest": "^26.5.2", - "metro": "^0.64.0", - "metro-config": "^0.64.0", - "metro-core": "^0.64.0", - "metro-react-native-babel-preset": "^0.64.0", - "metro-react-native-babel-transformer": "^0.64.0", - "metro-resolver": "^0.64.0", - "metro-runtime": "^0.64.0", - "react": "17.0.1", - "react-dom": "17.0.1", - "react-native": "^0.64.2", - "react-native-base64": "^0.2.1", - "react-native-floating-action": "^1.21.0", - "react-native-fs": "^2.17.0", - "react-native-gesture-handler": "^1.10.3", - "react-native-lazy-index": "^2.1.1", - "react-native-macos": "^0.64.0", - "react-native-modal": "^11.10.0", - "react-native-popover-view": "^4.0.3", - "react-native-reanimated": "^2.1.0", - "react-native-render-html": "^5.1.1", - "react-native-safe-area-context": "^3.2.0", - "react-native-screens": "^3.1.1", - "react-native-shimmer": "^0.5.0", - "react-native-sqlite-storage": "^5.0.0", - "react-native-svg": "^12.1.1", - "react-native-test-app": "^0.11.4", - "react-native-webview": "^11.4.2", - "react-native-windows": "^0.64.0", - "react-test-renderer": "17.0.1", - }, - "devDependencies": Object { - "@react-native-async-storage/async-storage": "^1.15.8", - "@react-native-clipboard/clipboard": "^1.8.3", - "@react-native-community/checkbox": "^0.5.8", - "@react-native-community/datetimepicker": "^3.4.6", - "@react-native-community/hooks": "^2.6.0", - "@react-native-community/netinfo": "^6.0.2", - "@react-native-masked-view/masked-view": "^0.2.4", - "@react-navigation/native": "^5.9.8", - "@react-navigation/stack": "^5.14.9", - "hermes-engine": "~0.7.0", - "jest": "^26.5.2", - "metro": "^0.64.0", - "metro-config": "^0.64.0", - "metro-core": "^0.64.0", - "metro-react-native-babel-preset": "^0.64.0", - "metro-react-native-babel-transformer": "^0.64.0", - "metro-resolver": "^0.64.0", - "metro-runtime": "^0.64.0", - "react": "17.0.1", - "react-dom": "17.0.1", - "react-native": "^0.64.2", - "react-native-base64": "^0.2.1", - "react-native-floating-action": "^1.21.0", - "react-native-fs": "^2.17.0", - "react-native-gesture-handler": "^1.10.3", - "react-native-lazy-index": "^2.1.1", - "react-native-macos": "^0.64.0", - "react-native-modal": "^11.10.0", - "react-native-popover-view": "^4.0.3", - "react-native-reanimated": "^2.1.0", - "react-native-render-html": "^5.1.1", - "react-native-safe-area-context": "^3.2.0", - "react-native-screens": "^3.1.1", - "react-native-shimmer": "^0.5.0", - "react-native-sqlite-storage": "^5.0.0", - "react-native-svg": "^12.1.1", - "react-native-test-app": "^0.11.4", - "react-native-webview": "^11.4.2", - "react-native-windows": "^0.64.0", - "react-test-renderer": "17.0.1", - }, - "name": "@rnx-kit/dep-check", - "peerDependencies": Object { - "@react-native-async-storage/async-storage": "^1.15.8", - "@react-native-clipboard/clipboard": "^1.8.3", - "@react-native-community/async-storage": "^1.12.1", - "@react-native-community/checkbox": "^0.5.7 || ^0.5.8", - "@react-native-community/clipboard": "^1.5.1", - "@react-native-community/datetimepicker": "^3.0.9 || ^3.4.6", - "@react-native-community/hooks": "^2.6.0", - "@react-native-community/netinfo": "^5.9.10 || ^6.0.2", - "@react-native-masked-view/masked-view": "^0.2.4", - "@react-navigation/native": "^5.9.4 || ^5.9.8", - "@react-navigation/stack": "^5.14.4 || ^5.14.9", - "hermes-engine": "~0.5.0 || ~0.7.0", - "react": "16.13.1 || 17.0.1", - "react-dom": "16.13.1 || 17.0.1", - "react-native": "^0.63.2 || ^0.64.2", - "react-native-base64": "^0.2.1", - "react-native-floating-action": "^1.21.0", - "react-native-fs": "^2.16.6 || ^2.17.0", - "react-native-gesture-handler": "^1.10.3", - "react-native-lazy-index": "^2.1.1", - "react-native-macos": "^0.63.0 || ^0.64.0", - "react-native-modal": "^11.5.6 || ^11.10.0", - "react-native-popover-view": "^3.1.1 || ^4.0.3", - "react-native-reanimated": "^1.13.3 || ^2.1.0", - "react-native-render-html": "^5.1.0 || ^5.1.1", - "react-native-safe-area-context": "^3.2.0", - "react-native-screens": "^2.18.1 || ^3.1.1", - "react-native-shimmer": "^0.5.0", - "react-native-sqlite-storage": "^3.3.11 || ^5.0.0", - "react-native-svg": "^12.1.1", - "react-native-webview": "^11.4.2", - "react-native-windows": "^0.63.0 || ^0.64.0", - }, - "version": "1.0.0-test", -} -`; diff --git a/packages/dep-check/test/capabilities.test.ts b/packages/dep-check/test/capabilities.test.ts deleted file mode 100644 index b7af4d7fe..000000000 --- a/packages/dep-check/test/capabilities.test.ts +++ /dev/null @@ -1,276 +0,0 @@ -import type { Capability } from "@rnx-kit/config"; -import { capabilitiesFor, resolveCapabilities } from "../src/capabilities"; -import profile_0_62 from "../src/presets/microsoft/profile-0.62"; -import profile_0_63 from "../src/presets/microsoft/profile-0.63"; -import profile_0_64 from "../src/presets/microsoft/profile-0.64"; -import { getProfilesFor } from "../src/profiles"; -import { pickPackage } from "./helpers"; - -describe("capabilitiesFor()", () => { - test("returns `undefined` when react-native is not a dependency", () => { - expect( - capabilitiesFor({ name: "@rnx-kit/dep-check", version: "1.0.0" }) - ).toBeUndefined(); - expect( - capabilitiesFor({ - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - react: "^17.0.1", - }, - }) - ).toBeUndefined(); - }); - - test("returns capabilities when react-native is under dependencies", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "react-native": "^0.64.1", - }, - }; - expect(capabilitiesFor(manifest)).toEqual({ - reactNativeVersion: "^0.64", - reactNativeDevVersion: "0.64.0", - kitType: "library", - capabilities: ["core", "core-android", "core-ios"], - }); - }); - - test("returns capabilities when react-native is under peerDependencies", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - peerDependencies: { - "react-native": "^0.64.1", - }, - }; - expect(capabilitiesFor(manifest)).toEqual({ - reactNativeVersion: "^0.64", - reactNativeDevVersion: "0.64.0", - kitType: "library", - capabilities: ["core", "core-android", "core-ios"], - }); - }); - - test("returns capabilities when react-native is under devDependencies", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - devDependencies: { - "react-native": "^0.64.1", - }, - }; - expect(capabilitiesFor(manifest)).toEqual({ - reactNativeVersion: "^0.64", - reactNativeDevVersion: "^0.64.1", - kitType: "library", - capabilities: ["core", "core-android", "core-ios"], - }); - }); - - test("returns kit config with app type instead of dev version", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - peerDependencies: { - "react-native": "^0.64.1", - }, - }; - expect(capabilitiesFor(manifest, { kitType: "app" })).toEqual({ - reactNativeVersion: "^0.64", - kitType: "app", - capabilities: ["core", "core-android", "core-ios"], - }); - }); - - test("ignores packages that are not managed by dep-check", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - peerDependencies: { - react: "17.0.1", - "react-native": "^0.64.1", - }, - devDependencies: { - "@rnx-kit/babel-preset-metro-react-native": "*", - "@rnx-kit/cli": "*", - }, - }; - expect(capabilitiesFor(manifest, { kitType: "app" })).toEqual({ - reactNativeVersion: "^0.64", - kitType: "app", - capabilities: ["core", "core-android", "core-ios", "react"], - }); - }); -}); - -describe("resolveCapabilities()", () => { - const consoleWarnSpy = jest.spyOn(global.console, "warn"); - - beforeEach(() => { - consoleWarnSpy.mockReset(); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - test("dedupes packages", () => { - const packages = resolveCapabilities( - ["core", "core", "test-app"], - [profile_0_64] - ); - - const { name } = profile_0_64["core"]; - const { name: reactName } = profile_0_64["react"]; - const { name: testAppName } = profile_0_64["test-app"]; - expect(packages).toEqual({ - [name]: [profile_0_64["core"]], - [reactName]: [profile_0_64["react"]], - [testAppName]: [profile_0_64["test-app"]], - }); - - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("dedupes package versions", () => { - const packages = resolveCapabilities( - ["webview"], - [profile_0_62, profile_0_63, profile_0_64] - ); - - const { name } = profile_0_64["webview"]; - expect(packages).toEqual({ - [name]: [profile_0_62["webview"], profile_0_64["webview"]], - }); - - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("ignores missing/unknown capabilities", () => { - const packages = resolveCapabilities( - ["skynet" as Capability, "svg"], - [profile_0_62, profile_0_63, profile_0_64] - ); - - const { name } = profile_0_64["svg"]; - expect(packages).toEqual({ [name]: [profile_0_64["svg"]] }); - expect(consoleWarnSpy).toBeCalledTimes(1); - }); - - test("resolves custom capabilities", () => { - const skynet = { name: "skynet", version: "1.0.0" }; - jest.mock( - "mock-custom-profiles-module", - () => ({ "0.62": { [skynet.name]: skynet } }), - { virtual: true } - ); - - const profiles = getProfilesFor( - "^0.62 || ^0.63 || ^0.64", - "mock-custom-profiles-module" - ); - - const packages = resolveCapabilities( - ["skynet" as Capability, "svg"], - profiles - ); - - const { name } = profile_0_64["svg"]; - expect(packages).toEqual({ - [name]: [profile_0_64["svg"]], - [skynet.name]: [skynet], - }); - }); - - test("resolves capabilities required by capabilities", () => { - const packages = resolveCapabilities( - ["core-windows"], - [profile_0_63, profile_0_64] - ); - - expect(packages).toEqual({ - react: [ - pickPackage(profile_0_63, "react"), - pickPackage(profile_0_64, "react"), - ], - "react-native": [ - pickPackage(profile_0_63, "core"), - pickPackage(profile_0_64, "core"), - ], - "react-native-windows": [ - pickPackage(profile_0_63, "core-windows"), - pickPackage(profile_0_64, "core-windows"), - ], - }); - - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("resolves meta packages", () => { - jest.mock( - "mock-meta-package", - () => ({ - "0.64": { - "core/all": { - name: "#meta", - capabilities: [ - "core-android", - "core-ios", - "core-macos", - "core-windows", - ], - }, - }, - }), - { virtual: true } - ); - - const packages = resolveCapabilities( - ["core/all" as Capability], - getProfilesFor("^0.64", "mock-meta-package") - ); - - expect(packages).toEqual({ - react: [pickPackage(profile_0_64, "react")], - "react-native": [pickPackage(profile_0_64, "core")], - "react-native-macos": [pickPackage(profile_0_64, "core-macos")], - "react-native-windows": [pickPackage(profile_0_64, "core-windows")], - }); - }); - - test("resolves meta packages with loops", () => { - jest.mock( - "mock-meta-package-loop", - () => ({ - "0.64": { - connor: { - name: "#meta", - capabilities: ["core", "reese"], - }, - reese: { - name: "#meta", - capabilities: ["t-800"], - }, - "t-800": { - name: "#meta", - capabilities: ["connor"], - }, - }, - }), - { virtual: true } - ); - - const packages = resolveCapabilities( - ["reese" as Capability], - getProfilesFor("^0.64", "mock-meta-package-loop") - ); - - expect(packages).toEqual({ - react: [pickPackage(profile_0_64, "react")], - "react-native": [pickPackage(profile_0_64, "core")], - }); - }); -}); diff --git a/packages/dep-check/test/check.app.test.ts b/packages/dep-check/test/check.app.test.ts deleted file mode 100644 index 97007b835..000000000 --- a/packages/dep-check/test/check.app.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import path from "path"; -import { checkPackageManifest } from "../src/check"; - -jest.mock("fs"); -jest.unmock("@rnx-kit/config"); - -function fixturePath(name: string) { - return path.join(process.cwd(), "test", "__fixtures__", name); -} - -describe("checkPackageManifest({ kitType: 'app' })", () => { - const fs = require("fs"); - const consoleWarnSpy = jest.spyOn(global.console, "warn"); - - beforeEach(() => { - consoleWarnSpy.mockReset(); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - test("adds required dependencies", () => { - const manifestPath = path.join(fixturePath("awesome-repo"), "package.json"); - - let destination = ""; - let updatedManifest = ""; - fs.__setMockFileWriter((dest, content) => { - destination = dest; - updatedManifest = content; - }); - - expect( - checkPackageManifest(manifestPath, { loose: false, write: true }) - ).toBe(0); - expect(consoleWarnSpy).not.toBeCalled(); - expect(destination).toBe(manifestPath); - expect(updatedManifest).toMatchSnapshot(); - }); -}); diff --git a/packages/dep-check/test/check.test.ts b/packages/dep-check/test/check.test.ts deleted file mode 100644 index 6f45426c3..000000000 --- a/packages/dep-check/test/check.test.ts +++ /dev/null @@ -1,359 +0,0 @@ -import semverCoerce from "semver/functions/coerce"; -import { checkPackageManifest, getCheckConfig } from "../src/check"; -import profile_0_62 from "../src/presets/microsoft/profile-0.62"; -import profile_0_63 from "../src/presets/microsoft/profile-0.63"; -import profile_0_64 from "../src/presets/microsoft/profile-0.64"; -import { packageVersion } from "./helpers"; - -jest.mock("fs"); - -describe("checkPackageManifest({ kitType: 'library' })", () => { - const rnxKitConfig = require("@rnx-kit/config"); - const fs = require("fs"); - - const consoleErrorSpy = jest.spyOn(global.console, "error"); - const consoleLogSpy = jest.spyOn(global.console, "log"); - const consoleWarnSpy = jest.spyOn(global.console, "warn"); - - const defaultOptions = { loose: false, write: false }; - - const mockManifest = { - name: "@rnx-kit/dep-check", - version: "0.0.1", - }; - - const react_v62_v63_v64 = [ - packageVersion(profile_0_62, "react"), - packageVersion(profile_0_63, "react"), - packageVersion(profile_0_64, "react"), - ].join(" || "); - - const v62_v63_v64 = [ - packageVersion(profile_0_62, "core"), - packageVersion(profile_0_63, "core"), - packageVersion(profile_0_64, "core"), - ].join(" || "); - - beforeEach(() => { - consoleErrorSpy.mockReset(); - consoleLogSpy.mockReset(); - consoleWarnSpy.mockReset(); - fs.__setMockContent({}); - rnxKitConfig.__setMockConfig(); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - test("returns error code when reading invalid manifests", () => { - expect(checkPackageManifest("package.json", defaultOptions)).not.toBe(0); - expect(consoleErrorSpy).toBeCalledTimes(1); - }); - - test("returns early if 'rnx-kit' is missing from the manifest", () => { - fs.__setMockContent({ - ...mockManifest, - dependencies: { "react-native-linear-gradient": "0.0.0" }, - }); - - const options = { ...defaultOptions, uncheckedReturnCode: -1 }; - expect(checkPackageManifest("package.json", options)).toBe(-1); - expect(consoleWarnSpy).toBeCalled(); - }); - - test("prints warnings when detecting bad packages", () => { - fs.__setMockContent({ - ...mockManifest, - dependencies: { "react-native-linear-gradient": "0.0.0" }, - peerDependencies: { - "react-native": profile_0_64["core"], - }, - devDependencies: { - "react-native": profile_0_64["core"], - }, - }); - rnxKitConfig.__setMockConfig({ reactNativeVersion: "0.64.0" }); - - expect(checkPackageManifest("package.json", defaultOptions)).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy.mock.calls).toMatchSnapshot(); - }); - - test("prints warnings when detecting bad packages (with version range)", () => { - fs.__setMockContent({ - ...mockManifest, - dependencies: { "react-native-linear-gradient": "0.0.0" }, - }); - rnxKitConfig.__setMockConfig({ reactNativeVersion: "^0.63.0 || ^0.64.0" }); - - expect(checkPackageManifest("package.json", defaultOptions)).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy.mock.calls).toMatchSnapshot(); - }); - - test("returns early if no capabilities are defined", () => { - fs.__setMockContent(mockManifest); - rnxKitConfig.__setMockConfig({ reactNativeVersion: "0.64.0" }); - - expect(checkPackageManifest("package.json", defaultOptions)).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("returns if no changes are needed", () => { - fs.__setMockContent({ - ...mockManifest, - peerDependencies: { - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }, - devDependencies: { - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }, - }); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "0.64.0", - capabilities: ["core-ios"], - }); - - expect(checkPackageManifest("package.json", defaultOptions)).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleLogSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("returns if no changes are needed (write: true)", () => { - let didWriteToPath = false; - - fs.__setMockContent({ - ...mockManifest, - peerDependencies: { - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }, - devDependencies: { - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }, - }); - fs.__setMockFileWriter((p, _content) => { - didWriteToPath = p; - }); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "0.64.0", - capabilities: ["core-ios"], - }); - - expect( - checkPackageManifest("package.json", { loose: false, write: true }) - ).toBe(0); - expect(didWriteToPath).toBe(false); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleLogSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("returns error code if changes are needed", () => { - fs.__setMockContent(mockManifest); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "0.64.0", - capabilities: ["core-ios"], - }); - - expect(checkPackageManifest("package.json", defaultOptions)).not.toBe(0); - expect(consoleErrorSpy).toBeCalledTimes(1); - expect(consoleWarnSpy).not.toBeCalled(); - expect(consoleLogSpy).toBeCalledTimes(2); - }); - - test("writes changes back to 'package.json'", () => { - let didWriteToPath = false; - - fs.__setMockContent(mockManifest); - fs.__setMockFileWriter((p, _content) => { - didWriteToPath = p; - }); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "0.64.0", - capabilities: ["core-ios"], - }); - - expect( - checkPackageManifest("package.json", { loose: false, write: true }) - ).toBe(0); - expect(didWriteToPath).toBe("package.json"); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - expect(consoleLogSpy).not.toBeCalled(); - }); - - test("preserves indentation in 'package.json'", () => { - let output = ""; - - fs.__setMockContent(mockManifest, "\t"); - fs.__setMockFileWriter((_, content) => { - output = content; - }); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "0.64.0", - capabilities: ["core-ios"], - }); - - expect( - checkPackageManifest("package.json", { loose: false, write: true }) - ).toBe(0); - expect(output).toMatchSnapshot(); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - expect(consoleLogSpy).not.toBeCalled(); - }); - - test("uses minimum supported version as development version", () => { - fs.__setMockContent({ - ...mockManifest, - peerDependencies: { - react: react_v62_v63_v64, - "react-native": v62_v63_v64, - }, - devDependencies: { - react: packageVersion(profile_0_62, "react"), - "react-native": packageVersion(profile_0_62, "core"), - }, - }); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "^0.62 || ^0.63 || ^0.64", - capabilities: ["core-ios"], - }); - - expect(checkPackageManifest("package.json", defaultOptions)).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleLogSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("uses declared development version", () => { - fs.__setMockContent({ - ...mockManifest, - peerDependencies: { - react: react_v62_v63_v64, - "react-native": v62_v63_v64, - }, - devDependencies: { - react: packageVersion(profile_0_63, "react"), - "react-native": packageVersion(profile_0_63, "core"), - }, - }); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "^0.62 || ^0.63 || ^0.64", - reactNativeDevVersion: "0.63.4", - capabilities: ["core-ios"], - }); - - expect(checkPackageManifest("package.json", defaultOptions)).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleLogSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("handles development version ranges", () => { - fs.__setMockContent({ - ...mockManifest, - peerDependencies: { - react: react_v62_v63_v64, - "react-native": v62_v63_v64, - }, - devDependencies: { - react: packageVersion(profile_0_63, "react"), - "react-native": packageVersion(profile_0_63, "core"), - }, - }); - rnxKitConfig.__setMockConfig({ - reactNativeVersion: "^0.62 || ^0.63 || ^0.64", - reactNativeDevVersion: "^0.63.4", - capabilities: ["core-ios"], - }); - - expect(checkPackageManifest("package.json", defaultOptions)).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleLogSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); -}); - -describe("getCheckConfig", () => { - const rnxKitConfig = require("@rnx-kit/config"); - const fs = require("fs"); - - const mockManifest = { - name: "@rnx-kit/dep-check", - version: "0.0.1", - }; - - const defaultOptions = { loose: false, write: false }; - - beforeEach(() => { - fs.__setMockContent(mockManifest); - rnxKitConfig.__setMockConfig(); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - test("returns early if the package is unconfigured", () => { - expect(getCheckConfig("package.json", defaultOptions)).toBe(0); - }); - - test("returns default values given react-native version", () => { - const reactNativeVersion = "^0.64"; - rnxKitConfig.__setMockConfig({ reactNativeVersion }); - - expect(getCheckConfig("package.json", defaultOptions)).toEqual({ - capabilities: [], - kitType: "library", - manifest: mockManifest, - reactNativeVersion, - reactNativeDevVersion: semverCoerce(reactNativeVersion).version, - }); - }); - - test("uses react-native version provided by vigilant flag if unspecified", () => { - const reactNativeVersion = "^0.64"; - rnxKitConfig.__setMockConfig({ customProfiles: "" }); - - expect( - getCheckConfig("package.json", { - ...defaultOptions, - supportedVersions: reactNativeVersion, - targetVersion: reactNativeVersion, - }) - ).toEqual({ - capabilities: [], - kitType: "library", - manifest: mockManifest, - reactNativeVersion, - reactNativeDevVersion: reactNativeVersion, - }); - }); - - test("does not overwrite existing config with the version provided by vigilant flag", () => { - const reactNativeVersion = "^0.64"; - rnxKitConfig.__setMockConfig({ reactNativeVersion }); - - expect( - getCheckConfig("package.json", { - ...defaultOptions, - supportedVersions: "1000.0", - targetVersion: "1000.0", - }) - ).toEqual({ - capabilities: [], - kitType: "library", - manifest: mockManifest, - reactNativeVersion, - reactNativeDevVersion: semverCoerce(reactNativeVersion).version, - }); - }); -}); diff --git a/packages/dep-check/test/dependencies.test.ts b/packages/dep-check/test/dependencies.test.ts deleted file mode 100644 index ba1c9e4f2..000000000 --- a/packages/dep-check/test/dependencies.test.ts +++ /dev/null @@ -1,239 +0,0 @@ -import { PackageManifest, readPackage } from "@rnx-kit/tools-node/package"; -import path from "path"; -import { getRequirements, visitDependencies } from "../src/dependencies"; - -jest.unmock("@rnx-kit/config"); - -function fixturePath(name: string) { - return path.join(process.cwd(), "test", "__fixtures__", name); -} - -function useFixture(name: string): [string, PackageManifest] { - const fixture = fixturePath(name); - return [fixture, readPackage(fixture)]; -} - -describe("visitDependencies()", () => { - const consoleWarnSpy = jest.spyOn(global.console, "warn"); - const currentWorkingDir = process.cwd(); - - beforeEach(() => { - consoleWarnSpy.mockReset(); - }); - - afterEach(() => { - process.chdir(currentWorkingDir); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - test("returns if there are no direct dependencies", () => { - const visited = new Set(); - - visitDependencies( - { name: "@rnx-kit/dep-check", version: "1.0.0" }, - process.cwd(), - () => 0, - visited - ); - expect(visited.size).toBe(0); - - const dependencies = { "react-native": "1000.0.0" }; - - visitDependencies( - { - name: "@rnx-kit/dep-check", - version: "1.0.0", - peerDependencies: dependencies, - devDependencies: dependencies, - }, - process.cwd(), - () => 0, - visited - ); - expect(visited.size).toBe(0); - - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("traverse transitive dependencies", () => { - const fixture = fixturePath("awesome-repo"); - process.chdir(fixture); - - const visited: string[] = []; - visitDependencies( - require(path.join(fixture, "package.json")), - process.cwd(), - (module) => { - visited.push(module); - } - ); - - expect(visited.sort()).toEqual([ - "conan", - "dutch", - "john", - "quaid", - "react", - "react-native", - "t-800", - ]); - - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("skips unresolved packages", () => { - const visited: string[] = []; - visitDependencies( - { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "this-does-not-exist": "1.0.0", - }, - }, - process.cwd(), - (module) => visited.push(module) - ); - - expect(visited.length).toBe(0); - expect(consoleWarnSpy).toBeCalledTimes(1); - }); -}); - -describe("getRequirements()", () => { - const consoleErrorSpy = jest.spyOn(global.console, "error"); - const consoleWarnSpy = jest.spyOn(global.console, "warn"); - const defaultOptions = { loose: false }; - - afterEach(() => { - consoleErrorSpy.mockReset(); - consoleWarnSpy.mockReset(); - }); - - test("gets requirements from all dependencies", () => { - const [fixture, manifest] = useFixture("awesome-repo"); - const { reactNativeVersion, capabilities } = getRequirements( - "^0.63 || ^0.64", - "app", - manifest, - fixture, - undefined, - defaultOptions - ); - - expect(reactNativeVersion).toBe("^0.63 || ^0.64"); - - expect(capabilities.sort()).toEqual([ - "animation", - "netinfo", - "storage", - "webview", - ]); - - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("gets requirements from all dependencies with custom profiles", () => { - const cyberdyne = { name: "cyberdyne", version: "1.0.0", devOnly: true }; - const skynet = { name: "skynet", version: "1.0.0" }; - jest.mock( - "awesome-dep-check-profiles", - () => ({ - "0.63": { - [cyberdyne.name]: cyberdyne, - [skynet.name]: skynet, - }, - "0.64": { - [cyberdyne.name]: cyberdyne, - [skynet.name]: skynet, - }, - }), - { virtual: true } - ); - - const [fixture, manifest] = useFixture("awesome-repo-extended"); - const { reactNativeVersion, capabilities } = getRequirements( - "^0.63 || ^0.64", - "app", - manifest, - fixture, - "awesome-dep-check-profiles", - defaultOptions - ); - - expect(reactNativeVersion).toBe("^0.63 || ^0.64"); - - expect(capabilities.sort()).toEqual([ - "animation", - "netinfo", - "skynet", - "storage", - "webview", - ]); - - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("throws if no profiles can satisfy required React Native version", () => { - expect(() => - getRequirements( - "0.60.6", - "app", - { - name: "@rnx-kit/dep-check", - version: "1.0.0", - }, - "", - undefined, - defaultOptions - ) - ).toThrow(); - - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("throws if no profiles can satisfy requirement of dependencies", () => { - const [fixture, manifest] = useFixture("no-profile-satisfying-deps"); - expect(() => - getRequirements( - "^0.64", - "app", - manifest, - fixture, - undefined, - defaultOptions - ) - ).toThrowError("No React Native profile could satisfy all dependencies"); - - expect(consoleErrorSpy).toBeCalledWith( - "error", - expect.stringContaining( - "No React Native profile could satisfy all dependencies" - ) - ); - expect(consoleWarnSpy).not.toBeCalled(); - }); - - test("does not throw if no profiles can satisfy requirement of dependencies in loose mode", () => { - const [fixture, manifest] = useFixture("no-profile-satisfying-deps"); - expect(() => - getRequirements("^0.64", "app", manifest, fixture, undefined, { - loose: true, - }) - ).not.toThrow(); - - expect(consoleErrorSpy).not.toBeCalled(); - expect(consoleWarnSpy).toBeCalledWith( - "warn", - expect.stringContaining( - "No React Native profile could satisfy all dependencies" - ) - ); - }); -}); diff --git a/packages/dep-check/test/findBadPackages.test.ts b/packages/dep-check/test/findBadPackages.test.ts deleted file mode 100644 index d027c691f..000000000 --- a/packages/dep-check/test/findBadPackages.test.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { findBadPackages } from "../src/findBadPackages"; - -describe("findBadPackages()", () => { - const dependenciesWithOneBadPackage = { - "react-native": "0.0.0", - "react-native-linear-gradient": "0.0.0", - }; - - const dependenciesWithMoreBadPackages = { - "react-native": "0.0.0", - "react-native-linear-gradient": "0.0.0", - "react-native-netinfo": "0.0.0", - }; - - test("finds bad packages in all dependencies", () => { - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - }) - ).toBeUndefined(); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - dependencies: dependenciesWithOneBadPackage, - })?.length - ).toBe(1); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - peerDependencies: dependenciesWithOneBadPackage, - })?.length - ).toBe(1); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - devDependencies: dependenciesWithOneBadPackage, - })?.length - ).toBe(1); - }); - - test("dedupes bad packages", () => { - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - dependencies: dependenciesWithOneBadPackage, - peerDependencies: dependenciesWithOneBadPackage, - })?.length - ).toBe(1); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - dependencies: dependenciesWithOneBadPackage, - devDependencies: dependenciesWithOneBadPackage, - })?.length - ).toBe(1); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - peerDependencies: dependenciesWithOneBadPackage, - devDependencies: dependenciesWithOneBadPackage, - })?.length - ).toBe(1); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - dependencies: dependenciesWithOneBadPackage, - peerDependencies: dependenciesWithOneBadPackage, - devDependencies: dependenciesWithOneBadPackage, - })?.length - ).toBe(1); - }); - - test("finds all bad packages", () => { - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - dependencies: dependenciesWithMoreBadPackages, - })?.length - ).toBe(2); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - dependencies: dependenciesWithOneBadPackage, - peerDependencies: dependenciesWithMoreBadPackages, - })?.length - ).toBe(2); - - expect( - findBadPackages({ - name: "Test", - version: "0.0.1", - dependencies: dependenciesWithOneBadPackage, - peerDependencies: dependenciesWithMoreBadPackages, - devDependencies: dependenciesWithMoreBadPackages, - })?.length - ).toBe(2); - }); -}); diff --git a/packages/dep-check/test/helpers.test.ts b/packages/dep-check/test/helpers.test.ts deleted file mode 100644 index 1136897e3..000000000 --- a/packages/dep-check/test/helpers.test.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { compare } from "../src/helpers"; - -describe("compare", () => { - test("compares values", () => { - expect(compare(0, 0)).toBe(0); - expect(compare(0, 1)).toBe(-1); - expect(compare(1, 0)).toBe(1); - - expect(compare("dutch", "dutch")).toBe(0); - expect(compare("dutch", "quaid")).toBe(-1); - expect(compare("quaid", "dutch")).toBe(1); - expect(compare("dutch", "dutchess")).toBe(-1); - expect(compare("dutchess", "dutch")).toBe(1); - - expect(compare("hyphen-before-lowbar", "hyphen_before_lowbar")).toBe(-1); - }); -}); diff --git a/packages/dep-check/test/helpers.ts b/packages/dep-check/test/helpers.ts deleted file mode 100644 index cbecacf00..000000000 --- a/packages/dep-check/test/helpers.ts +++ /dev/null @@ -1,20 +0,0 @@ -import type { Capability } from "@rnx-kit/config"; -import type { Profile, Package } from "../src/types"; - -export function pickPackage(profile: Profile, capability: string): Package { - const pkg = profile[capability]; - if (!pkg) { - throw new Error(`Could not resolve '${capability}'`); - } else if (!("version" in pkg)) { - throw new Error(`'${capability}' is a meta package`); - } - - return pkg; -} - -export function packageVersion( - profile: Profile, - capability: Capability -): string { - return pickPackage(profile, capability).version; -} diff --git a/packages/dep-check/test/initialize.test.ts b/packages/dep-check/test/initialize.test.ts deleted file mode 100644 index 5a5d2fedd..000000000 --- a/packages/dep-check/test/initialize.test.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { initializeConfig } from "../src/initialize"; - -jest.mock("fs"); - -describe("initializeConfig()", () => { - const fs = require("fs"); - - const bundle = { - entryPath: "src/index.ts", - distPath: "dist", - assetsPath: "dist", - bundlePrefix: "main", - targets: ["ios", "android", "macos", "windows"], - platforms: { - android: { - assetsPath: "dist/res", - }, - }, - }; - - const mockManifest = { - dependencies: { - "react-native": "^0.64.1", - }, - peerDependencies: { - "@react-native-community/netinfo": "^5.9.10", - "react-native-webview": "^10.10.2", - }, - "rnx-kit": { - bundle, - }, - }; - - const mockCapabilities = [ - "core", - "core-android", - "core-ios", - "netinfo", - "webview", - ]; - - beforeEach(() => { - const unset = () => { - throw new Error("unset"); - }; - fs.__setMockContent(unset); - fs.__setMockFileWriter(unset); - }); - - test("returns early if capabilities are declared", () => { - fs.__setMockContent({ "rnx-kit": { capabilities: [] } }); - - let didWrite = false; - fs.__setMockFileWriter(() => { - didWrite = true; - }); - - initializeConfig("package.json", {}); - expect(didWrite).toBe(false); - }); - - test("returns early if no capabilities are found", () => { - fs.__setMockContent({ name: "@rnx-kit/dep-check", version: "1.0.0-test" }); - - let didWrite = false; - fs.__setMockFileWriter(() => { - didWrite = true; - }); - - initializeConfig("package.json", {}); - expect(didWrite).toBe(false); - }); - - test("keeps existing config", () => { - fs.__setMockContent({ - dependencies: { - "react-native": "^0.64.1", - }, - "rnx-kit": { - platformBundle: false, - bundle, - }, - }); - - let content = {}; - fs.__setMockFileWriter((_: string, data: string) => { - content = JSON.parse(data); - }); - - initializeConfig("package.json", {}); - - const kitConfig = content["rnx-kit"]; - if (!kitConfig) { - fail(); - } - - expect(kitConfig["platformBundle"]).toBe(false); - expect(kitConfig["bundle"]).toEqual(bundle); - }); - - test('adds config with type "app"', () => { - fs.__setMockContent(mockManifest); - - let content = {}; - fs.__setMockFileWriter((_: string, data: string) => { - content = JSON.parse(data); - }); - - initializeConfig("package.json", { kitType: "app" }); - - const kitConfig = content["rnx-kit"]; - if (!kitConfig) { - fail(); - } - - expect(kitConfig["bundle"]).toEqual(bundle); - expect(kitConfig["reactNativeVersion"]).toEqual("^0.64"); - expect(kitConfig["reactNativeDevVersion"]).toBeUndefined(); - expect(kitConfig["kitType"]).toEqual("app"); - expect(kitConfig["capabilities"]).toEqual(mockCapabilities); - expect(kitConfig["customProfiles"]).toBeUndefined(); - }); - - test('adds config with type "library"', () => { - fs.__setMockContent(mockManifest); - - let content = {}; - fs.__setMockFileWriter((_: string, data: string) => { - content = JSON.parse(data); - }); - - initializeConfig("package.json", { kitType: "library" }); - - const kitConfig = content["rnx-kit"]; - if (!kitConfig) { - fail(); - } - - expect(kitConfig["bundle"]).toEqual(bundle); - expect(kitConfig["reactNativeVersion"]).toEqual("^0.64"); - expect(kitConfig["reactNativeDevVersion"]).toEqual("0.64.0"); - expect(kitConfig["kitType"]).toEqual("library"); - expect(kitConfig["capabilities"]).toEqual(mockCapabilities); - expect(kitConfig["customProfiles"]).toBeUndefined(); - }); - - // Test disabled because custom profile now depends on align-deps - xtest("adds config with custom profiles", () => { - fs.__setMockContent(mockManifest); - - let content = {}; - fs.__setMockFileWriter((_: string, data: string) => { - content = JSON.parse(data); - }); - - initializeConfig("package.json", { - kitType: "library", - customProfilesPath: "@rnx-kit/scripts/align-deps-preset.js", - }); - - const kitConfig = content["rnx-kit"]; - if (!kitConfig) { - fail(); - } - - expect(kitConfig["customProfiles"]).toEqual( - "@rnx-kit/scripts/align-deps-preset.js" - ); - }); -}); diff --git a/packages/dep-check/test/manifest.test.ts b/packages/dep-check/test/manifest.test.ts deleted file mode 100644 index f74b4a367..000000000 --- a/packages/dep-check/test/manifest.test.ts +++ /dev/null @@ -1,312 +0,0 @@ -import { - removeKeys, - updateDependencies, - updatePackageManifest, -} from "../src/manifest"; -import profile_0_63 from "../src/presets/microsoft/profile-0.63"; -import profile_0_64 from "../src/presets/microsoft/profile-0.64"; -import type { Package } from "../src/types"; -import { packageVersion, pickPackage } from "./helpers"; - -const mockDependencies = { - typescript: "0.0.0", - react: "0.0.0", - "react-native-test-app": "0.0.0", - "react-native": "0.0.0", -}; - -describe("removeKeys()", () => { - test("returns a new copy of object with specified keys removed", () => { - const original = { x: "1", y: "2", z: "3" }; - const originalKeys = Object.keys(original); - const modified = removeKeys(original, ["x", "z"]); - expect(modified).not.toBe(original); - expect(Object.keys(original)).toEqual(originalKeys); - expect(modified).toEqual({ y: original.y }); - }); - - test("returns a new copy of object even if no keys are removed", () => { - const original = { x: "1", y: "2", z: "3" }; - const originalKeys = Object.keys(original); - const modified = removeKeys(original, ["a", "b"]); - expect(modified).not.toBe(original); - expect(Object.keys(original)).toEqual(originalKeys); - expect(modified).toEqual(original); - }); - - test("handles undefined objects", () => { - expect(removeKeys(undefined, ["x", "y"])).toBeUndefined(); - }); -}); - -describe("updateDependencies()", () => { - const resolvedPackages: Record = { - react: [ - pickPackage(profile_0_63, "react"), - pickPackage(profile_0_64, "react"), - ], - "react-native": [ - pickPackage(profile_0_63, "core"), - pickPackage(profile_0_64, "core"), - ], - "react-native-macos": [ - pickPackage(profile_0_63, "core-macos"), - pickPackage(profile_0_64, "core-macos"), - ], - "react-native-test-app": [pickPackage(profile_0_64, "test-app")], - "react-native-windows": [ - pickPackage(profile_0_63, "core-windows"), - pickPackage(profile_0_64, "core-windows"), - ], - }; - - test("bumps dependencies to maximum supported version", () => { - const updated = updateDependencies( - mockDependencies, - resolvedPackages, - "direct" - ); - expect(updated).toEqual({ - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - "react-native-macos": packageVersion(profile_0_64, "core-macos"), - "react-native-test-app": "0.0.0", - "react-native-windows": packageVersion(profile_0_64, "core-windows"), - typescript: "0.0.0", - }); - }); - - test("bumps dependencies to minimum supported version", () => { - const updated = updateDependencies( - mockDependencies, - resolvedPackages, - "development" - ); - expect(updated).toEqual({ - react: packageVersion(profile_0_63, "react"), - "react-native": packageVersion(profile_0_63, "core"), - "react-native-macos": packageVersion(profile_0_63, "core-macos"), - "react-native-test-app": packageVersion(profile_0_63, "test-app"), - "react-native-windows": packageVersion(profile_0_63, "core-windows"), - typescript: "0.0.0", - }); - }); - - test("bumps dependencies to widest possible version range", () => { - const updated = updateDependencies( - mockDependencies, - resolvedPackages, - "peer" - ); - expect(updated).toEqual({ - react: `${packageVersion(profile_0_63, "react")} || ${packageVersion( - profile_0_64, - "react" - )}`, - "react-native": `${packageVersion( - profile_0_63, - "core" - )} || ${packageVersion(profile_0_64, "core")}`, - "react-native-macos": `${packageVersion( - profile_0_63, - "core-macos" - )} || ${packageVersion(profile_0_64, "core-macos")}`, - "react-native-test-app": "0.0.0", - "react-native-windows": `${packageVersion( - profile_0_63, - "core-windows" - )} || ${packageVersion(profile_0_64, "core-windows")}`, - typescript: "0.0.0", - }); - }); - - test("sorts keys", () => { - const updated = updateDependencies( - mockDependencies, - resolvedPackages, - "development" - ); - const updatedKeys = Object.keys(updated); - const originalKeys = Object.keys(mockDependencies); - expect(updatedKeys).not.toEqual(originalKeys); - expect(updatedKeys.sort()).not.toEqual(originalKeys); - }); - - test("sets undefined dependencies", () => { - expect( - updateDependencies(undefined, resolvedPackages, "development") - ).toEqual({ - react: packageVersion(profile_0_63, "react"), - "react-native": packageVersion(profile_0_63, "core"), - "react-native-macos": packageVersion(profile_0_63, "core-macos"), - "react-native-test-app": packageVersion(profile_0_63, "test-app"), - "react-native-windows": packageVersion(profile_0_63, "core-windows"), - }); - }); -}); - -describe("updatePackageManifest()", () => { - test("sets direct dependencies for apps", () => { - const { dependencies, devDependencies, peerDependencies } = - updatePackageManifest( - { - name: "Test", - version: "0.0.1", - dependencies: mockDependencies, - peerDependencies: {}, - devDependencies: {}, - }, - ["core-android", "core-ios"], - [profile_0_63, profile_0_64], - [profile_0_64], - "app" - ); - expect(dependencies).toEqual({ - ...mockDependencies, - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }); - expect(peerDependencies).toBeUndefined(); - expect(devDependencies).toBeUndefined(); - }); - - test("removes dependencies from devDependencies for apps", () => { - const { dependencies, devDependencies, peerDependencies } = - updatePackageManifest( - { - name: "Test", - version: "0.0.1", - dependencies: {}, - peerDependencies: {}, - devDependencies: mockDependencies, - }, - ["core-android", "core-ios", "react"], - [profile_0_63, profile_0_64], - [profile_0_64], - "app" - ); - expect(dependencies).toEqual({ - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }); - expect(peerDependencies).toBeUndefined(); - expect(devDependencies).toEqual({ - "react-native-test-app": "0.0.0", - typescript: "0.0.0", - }); - }); - - test("removes dependencies from peerDependencies for apps", () => { - const { dependencies, devDependencies, peerDependencies } = - updatePackageManifest( - { - name: "Test", - version: "0.0.1", - dependencies: {}, - peerDependencies: mockDependencies, - devDependencies: {}, - }, - ["core-android", "core-ios", "react"], - [profile_0_63, profile_0_64], - [profile_0_64], - "app" - ); - expect(dependencies).toEqual({ - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }); - expect(peerDependencies).toEqual({ - "react-native-test-app": "0.0.0", - typescript: "0.0.0", - }); - expect(devDependencies).toBeUndefined(); - }); - - test("sets dev/peer dependencies for libraries", () => { - const { dependencies, devDependencies, peerDependencies } = - updatePackageManifest( - { - name: "Test", - version: "0.0.1", - dependencies: { "@rnx-kit/dep-check": "^1.0.0" }, - peerDependencies: mockDependencies, - }, - ["core-android", "core-ios"], - [profile_0_63, profile_0_64], - [profile_0_64], - "library" - ); - expect(dependencies).toEqual({ "@rnx-kit/dep-check": "^1.0.0" }); - expect(peerDependencies).toEqual({ - ...mockDependencies, - react: [ - packageVersion(profile_0_63, "react"), - packageVersion(profile_0_64, "react"), - ].join(" || "), - "react-native": [ - packageVersion(profile_0_63, "core"), - packageVersion(profile_0_64, "core"), - ].join(" || "), - }); - expect(devDependencies).toEqual({ - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }); - }); - - test("removes dependencies from direct dependencies for libraries", () => { - const { dependencies, devDependencies, peerDependencies } = - updatePackageManifest( - { - name: "Test", - version: "0.0.1", - dependencies: { - "@rnx-kit/dep-check": "^1.0.0", - "react-native": "0.0.0", - }, - peerDependencies: mockDependencies, - devDependencies: {}, - }, - ["core-android", "core-ios"], - [profile_0_64], - [profile_0_64], - "library" - ); - expect(dependencies).toEqual({ "@rnx-kit/dep-check": "^1.0.0" }); - expect(peerDependencies).toEqual({ - ...mockDependencies, - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }); - expect(devDependencies).toEqual({ - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }); - }); - - test("always sets dev-only dependencies", () => { - const { dependencies, devDependencies, peerDependencies } = - updatePackageManifest( - { - name: "Test", - version: "0.0.1", - dependencies: mockDependencies, - peerDependencies: {}, - devDependencies: {}, - }, - ["core-android", "core-ios", "test-app"], - [profile_0_63, profile_0_64], - [profile_0_64], - "app" - ); - expect(dependencies).toEqual({ - ...mockDependencies, - react: packageVersion(profile_0_64, "react"), - "react-native": packageVersion(profile_0_64, "core"), - }); - expect(peerDependencies).toBeUndefined(); - expect(devDependencies).toEqual({ - "react-native-test-app": packageVersion(profile_0_64, "test-app"), - }); - }); -}); diff --git a/packages/dep-check/test/profiles.test.ts b/packages/dep-check/test/profiles.test.ts deleted file mode 100644 index 03a493fc1..000000000 --- a/packages/dep-check/test/profiles.test.ts +++ /dev/null @@ -1,265 +0,0 @@ -import * as path from "path"; -import semver from "semver"; -import preset from "../src/presets/microsoft"; -import profile_0_62 from "../src/presets/microsoft/profile-0.62"; -import profile_0_63 from "../src/presets/microsoft/profile-0.63"; -import profile_0_64 from "../src/presets/microsoft/profile-0.64"; -import { - getProfilesFor, - getProfileVersionsFor, - loadCustomProfiles, - profilesSatisfying, - resolveCustomProfiles, -} from "../src/profiles"; -import { ProfileVersion } from "../src/types"; - -describe("Microsoft preset", () => { - test("matches react-native versions", () => { - const includePrerelease = { - includePrerelease: true, - }; - Object.entries(preset).forEach(([version, capabilities]) => { - const versionRange = "^" + version; - Object.entries(capabilities).forEach(([capability, pkg]) => { - if (capability === "core") { - expect( - "version" in pkg && - semver.subset(pkg.version, versionRange, includePrerelease) - ).toBe(true); - } - }); - }); - }); -}); - -describe("getProfileVersionsFor()", () => { - test("returns profile versions for specific version", () => { - expect(getProfileVersionsFor("0.61.5")).toEqual(["0.61"]); - expect(getProfileVersionsFor("0.62.2")).toEqual(["0.62"]); - expect(getProfileVersionsFor("0.63.4")).toEqual(["0.63"]); - expect(getProfileVersionsFor("0.64.0")).toEqual(["0.64"]); - }); - - test("returns profile for one version range", () => { - expect(getProfileVersionsFor("^0.62.2")).toEqual(["0.62"]); - expect(getProfileVersionsFor("^0.63.4")).toEqual(["0.63"]); - expect(getProfileVersionsFor("^0.64.0")).toEqual(["0.64"]); - }); - - test("returns profiles for bigger version ranges", () => { - const profiles = getProfileVersionsFor(">=0.66.4"); - expect(profiles).toEqual(["0.66", "0.67", "0.68", "0.69", "0.70"]); - }); - - test("returns profiles for multiple version ranges", () => { - const profiles = getProfileVersionsFor("^0.63.0 || ^0.64.0"); - expect(profiles).toEqual(["0.63", "0.64"]); - }); - - test("returns an empty array when an unsupported version is provided", () => { - expect(getProfileVersionsFor("^0.60.6")).toEqual([]); - }); - - test("throws when an invalid version is provided", () => { - expect(() => getProfileVersionsFor("invalid")).toThrowError( - "Invalid 'react-native' version" - ); - }); -}); - -describe("getProfilesFor()", () => { - const consoleErrorSpy = jest.spyOn(global.console, "error"); - - beforeEach(() => { - consoleErrorSpy.mockReset(); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - test("returns profile for specific version", () => { - const profiles = getProfilesFor("0.64.0", undefined); - expect(profiles).toEqual([profile_0_64]); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("returns profile for one version range", () => { - expect(getProfilesFor("^0.62.2", undefined)).toEqual([profile_0_62]); - expect(getProfilesFor("^0.63.4", undefined)).toEqual([profile_0_63]); - expect(getProfilesFor("^0.64.0", undefined)).toEqual([profile_0_64]); - }); - - test("returns profiles for bigger version ranges", () => { - const profiles = getProfilesFor(">=0.62.2", undefined); - expect(profiles.slice(0, 3)).toEqual([ - profile_0_62, - profile_0_63, - profile_0_64, - ]); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("returns profiles for multiple version ranges", () => { - const profiles = getProfilesFor("^0.63.0 || ^0.64.0", undefined); - expect(profiles).toEqual([profile_0_63, profile_0_64]); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("throws when an unsupported version is provided", () => { - expect(() => getProfilesFor("^0.60.6", undefined)).toThrowError( - "Unsupported 'react-native' version" - ); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("throws when an invalid version is provided", () => { - expect(() => getProfilesFor("invalid", undefined)).toThrowError( - "Invalid 'react-native' version" - ); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("throws if custom profiles module does not exist", () => { - expect(() => - getProfilesFor("^0.59", "non-existent-profiles-module") - ).toThrow(`Cannot find module 'non-existent-profiles-module'`); - }); - - test("throws if custom profiles module does not default export an object", () => { - jest.mock("bad-profiles-module", () => null, { virtual: true }); - - expect(() => getProfilesFor("^0.59", "bad-profiles-module")).toThrow( - "'bad-profiles-module' doesn't default export profiles" - ); - - expect(consoleErrorSpy).toBeCalledTimes(1); - }); - - test("appends custom profiles", () => { - const skynet = { name: "skynet", version: "1.0.0" }; - jest.mock( - "good-profiles-module", - () => ({ "0.62": { [skynet.name]: skynet } }), - { virtual: true } - ); - - const [profile_0_62, profile_0_63] = getProfilesFor( - "^0.62 || ^0.63", - "good-profiles-module" - ); - - expect(skynet.name in profile_0_62).toBe(true); - expect(skynet.name in profile_0_63).toBe(false); - - expect(consoleErrorSpy).not.toBeCalled(); - }); -}); - -describe("loadCustomProfiles()", () => { - test("returns any empty object if no custom profiles are specified", () => { - expect(loadCustomProfiles(undefined)).toEqual({}); - }); - - test("throws if custom profiles are not the right shape", () => { - expect(() => - loadCustomProfiles( - path.join( - __dirname, - "__fixtures__", - "custom-profiles", - "local-profiles.js" - ) - ) - ).toThrow("doesn't default export profiles"); - }); - - test("loads valid custom profiles", () => { - expect( - loadCustomProfiles( - path.join( - __dirname, - "__fixtures__", - "custom-profiles", - "valid-profiles.js" - ) - ) - ).toMatchSnapshot(); - }); - - test("prepends root-level capabilities to all profiles", () => { - expect( - loadCustomProfiles( - path.join( - __dirname, - "__fixtures__", - "custom-profiles", - "root-level-profiles.js" - ) - ) - ).toMatchSnapshot(); - }); -}); - -describe("profilesSatisfying()", () => { - const profileVersions: ProfileVersion[] = ["0.61", "0.62", "0.63", "0.64"]; - - test("returns an empty array when no profiles can satisfy requirements", () => { - expect(profilesSatisfying([], "^0.63.0 || ^0.64.0")).toEqual([]); - expect(profilesSatisfying(["0.61"], "^0.63.0 || ^0.64.0")).toEqual([]); - }); - - test("returns all profiles satisfying version", () => { - expect(profilesSatisfying(profileVersions, "0.63.2")).toEqual(["0.63"]); - expect(profilesSatisfying(profileVersions, "0.64.0-rc1")).toEqual(["0.64"]); - expect(profilesSatisfying(profileVersions, "0.64.0")).toEqual(["0.64"]); - }); - - test("returns all profiles satisfying version range", () => { - expect( - profilesSatisfying(profileVersions, "^0.63.0-0 || ^0.64.0-0") - ).toEqual(["0.63", "0.64"]); - expect(profilesSatisfying(profileVersions, "^0.63.0 || ^0.64.0")).toEqual([ - "0.63", - "0.64", - ]); - }); -}); - -describe("resolveCustomProfiles()", () => { - const projectRoot = `${__dirname}/__fixtures__/custom-profiles`; - - test("handles undefined and empty strings", () => { - expect(resolveCustomProfiles(projectRoot, undefined)).toBeUndefined(); - expect(resolveCustomProfiles(projectRoot, "")).toBeUndefined(); - }); - - test("throws if the module cannot be resolved", () => { - expect(() => - resolveCustomProfiles(projectRoot, "non-existent-custom-profiles") - ).toThrow("Cannot resolve module"); - }); - - test("returns absolute path for module ids", () => { - const profilesPkg = "custom-profiles-package"; - expect(resolveCustomProfiles(projectRoot, profilesPkg)).toEqual( - expect.stringContaining( - path.join( - "__fixtures__", - "custom-profiles", - "node_modules", - profilesPkg, - "index.js" - ) - ) - ); - }); - - test("returns absolute path for relative paths", () => { - expect(resolveCustomProfiles(projectRoot, "./local-profiles.js")).toEqual( - expect.stringContaining( - path.join("__fixtures__", "custom-profiles", "local-profiles.js") - ) - ); - }); -}); diff --git a/packages/dep-check/test/setVersion.test.ts b/packages/dep-check/test/setVersion.test.ts deleted file mode 100644 index e29165927..000000000 --- a/packages/dep-check/test/setVersion.test.ts +++ /dev/null @@ -1,204 +0,0 @@ -import type { PackageManifest } from "@rnx-kit/tools-node/package"; -import prompts from "prompts"; -import { makeSetVersionCommand } from "../src/setVersion"; - -jest.mock("fs"); - -type Result = { - didWrite: boolean; - manifest: Record; -}; - -describe("makeSetVersionCommand()", () => { - const rnxKitConfig = require("@rnx-kit/config"); - const fs = require("fs"); - - function setupMocks(manifest: PackageManifest): Result { - fs.__setMockContent(manifest); - - const result: Result = { didWrite: false, manifest: {} }; - fs.__setMockFileWriter((_: string, content: string) => { - const updatedManifest = JSON.parse(content); - fs.__setMockContent(updatedManifest); - rnxKitConfig.__setMockConfig(updatedManifest["rnx-kit"]); - - result.didWrite = true; - result.manifest = updatedManifest; - }); - - return result; - } - - const mockManifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0-test", - dependencies: { - react: "16.13.1", - "react-native": "^0.63.2", - }, - devDependencies: {}, - "rnx-kit": { - reactNativeVersion: "^0.63", - kitType: "app", - capabilities: ["core"], - }, - }; - - afterEach(() => { - fs.__setMockContent({}); - rnxKitConfig.__setMockConfig(); - jest.clearAllMocks(); - }); - - test("rejects unsupported versions `react-native`", async () => { - expect(makeSetVersionCommand("0.59")).rejects.toEqual( - expect.objectContaining({ - message: expect.stringContaining( - "Unsupported 'react-native' version/range:" - ), - }) - ); - }); - - test("updates dependencies", async () => { - const result = setupMocks({ - ...mockManifest, - "rnx-kit": { - ...mockManifest["rnx-kit"], - kitType: "library", - reactNativeDevVersion: "^0.63.0", - }, - }); - - const command = await makeSetVersionCommand("0.64,0.63"); - expect(typeof command).toBe("function"); - expect(command("package.json")).toBe(0); - expect(result.manifest).toEqual({ - ...mockManifest, - dependencies: undefined, - devDependencies: { - react: "17.0.1", - "react-native": "^0.64.2", - }, - peerDependencies: { - react: "16.13.1 || 17.0.1", - "react-native": "^0.63.2 || ^0.64.2", - }, - "rnx-kit": { - ...mockManifest["rnx-kit"], - kitType: "library", - reactNativeVersion: "^0.63.0 || ^0.64.0", - reactNativeDevVersion: "^0.64.0", - }, - }); - }); - - test("removes `reactNativeDevVersion` if `kitType` is `app`", async () => { - const result = setupMocks({ - ...mockManifest, - "rnx-kit": { - ...mockManifest["rnx-kit"], - reactNativeDevVersion: "^0.63.0", - }, - }); - - const command = await makeSetVersionCommand("0.64,0.63"); - expect(typeof command).toBe("function"); - expect(command("package.json")).toBe(0); - expect(result.manifest).toEqual({ - ...mockManifest, - dependencies: { - react: "17.0.1", - "react-native": "^0.64.2", - }, - devDependencies: undefined, - "rnx-kit": { - ...mockManifest["rnx-kit"], - reactNativeVersion: "^0.63.0 || ^0.64.0", - }, - }); - }); - - test("prompts the user if no version is specified", async () => { - const result = setupMocks(mockManifest); - - prompts.inject([["0.63", "0.64"], "0.64"]); - - const command = await makeSetVersionCommand(""); - expect(typeof command).toBe("function"); - expect(command("package.json")).toBe(0); - expect(result.manifest).toEqual({ - ...mockManifest, - dependencies: { - react: "17.0.1", - "react-native": "^0.64.2", - }, - devDependencies: undefined, - "rnx-kit": { - ...mockManifest["rnx-kit"], - reactNativeVersion: "^0.63 || ^0.64", - }, - }); - }); - - test("skips the second prompt if only one version is supported", async () => { - const result = setupMocks(mockManifest); - - prompts.inject([["0.64"]]); - - const command = await makeSetVersionCommand(""); - expect(typeof command).toBe("function"); - expect(command("package.json")).toBe(0); - expect(result.manifest).toEqual({ - ...mockManifest, - dependencies: { - react: "17.0.1", - "react-native": "^0.64.2", - }, - devDependencies: undefined, - "rnx-kit": { - ...mockManifest["rnx-kit"], - reactNativeVersion: "^0.64", - }, - }); - }); - - test('skips "dirty" packages', async () => { - rnxKitConfig.__setMockConfig(mockManifest["rnx-kit"]); - const result = setupMocks({ - ...mockManifest, - dependencies: { - "react-native": "^0.62.3", - }, - }); - - prompts.inject([["0.64"]]); - - const command = await makeSetVersionCommand(""); - expect(typeof command).toBe("function"); - expect(command("package.json")).not.toBe(0); - expect(result.didWrite).toBe(false); - }); - - test("skips unconfigured packages", async () => { - const result = setupMocks({ - ...mockManifest, - "rnx-kit": undefined, - } as PackageManifest); - - prompts.inject([["0.64"]]); - - const command = await makeSetVersionCommand(""); - expect(typeof command).toBe("function"); - expect(command("package.json")).toBe(0); - expect(result.didWrite).toBe(false); - }); - - test("exits if the user cancels during prompts", async () => { - prompts.inject([undefined]); - expect(await makeSetVersionCommand("")).toBeUndefined(); - - prompts.inject([["0.63", "0.64"], undefined]); - expect(await makeSetVersionCommand("")).toBeUndefined(); - }); -}); diff --git a/packages/dep-check/test/vigilant.test.ts b/packages/dep-check/test/vigilant.test.ts deleted file mode 100644 index 9876be268..000000000 --- a/packages/dep-check/test/vigilant.test.ts +++ /dev/null @@ -1,477 +0,0 @@ -import { parseProfilesString } from "../src/profiles"; -import { - buildManifestProfile, - buildProfileFromConfig, - inspect, - makeVigilantCommand, -} from "../src/vigilant"; - -jest.mock("fs"); - -describe("buildManifestProfile()", () => { - const testVersion = "1.0.0-test"; - - test("builds a package manifest for a single profile version", () => { - const profiles = parseProfilesString("0.64", undefined); - const profile = buildManifestProfile(profiles); - profile.version = testVersion; - expect(profile).toMatchSnapshot(); - }); - - test("builds a package manifest for multiple profile versions", () => { - const profiles = parseProfilesString("0.64,0.63", undefined); - const profile = buildManifestProfile(profiles); - profile.version = testVersion; - expect(profile).toMatchSnapshot(); - }); - - test("includes devOnly packages under `dependencies`", () => { - const profiles = parseProfilesString("0.64", undefined); - const { dependencies, devDependencies, peerDependencies } = - buildManifestProfile(profiles); - - expect("react-native-test-app" in dependencies).toBe(true); - expect("react-native-test-app" in peerDependencies).toBe(false); - expect("react-native-test-app" in devDependencies).toBe(true); - }); - - test("includes custom profiles", () => { - const skynet = { name: "skynet", version: "1.0.0" }; - jest.mock( - "vigilant-custom-profiles", - () => ({ "0.64": { [skynet.name]: skynet } }), - { virtual: true } - ); - - const profiles = parseProfilesString("0.64", "vigilant-custom-profiles"); - const { dependencies, devDependencies, peerDependencies } = - buildManifestProfile(profiles); - - expect(skynet.name in dependencies).toBe(true); - expect(skynet.name in peerDependencies).toBe(true); - expect(skynet.name in devDependencies).toBe(true); - }); - - test("throws when no profiles match the requested versions", () => { - expect(() => parseProfilesString("0.59", undefined)).toThrow(); - expect(() => parseProfilesString("0.59,0.64", undefined)).toThrow(); - }); -}); - -describe("buildProfileFromConfig()", () => { - const profiles = parseProfilesString("0.64", undefined); - const defaultProfile = buildManifestProfile(profiles); - - test("returns default profile if there is no config", () => { - expect(buildProfileFromConfig(0, defaultProfile)).toBe(defaultProfile); - }); - - test("filters out managed capabilities", () => { - const dependencies = [ - "dependencies", - "peerDependencies", - "devDependencies", - ] as const; - const config = { - kitType: "library" as const, - reactNativeVersion: "0.64", - reactNativeDevVersion: "0.64", - capabilities: [], - manifest: { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "react-native": "^0.64.0", - }, - }, - }; - const profile = buildProfileFromConfig(config, defaultProfile); - dependencies.forEach((section) => { - expect(Object.keys(profile[section])).toContain("react"); - expect(Object.keys(profile[section])).toContain("react-native"); - }); - - const withCapabilities = buildProfileFromConfig( - { - ...config, - capabilities: ["core-android", "core-ios"], - }, - defaultProfile - ); - - dependencies.forEach((section) => { - expect(Object.keys(withCapabilities[section])).not.toContain("react"); - expect(Object.keys(withCapabilities[section])).not.toContain( - "react-native" - ); - }); - }); -}); - -describe("inspect()", () => { - const mockManifestProfile = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "react-native": "^0.63.2", - }, - peerDependencies: { - "react-native": "^0.63 || ^0.64", - }, - devDependencies: { - "react-native": "^0.63.2", - }, - }; - - test("handles empty dependencies", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - }; - expect(inspect(manifest, mockManifestProfile, false)).toEqual([]); - expect(inspect(manifest, mockManifestProfile, true)).toEqual([]); - }); - - test("ignores unmanaged dependencies", () => { - const dependencies = { - "@babel/core": "^7.0.0", - "react-native": "0.63.2", - }; - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies, - }; - - const expectedChanges = [ - { - name: "react-native", - from: manifest.dependencies["react-native"], - to: mockManifestProfile.dependencies["react-native"], - section: "dependencies", - }, - ]; - - expect(inspect(manifest, mockManifestProfile, false)).toEqual( - expectedChanges - ); - expect(manifest.dependencies).toEqual(dependencies); - }); - - test("inspects all dependency types", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "@babel/core": "^7.0.0", - }, - peerDependencies: { - "react-native": "0.63.2", - }, - devDependencies: { - "react-native": "0.63.2", - }, - }; - - const expectedChanges = [ - { - name: "react-native", - from: manifest.peerDependencies["react-native"], - to: mockManifestProfile.peerDependencies["react-native"], - section: "peerDependencies", - }, - { - name: "react-native", - from: manifest.devDependencies["react-native"], - to: mockManifestProfile.devDependencies["react-native"], - section: "devDependencies", - }, - ]; - - expect(inspect(manifest, mockManifestProfile, false)).toEqual( - expectedChanges - ); - }); - - test("modifies the manifest when `write: true`", () => { - const dependencies = { - "@babel/core": "^7.0.0", - "react-native": "0.63.2", - }; - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { ...dependencies }, - }; - - const expectedChanges = [ - { - name: "react-native", - from: manifest.dependencies["react-native"], - to: mockManifestProfile.dependencies["react-native"], - section: "dependencies", - }, - ]; - - expect(inspect(manifest, mockManifestProfile, true)).toEqual( - expectedChanges - ); - expect(manifest.dependencies).not.toEqual(dependencies); - }); - - test("does not rewrite peerDependencies if superset", () => { - const manifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - react: "^16.8.1", - }, - peerDependencies: { - metro: "*", - react: ">=16.8.0 <18.0.0", - "react-native": ">=0.64", - }, - devDependencies: {}, - }; - const profile = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - react: "~17.0.1", - }, - peerDependencies: { - metro: "^0.66.2", - react: "~17.0.1", - "react-native": "^0.66.0-0", - }, - devDependencies: {}, - }; - const expectedChanges = [ - { - name: "react", - from: manifest.dependencies["react"], - to: profile.dependencies["react"], - section: "dependencies", - }, - ]; - - expect(inspect(manifest, profile, false)).toEqual(expectedChanges); - }); -}); - -describe("makeVigilantCommand()", () => { - const rnxKitConfig = require("@rnx-kit/config"); - const fs = require("fs"); - - const consoleErrorSpy = jest.spyOn(global.console, "error"); - - beforeEach(() => { - consoleErrorSpy.mockReset(); - fs.__setMockContent({}); - fs.__setMockFileWriter(() => { - throw new Error("mock for fs.writeFileSync is not set"); - }); - }); - - afterAll(() => { - jest.clearAllMocks(); - }); - - test("returns no command if no versions are specified", () => { - expect( - makeVigilantCommand({ versions: "", loose: false, write: false }) - ).toBeUndefined(); - }); - - test("returns exit code 0 when there are no violations", () => { - fs.__setMockContent({ - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "react-native": "^0.63.2", - }, - }); - - let didWrite = false; - fs.__setMockFileWriter(() => { - didWrite = true; - }); - - const result = makeVigilantCommand({ - versions: "0.63", - loose: false, - write: false, - })("package.json"); - expect(result).toBe(0); - expect(didWrite).toBe(false); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("returns non-zero exit code when there are violations", () => { - fs.__setMockContent({ - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "react-native": "0.63.2", - }, - }); - - let didWrite = false; - fs.__setMockFileWriter(() => { - didWrite = true; - }); - - const result = makeVigilantCommand({ - versions: "0.63", - loose: false, - write: false, - })("package.json"); - expect(result).not.toBe(0); - expect(didWrite).toBe(false); - expect(consoleErrorSpy).toBeCalledTimes(1); - }); - - test("returns exit code 0 when writing", () => { - fs.__setMockContent({ - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "react-native": "0.63.2", - }, - }); - - let didWrite = false; - fs.__setMockFileWriter(() => { - didWrite = true; - }); - - const result = makeVigilantCommand({ - versions: "0.63", - loose: false, - write: true, - })("package.json"); - expect(result).toBe(0); - expect(didWrite).toBe(true); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("excludes specified packages", () => { - fs.__setMockContent({ - name: "@rnx-kit/dep-check", - version: "1.0.0", - dependencies: { - "react-native": "0.59.10", - }, - }); - - let didWrite = false; - fs.__setMockFileWriter(() => { - didWrite = true; - }); - - const result = makeVigilantCommand({ - versions: "0.63", - write: false, - excludePackages: "@rnx-kit/dep-check", - loose: false, - })("package.json"); - expect(result).toBe(0); - expect(didWrite).toBe(false); - expect(consoleErrorSpy).not.toBeCalled(); - }); - - test("uses package-specific custom profiles", () => { - const fixture = `${__dirname}/__fixtures__/config-custom-profiles-only`; - const kitConfig = { - customProfiles: `${fixture}/packageSpecificProfiles.js`, - }; - const inputManifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - peerDependencies: { - react: "17.0.1", - "react-native": "0.64.0", - }, - devDependencies: { - react: "17.0.1", - "react-native": "0.64.0", - }, - "rnx-kit": kitConfig, - }; - - rnxKitConfig.__setMockConfig(kitConfig); - fs.__setMockContent(inputManifest); - - let manifest = undefined; - fs.__setMockFileWriter((_, content) => { - manifest = JSON.parse(content); - }); - - const result = makeVigilantCommand({ - versions: "0.64,0.65", - loose: false, - write: true, - })("package.json"); - expect(result).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(manifest).toEqual({ - ...inputManifest, - devDependencies: { - react: "17.0.2", - "react-native": "0.64.3", - }, - peerDependencies: { - react: "17.0.2", - "react-native": "0.64.3 || 0.65.2 || ^0.64.2 || ^0.65.0", - }, - }); - }); - - test("prefers package-specific React Native versions", () => { - const fixture = `${__dirname}/__fixtures__/config-custom-profiles-only`; - const kitConfig = { - reactNativeVersion: "0.64", - customProfiles: `${fixture}/packageSpecificProfiles.js`, - }; - const inputManifest = { - name: "@rnx-kit/dep-check", - version: "1.0.0", - peerDependencies: { - react: "17.0.1", - "react-native": "0.64.0", - }, - devDependencies: { - react: "17.0.1", - "react-native": "0.64.0", - }, - "rnx-kit": kitConfig, - }; - - rnxKitConfig.__setMockConfig(kitConfig); - fs.__setMockContent(inputManifest); - - let manifest = undefined; - fs.__setMockFileWriter((_, content) => { - manifest = JSON.parse(content); - }); - - const result = makeVigilantCommand({ - versions: "0.64,0.65", - loose: false, - write: true, - })("package.json"); - expect(result).toBe(0); - expect(consoleErrorSpy).not.toBeCalled(); - expect(manifest).toEqual({ - ...inputManifest, - devDependencies: { - react: "17.0.2", - "react-native": "0.64.3", - }, - peerDependencies: { - react: "17.0.2", - "react-native": "0.64.3 || ^0.64.2", - }, - }); - }); -});