-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: update shallow comparison logic, enhance error handling, upgrad…
…e merge method, and increment version to 1.0.3
- Loading branch information
Showing
21 changed files
with
1,087 additions
and
78 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
{ | ||
"name": "muya", | ||
"version": "1.0.2", | ||
"version": "1.0.3", | ||
"author": "[email protected]", | ||
"description": "👀 Another React state management library", | ||
"license": "MIT", | ||
|
@@ -40,6 +40,7 @@ | |
"@stylistic/eslint-plugin-jsx": "^2.9.0", | ||
"@stylistic/eslint-plugin-ts": "^2.9.0", | ||
"@testing-library/react": "^16.0.1", | ||
"@testing-library/react-hooks": "^8.0.1", | ||
"@types/bun": "^1.1.13", | ||
"@types/eslint": "^9.6.0", | ||
"@types/jest": "^29.5.12", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { cancelablePromise, toType, useSyncExternalStore } from '../common' | ||
import { renderHook } from '@testing-library/react-hooks' | ||
import { createEmitter } from '../create-emitter' | ||
import { longPromise } from './test-utils' | ||
|
||
describe('toType', () => { | ||
it('should cast object to specified type', () => { | ||
const object = { a: 1 } | ||
const result = toType<{ a: number }>(object) | ||
expect(result.a).toBe(1) | ||
}) | ||
}) | ||
|
||
describe('useSyncExternalStore', () => { | ||
it('should return the initial state value', () => { | ||
const emitter = createEmitter(() => 0) | ||
const { result } = renderHook(() => useSyncExternalStore(emitter, (state) => state)) | ||
expect(result.current).toBe(0) | ||
}) | ||
|
||
it('should update when the state value changes', () => { | ||
let value = 0 | ||
const emitter = createEmitter(() => value) | ||
const { result } = renderHook(() => useSyncExternalStore(emitter, (state) => state)) | ||
|
||
value = 1 | ||
emitter.emit() | ||
expect(result.current).toBe(1) | ||
}) | ||
|
||
it('should use the selector function', () => { | ||
let value = 0 | ||
const emitter = createEmitter(() => ({ count: value })) | ||
const { result } = renderHook(() => useSyncExternalStore(emitter, (state: { count: number }) => state.count)) | ||
|
||
value = 1 | ||
emitter.emit() | ||
expect(result.current).toBe(1) | ||
}) | ||
|
||
it('should use the isEqual function', () => { | ||
let value = 0 | ||
const emitter = createEmitter(() => ({ count: value })) | ||
const isEqual = jest.fn((a, b) => a === b) | ||
const { result } = renderHook(() => useSyncExternalStore(emitter, (state: { count: number }) => state.count, isEqual)) | ||
|
||
value = 1 | ||
emitter.emit() | ||
expect(result.current).toBe(1) | ||
expect(isEqual).toHaveBeenCalled() | ||
}) | ||
|
||
it('should test cancelable promise to abort', async () => { | ||
const { promise, controller } = cancelablePromise(longPromise(1000 * 1000)) | ||
controller.abort() | ||
expect(promise).rejects.toThrow('aborted') | ||
}) | ||
|
||
it('should test cancelable promise to resolve', async () => { | ||
const { promise } = cancelablePromise(longPromise(0)) | ||
expect(await promise).toBe(0) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { Suspense } from 'react' | ||
import { create } from '../create' | ||
import { renderHook, waitFor, act, render } from '@testing-library/react' | ||
import { ErrorBoundary, longPromise } from './test-utils' | ||
|
||
describe('create', () => { | ||
it('should create test with base value', () => { | ||
const state = create(0) | ||
const result = renderHook(() => state()) | ||
expect(result.result.current).toBe(0) | ||
}) | ||
it('should create test with function', () => { | ||
const state = create(() => 0) | ||
const result = renderHook(() => state()) | ||
expect(result.result.current).toBe(0) | ||
}) | ||
it('should create test with promise', async () => { | ||
const state = create(Promise.resolve(0)) | ||
const result = renderHook(() => state()) | ||
await waitFor(() => { | ||
expect(result.result.current).toBe(0) | ||
}) | ||
}) | ||
it('should create test with promise and wait to be resolved', async () => { | ||
const state = create(longPromise) | ||
const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> }) | ||
|
||
await waitFor(() => { | ||
expect(result.result.current).toBe(0) | ||
}) | ||
}) | ||
it('should create test with lazy promise and wait to be resolved', async () => { | ||
const state = create(async () => await longPromise()) | ||
const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> }) | ||
|
||
await waitFor(() => { | ||
expect(result.result.current).toBe(0) | ||
}) | ||
}) | ||
it('should create test with promise and set value during the promise is pending', async () => { | ||
const state = create(longPromise) | ||
const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> }) | ||
|
||
act(() => { | ||
state.setState(10) | ||
}) | ||
await waitFor(() => { | ||
expect(result.result.current).toBe(10) | ||
}) | ||
}) | ||
|
||
it('should create test with lazy promise and set value during the promise is pending', async () => { | ||
const state = create(async () => await longPromise()) | ||
const result = renderHook(() => state(), { wrapper: ({ children }) => <Suspense fallback={null}>{children}</Suspense> }) | ||
|
||
act(() => { | ||
state.setState(10) | ||
}) | ||
await waitFor(() => { | ||
expect(result.result.current).toBe(10) | ||
}) | ||
}) | ||
|
||
it('should fail inside the hook when the promise is rejected with not abort isWithError', async () => { | ||
const state = create(Promise.reject('error-message')) | ||
|
||
function Component() { | ||
state() | ||
return null | ||
} | ||
|
||
const result = render( | ||
<ErrorBoundary fallback={<div>An error occurred.</div>}> | ||
<Suspense fallback={'suspense-error'}> | ||
<Component /> | ||
</Suspense> | ||
</ErrorBoundary>, | ||
) | ||
|
||
await waitFor(() => { | ||
expect(result.container.textContent).toBe('An error occurred.') | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.