diff --git a/js/test/demo-hooks.test.tsx b/js/test/demo-hooks.test.tsx index da225ad1..ca7282f4 100644 --- a/js/test/demo-hooks.test.tsx +++ b/js/test/demo-hooks.test.tsx @@ -1,34 +1,109 @@ -/** - * @jest-environment jsdom - */ - -import { ApiProvider } from '@gear-js/react-hooks'; +import { HexString } from '@gear-js/api'; +import * as GearHooks from '@gear-js/react-hooks'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { renderHook as renderReactHook, waitFor } from '@testing-library/react'; +import { renderHook as renderReactHook } from '@testing-library/react'; import { ReactNode } from 'react'; +import { test, expect, vi } from 'vitest'; import { Program } from './demo/lib'; -import { useProgram } from './demo/hooks'; +import { + useCounterAddedEvent, + useCounterValueQuery, + useDogAvgWeightQuery, + useDogBarkedEvent, + usePrepareCounterAddTransaction, + usePrepareDogMakeSoundTransaction, + usePreparePingPongPingTransaction, + usePrepareReferencesSetNumTransaction, + usePrepareThisThatNoopTransaction, + useProgram, + useReferencesLastByteQuery, + useSendCounterAddTransaction, + useSendDogMakeSoundTransaction, + useSendPingPongPingTransaction, + useSendReferencesSetNumTransaction, + useSendThisThatNoopTransaction, + useThisThatThatQuery, +} from './demo/hooks'; -const API_ARGS = { endpoint: 'ws://127.0.0.1:9944' }; const QUERY_CLIENT = new QueryClient(); +const useProgramSpy = vi.spyOn(GearHooks, 'useProgram'); +const useSendTransactionSpy = vi.spyOn(GearHooks, 'useSendProgramTransaction'); +const usePrepareTransactionSpy = vi.spyOn(GearHooks, 'usePrepareProgramTransaction'); +const useQuerySpy = vi.spyOn(GearHooks, 'useProgramQuery'); +const useEventSpy = vi.spyOn(GearHooks, 'useProgramEvent'); + const Providers = ({ children }: { children: ReactNode }) => ( - - {children} - + {children} ); const renderHook = (hook: (initialProps: TProps) => TReturn) => renderReactHook(hook, { wrapper: Providers }); -describe('program hook', () => { - test('useProgram hook', async () => { - const { result } = renderHook(() => useProgram({ id: '0x01' })); +test('useProgram', () => { + const ARGS = { id: '0x01' as HexString, query: { enabled: true } }; + renderHook(() => useProgram(ARGS)); + + expect(useProgramSpy).toHaveBeenCalledWith({ library: Program, ...ARGS }); +}); + +test('useSendTransaction', () => { + const { result } = renderHook(() => useProgram({ id: '0x01' })); + const program = result.current.data; + + renderHook(() => useSendCounterAddTransaction({ program })); + renderHook(() => useSendDogMakeSoundTransaction({ program })); + renderHook(() => useSendPingPongPingTransaction({ program })); + renderHook(() => useSendReferencesSetNumTransaction({ program })); + renderHook(() => useSendThisThatNoopTransaction({ program })); + + expect(useSendTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'counter', functionName: 'add' }); + expect(useSendTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'dog', functionName: 'makeSound' }); + expect(useSendTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'pingPong', functionName: 'ping' }); + expect(useSendTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'references', functionName: 'setNum' }); + expect(useSendTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'thisThat', functionName: 'noop' }); +}); + +test('usePrepareTransaction', () => { + const { result } = renderHook(() => useProgram({ id: '0x01' })); + const program = result.current.data; + + renderHook(() => usePrepareCounterAddTransaction({ program })); + renderHook(() => usePrepareDogMakeSoundTransaction({ program })); + renderHook(() => usePreparePingPongPingTransaction({ program })); + renderHook(() => usePrepareReferencesSetNumTransaction({ program })); + renderHook(() => usePrepareThisThatNoopTransaction({ program })); + + expect(usePrepareTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'counter', functionName: 'add' }); + expect(usePrepareTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'dog', functionName: 'makeSound' }); + expect(usePrepareTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'pingPong', functionName: 'ping' }); + expect(usePrepareTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'references', functionName: 'setNum' }); + expect(usePrepareTransactionSpy).toHaveBeenCalledWith({ program, serviceName: 'thisThat', functionName: 'noop' }); +}); + +test('useQuery', () => { + const { result } = renderHook(() => useProgram({ id: '0x01' })); + const ARGS = { program: result.current.data, query: { enabled: true } }; + + renderHook(() => useCounterValueQuery({ ...ARGS, args: [] })); + renderHook(() => useDogAvgWeightQuery({ ...ARGS, args: [] })); + renderHook(() => useReferencesLastByteQuery({ ...ARGS, args: [] })); + renderHook(() => useThisThatThatQuery({ ...ARGS, args: [] })); + + expect(useQuerySpy).toHaveBeenCalledWith({ ...ARGS, serviceName: 'counter', functionName: 'value', args: [] }); + expect(useQuerySpy).toHaveBeenCalledWith({ ...ARGS, serviceName: 'dog', functionName: 'avgWeight', args: [] }); + expect(useQuerySpy).toHaveBeenCalledWith({ ...ARGS, serviceName: 'references', functionName: 'lastByte', args: [] }); + expect(useQuerySpy).toHaveBeenCalledWith({ ...ARGS, serviceName: 'thisThat', functionName: 'that', args: [] }); +}); + +test('useEvent', () => { + const { result } = renderHook(() => useProgram({ id: '0x01' })); + const ARGS = { program: result.current.data, query: { enabled: true }, onData: () => {} }; + + renderHook(() => useCounterAddedEvent(ARGS)); + renderHook(() => useDogBarkedEvent(ARGS)); - await waitFor(() => { - expect(result.current.data).toBeInstanceOf(Program); - expect(result.current.data.programId).toBe('0x01'); - }); - }); + expect(useEventSpy).toHaveBeenCalledWith({ ...ARGS, serviceName: 'counter', functionName: 'subscribeToAddedEvent' }); + expect(useEventSpy).toHaveBeenCalledWith({ ...ARGS, serviceName: 'dog', functionName: 'subscribeToBarkedEvent' }); }); diff --git a/js/vitest.config.ts b/js/vitest.config.ts new file mode 100644 index 00000000..6bf6be09 --- /dev/null +++ b/js/vitest.config.ts @@ -0,0 +1,17 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + // resolving manually cuz vitest is using nodejs resolution, remove after hooks update + // https://github.com/vitest-dev/vitest/discussions/4233 + resolve: { alias: { '@gear-js/react-hooks': '@gear-js/react-hooks/dist/esm/index.mjs' } }, + + test: { + // globalSetup: 'test/setup.js', + include: ['**/*-hooks.test.ts?(x)'], // targeting only hooks + environment: 'happy-dom', // faster than jsdom + watch: false, // fire one time + + // patching esm to allow spying + server: { deps: { inline: ['@gear-js/react-hooks'] } }, + }, +});