import React, { Suspense } from "react" import { render, fireEvent, screen } from "@testing-library/react" import { connectObservable, suspend, suspended, switchMapSuspended, } from "../src" import { from, of, defer, Subject, concat } from "rxjs" import { renderHook } from "@testing-library/react-hooks" import { delay, scan, take, mergeMapTo } from "rxjs/operators" const wait = (ms: number) => new Promise(res => setTimeout(res, ms)) describe("connectObservable", () => { const originalError = console.error beforeAll(() => { console.error = (...args: any) => { if (/Warning.*not wrapped in act/.test(args[0])) { return } originalError.call(console, ...args) } }) afterAll(() => { console.error = originalError }) it("sets the initial state synchronously if it's available", async () => { const observable$ = of(1) const [useLatestNumber] = connectObservable(observable$) const { result } = renderHook(() => useLatestNumber()) expect(result.current).toEqual(1) }) it("shares the source subscription until the refCount has stayed at zero for the grace-period", async () => { let nInitCount = 0 const observable$ = defer(() => { nInitCount += 1 return from([1, 2, 3, 4, 5]) }) const [useLatestNumber] = connectObservable(observable$, { unsubscribeGraceTime: 100, }) const { unmount } = renderHook(() => useLatestNumber()) const { unmount: unmount2 } = renderHook(() => useLatestNumber()) const { unmount: unmount3 } = renderHook(() => useLatestNumber()) expect(nInitCount).toBe(1) unmount() unmount2() unmount3() await wait(90) const { unmount: unmount4 } = renderHook(() => useLatestNumber()) expect(nInitCount).toBe(1) unmount4() await wait(110) renderHook(() => useLatestNumber()) expect(nInitCount).toBe(2) }) it("works with suspense", async () => { const subject$ = new Subject() const source$ = concat( subject$.pipe( take(2), scan(a => a + 1, 0), switchMapSuspended(x => of(x).pipe(delay(100))), ), subject$.pipe(take(1), mergeMapTo(of(3).pipe(delay(100), suspended()))), subject$.pipe(take(1), mergeMapTo(suspend(of(4).pipe(delay(100))))), ) const [useDelayedNumber] = connectObservable(source$) const Result: React.FC = () =>