import { describe, it, expect } from 'vitest'; import { RemoteData, fromLoadLifecycle, map2, map, successOf } from './remote-data'; import { loading, failure, empty, success } from '../testing/remote-data'; const loadingRd: RemoteData = loading(); const failureRd: RemoteData = failure('x'); const ok = (n: number): RemoteData => success(n); describe('RemoteData combinators', () => { it('map only touches Success', () => { const times10 = (n: number) => n * 10; expect(map(ok(2), times10)).toEqual({ tag: 'Success', value: 20 }); expect(map(loadingRd, times10)).toEqual(loadingRd); }); it('map2 precedence: Failure > Loading > Success', () => { const add = (a: number, b: number) => a + b; expect(map2(failureRd, ok(1), add)).toEqual(failureRd); // a failed expect(map2(ok(1), failureRd, add)).toEqual(failureRd); // b failed expect(map2(loadingRd, ok(1), add)).toEqual({ tag: 'Loading' }); expect(map2(ok(2), ok(3), add)).toEqual({ tag: 'Success', value: 5 }); }); }); describe('successOf', () => { it('unwraps a Success value', () => { expect(successOf(ok(2))).toBe(2); }); it('is undefined for every other state', () => { expect(successOf(loadingRd)).toBeUndefined(); expect(successOf(failureRd)).toBeUndefined(); expect(successOf(empty())).toBeUndefined(); }); }); describe('fromLoadLifecycle', () => { it('maps Loading → Loading', () => { expect(fromLoadLifecycle({ tag: 'Loading' })).toEqual(loading()); }); it('maps Failed → Failure carrying an Error with the reason', () => { const rd = fromLoadLifecycle({ tag: 'Failed', reason: 'boom' }); expect(rd.tag).toBe('Failure'); if (rd.tag === 'Failure') expect(rd.error.message).toBe('boom'); }); it('maps Loaded → Success carrying the whole loaded state', () => { const loadedState = { tag: 'Loaded', foo: 42 } as const; expect(fromLoadLifecycle(loadedState)).toEqual(success(loadedState)); }); });