@zeix/cause-effect
Version:
Cause & Effect - reactive state management with signals.
157 lines (131 loc) • 4.57 kB
text/typescript
import { describe, test, expect } from 'bun:test'
import { isComputed, isState, state } from '../'
/* === Tests === */
describe('State', function () {
describe('State type guard', () => {
test('isState identifies state signals', () => {
const count = state(42)
expect(isState(count)).toBe(true)
expect(isComputed(count)).toBe(false)
})
})
describe('Boolean cause', function () {
test('should be boolean', function () {
const cause = state(false)
expect(typeof cause.get()).toBe('boolean')
})
test('should set initial value to false', function () {
const cause = state(false)
expect(cause.get()).toBe(false)
})
test('should set initial value to true', function () {
const cause = state(true)
expect(cause.get()).toBe(true)
})
test('should set new value with .set(true)', function () {
const cause = state(false)
cause.set(true)
expect(cause.get()).toBe(true)
})
test('should toggle initial value with .set(v => !v)', function () {
const cause = state(false)
cause.update(v => !v)
expect(cause.get()).toBe(true)
})
})
describe('Number cause', function () {
test('should be number', function () {
const cause = state(0)
expect(typeof cause.get()).toBe('number')
})
test('should set initial value to 0', function () {
const cause = state(0)
expect(cause.get()).toBe(0)
})
test('should set new value with .set(42)', function () {
const cause = state(0)
cause.set(42)
expect(cause.get()).toBe(42)
})
test('should increment value with .set(v => ++v)', function () {
const cause = state(0)
cause.update(v => ++v)
expect(cause.get()).toBe(1)
})
})
describe('String cause', function () {
test('should be string', function () {
const cause = state('foo')
expect(typeof cause.get()).toBe('string')
})
test('should set initial value to "foo"', function () {
const cause = state('foo')
expect(cause.get()).toBe('foo')
})
test('should set new value with .set("bar")', function () {
const cause = state('foo')
cause.set('bar')
expect(cause.get()).toBe('bar')
})
test('should upper case value with .set(v => v.toUpperCase())', function () {
const cause = state('foo')
cause.update(v => (v ? v.toUpperCase() : ''))
expect(cause.get()).toBe('FOO')
})
})
describe('Array cause', function () {
test('should be array', function () {
const cause = state([1, 2, 3])
expect(Array.isArray(cause.get())).toBe(true)
})
test('should set initial value to [1, 2, 3]', function () {
const cause = state([1, 2, 3])
expect(cause.get()).toEqual([1, 2, 3])
})
test('should set new value with .set([4, 5, 6])', function () {
const cause = state([1, 2, 3])
cause.set([4, 5, 6])
expect(cause.get()).toEqual([4, 5, 6])
})
test('should reflect current value of array after modification', function () {
const array = [1, 2, 3]
const cause = state(array)
array.push(4) // don't do this! the result will be correct, but we can't trigger effects
expect(cause.get()).toEqual([1, 2, 3, 4])
})
test('should set new value with .set([...array, 4])', function () {
const array = [1, 2, 3]
const cause = state(array)
cause.set([...array, 4]) // use destructuring instead!
expect(cause.get()).toEqual([1, 2, 3, 4])
})
})
describe('Object cause', function () {
test('should be object', function () {
const cause = state({ a: 'a', b: 1 })
expect(typeof cause.get()).toBe('object')
})
test('should set initial value to { a: "a", b: 1 }', function () {
const cause = state({ a: 'a', b: 1 })
expect(cause.get()).toEqual({ a: 'a', b: 1 })
})
test('should set new value with .set({ c: true })', function () {
const cause = state<Record<string, any>>({ a: 'a', b: 1 })
cause.set({ c: true })
expect(cause.get()).toEqual({ c: true })
})
test('should reflect current value of object after modification', function () {
const obj = { a: 'a', b: 1 }
const cause = state<Record<string, any>>(obj)
// @ts-expect-error Property 'c' does not exist on type '{ a: string; b: number; }'. (ts 2339)
obj.c = true // don't do this! the result will be correct, but we can't trigger effects
expect(cause.get()).toEqual({ a: 'a', b: 1, c: true })
})
test('should set new value with .set({...obj, c: true})', function () {
const obj = { a: 'a', b: 1 }
const cause = state<Record<string, any>>(obj)
cause.set({ ...obj, c: true }) // use destructuring instead!
expect(cause.get()).toEqual({ a: 'a', b: 1, c: true })
})
})
})