fuzzyworld

explodorama / files / test / padGlyph.test.ts

padGlyph.test.ts

6.5 KB · history · blame

1import { existsSync } from 'node:fs'
2import { describe, expect, it } from 'vitest'
3import { glyphFor, shoulderGlyph, type GlyphButton } from '../src/ui/padGlyph'
4
5describe('shoulder glyphs (the board hint)', () => {
6 it('every family and side resolves to a file in assets/kenney-input-prompts', () => {
7 for (const family of ['playstation', 'xbox', 'nintendo', 'generic'] as const) {
8 for (const side of ['l', 'r'] as const) expect(existsSync(`assets/kenney-input-prompts/${shoulderGlyph(family, side)}.png`), `${family} ${side}`).toBe(true)
9 }
10 })
11 it('names: L1 / R1, LB / RB, L / R; any other pad gets the Xbox ones', () => {
12 expect(shoulderGlyph('playstation', 'l')).toBe('playstation_trigger_l1')
13 expect(shoulderGlyph('xbox', 'r')).toBe('xbox_rb')
14 expect(shoulderGlyph('nintendo', 'l')).toBe('switch_button_l')
15 expect(shoulderGlyph('generic', 'l')).toBe('xbox_lb')
16 })
17})
18
19const BUTTONS: GlyphButton[] = ['move', 'bomb', 'charge', 'wait']
20
21describe('controller glyphs on the action bar', () => {
22 it('every family and button resolves to a file in assets/kenney-input-prompts', () => {
23 for (const family of ['playstation', 'xbox', 'nintendo', 'generic'] as const) {
24 for (const button of BUTTONS) expect(existsSync(`assets/kenney-input-prompts/${glyphFor(family, button)}.png`), `${family} ${button}`).toBe(true)
25 }
26 })
27 it('PlayStation: Move Cross, Bomb Square, Charge Triangle, Wait Circle', () => {
28 expect(BUTTONS.map((b) => glyphFor('playstation', b))).toEqual([
29 'playstation_button_color_cross', 'playstation_button_color_square', 'playstation_button_color_triangle', 'playstation_button_color_circle',
30 ])
31 })
32 it('Xbox: Move A, Bomb X, Charge Y, Wait B; any other pad gets the same', () => {
33 expect(BUTTONS.map((b) => glyphFor('xbox', b))).toEqual(['xbox_button_color_a', 'xbox_button_color_x', 'xbox_button_color_y', 'xbox_button_color_b'])
34 expect(BUTTONS.map((b) => glyphFor('generic', b))).toEqual(BUTTONS.map((b) => glyphFor('xbox', b)))
35 })
36})
37
38describe('Nintendo: A confirms (right), B backs out (bottom)', () => {
39 it('Move is A, Wait is B, Bomb Y, Charge X', () => {
40 expect(glyphFor('nintendo', 'move')).toBe('switch_button_a')
41 expect(glyphFor('nintendo', 'wait')).toBe('switch_button_b')
42 expect(glyphFor('nintendo', 'bomb')).toBe('switch_button_y')
43 expect(glyphFor('nintendo', 'charge')).toBe('switch_button_x')
44 })
45 it('the raw buttons are by position: bottom B, right A, left Y, top X', async () => {
46 const { faceGlyph } = await import('../src/ui/padGlyph')
47 expect(([0, 1, 2, 3] as const).map((f) => faceGlyph('nintendo', f))).toEqual(['switch_button_b', 'switch_button_a', 'switch_button_y', 'switch_button_x'])
48 })
49 it('every action\'s picture is the picture of the face button that does it, in every family', async () => {
50 const { faceGlyph } = await import('../src/ui/padGlyph')
51 const { faceOf } = await import('../src/ui/padMap')
52 for (const family of ['playstation', 'xbox', 'nintendo', 'generic'] as const) {
53 for (const b of BUTTONS) expect(glyphFor(family, b), `${family} ${b}`).toBe(faceGlyph(family, faceOf(family, b)))
54 }
55 })
56 it('the demo caption {move} is A on a Nintendo pad', async () => {
57 const { padCaptionHtml } = await import('../src/ui/padGlyph')
58 expect(padCaptionHtml('Hold {move} to play', 'nintendo', (n) => n)).toContain('src="switch_button_a"')
59 })
60})
61
62describe('controller glyphs in dialogs', () => {
63 it('each raw face button has a file, per family', async () => {
64 const { faceGlyph } = await import('../src/ui/padGlyph')
65 for (const family of ['playstation', 'xbox', 'nintendo', 'generic'] as const) {
66 for (const face of [0, 1, 2, 3] as const) expect(existsSync(`assets/kenney-input-prompts/${faceGlyph(family, face)}.png`), `${family} ${face}`).toBe(true)
67 }
68 expect(faceGlyph('playstation', 0)).toBe('playstation_button_color_cross')
69 expect(faceGlyph('xbox', 1)).toBe('xbox_button_color_b')
70 expect(faceGlyph('playstation', 3)).toBe('playstation_button_color_triangle')
71 })
72})
73
74const FAMILIES = ['playstation', 'xbox', 'nintendo', 'generic'] as const
75
76describe('controller glyphs for the demo overlay', () => {
77 it('every family and direction resolves to a file', async () => {
78 const { dpadGlyph, stickGlyph, startGlyph } = await import('../src/ui/padGlyph')
79 for (const family of FAMILIES) {
80 for (const dir of ['none', 'up', 'down', 'left', 'right'] as const) expect(existsSync(`assets/kenney-input-prompts/${dpadGlyph(family, dir)}.png`), `${family} dpad ${dir}`).toBe(true)
81 for (const dir of ['none', 'left', 'right', 'up', 'down', 'press'] as const) expect(existsSync(`assets/kenney-input-prompts/${stickGlyph(family, dir)}.png`), `${family} stick ${dir}`).toBe(true)
82 expect(existsSync(`assets/kenney-input-prompts/${startGlyph(family)}.png`), `${family} start`).toBe(true)
83 }
84 })
85 it('names, and a pad that is none of the three gets the Xbox ones', async () => {
86 const { dpadGlyph, stickGlyph, startGlyph } = await import('../src/ui/padGlyph')
87 expect(dpadGlyph('playstation', 'up')).toBe('playstation_dpad_up')
88 expect(dpadGlyph('nintendo', 'none')).toBe('switch_dpad')
89 expect(stickGlyph('xbox', 'none')).toBe('xbox_stick_r')
90 expect(stickGlyph('xbox', 'press')).toBe('xbox_stick_r_press')
91 expect(startGlyph('playstation')).toBe('playstation5_button_options')
92 expect(startGlyph('nintendo')).toBe('switch_button_plus')
93 expect(dpadGlyph('generic', 'left')).toBe(dpadGlyph('xbox', 'left'))
94 expect(stickGlyph('generic', 'up')).toBe(stickGlyph('xbox', 'up'))
95 expect(startGlyph('generic')).toBe(startGlyph('xbox'))
96 })
97})
98
99describe('padCaptionHtml', () => {
100 it('replaces every token with the family\'s picture', async () => {
101 const { padCaptionHtml } = await import('../src/ui/padGlyph')
102 const html = padCaptionHtml('{dpad} {move} {bomb} {charge} {wait} {l1} {r1} {stick} {start}', 'playstation', (n) => `/${n}.png`)
103 expect(html).not.toContain('{')
104 expect(html.match(/<img class="pad-glyph"/g)).toHaveLength(9)
105 expect(html).toContain('src="/playstation_dpad.png"')
106 expect(html).toContain('src="/playstation_button_color_cross.png"')
107 expect(html).toContain('src="/playstation5_button_options.png"')
108 })
109 it('leaves the words alone, and throws on an unknown token', async () => {
110 const { padCaptionHtml } = await import('../src/ui/padGlyph')
111 expect(padCaptionHtml('Press now.', 'xbox', (n) => n)).toBe('Press now.')
112 expect(() => padCaptionHtml('Press {nope}.', 'xbox', (n) => n)).toThrow('nope')
113 })
114})