Files
tevansandClaude Opus 4.8 549cb190d2 feat: <dice-tray> roller wired to rule-packs
Implement Task 10: dice-tray Web Component with:
- Polyhedral die picker (d4-d20, d100)
- Deterministic roll() using injected RNG
- Rule-pack interpretation for successes/ones/verdict
- Event emission on roll completion
- Reactive rendering on die type/count change

TDD: 3 passing tests (picker render, roll+interpret+verdict, die-type switching)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 14:05:52 +01:00

37 lines
1.2 KiB
JavaScript

import { describe, it, expect, beforeEach } from 'vitest';
import '../../src/components/dice-tray.js';
function seq(values) { let i = 0; return () => values[i++ % values.length]; }
describe('<dice-tray>', () => {
let el;
beforeEach(() => {
document.body.innerHTML = '';
el = document.createElement('dice-tray');
el.systemId = 'year-zero';
document.body.appendChild(el);
});
it('renders the polyhedral picker', () => {
expect(el.querySelector('[data-sides="20"]')).not.toBe(null);
expect(el.querySelector('[data-sides="4"]')).not.toBe(null);
});
it('rolls, interprets via the rule-pack, and reports successes', () => {
el.sides = 8; el.count = 3;
el.rng = seq([0.9, 0.0, 0.7]); // d8 -> 8, 1, 6 => 2 successes, 1 one
let detail = null;
el.addEventListener('rolled', (e) => { detail = e.detail; });
el.roll();
expect(el.last.verdict.successes).toBe(2);
expect(el.last.verdict.ones).toBe(1);
expect(detail.verdict.successes).toBe(2);
expect(el.querySelector('[data-role=verdict]').textContent).toContain('2 success');
});
it('changes die type when a picker button is clicked', () => {
el.querySelector('[data-sides="20"]').click();
expect(el.sides).toBe(20);
});
});