UNPKG

@zeix/cause-effect

Version:

Cause & Effect - reactive state management with signals.

101 lines (83 loc) 2.26 kB
import { describe, test, expect } from 'bun:test' import { state, computed, effect, batch } from '../' /* === Utility Functions === */ const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms)) /* === Tests === */ describe('Batch', function () { test('should be triggered only once after repeated state change', function() { const cause = state(0) let result = 0 let count = 0 cause.tap(res => { result = res count++ }) batch(() => { for (let i = 1; i <= 10; i++) { cause.set(i) } }) expect(result).toBe(10) expect(count).toBe(2); // + 1 for effect initialization }) test('should be triggered only once when multiple signals are set', function() { const a = state(3) const b = state(4) const c = state(5) const sum = computed(() => a.get() + b.get() + c.get()) let result = 0 let count = 0 sum.tap({ ok: res => { result = res count++ }, err: () => {}, }) batch(() => { a.set(6) b.set(8) c.set(10) }) expect(result).toBe(24) expect(count).toBe(2); // + 1 for effect initialization }) test('should prove example from README works', function() { // State: define an array of Signal<number> const signals = [state(2), state(3), state(5)] // Computed: derive a calculation ... const sum = computed(() => signals.reduce((total, v) => total + v.get(), 0)) .map(v => { // ... perform validation and handle errors if (!Number.isFinite(v)) throw new Error('Invalid value') return v }) let result = 0 let okCount = 0 let errCount = 0 // Effect: switch cases for the result sum.tap({ ok: v => { result = v okCount++ // console.log('Sum:', v) }, err: _error => { errCount++ // console.error('Error:', error) } }) expect(okCount).toBe(1) expect(result).toBe(10) // Batch: apply changes to all signals in a single transaction batch(() => { signals.forEach(signal => signal.update(v => v * 2)) }) expect(okCount).toBe(2) expect(result).toBe(20) // Provoke an error signals[0].set(NaN) expect(errCount).toBe(1) expect(okCount).toBe(2); // should not have changed due to error expect(result).toBe(20); // should not have changed due to error }) })