// @vitest-environment jsdom import { expect, test } from 'vitest'; import { applyWoodenFishTap, chooseWoodenFishFloatingWord, formatWoodenFishFloatingText, isWoodenFishFunctionalTarget, normalizeWoodenFishFloatingWords, } from './woodenFishRuntimeModel'; test('applyWoodenFishTap creates word counter on first appearance', () => { const snapshot = applyWoodenFishTap( { totalTapCount: 0, wordCounters: [], }, '幸运', ); expect(snapshot).toEqual({ totalTapCount: 1, wordCounters: [{ text: '幸运', count: 1 }], }); }); test('applyWoodenFishTap keeps counting repeated and rapid taps', () => { const first = applyWoodenFishTap( { totalTapCount: 0, wordCounters: [], }, '功德', ); const second = applyWoodenFishTap(first, '功德'); const third = applyWoodenFishTap(second, '健康'); expect(third.totalTapCount).toBe(3); expect(third.wordCounters).toEqual([ { text: '功德', count: 2 }, { text: '健康', count: 1 }, ]); }); test('chooseWoodenFishFloatingWord samples normalized words by random index', () => { expect(chooseWoodenFishFloatingWord(['幸运', '功德'], () => 0.72)).toBe( '功德', ); expect(chooseWoodenFishFloatingWord([], () => 0)).toBe('幸运'); }); test('floating word model stores base terms and formats runtime reward text', () => { expect(normalizeWoodenFishFloatingWords([' 幸运+1 ', '幸运', '健康+1'])).toEqual( ['幸运', '健康'], ); expect(formatWoodenFishFloatingText('幸运')).toBe('幸运+1'); expect(formatWoodenFishFloatingText('功德+1')).toBe('功德+1'); }); test('isWoodenFishFunctionalTarget detects functional controls', () => { const root = document.createElement('div'); const button = document.createElement('button'); button.dataset.woodenFishFunctional = 'true'; const icon = document.createElement('span'); button.appendChild(icon); root.appendChild(button); expect(isWoodenFishFunctionalTarget(icon)).toBe(true); expect(isWoodenFishFunctionalTarget(root)).toBe(false); });