explodorama / files / test / changelog.test.ts
changelog.test.ts
| 1 | import { readFileSync } from 'node:fs' |
| 2 | import { describe, expect, it } from 'vitest' |
| 3 | import { spriteUrl } from '../src/render/sprites' |
| 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 | |
| 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 | |
| 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 | }) |