75 lines
3.9 KiB
TypeScript
75 lines
3.9 KiB
TypeScript
import { describe, expect, test } from 'bun:test';
|
|
import { mkdirSync, mkdtempSync, readFileSync, writeFileSync } from 'node:fs';
|
|
import { tmpdir } from 'node:os';
|
|
import { join } from 'node:path';
|
|
import { spawnSync } from 'node:child_process';
|
|
import { appleMinSdk, appleSdkProblem, PLAY_TARGET_SDK_TABLE, playTargetSdk, playTargetSdkProblem, targetSdkFile } from '../cli/lib/store-minimums';
|
|
import { readRegistry } from '../cli/lib/registry';
|
|
|
|
const ROOT = join(import.meta.dir, '..');
|
|
|
|
describe('Google Play target API level', () => {
|
|
test('the dated table picks the row in force', () => {
|
|
expect(playTargetSdk('phone', '2026-08-30')!.min).toBe(35);
|
|
expect(playTargetSdk('phone', '2026-08-31')!.min).toBe(36);
|
|
expect(playTargetSdk('wear', '2026-10-20')!.min).toBe(35);
|
|
expect(PLAY_TARGET_SDK_TABLE.map(r => r.since)).toEqual([...PLAY_TARGET_SDK_TABLE.map(r => r.since)].sort());
|
|
});
|
|
test('below the minimum: requirement, date and fix in one line', () => {
|
|
const m = playTargetSdkProblem(35, { date: '2026-10-20', where: 'android/variables.gradle' })!;
|
|
expect(m).toContain('targetSdkVersion 35 < 36');
|
|
expect(m).toContain('2026-08-31');
|
|
expect(m).toContain('set targetSdkVersion = 36');
|
|
expect(m).toContain('android/variables.gradle');
|
|
expect(playTargetSdkProblem(36, { date: '2026-10-20' })).toBeNull();
|
|
expect(playTargetSdkProblem(undefined)).toBeNull();
|
|
});
|
|
test('the fix names the file that sets it (Capacitor variables.gradle)', () => {
|
|
const d = mkdtempSync(join(tmpdir(), 'sb-sdk-'));
|
|
mkdirSync(join(d, 'android'));
|
|
writeFileSync(join(d, 'android/variables.gradle'), 'ext {\n targetSdkVersion = 35\n}\n');
|
|
expect(targetSdkFile(d)).toBe('android/variables.gradle');
|
|
});
|
|
});
|
|
|
|
describe('App Store minimum Xcode / SDK', () => {
|
|
test('table and IPA build fields', () => {
|
|
expect(appleMinSdk('2026-05-01')).toMatchObject({ xcode: 26, sdk: 26 });
|
|
expect(appleMinSdk('2026-04-01')).toMatchObject({ xcode: 16, sdk: 18 });
|
|
const m = appleSdkProblem({ xcode: '1640', sdkName: 'iphoneos18.4', platformVersion: '18.4' }, '2026-10-20')!;
|
|
expect(m).toContain('Xcode 16');
|
|
expect(m).toContain('Xcode 26');
|
|
expect(m).toContain('2026-04-28');
|
|
expect(appleSdkProblem({ xcode: '2600', sdkName: 'iphoneos26.0', platformVersion: '26.0' }, '2026-10-20')).toBeNull();
|
|
expect(appleSdkProblem({}, '2026-10-20')).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe('apps folders add', () => {
|
|
const cli = (cwd: string, reg: string, ...args: string[]) => spawnSync(process.execPath, [join(ROOT, 'cli/index.ts'), ...args], { cwd, encoding: 'utf8', env: { ...process.env, STOREBOUND_REGISTRY: reg, STOREBOUND_NO_UPDATE: '1' } });
|
|
const fresh = () => {
|
|
const d = mkdtempSync(join(tmpdir(), 'sb-folder-'));
|
|
writeFileSync(join(d, 'storebound.config.ts'), "export default { app: { name: 'Example App' }, apple: { bundleId: 'com.example.app' } };\n");
|
|
return { d, reg: join(d, 'reg.json') };
|
|
};
|
|
test('a freshly init-ed folder is added (bare form = cwd), with a template note', () => {
|
|
const { d, reg } = fresh();
|
|
const r = cli(d, reg, 'apps', 'folders', 'add');
|
|
expect(r.status).toBe(0);
|
|
expect(readRegistry(reg).projects.map(p => p.path)).toEqual([readRegistry(reg).projects[0]!.path]);
|
|
expect(readRegistry(reg).projects[0]!.path.endsWith(d.split('/').pop()!)).toBe(true);
|
|
expect(r.stderr + r.stdout).toContain("'Example App'");
|
|
});
|
|
test('with a path, like apps add', () => {
|
|
const { d, reg } = fresh();
|
|
expect(cli(tmpdir(), reg, 'apps', 'folders', 'add', d).status).toBe(0);
|
|
expect(JSON.parse(readFileSync(reg, 'utf8')).projects).toHaveLength(1);
|
|
});
|
|
test('no config: refused with the reason and the fix', () => {
|
|
const d = mkdtempSync(join(tmpdir(), 'sb-empty-'));
|
|
const r = cli(d, join(d, 'reg.json'), 'apps', 'folders', 'add');
|
|
expect(r.status).not.toBe(0);
|
|
expect(r.stderr).toContain('no storebound config');
|
|
expect(r.stderr).toContain('storebound init');
|
|
});
|
|
});
|