storebound/tests/deps.test.ts

36 lines
2.4 KiB
TypeScript

// Build dependencies: the JDK the project needs, version parsing, and doctor --install planning.
import { describe, expect, test } from 'bun:test';
import { mkdirSync, mkdtempSync, writeFileSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
import { installPlan, type DoctorResult } from '../cli/doctor';
import { installCommands, majorOf, parseVersion, requiredJdk } from '../cli/lib/tools';
function project(files: Record<string, string>): string {
const dir = mkdtempSync(join(tmpdir(), 'sb-deps-'));
for (const [p, text] of Object.entries(files)) { mkdirSync(join(dir, p, '..'), { recursive: true }); writeFileSync(join(dir, p), text); }
return dir;
}
describe('build dependencies', () => {
test('JDK version from java -version and majors', () => {
expect(parseVersion('openjdk version "17.0.9" 2023-10-17')).toBe('17.0.9');
expect(parseVersion('java version "1.8.0_392"')).toBe('1.8.0_392');
expect(majorOf('17.0.9')).toBe(17);
expect(majorOf('1.8.0_392')).toBe(8);
});
test('the JDK a project needs: AGP minimum, jvmToolchain wins when higher', () => {
expect(requiredJdk(project({ 'android/build.gradle': "classpath 'com.android.tools.build:gradle:8.7.2'" }))).toBe('17');
expect(requiredJdk(project({ 'android/build.gradle': "classpath 'com.android.tools.build:gradle:7.4.2'" }))).toBe('11');
expect(requiredJdk(project({ 'android/gradle/libs.versions.toml': 'agp = "8.5.0"', 'android/app/build.gradle.kts': 'kotlin { jvmToolchain(21) }' }))).toBe('21');
expect(requiredJdk(project({ 'package.json': '{}' }))).toBeNull();
});
test('install commands per OS; doctor --install runs only package-manager commands, never sudo', () => {
expect(installCommands('java', 'win32')[0]).toBe('winget install --id EclipseAdoptium.Temurin.17.JDK');
expect(installCommands('sdkmanager', 'darwin')[0]).toBe('brew install --cask android-commandlinetools');
const r = { tools: [{ id: 'java', name: 'JDK (Java)', found: false, version: null, path: null, source: null, usedFor: '', install: [], url: null, status: 'missing' }] } as unknown as DoctorResult;
expect(installPlan(r, 'java', 'win32')).toMatchObject({ command: 'winget install --id EclipseAdoptium.Temurin.17.JDK', runnable: true });
expect(installPlan(r, 'java', 'linux').runnable).toBe(false);
expect(() => installPlan(r, 'nope', 'win32')).toThrow('no tool "nope"');
});
});