UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

115 lines (105 loc) • 3.5 kB
import { spawnSync } from 'node:child_process' import { chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync, } from 'node:fs' import { tmpdir } from 'node:os' import { join } from 'node:path' import { afterEach, beforeEach, expect, test } from 'vitest' const fixture = join(import.meta.dirname, '../../../tests/native-features') let root: string beforeEach(() => { root = mkdtempSync(join(tmpdir(), 'one-fixture-prebuild-')) mkdirSync(join(root, 'scripts')) mkdirSync(join(root, 'bin')) copyFileSync(join(fixture, 'package.json'), join(root, 'package.json')) copyFileSync( join(fixture, 'scripts/prebuild-native.ts'), join(root, 'scripts/prebuild-native.ts') ) for (const hook of ['audio-interruption', 'background-tasks']) { writeFileSync( join(root, 'scripts', `prepare-ios-${hook}.ts`), ` import { appendFileSync } from 'node:fs' appendFileSync(process.env.HOOK_FILE!, JSON.stringify('${hook}') + '\\n') ` ) } writeFileSync( join(root, 'scripts', 'prepare-android-background-tasks.ts'), ` import { appendFileSync } from 'node:fs' appendFileSync(process.env.HOOK_FILE!, JSON.stringify('android-background-tasks') + '\\n') ` ) const one = join(root, 'bin', 'one') writeFileSync( one, `#!/usr/bin/env node import { writeFileSync } from 'node:fs' writeFileSync(process.env.RECORD_FILE, JSON.stringify(process.argv.slice(2))) process.exit(Number(process.env.PREBUILD_EXIT_CODE ?? 0)) ` ) chmodSync(one, 0o755) }) afterEach(() => rmSync(root, { recursive: true, force: true })) function run(args: string[], exitCode = 0) { return spawnSync('bun', ['run', 'prebuild:native', ...args], { cwd: root, encoding: 'utf8', env: { ...process.env, PATH: `${join(root, 'bin')}:${process.env.PATH}`, RECORD_FILE: join(root, 'args.json'), HOOK_FILE: join(root, 'hooks.jsonl'), PREBUILD_EXIT_CODE: String(exitCode), }, }) } function hooks() { return readFileSync(join(root, 'hooks.jsonl'), 'utf8') .trim() .split('\n') .map((line) => JSON.parse(line)) } test('Android prebuild forwards CLI options and succeeds without an iOS project', () => { const result = run(['--platform', 'android', '--no-install']) expect(result.status, result.stderr).toBe(0) expect(JSON.parse(readFileSync(join(root, 'args.json'), 'utf8'))).toEqual([ 'prebuild', '--platform', 'android', '--no-install', ]) expect(existsSync(join(root, 'ios'))).toBe(false) expect(hooks()).toEqual(['android-background-tasks']) }) test('iOS prebuild forwards CLI options and installs both simulator hooks', () => { const result = run(['--platform', 'ios', '--no-install']) expect(result.status, result.stderr).toBe(0) expect(JSON.parse(readFileSync(join(root, 'args.json'), 'utf8'))).toEqual([ 'prebuild', '--platform', 'ios', '--no-install', ]) expect(hooks()).toEqual(['audio-interruption', 'background-tasks']) }) test('a failed prebuild preserves its exit status and leaves simulator hooks untouched', () => { const result = run(['--platform', 'ios'], 42) expect(result.status, result.stderr).toBe(42) expect(existsSync(join(root, 'hooks.jsonl'))).toBe(false) }) test('prebuilding both platforms still installs the iOS simulator hooks', () => { const result = run([]) expect(result.status, result.stderr).toBe(0) expect(hooks()).toEqual(['audio-interruption', 'background-tasks']) })