-
Notifications
You must be signed in to change notification settings - Fork 558
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Seperated types from hook functions * Adding a helper to generate a random realm path * Use eslint-disable-next-line comment to disable a warning * Adding a profileHook utility on-top-of renderHook * Adding overloads to useQuery * Adding failing tests * Refactored tests into using a "realm test context" * Passing key-paths through useQuery into the SDK's addListener method * Reusing randomRealmPath * Made useObject tests use createRealmTestContext * adding a useObject test for re-render on object creation * Implement keyPaths on useObject * Incorporating feedback * Allow passing a string as "keyPaths" * Exporting types * Adding @overload doc comments * Focusing docs on the desired call-pattern * Ran lint --fix * Adding a AnyRealmObject utility type * Using the `options` overload in the readme * Adding a non-deprecated single argument overload * Apply suggestions from code review Co-authored-by: LJ <81748770+elle-j@users.noreply.github.com> * Using asserts instead of if-statements * Moved RealmClassType, AnyRealmObject and isClassModelConstructor into helpers * Implemented options object overload on useObject hook * Adding a note to the changelog * Update packages/realm-react/CHANGELOG.md Co-authored-by: Andrew Meyer <andrew.meyer@mongodb.com> --------- Co-authored-by: LJ <81748770+elle-j@users.noreply.github.com> Co-authored-by: Andrew Meyer <andrew.meyer@mongodb.com>
- Loading branch information
1 parent
cb95630
commit b54d7f6
Showing
17 changed files
with
591 additions
and
113 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
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
68 changes: 68 additions & 0 deletions
68
packages/realm-react/src/__tests__/createRealmTestContext.ts
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,68 @@ | ||
//////////////////////////////////////////////////////////////////////////// | ||
// | ||
// Copyright 2024 Realm Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
//////////////////////////////////////////////////////////////////////////// | ||
|
||
import assert from "node:assert"; | ||
import Realm, { Configuration } from "realm"; | ||
import { act } from "@testing-library/react-native"; | ||
|
||
import { randomRealmPath } from "./helpers"; | ||
|
||
export type RealmTestContext = { | ||
realm: Realm; | ||
useRealm: () => Realm; | ||
write(cb: () => void): void; | ||
openRealm(config?: Configuration): Realm; | ||
cleanup(): void; | ||
}; | ||
|
||
/** | ||
* Opens a test realm at a randomized and temporary path. | ||
* @returns The `realm` and a `write` function, which will wrap `realm.write` with an `act` and prepand a second `realm.write` to force notifications to trigger synchronously. | ||
*/ | ||
export function createRealmTestContext(rootConfig: Configuration = {}): RealmTestContext { | ||
let realm: Realm | null = null; | ||
const context = { | ||
get realm(): Realm { | ||
assert(realm, "Open the Realm first"); | ||
return realm; | ||
}, | ||
useRealm() { | ||
return context.realm; | ||
}, | ||
openRealm(config: Configuration = {}) { | ||
if (realm) { | ||
// Close any realm, previously opened | ||
realm.close(); | ||
} | ||
realm = new Realm({ ...rootConfig, ...config, path: randomRealmPath() }); | ||
return realm; | ||
}, | ||
write(callback: () => void) { | ||
act(() => { | ||
context.realm.write(callback); | ||
// Starting another write transaction will force notifications to fire synchronously | ||
context.realm.beginTransaction(); | ||
context.realm.cancelTransaction(); | ||
}); | ||
}, | ||
cleanup() { | ||
Realm.clearTestState(); | ||
}, | ||
}; | ||
return context; | ||
} |
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 |
---|---|---|
@@ -0,0 +1,76 @@ | ||
//////////////////////////////////////////////////////////////////////////// | ||
// | ||
// Copyright 2024 Realm Inc. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
// | ||
//////////////////////////////////////////////////////////////////////////// | ||
|
||
import React, { Profiler, ProfilerOnRenderCallback } from "react"; | ||
import { renderHook, RenderHookResult, RenderHookOptions } from "@testing-library/react-native"; | ||
|
||
function generateProfilerId() { | ||
const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER); | ||
return `test-${nonce}`; | ||
} | ||
|
||
type RenderEvent = { | ||
phase: "mount" | "update"; | ||
actualDuration: number; | ||
baseDuration: number; | ||
}; | ||
|
||
type ProfileWrapper = { | ||
wrapper: React.ComponentType<React.PropsWithChildren>; | ||
renders: RenderEvent[]; | ||
}; | ||
|
||
function createProfilerWrapper(Parent: undefined | React.ComponentType<React.PropsWithChildren>): ProfileWrapper { | ||
const renders: RenderEvent[] = []; | ||
const id = generateProfilerId(); | ||
const handleRender: ProfilerOnRenderCallback = ( | ||
id, | ||
phase, | ||
actualDuration, | ||
baseDuration, | ||
startTime, | ||
commitTime, | ||
interactions, | ||
) => { | ||
renders.push({ phase, actualDuration, baseDuration }); | ||
}; | ||
|
||
const Wrapper: React.ComponentType<React.PropsWithChildren> = ({ children }) => ( | ||
<Profiler id={id} onRender={handleRender} children={children} /> | ||
); | ||
|
||
return { | ||
wrapper: Parent | ||
? ({ children }) => ( | ||
<Parent> | ||
<Wrapper children={children} /> | ||
</Parent> | ||
) | ||
: Wrapper, | ||
renders, | ||
}; | ||
} | ||
|
||
export function profileHook<Result, Props>( | ||
callback: (props: Props) => Result, | ||
options?: RenderHookOptions<Props>, | ||
): RenderHookResult<Result, Props> & { renders: RenderEvent[] } { | ||
const { wrapper, renders } = createProfilerWrapper(options?.wrapper); | ||
const result = renderHook<Result, Props>(callback, { ...options, wrapper }); | ||
return { ...result, renders }; | ||
} |
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
Oops, something went wrong.