166 行
6.0 KiB
JavaScript
166 行
6.0 KiB
JavaScript
|
|
import assert from 'node:assert/strict'
|
||
|
|
import { execFileSync } from 'node:child_process'
|
||
|
|
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'
|
||
|
|
import { tmpdir } from 'node:os'
|
||
|
|
import path from 'node:path'
|
||
|
|
import test from 'node:test'
|
||
|
|
|
||
|
|
const cli = new URL('./xuqm-rn.mjs', import.meta.url).pathname
|
||
|
|
|
||
|
|
test('embed creates a complete versioned manifest from a host fixture', () => {
|
||
|
|
const root = mkdtempSync(path.join(tmpdir(), 'xuqm-cli-'))
|
||
|
|
const output = path.join(root, 'generated', 'rn-bundles')
|
||
|
|
try {
|
||
|
|
writeFileSync(
|
||
|
|
path.join(root, 'package.json'),
|
||
|
|
JSON.stringify({
|
||
|
|
name: 'fixture',
|
||
|
|
version: '7.2.14',
|
||
|
|
dependencies: { '@xuqm/rn-update': '0.5.0-alpha.5' },
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
writeFileSync(path.join(root, 'common.ts'), '')
|
||
|
|
writeFileSync(path.join(root, 'app.ts'), '')
|
||
|
|
writeFileSync(
|
||
|
|
path.join(root, 'xuqm.config.json'),
|
||
|
|
JSON.stringify({
|
||
|
|
schemaVersion: 3,
|
||
|
|
appId: 'fixture.app',
|
||
|
|
mainModuleName: 'Fixture',
|
||
|
|
pluginVersion: '1.0.0',
|
||
|
|
appVersionRange: '>=7.2.14 <8.0.0',
|
||
|
|
outputDir: './bundle',
|
||
|
|
embeddedOutput: { android: './unused' },
|
||
|
|
modules: [
|
||
|
|
{ id: 'common', type: 'common', entry: './common.ts' },
|
||
|
|
{ id: 'app', type: 'app', entry: './app.ts' },
|
||
|
|
],
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
for (const moduleId of ['common', 'app']) {
|
||
|
|
const directory = path.join(root, 'bundle', 'android', moduleId)
|
||
|
|
mkdirSync(directory, { recursive: true })
|
||
|
|
writeFileSync(path.join(directory, `${moduleId}.android.bundle`), moduleId)
|
||
|
|
}
|
||
|
|
|
||
|
|
execFileSync(process.execPath, [cli, 'embed', 'android', '--skip-build', '--output', output], {
|
||
|
|
cwd: root,
|
||
|
|
stdio: 'pipe',
|
||
|
|
})
|
||
|
|
|
||
|
|
const manifest = JSON.parse(readFileSync(path.join(output, 'manifest.json'), 'utf8'))
|
||
|
|
assert.equal(manifest.appVersion, '7.2.14')
|
||
|
|
assert.equal(manifest.modules.common.moduleVersion, '1.0.0')
|
||
|
|
assert.equal(manifest.modules.app.moduleVersion, '1.0.0')
|
||
|
|
assert.equal(manifest.modules.app.commonVersionRange, '>=1.0.0 <2.0.0')
|
||
|
|
assert.equal(manifest.modules.app.minNativeApiLevel, 1)
|
||
|
|
assert.equal(manifest.modules.app.appVersionRange, '>=7.2.14 <8.0.0')
|
||
|
|
assert.equal(readFileSync(path.join(output, 'app.android.bundle'), 'utf8'), 'app')
|
||
|
|
} finally {
|
||
|
|
rmSync(root, { recursive: true, force: true })
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
test('build invokes the host-local React Native CLI with a consistent color environment', () => {
|
||
|
|
const root = mkdtempSync(path.join(tmpdir(), 'xuqm-cli-local-rn-'))
|
||
|
|
try {
|
||
|
|
writeFileSync(
|
||
|
|
path.join(root, 'package.json'),
|
||
|
|
JSON.stringify({
|
||
|
|
name: 'fixture',
|
||
|
|
version: '1.0.0',
|
||
|
|
dependencies: { '@xuqm/rn-update': '0.5.0-alpha.8' },
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
writeFileSync(path.join(root, 'common.ts'), '')
|
||
|
|
writeFileSync(
|
||
|
|
path.join(root, 'xuqm.config.json'),
|
||
|
|
JSON.stringify({
|
||
|
|
schemaVersion: 3,
|
||
|
|
appId: 'fixture.app',
|
||
|
|
mainModuleName: 'Fixture',
|
||
|
|
pluginVersion: '1.0.0',
|
||
|
|
appVersionRange: '>=1.0.0 <2.0.0',
|
||
|
|
outputDir: './bundle',
|
||
|
|
embeddedOutput: { android: './generated' },
|
||
|
|
modules: [{ id: 'common', type: 'common', entry: './common.ts' }],
|
||
|
|
}),
|
||
|
|
)
|
||
|
|
const reactNativeDirectory = path.join(root, 'node_modules', 'react-native')
|
||
|
|
mkdirSync(reactNativeDirectory, { recursive: true })
|
||
|
|
writeFileSync(
|
||
|
|
path.join(reactNativeDirectory, 'cli.js'),
|
||
|
|
`
|
||
|
|
const fs = require('node:fs');
|
||
|
|
const path = require('node:path');
|
||
|
|
const args = process.argv.slice(2);
|
||
|
|
const output = args[args.indexOf('--bundle-output') + 1];
|
||
|
|
fs.mkdirSync(path.dirname(output), { recursive: true });
|
||
|
|
fs.writeFileSync(output, 'bundle');
|
||
|
|
fs.writeFileSync(path.join(process.cwd(), 'child.json'), JSON.stringify({
|
||
|
|
args,
|
||
|
|
forceColor: process.env.FORCE_COLOR ?? null,
|
||
|
|
noColor: process.env.NO_COLOR ?? null,
|
||
|
|
}));
|
||
|
|
`,
|
||
|
|
)
|
||
|
|
|
||
|
|
execFileSync(process.execPath, [cli, 'build', 'android'], {
|
||
|
|
cwd: root,
|
||
|
|
env: { ...process.env, FORCE_COLOR: '1', NO_COLOR: '1' },
|
||
|
|
stdio: 'pipe',
|
||
|
|
})
|
||
|
|
|
||
|
|
const child = JSON.parse(readFileSync(path.join(root, 'child.json'), 'utf8'))
|
||
|
|
assert.equal(child.args[0], 'bundle')
|
||
|
|
assert.equal(child.forceColor, '0')
|
||
|
|
assert.equal(child.noColor, null)
|
||
|
|
} finally {
|
||
|
|
rmSync(root, { recursive: true, force: true })
|
||
|
|
}
|
||
|
|
})
|
||
|
|
|
||
|
|
test('start and run forward arguments through the host-local React Native CLI', () => {
|
||
|
|
const root = mkdtempSync(path.join(tmpdir(), 'xuqm-cli-run-rn-'))
|
||
|
|
try {
|
||
|
|
const reactNativeDirectory = path.join(root, 'node_modules', 'react-native')
|
||
|
|
mkdirSync(reactNativeDirectory, { recursive: true })
|
||
|
|
writeFileSync(
|
||
|
|
path.join(reactNativeDirectory, 'cli.js'),
|
||
|
|
`
|
||
|
|
const fs = require('node:fs');
|
||
|
|
const callsFile = require('node:path').join(process.cwd(), 'calls.json');
|
||
|
|
const calls = fs.existsSync(callsFile) ? JSON.parse(fs.readFileSync(callsFile, 'utf8')) : [];
|
||
|
|
calls.push({
|
||
|
|
args: process.argv.slice(2),
|
||
|
|
forceColor: process.env.FORCE_COLOR ?? null,
|
||
|
|
noColor: process.env.NO_COLOR ?? null,
|
||
|
|
});
|
||
|
|
fs.writeFileSync(callsFile, JSON.stringify(calls));
|
||
|
|
`,
|
||
|
|
)
|
||
|
|
|
||
|
|
const environment = { ...process.env, FORCE_COLOR: '1', NO_COLOR: '1' }
|
||
|
|
execFileSync(process.execPath, [cli, 'start', '--reset-cache'], {
|
||
|
|
cwd: root,
|
||
|
|
env: environment,
|
||
|
|
stdio: 'pipe',
|
||
|
|
})
|
||
|
|
execFileSync(process.execPath, [cli, 'run', 'android', '--device', 'emulator-5554'], {
|
||
|
|
cwd: root,
|
||
|
|
env: environment,
|
||
|
|
stdio: 'pipe',
|
||
|
|
})
|
||
|
|
|
||
|
|
const calls = JSON.parse(readFileSync(path.join(root, 'calls.json'), 'utf8'))
|
||
|
|
assert.deepEqual(calls[0].args, ['start', '--reset-cache'])
|
||
|
|
assert.deepEqual(calls[1].args, ['run-android', '--device', 'emulator-5554'])
|
||
|
|
assert.equal(calls[0].forceColor, '0')
|
||
|
|
assert.equal(calls[1].forceColor, '0')
|
||
|
|
assert.equal(calls[0].noColor, null)
|
||
|
|
assert.equal(calls[1].noColor, null)
|
||
|
|
} finally {
|
||
|
|
rmSync(root, { recursive: true, force: true })
|
||
|
|
}
|
||
|
|
})
|