slop game oder so
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
|
||||
import { ORBITAL } from '../../app/static/js/config.js';
|
||||
import {
|
||||
codeToDirection,
|
||||
ComboInput,
|
||||
isPrefix,
|
||||
validateCommands,
|
||||
} from '../../app/static/js/logic/comboInput.js';
|
||||
|
||||
const COMMANDS = [
|
||||
{ id: 'strike', sequence: ['up', 'right', 'down', 'down'] },
|
||||
{ id: 'supply', sequence: ['down', 'down', 'up', 'right'] },
|
||||
{ id: 'turret', sequence: ['down', 'up', 'right', 'right', 'up'] },
|
||||
];
|
||||
|
||||
const typeAll = (combo, dirs) => dirs.map((d) => combo.push(d));
|
||||
|
||||
describe('codeToDirection', () => {
|
||||
it('bildet Pfeiltasten und WASD (physische Position) ab', () => {
|
||||
expect(codeToDirection('ArrowUp')).toBe('up');
|
||||
expect(codeToDirection('KeyW')).toBe('up');
|
||||
expect(codeToDirection('KeyA')).toBe('left');
|
||||
expect(codeToDirection('ArrowRight')).toBe('right');
|
||||
expect(codeToDirection('KeyS')).toBe('down');
|
||||
expect(codeToDirection('KeyQ')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isPrefix', () => {
|
||||
it('erkennt Anfänge von Folgen', () => {
|
||||
expect(isPrefix([], ['up'])).toBe(true);
|
||||
expect(isPrefix(['up'], ['up', 'down'])).toBe(true);
|
||||
expect(isPrefix(['down'], ['up', 'down'])).toBe(false);
|
||||
expect(isPrefix(['up', 'down', 'up'], ['up', 'down'])).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateCommands', () => {
|
||||
it('akzeptiert die Befehle aus der Konfiguration', () => {
|
||||
expect(() => validateCommands(ORBITAL.commands)).not.toThrow();
|
||||
});
|
||||
|
||||
it('lehnt Folgen ab, die Anfang einer anderen sind', () => {
|
||||
expect(() =>
|
||||
validateCommands([
|
||||
{ id: 'a', sequence: ['up', 'down'] },
|
||||
{ id: 'b', sequence: ['up', 'down', 'left'] },
|
||||
]),
|
||||
).toThrow(/Anfang/);
|
||||
});
|
||||
|
||||
it('lehnt doppelte IDs, leere Folgen und unbekannte Richtungen ab', () => {
|
||||
expect(() => validateCommands([{ id: 'a', sequence: ['up'] }, { id: 'a', sequence: ['down'] }])).toThrow();
|
||||
expect(() => validateCommands([{ id: 'a', sequence: [] }])).toThrow();
|
||||
expect(() => validateCommands([{ id: 'a', sequence: ['oben'] }])).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('ComboInput', () => {
|
||||
it('ignoriert Eingaben, solange die Halte-Taste nicht gedrückt ist', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
expect(combo.push('up').status).toBe('inactive');
|
||||
});
|
||||
|
||||
it('erkennt eine vollständige Folge', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
combo.begin();
|
||||
const results = typeAll(combo, ['up', 'right', 'down', 'down']);
|
||||
expect(results.slice(0, 3).map((r) => r.status)).toEqual(['progress', 'progress', 'progress']);
|
||||
expect(results[3]).toEqual({ status: 'match', commandId: 'strike' });
|
||||
expect(combo.buffer).toEqual([]);
|
||||
});
|
||||
|
||||
it('meldet passende Kandidaten während der Eingabe', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
combo.begin();
|
||||
expect(combo.push('down')).toEqual({ status: 'progress', candidates: ['supply', 'turret'] });
|
||||
expect(combo.push('up')).toEqual({ status: 'progress', candidates: ['turret'] });
|
||||
});
|
||||
|
||||
it('meldet Fehleingaben und erlaubt direkt einen neuen Versuch', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
combo.begin();
|
||||
combo.push('up');
|
||||
expect(combo.push('up').status).toBe('fail');
|
||||
expect(combo.buffer).toEqual([]);
|
||||
const retry = typeAll(combo, ['down', 'down', 'up', 'right']);
|
||||
expect(retry.at(-1)).toEqual({ status: 'match', commandId: 'supply' });
|
||||
});
|
||||
|
||||
it('erlaubt mehrere Befehle hintereinander, solange die Taste gehalten wird', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
combo.begin();
|
||||
expect(typeAll(combo, ['up', 'right', 'down', 'down']).at(-1).commandId).toBe('strike');
|
||||
expect(typeAll(combo, ['down', 'up', 'right', 'right', 'up']).at(-1).commandId).toBe('turret');
|
||||
});
|
||||
|
||||
it('verwirft halbe Eingaben beim Loslassen', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
combo.begin();
|
||||
typeAll(combo, ['up', 'right']);
|
||||
combo.end();
|
||||
combo.begin();
|
||||
expect(combo.push('down').status).toBe('progress');
|
||||
expect(combo.buffer).toEqual(['down']);
|
||||
});
|
||||
|
||||
it('ignoriert unbekannte Richtungen ohne den Puffer zu verändern', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
combo.begin();
|
||||
combo.push('up');
|
||||
expect(combo.push('diagonal').status).toBe('ignored');
|
||||
expect(combo.buffer).toEqual(['up']);
|
||||
});
|
||||
|
||||
it('zeigt den Fortschritt je Befehl für das HUD', () => {
|
||||
const combo = new ComboInput(COMMANDS);
|
||||
combo.begin();
|
||||
typeAll(combo, ['down', 'down']);
|
||||
expect(combo.progressFor('supply')).toBe(2);
|
||||
expect(combo.progressFor('turret')).toBe(0);
|
||||
expect(combo.progressFor('strike')).toBe(0);
|
||||
expect(combo.progressFor('unbekannt')).toBe(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user