explodorama / files / test / changelog.test.ts
changelog.test.ts
5607bea2 2026-10-31 Pavel Safronov | 1 | import { readFileSync } from 'node:fs' |
| 2 | import { describe, expect, it } from 'vitest' | |
805e7a9f 2026-11-03 Pavel Safronov | 3 | import { spriteUrl } from '../src/render/sprites' |
5607bea2 2026-10-31 Pavel Safronov | 4 | import { compareVersions, newsFor, parseVersion, RELEASES, releasesSince, UNRELEASED, VERSION, type Release } from '../src/changelog' |
| 5 | ||
| 6 | const release = (version: string): Release => ({ version, date: '2026-01-01', summary: '', changes: [] }) | |
| 7 | ||
| 8 | describe('changelog', () => { | |
| 9 | it('the newest release is the version in package.json', () => { | |
| 10 | expect(VERSION).toBe(JSON.parse(readFileSync('package.json', 'utf8')).version) | |
| 11 | }) | |
| 12 | ||
| 13 | it('releases are valid semver, newest first, with no repeats', () => { | |
| 14 | for (const r of RELEASES) expect(parseVersion(r.version), r.version).not.toBeNull() | |
| 15 | for (let i = 1; i < RELEASES.length; i++) { | |
| 16 | expect(compareVersions(RELEASES[i - 1]!.version, RELEASES[i]!.version)).toBeGreaterThan(0) | |
| 17 | } | |
| 18 | }) | |
| 19 | ||
| 20 | it('every change has a date, a title and text', () => { | |
| 21 | for (const c of [...UNRELEASED, ...RELEASES.flatMap((r) => r.changes)]) { | |
| 22 | expect(c.date).toMatch(/^\d{4}-\d{2}-\d{2}$/) | |
| 23 | expect(c.title).not.toBe('') | |
| 24 | expect(c.text.length).toBeGreaterThan(0) | |
| 25 | } | |
| 26 | }) | |
| 27 | ||
805e7a9f 2026-11-03 Pavel Safronov | 28 | it('every change icon is a sprite the game loads', () => { |
| 29 | for (const c of [...UNRELEASED, ...RELEASES.flatMap((r) => r.changes)]) expect(() => spriteUrl(c.icon), c.title).not.toThrow() | |
| 30 | }) | |
| 31 | ||
5607bea2 2026-10-31 Pavel Safronov | 32 | it('compares numerically, not as text', () => { |
| 33 | expect(compareVersions('0.10.0', '0.9.0')).toBeGreaterThan(0) | |
| 34 | expect(compareVersions('1.0.0', '0.99.99')).toBeGreaterThan(0) | |
| 35 | expect(compareVersions('0.1.0', '0.1.0')).toBe(0) | |
| 36 | }) | |
| 37 | ||
| 38 | it('lists the releases after the last one played', () => { | |
| 39 | const all = [release('0.3.0'), release('0.2.0'), release('0.1.0')] | |
| 40 | expect(releasesSince('0.1.0', all).map((r) => r.version)).toEqual(['0.3.0', '0.2.0']) | |
| 41 | expect(releasesSince('0.3.0', all)).toEqual([]) | |
| 42 | expect(releasesSince('0.4.0', all)).toEqual([]) | |
| 43 | }) | |
| 44 | ||
| 45 | it('decides what a returning player sees', () => { | |
| 46 | const all = [release('0.2.0'), release('0.1.0')] | |
| 47 | expect(newsFor(null, all)).toEqual({ news: [], record: true }) | |
| 48 | expect(newsFor('0.1.0', all)).toEqual({ news: [all[0]], record: false }) | |
| 49 | expect(newsFor('0.2.0', all)).toEqual({ news: [], record: false }) | |
| 50 | expect(newsFor('0.3.0', all)).toEqual({ news: [], record: false }) | |
| 51 | // A stored value that isn't a version counts as older than any: everything is shown. | |
| 52 | expect(newsFor('junk', all).news).toEqual(all) | |
| 53 | }) | |
| 54 | ||
| 55 | it('the README states the current version', () => { | |
| 56 | expect(readFileSync('README.md', 'utf8')).toContain(`Version: **${VERSION}**`) | |
| 57 | }) | |
| 58 | }) |