From 8d9316367a305c1feae1c8e1d9f25c582e7eff18 Mon Sep 17 00:00:00 2001 From: Kazi Rezoanur Rahman Date: Thu, 15 Oct 2026 12:03:58 +0000 Subject: [PATCH 1/2] fix(create-react-native-library): use latest Community CLI Updated vanilla example generation to use `@react-native-community/cli@latest`. Added a behavioral regression test for the generated `npx` command. Lint and typecheck pass; the full suite passes 30/30 with an extended timeout. Closes #958 --- .../src/exampleApp/generateExampleApp.test.ts | 78 +++++++++++++++++++ .../src/exampleApp/generateExampleApp.ts | 4 +- 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts new file mode 100644 index 000000000..89656c0f8 --- /dev/null +++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts @@ -0,0 +1,78 @@ +import os from 'node:os'; +import path from 'node:path'; +import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'; +// Vitest is provided by the repository test runner and is not a package dependency. +// eslint-disable-next-line import-x/no-extraneous-dependencies +import { afterEach, expect, test, vi } from 'vitest'; +import type { TemplateConfiguration } from '../template.ts'; +import { spawn } from '../utils/spawn.ts'; +import generateExampleApp from './generateExampleApp.ts'; + +vi.mock('../utils/spawn.ts', () => ({ + spawn: vi.fn(), +})); + +afterEach(() => { + vi.clearAllMocks(); +}); + +test('uses the latest Community CLI for vanilla example apps', async () => { + const root = await mkdtemp( + path.join(os.tmpdir(), 'create-react-native-library-') + ); + + try { + await mkdir(path.join(root, 'example')); + await writeFile( + path.join(root, 'example', 'package.json'), + JSON.stringify({ + dependencies: {}, + devDependencies: {}, + scripts: {}, + }) + ); + + const config: TemplateConfiguration = { + author: { + email: '', + name: '', + url: '', + }, + example: 'vanilla', + project: { + cpp: false, + description: 'Test project', + identifier: 'test', + moduleConfig: 'turbo-modules', + name: 'Test', + native: true, + package: 'test', + package_cpp: 'test', + package_dir: 'test', + slug: 'test', + sourceCondition: 'test-source', + swift: false, + viewConfig: null, + }, + repo: '', + tools: [], + versions: { + bob: '0.0.0', + nitro: undefined, + }, + year: 2026, + }; + + await generateExampleApp({ + config, + reactNativeVersion: undefined, + root, + }); + + const args = vi.mocked(spawn).mock.calls[0]?.[1]; + + expect(args?.[0]).toBe('@react-native-community/cli@latest'); + } finally { + await rm(root, { force: true, recursive: true }); + } +}); diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts index 92326ebf4..303d2a341 100644 --- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts +++ b/packages/create-react-native-library/src/exampleApp/generateExampleApp.ts @@ -139,9 +139,9 @@ export default async function generateExampleApp({ ); } - // `npx @react-native-community/cli init --directory example --skip-install` + // `npx @react-native-community/cli@latest init --directory example --skip-install` args = [ - `@react-native-community/cli`, + `@react-native-community/cli@latest`, 'init', `${config.project.name}Example`, '--package-name', From 18fc01245ca7d5b4f0edef496a75cd82cf297428 Mon Sep 17 00:00:00 2001 From: Satyajit Sahoo Date: Wed, 21 Oct 2026 14:54:51 +0200 Subject: [PATCH 2/2] test: remove the generateExampleApp test --- .../src/exampleApp/generateExampleApp.test.ts | 78 ------------------- 1 file changed, 78 deletions(-) delete mode 100644 packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts diff --git a/packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts b/packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts deleted file mode 100644 index 89656c0f8..000000000 --- a/packages/create-react-native-library/src/exampleApp/generateExampleApp.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import os from 'node:os'; -import path from 'node:path'; -import { mkdtemp, mkdir, rm, writeFile } from 'node:fs/promises'; -// Vitest is provided by the repository test runner and is not a package dependency. -// eslint-disable-next-line import-x/no-extraneous-dependencies -import { afterEach, expect, test, vi } from 'vitest'; -import type { TemplateConfiguration } from '../template.ts'; -import { spawn } from '../utils/spawn.ts'; -import generateExampleApp from './generateExampleApp.ts'; - -vi.mock('../utils/spawn.ts', () => ({ - spawn: vi.fn(), -})); - -afterEach(() => { - vi.clearAllMocks(); -}); - -test('uses the latest Community CLI for vanilla example apps', async () => { - const root = await mkdtemp( - path.join(os.tmpdir(), 'create-react-native-library-') - ); - - try { - await mkdir(path.join(root, 'example')); - await writeFile( - path.join(root, 'example', 'package.json'), - JSON.stringify({ - dependencies: {}, - devDependencies: {}, - scripts: {}, - }) - ); - - const config: TemplateConfiguration = { - author: { - email: '', - name: '', - url: '', - }, - example: 'vanilla', - project: { - cpp: false, - description: 'Test project', - identifier: 'test', - moduleConfig: 'turbo-modules', - name: 'Test', - native: true, - package: 'test', - package_cpp: 'test', - package_dir: 'test', - slug: 'test', - sourceCondition: 'test-source', - swift: false, - viewConfig: null, - }, - repo: '', - tools: [], - versions: { - bob: '0.0.0', - nitro: undefined, - }, - year: 2026, - }; - - await generateExampleApp({ - config, - reactNativeVersion: undefined, - root, - }); - - const args = vi.mocked(spawn).mock.calls[0]?.[1]; - - expect(args?.[0]).toBe('@react-native-community/cli@latest'); - } finally { - await rm(root, { force: true, recursive: true }); - } -});