Skip to content

Commit

Permalink
test: useLoader tests now check fetched json
Browse files Browse the repository at this point in the history
  • Loading branch information
krispya committed May 2, 2024
1 parent bef5d93 commit 5e53956
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 65 deletions.
67 changes: 16 additions & 51 deletions packages/fiber/tests/hooks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,10 @@ describe('hooks', () => {
})

it('can handle useLoader hook', async () => {
const MockMesh = new THREE.Mesh()
MockMesh.name = 'Scene'
let gltf: Record<string, any> = {}

class MockGLTFLoader extends THREE.Loader {
load(url: string, onLoad: (gltf: GLTF) => void): void {
onLoad({ scene: MockMesh })
}
}

let gltf!: GLTF & ObjectMap
const Component = () => {
gltf = useLoader(MockGLTFLoader, gltfUri)
gltf = useLoader(MockLoader, gltfs.diamond)
return <primitive object={gltf.scene} />
}

Expand All @@ -115,23 +107,15 @@ describe('hooks', () => {
expect(scene.children[0]).toBe(MockMesh)
expect(gltf.scene).toBe(MockMesh)
expect(gltf.nodes.Scene).toBe(MockMesh)
expect(gltf.json.nodes[0].name).toEqual('Diamond')
})

it('can handle useLoader with an existing loader instance', async () => {
const MockMesh = new THREE.Mesh()
MockMesh.name = 'Scene'

class MockGLTFLoader extends THREE.Loader {
load(url: string, onLoad: (gltf: GLTF) => void): void {
onLoad({ scene: MockMesh })
}
}
let gltf: Record<string, any> = {}
const loader = new MockLoader()

const loader = new MockGLTFLoader()

let gltf!: GLTF & ObjectMap
const Component = () => {
gltf = useLoader(loader, gltfUri)
gltf = useLoader(loader, gltfs.diamond)
return <primitive object={gltf.scene} />
}

Expand All @@ -141,50 +125,31 @@ describe('hooks', () => {
expect(scene.children[0]).toBe(MockMesh)
expect(gltf.scene).toBe(MockMesh)
expect(gltf.nodes.Scene).toBe(MockMesh)
expect(gltf.json.nodes[0].name).toEqual('Diamond')
})

it('can handle useLoader hook with an array of strings', async () => {
const MockMesh = new THREE.Mesh()

const MockGroup = new THREE.Group()
const mat1 = new THREE.MeshBasicMaterial()
mat1.name = 'Mat 1'
const mesh1 = new THREE.Mesh(new THREE.BoxGeometry(2, 2), mat1)
mesh1.name = 'Mesh 1'
const mat2 = new THREE.MeshBasicMaterial()
mat2.name = 'Mat 2'
const mesh2 = new THREE.Mesh(new THREE.BoxGeometry(2, 2), mat2)
mesh2.name = 'Mesh 2'
MockGroup.add(mesh1, mesh2)

// Note: This will fail if loader gets two of the same urls since it will only call once instead of twice due to caching.
class TestLoader extends THREE.Loader {
load = jest
.fn()
.mockImplementationOnce((_url, onLoad) => {
onLoad(MockMesh)
})
.mockImplementationOnce((_url, onLoad) => {
onLoad(MockGroup)
})
}
let results: Record<string, any>[] = []

// The same MockMesh gets returned for each url, but the json is different.
// Because of this we clone for the test.
const Component = () => {
const [mockMesh, mockScene] = useLoader(TestLoader, [gltfUri, altGltfUri])
results = useLoader(MockLoader, [gltfs.diamond, gltfs.lightning])

return (
<>
<primitive object={mockMesh as THREE.Mesh} />
<primitive object={mockScene as THREE.Scene} />
<primitive object={results[0].scene.clone()} />
<primitive object={results[1].scene.clone()} />
</>
)
}

const store = await act(async () => root.render(<Component />))
const { scene } = store.getState()

expect(scene.children[0]).toBe(MockMesh)
expect(scene.children[1]).toBe(MockGroup)
expect(scene.children).toHaveLength(2)
expect(results[0].json.nodes[0].name).toEqual('Diamond')
expect(results[1].json.nodes[0].name).toEqual('lightning')
})

it('can handle useGraph hook', async () => {
Expand Down
31 changes: 25 additions & 6 deletions packages/shared/setupTests.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import * as THREE from 'three'
import { WebGL2RenderingContext } from '@react-three/test-renderer/src/WebGL2RenderingContext'
import { extend } from '@react-three/fiber'
// import 'whatwg-fetch'
import { createDataUriFromGltf } from './utils/createDataUriFromGltf'

declare global {
var IS_REACT_ACT_ENVIRONMENT: boolean
var IS_REACT_NATIVE_TEST_ENVIRONMENT: boolean // https://github.com/facebook/react/pull/28419
var gltfUri: string
var altGltfUri: string
var gltfs: {
diamond: string
lightning: string
}
var MockLoader: typeof _MockLoader
var MockMesh: THREE.Mesh
}

// Let React know that we'll be testing effectful components
Expand Down Expand Up @@ -97,6 +100,22 @@ class MockCacheStorage {

globalThis.caches = new MockCacheStorage() as any

// Add gltf data URI to global scope
globalThis.gltfUri = createDataUriFromGltf(__dirname + '/assets/diamond.gltf')
globalThis.altGltfUri = createDataUriFromGltf(__dirname + '/assets/lightning.gltf')
// Add gltf data URIs to the global scope
globalThis.gltfs = {
diamond: createDataUriFromGltf(__dirname + '/assets/diamond.gltf'),
lightning: createDataUriFromGltf(__dirname + '/assets/lightning.gltf'),
}

// Add mock gltf loader to the global scope
globalThis.MockMesh = new THREE.Mesh()
globalThis.MockMesh.name = 'Scene'

class _MockLoader extends THREE.Loader {
load(url: string, onLoad: (result: { scene: THREE.Mesh; json: Record<string, any> }) => void): void {
fetch(url)
.then((response) => response.json())
.then((data) => onLoad({ scene: globalThis.MockMesh, json: data }))
}
}

globalThis.MockLoader = _MockLoader
14 changes: 6 additions & 8 deletions packages/test-renderer/src/__tests__/RTTR.hooks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,19 @@ describe('ReactThreeTestRenderer Hooks', () => {
})

it('can handle useLoader hook', async () => {
const MockMesh = new THREE.Mesh()
class MockLoader extends THREE.Loader {
load(url: string, onLoad: (mesh: THREE.Mesh) => void): void {
onLoad(MockMesh)
}
}
let json: Record<string, any> = {}

const Component = () => {
const model = useLoader(MockLoader, gltfUri)
const gltf = useLoader(MockLoader, gltfs.diamond)
json = gltf.json

return <primitive object={model} />
return <primitive object={gltf.scene} />
}

const renderer = await ReactThreeTestRenderer.create(<Component />)

expect(renderer.scene.children[0].instance).toBe(MockMesh)
expect(json.nodes[0].name).toEqual('Diamond')
})

it('can handle useFrame hook using test renderers advanceFrames function', async () => {
Expand Down

0 comments on commit 5e53956

Please sign in to comment.