mirror of
https://github.com/garrytan/gbrain.git
synced 2026-07-30 19:49:14 +00:00
Signed-off-by: arisgysel-design <arisgysel-design@users.noreply.github.com> Co-authored-by: arisgysel-design <arisgysel-design@users.noreply.github.com>
197 lines
5.6 KiB
TypeScript
197 lines
5.6 KiB
TypeScript
import { describe, test, expect } from 'bun:test';
|
|
import {
|
|
parseSemver,
|
|
isMinorOrMajorBump,
|
|
isNewerVersion,
|
|
extractChangelogBetween,
|
|
} from '../src/commands/check-update.ts';
|
|
|
|
describe('parseSemver', () => {
|
|
test('parses standard version', () => {
|
|
expect(parseSemver('0.4.0')).toEqual([0, 4, 0, 0]);
|
|
});
|
|
|
|
test('strips v prefix', () => {
|
|
expect(parseSemver('v0.5.0')).toEqual([0, 5, 0, 0]);
|
|
});
|
|
|
|
test('returns null for malformed version', () => {
|
|
expect(parseSemver('0.4')).toBeNull();
|
|
expect(parseSemver('abc')).toBeNull();
|
|
expect(parseSemver('')).toBeNull();
|
|
});
|
|
|
|
test('preserves the 4th micro segment', () => {
|
|
expect(parseSemver('0.2.0.1')).toEqual([0, 2, 0, 1]);
|
|
});
|
|
});
|
|
|
|
describe('isNewerVersion', () => {
|
|
test('detects the patch segment used by the gbrain release train', () => {
|
|
expect(isNewerVersion('0.42.10.0', '0.42.66.0')).toBe(true);
|
|
});
|
|
|
|
test('detects a micro follow-up release', () => {
|
|
expect(isNewerVersion('0.42.66.0', '0.42.66.1')).toBe(true);
|
|
});
|
|
|
|
test('rejects equal, older, and malformed versions', () => {
|
|
expect(isNewerVersion('0.42.66.0', '0.42.66.0')).toBe(false);
|
|
expect(isNewerVersion('0.42.66.1', '0.42.66.0')).toBe(false);
|
|
expect(isNewerVersion('0.42.66.0', 'garbage')).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe('isMinorOrMajorBump', () => {
|
|
test('0.4.0 vs 0.5.0 → update available (minor bump)', () => {
|
|
expect(isMinorOrMajorBump('0.4.0', '0.5.0')).toBe(true);
|
|
});
|
|
|
|
test('0.4.0 vs 0.4.1 → NOT available (patch only)', () => {
|
|
expect(isMinorOrMajorBump('0.4.0', '0.4.1')).toBe(false);
|
|
});
|
|
|
|
test('0.4.0 vs 1.0.0 → update available (major bump)', () => {
|
|
expect(isMinorOrMajorBump('0.4.0', '1.0.0')).toBe(true);
|
|
});
|
|
|
|
test('0.4.0 vs 0.4.0 → NOT available (same version)', () => {
|
|
expect(isMinorOrMajorBump('0.4.0', '0.4.0')).toBe(false);
|
|
});
|
|
|
|
test('0.4.0 vs 0.3.0 → NOT available (older)', () => {
|
|
expect(isMinorOrMajorBump('0.4.0', '0.3.0')).toBe(false);
|
|
});
|
|
|
|
test('0.4.1 vs 0.5.0 → update available (minor bump, different patch)', () => {
|
|
expect(isMinorOrMajorBump('0.4.1', '0.5.0')).toBe(true);
|
|
});
|
|
|
|
test('malformed version → returns false', () => {
|
|
expect(isMinorOrMajorBump('0.4.0', 'abc')).toBe(false);
|
|
expect(isMinorOrMajorBump('bad', '0.5.0')).toBe(false);
|
|
});
|
|
|
|
test('handles v prefix on latest', () => {
|
|
expect(isMinorOrMajorBump('0.4.0', 'v0.5.0')).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe('extractChangelogBetween', () => {
|
|
const changelog = `# Changelog
|
|
|
|
## [0.5.0] - 2026-05-01
|
|
|
|
### Added
|
|
- Feature X
|
|
|
|
## [0.4.1] - 2026-04-15
|
|
|
|
### Fixed
|
|
- Bug Y
|
|
|
|
## [0.4.0] - 2026-04-09
|
|
|
|
### Added
|
|
- Feature Z
|
|
|
|
## [0.3.0] - 2026-04-08
|
|
|
|
### Added
|
|
- Feature W
|
|
`;
|
|
|
|
test('extracts entries between 0.4.0 and 0.5.0', () => {
|
|
const result = extractChangelogBetween(changelog, '0.4.0', '0.5.0');
|
|
expect(result).toContain('Feature X');
|
|
expect(result).toContain('Bug Y');
|
|
expect(result).not.toContain('Feature Z');
|
|
expect(result).not.toContain('Feature W');
|
|
});
|
|
|
|
test('extracts only 0.5.0 when upgrading from 0.4.1', () => {
|
|
const result = extractChangelogBetween(changelog, '0.4.1', '0.5.0');
|
|
expect(result).toContain('Feature X');
|
|
expect(result).not.toContain('Bug Y');
|
|
});
|
|
|
|
test('returns empty for same version', () => {
|
|
const result = extractChangelogBetween(changelog, '0.5.0', '0.5.0');
|
|
expect(result).toBe('');
|
|
});
|
|
|
|
test('returns empty for malformed from version', () => {
|
|
const result = extractChangelogBetween(changelog, 'bad', '0.5.0');
|
|
expect(result).toBe('');
|
|
});
|
|
|
|
test('does not capture older major versions incorrectly', () => {
|
|
const crossMajor = `# Changelog
|
|
|
|
## [2.0.0] - 2026-06-01
|
|
### Added
|
|
- Major 2
|
|
|
|
## [0.5.0] - 2026-05-01
|
|
### Added
|
|
- Minor 5
|
|
`;
|
|
const result = extractChangelogBetween(crossMajor, '1.2.0', '2.0.0');
|
|
expect(result).toContain('Major 2');
|
|
expect(result).not.toContain('Minor 5');
|
|
});
|
|
|
|
test('distinguishes micro releases', () => {
|
|
const micro = `# Changelog
|
|
|
|
## [0.42.66.1] - 2026-07-26
|
|
- Follow-up fix
|
|
|
|
## [0.42.66.0] - 2026-07-25
|
|
- Original release
|
|
`;
|
|
const result = extractChangelogBetween(micro, '0.42.66.0', '0.42.66.1');
|
|
expect(result).toContain('Follow-up fix');
|
|
expect(result).not.toContain('Original release');
|
|
});
|
|
});
|
|
|
|
describe('check-update CLI', () => {
|
|
test('check-update is in CLI_ONLY set', async () => {
|
|
const source = await Bun.file(
|
|
new URL('../src/cli.ts', import.meta.url).pathname
|
|
).text();
|
|
expect(source).toContain("'check-update'");
|
|
});
|
|
|
|
test('--help prints usage and exits 0', async () => {
|
|
const proc = Bun.spawn(['bun', 'run', 'src/cli.ts', 'check-update', '--help'], {
|
|
cwd: new URL('..', import.meta.url).pathname,
|
|
stdout: 'pipe',
|
|
stderr: 'pipe',
|
|
});
|
|
const stdout = await new Response(proc.stdout).text();
|
|
const exitCode = await proc.exited;
|
|
expect(stdout).toContain('check-update');
|
|
expect(exitCode).toBe(0);
|
|
});
|
|
|
|
test('--json returns valid JSON with required fields', async () => {
|
|
const proc = Bun.spawn(['bun', 'run', 'src/cli.ts', 'check-update', '--json'], {
|
|
cwd: new URL('..', import.meta.url).pathname,
|
|
stdout: 'pipe',
|
|
stderr: 'pipe',
|
|
});
|
|
const stdout = await new Response(proc.stdout).text();
|
|
const exitCode = await proc.exited;
|
|
expect(exitCode).toBe(0);
|
|
|
|
const output = JSON.parse(stdout);
|
|
expect(output).toHaveProperty('current_version');
|
|
expect(output).toHaveProperty('update_available');
|
|
expect(output).toHaveProperty('upgrade_command');
|
|
expect(output).toHaveProperty('current_source', 'package-json');
|
|
expect(typeof output.update_available).toBe('boolean');
|
|
});
|
|
});
|