Add missing tests in modules/ui/utilities/recoil-scope (#3581)
Co-authored-by: gitstart-twenty <gitstart-twenty@users.noreply.github.com> Co-authored-by: Matheus <matheus_benini@hotmail.com>
This commit is contained in:
@ -0,0 +1,44 @@
|
|||||||
|
import { createContext } from 'react';
|
||||||
|
import { renderHook } from '@testing-library/react';
|
||||||
|
|
||||||
|
import { useScopeInternalContextOrThrow } from '@/ui/utilities/recoil-scope/scopes-internal/hooks/useScopeInternalContextOrThrow';
|
||||||
|
import { ScopeInternalContext } from '@/ui/utilities/recoil-scope/scopes-internal/types/ScopeInternalContext';
|
||||||
|
|
||||||
|
const mockedContextValue = 'mocked-scope-id';
|
||||||
|
const MockedContext = createContext<string | null>(mockedContextValue);
|
||||||
|
const nullContext = createContext<string | null>(null);
|
||||||
|
|
||||||
|
const ERROR_MESSAGE =
|
||||||
|
'Using a scope context without a ScopeInternalContext.Provider wrapper for context';
|
||||||
|
|
||||||
|
const Wrapper = ({ children }: { children: React.ReactNode }) => (
|
||||||
|
<MockedContext.Provider value={mockedContextValue}>
|
||||||
|
{children}
|
||||||
|
</MockedContext.Provider>
|
||||||
|
);
|
||||||
|
|
||||||
|
describe('useScopeInternalContextOrThrow', () => {
|
||||||
|
it('should work as expected', () => {
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useScopeInternalContextOrThrow(
|
||||||
|
MockedContext as ScopeInternalContext<{ scopeId: string }>,
|
||||||
|
),
|
||||||
|
{
|
||||||
|
wrapper: Wrapper,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).toBe(mockedContextValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error when used outside of the specified context', () => {
|
||||||
|
expect(() => {
|
||||||
|
renderHook(() =>
|
||||||
|
useScopeInternalContextOrThrow(
|
||||||
|
nullContext as ScopeInternalContext<{ scopeId: string }>,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}).toThrow(ERROR_MESSAGE);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,192 @@
|
|||||||
|
import { expect } from '@storybook/test';
|
||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import {
|
||||||
|
atomFamily,
|
||||||
|
RecoilRoot,
|
||||||
|
selector,
|
||||||
|
useRecoilCallback,
|
||||||
|
useRecoilState,
|
||||||
|
useRecoilValue,
|
||||||
|
} from 'recoil';
|
||||||
|
|
||||||
|
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||||
|
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
|
||||||
|
import { getFamilyScopeInjector } from '@/ui/utilities/recoil-scope/utils/getFamilyScopeInjector';
|
||||||
|
import { getScopeInjector } from '@/ui/utilities/recoil-scope/utils/getScopeInjector';
|
||||||
|
import { getSelectorScopeInjector } from '@/ui/utilities/recoil-scope/utils/getSelectorScopeInjector';
|
||||||
|
|
||||||
|
import { useScopedState } from '../useScopedState';
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
|
||||||
|
// scoped state
|
||||||
|
const defaultScopedState = 'defaultString';
|
||||||
|
const scopedState = atomFamily<string, StateScopeMapKey>({
|
||||||
|
key: 'ScopedStateKey',
|
||||||
|
default: defaultScopedState,
|
||||||
|
});
|
||||||
|
const scopedStateScopeInjector = getScopeInjector(scopedState);
|
||||||
|
|
||||||
|
// scoped selector
|
||||||
|
const anotherScopedState = atomFamily<number[], StateScopeMapKey>({
|
||||||
|
key: 'ScopedStateKey',
|
||||||
|
default: [1, 2, 3, 4, 5],
|
||||||
|
});
|
||||||
|
const scopedSelector = ({ scopeId }: StateScopeMapKey) =>
|
||||||
|
selector({
|
||||||
|
key: 'FilteredState',
|
||||||
|
get: ({ get }) => {
|
||||||
|
const scopedStateValue = get(anotherScopedState({ scopeId }));
|
||||||
|
return scopedStateValue.filter((value) => value % 2 === 0);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const selectorScopeInjector = getSelectorScopeInjector(scopedSelector);
|
||||||
|
|
||||||
|
// family state
|
||||||
|
const defaultValue = 'defaultString';
|
||||||
|
const scopedFamilyState = createFamilyStateScopeMap<string, string>({
|
||||||
|
key: 'FamilyStateKey',
|
||||||
|
defaultValue,
|
||||||
|
});
|
||||||
|
const familyScopeInjector = getFamilyScopeInjector(scopedFamilyState);
|
||||||
|
|
||||||
|
describe('useScopedState', () => {
|
||||||
|
it('should get scoped state', () => {
|
||||||
|
const {
|
||||||
|
result: {
|
||||||
|
current: { getScopedState },
|
||||||
|
},
|
||||||
|
} = renderHook(() => useScopedState(scopeId));
|
||||||
|
|
||||||
|
const scopedState = getScopedState(scopedStateScopeInjector);
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
const [scoped, setScoped] = useRecoilState(scopedState);
|
||||||
|
return { scoped, setScoped };
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: RecoilRoot,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.scoped).toBe(defaultScopedState);
|
||||||
|
|
||||||
|
const newValue = 'anotherValue';
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.setScoped(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.scoped).toBe(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get scoped snapshot value', () => {
|
||||||
|
const {
|
||||||
|
result: {
|
||||||
|
current: { getScopedSnapshotValue },
|
||||||
|
},
|
||||||
|
} = renderHook(() => useScopedState(scopeId));
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
() =>
|
||||||
|
getScopedSnapshotValue(snapshot, scopedStateScopeInjector),
|
||||||
|
)(),
|
||||||
|
{ wrapper: RecoilRoot },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).toBe(defaultScopedState);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get scoped selector', () => {
|
||||||
|
const {
|
||||||
|
result: {
|
||||||
|
current: { getScopedSelector },
|
||||||
|
},
|
||||||
|
} = renderHook(() => useScopedState(scopeId));
|
||||||
|
|
||||||
|
const recoilValue = getScopedSelector(selectorScopeInjector);
|
||||||
|
|
||||||
|
const { result } = renderHook(() => useRecoilValue(recoilValue), {
|
||||||
|
wrapper: RecoilRoot,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current).toEqual([2, 4]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get scoped selector snapshot value', () => {
|
||||||
|
const {
|
||||||
|
result: {
|
||||||
|
current: { getScopedSelectorSnapshotValue },
|
||||||
|
},
|
||||||
|
} = renderHook(() => useScopedState(scopeId));
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
() =>
|
||||||
|
getScopedSelectorSnapshotValue(snapshot, selectorScopeInjector),
|
||||||
|
)(),
|
||||||
|
{ wrapper: RecoilRoot },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current).toEqual([2, 4]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get scoped family state', () => {
|
||||||
|
const {
|
||||||
|
result: {
|
||||||
|
current: { getScopedFamilyState },
|
||||||
|
},
|
||||||
|
} = renderHook(() => useScopedState(scopeId));
|
||||||
|
|
||||||
|
const scopedFamilyState = getScopedFamilyState(familyScopeInjector);
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
const [familyState, setFamilyState] = useRecoilState(
|
||||||
|
scopedFamilyState('familyKey'),
|
||||||
|
);
|
||||||
|
|
||||||
|
return { familyState, setFamilyState };
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: RecoilRoot,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.familyState).toBe('defaultString');
|
||||||
|
|
||||||
|
const newValue = 'newValue';
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.setFamilyState(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.familyState).toBe(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get scoped family snapshot value', () => {
|
||||||
|
const {
|
||||||
|
result: {
|
||||||
|
current: { getScopedFamilySnapshotValue },
|
||||||
|
},
|
||||||
|
} = renderHook(() => useScopedState(scopeId));
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() =>
|
||||||
|
useRecoilCallback(
|
||||||
|
({ snapshot }) =>
|
||||||
|
() =>
|
||||||
|
getScopedFamilySnapshotValue(snapshot, familyScopeInjector),
|
||||||
|
)(),
|
||||||
|
{ wrapper: RecoilRoot },
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current('sampleKey')).toBe('defaultString');
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { RecoilRoot, useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { createFamilyStateScopeMap } from '@/ui/utilities/recoil-scope/utils/createFamilyStateScopeMap';
|
||||||
|
|
||||||
|
import { getFamilyScopeInjector } from '../getFamilyScopeInjector';
|
||||||
|
|
||||||
|
const defaultValue = 'defaultString';
|
||||||
|
|
||||||
|
const testState = createFamilyStateScopeMap<string, string>({
|
||||||
|
key: 'familyStateKey',
|
||||||
|
defaultValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getFamilyScopeInjector', () => {
|
||||||
|
it('should return a scoped family state', () => {
|
||||||
|
const familyScopeInjector = getFamilyScopeInjector(testState);
|
||||||
|
const familyState = familyScopeInjector('scopeId', 'familyKey');
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
const [family, setFamily] = useRecoilState(familyState);
|
||||||
|
return { family, setFamily };
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: RecoilRoot,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.family).toBe(defaultValue);
|
||||||
|
|
||||||
|
const newValue = 'anotherValue';
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.setFamily(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.family).toBe(newValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,45 @@
|
|||||||
|
import { act, renderHook } from '@testing-library/react';
|
||||||
|
import { atomFamily, RecoilRoot, useRecoilState } from 'recoil';
|
||||||
|
|
||||||
|
import { getScopeInjector } from '../getScopeInjector';
|
||||||
|
|
||||||
|
const defaultValue = 'defaultString';
|
||||||
|
|
||||||
|
const scopedState = atomFamily<
|
||||||
|
string,
|
||||||
|
{
|
||||||
|
scopeId: string;
|
||||||
|
}
|
||||||
|
>({
|
||||||
|
key: 'myStateKey',
|
||||||
|
default: defaultValue,
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getScopeInjector', () => {
|
||||||
|
it('should return the scoped state for the given scopeId', () => {
|
||||||
|
const scopeInjector = getScopeInjector(scopedState);
|
||||||
|
|
||||||
|
const scopeId = 'scopeId';
|
||||||
|
const recoilState = scopeInjector(scopeId);
|
||||||
|
|
||||||
|
const { result } = renderHook(
|
||||||
|
() => {
|
||||||
|
const [recoil, setRecoil] = useRecoilState(recoilState);
|
||||||
|
return { recoil, setRecoil };
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wrapper: RecoilRoot,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(result.current.recoil).toBe(defaultValue);
|
||||||
|
|
||||||
|
const newValue = 'anotherValue';
|
||||||
|
|
||||||
|
act(() => {
|
||||||
|
result.current.setRecoil(newValue);
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current.recoil).toBe(newValue);
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
import { renderHook } from '@testing-library/react';
|
||||||
|
import { atomFamily, RecoilRoot, selector, useRecoilValue } from 'recoil';
|
||||||
|
|
||||||
|
import { StateScopeMapKey } from '@/ui/utilities/recoil-scope/scopes-internal/types/StateScopeMapKey';
|
||||||
|
|
||||||
|
import { getSelectorScopeInjector } from '../getSelectorScopeInjector';
|
||||||
|
|
||||||
|
const scopedState = atomFamily<
|
||||||
|
number[],
|
||||||
|
{
|
||||||
|
scopeId: string;
|
||||||
|
}
|
||||||
|
>({
|
||||||
|
key: 'myStateKey',
|
||||||
|
default: [1, 2, 3, 4, 5],
|
||||||
|
});
|
||||||
|
|
||||||
|
const scopedSelector = ({ scopeId }: StateScopeMapKey) =>
|
||||||
|
selector({
|
||||||
|
key: 'FilteredState',
|
||||||
|
get: ({ get }) => {
|
||||||
|
const scopedStateValue = get(scopedState({ scopeId }));
|
||||||
|
return scopedStateValue.filter((value) => value % 2 === 0);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getSelectorScopeInjector', () => {
|
||||||
|
it('should return a valid SelectorScopeInjector', () => {
|
||||||
|
const selectorScopeInjector = getSelectorScopeInjector(scopedSelector);
|
||||||
|
const recoilValue = selectorScopeInjector('scopeId');
|
||||||
|
|
||||||
|
const { result } = renderHook(() => useRecoilValue(recoilValue), {
|
||||||
|
wrapper: RecoilRoot,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(result.current).toEqual([2, 4]);
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user