import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; import { bumpPatch, listAndroidReleases, nextAndroidVersion, parseAndroidTag, readBaseline, } from './android-version.mjs'; const gradle = readFileSync( join(dirname(fileURLToPath(import.meta.url)), '../android/app/build.gradle'), 'utf8', ); const floor = { versionName: '0.1.0', versionCode: 1 }; describe('android version', () => { it('reads the floor still written in build.gradle', () => { assert.deepEqual(readBaseline(gradle), floor); }); it('assigns versionCode from a resolved int, not a parenthesized cast', () => { assert.match(gradle, /versionCode resolvedVersionCode/); assert.doesNotMatch(gradle, /versionCode\s*\(/); }); it('parses Play release tags and ignores other tags', () => { assert.deepEqual(parseAndroidTag('android-v1.0.2-3'), { versionName: '1.0.2', versionCode: 3, }); assert.equal(parseAndroidTag('web-v1.0.2'), null); }); it('bumps the patch', () => { assert.equal(bumpPatch('0.1.0'), '0.1.1'); assert.equal(bumpPatch('1.0.9'), '1.0.10'); }); it('steps past the floor when nothing has been released yet', () => { assert.deepEqual( nextAndroidVersion({ baseline: floor, releases: [], sha: 'abc' }), { versionName: '0.1.1', versionCode: 2, reused: false, }, ); }); it('reuses the release that already points at this commit', () => { assert.deepEqual( nextAndroidVersion({ baseline: floor, sha: 'abc', releases: [{ versionName: '0.1.1', versionCode: 2, sha: 'abc' }], }), { versionName: '0.1.1', versionCode: 2, reused: true }, ); }); it('bumps from the highest release rather than the gradle floor', () => { assert.deepEqual( nextAndroidVersion({ baseline: floor, sha: 'def', releases: [ { versionName: '0.1.1', versionCode: 2, sha: 'abc' }, { versionName: '0.1.4', versionCode: 5, sha: 'old' }, ], }), { versionName: '0.1.5', versionCode: 6, reused: false }, ); }); it('keeps a hand-raised floor ahead of older releases', () => { assert.deepEqual( nextAndroidVersion({ baseline: { versionName: '1.1.0', versionCode: 10 }, sha: 'def', releases: [{ versionName: '0.1.4', versionCode: 5, sha: 'old' }], }), { versionName: '1.1.1', versionCode: 11, reused: false }, ); }); it('lists only android release tags', async () => { const fetchImpl = async () => ({ ok: true, status: 200, json: async () => [ { tag_name: 'android-v0.1.1-2', target_commitish: 'abc' }, { tag_name: 'v0.1.1', target_commitish: 'nope' }, ], }); await assert.doesNotReject( listAndroidReleases({ apiUrl: 'https://git.example/api/v1', token: 'token', owner: 'ai_ml_operations', repo: 'chat_web_app', fetchImpl, }).then((releases) => { assert.deepEqual(releases, [ { versionName: '0.1.1', versionCode: 2, sha: 'abc' }, ]); }), ); }); });