Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions .changeset/config.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"$schema": "https://unpkg.com/@changesets/config@3.0.1/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
"$schema": "https://unpkg.com/@changesets/config@3.0.1/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": []
}
5 changes: 5 additions & 0 deletions .changeset/strong-cameras-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@threlte/test': major
---

Add Threlte 8 support, remove Threlte 7 support
13 changes: 0 additions & 13 deletions .eslintignore

This file was deleted.

47 changes: 0 additions & 47 deletions .eslintrc.cjs

This file was deleted.

17 changes: 12 additions & 5 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,29 @@ jobs:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Setup Node
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 10
run_install: false

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: 'pnpm'

- name: Install and Build 🔧
run: |
npm ci
npm run build
pnpm i
pnpm build

- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
# This expects you to have a script called release which does a build for your packages and calls changeset publish
publish: npm run release
publish: pnpm run release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
58 changes: 50 additions & 8 deletions .github/workflows/pullrequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,48 @@ jobs:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Setup Node
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 10
run_install: false

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: 'pnpm'

- name: Install 🔧
run: npm ci
run: pnpm i

- name: Prettier 💅
run: npm run prettier
run: pnpm prettier

lint:
runs-on: ubuntu-latest

steps:
- name: Checkout 🛎️
uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 10
run_install: false

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: 'pnpm'

- name: Install 🔧
run: pnpm i

- name: Lint 💅
run: pnpm lint

unit-test:
runs-on: ubuntu-latest
Expand All @@ -31,13 +63,23 @@ jobs:
- name: Checkout 🛎️
uses: actions/checkout@v4

- name: Setup Node
- uses: pnpm/action-setup@v4
name: Install pnpm
with:
version: 10
run_install: false

- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
cache: 'pnpm'

- name: Install 🔧
run: npm ci
run: pnpm i

- name: Install playwright 🔧
run: npx playwright install chromium --with-deps

- name: Test 🔬
run: npm run test
run: pnpm test
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
pnpm-lock.yaml
package-lock.json
yarn.lock
README.md
README.md
19 changes: 12 additions & 7 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "es5",
"printWidth": 100,
"semi": false,
"plugins": ["prettier-plugin-svelte"],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }]
"semi": false,
"singleQuote": true,
"trailingComma": "es5",
"plugins": ["prettier-plugin-svelte"],
"overrides": [
{
"files": "*.svelte",
"options": {
"parser": "svelte"
}
}
]
}
8 changes: 8 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"eslint.validate": ["javascript", "svelte"],
"prettier.documentSelectors": ["**/*.svelte"],
"typescript.preferences.importModuleSpecifier": "relative",
"[svelte]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
32 changes: 13 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
npm i @threlte/test
```

It supports Svelte 4 + Threlte 7 and Svelte 5 + Threlte 8.
It supports Svelte 5 + Threlte 8 onwards.

```ts
import { describe, it, expect } from 'vitest'
Expand Down Expand Up @@ -34,7 +34,7 @@ const {
component, // SvelteComponent
scene, // THREE.Scene
camera, // CurrentWritable<THREE.Camera>
advance, // (delta?: number) => void
advance, // ({ count?: number; delta?: number }) => void
fireEvent, // (object3D: THREE.Object3D, event, payload) => Promise<void>
rerender, // (props) => Promise<void>
unmount, // () => void
Expand All @@ -54,40 +54,36 @@ In the test renderer environment, Threlte's render mode is set to `manual`. If y
advance({ delta: 33.3, count: 10 })
```

`advance` will also return a flag indicating whether calling it resulted in a frame invalidation.

```ts
const { frameInvalidated } = advance()
```

### fireEvent

If your component uses the `interactivity` plugin, you can test events using the `fireEvent` function. Let's say we have a component like this:

```svelte
<script lang="ts">
export let onClick
<script>
let { onclick } = $props()
</script>

<T.Mesh on:click={onClick}>...</T.Mesh>
<T.Mesh {onclick} />
```

We can write a test like this:

```ts
const onClick = vi.fn()
const { render, fireEvent } = render(Scene, { onClick })
const onclick = vi.fn()
const { render, fireEvent } = render(Scene, {
props: { onclick }
})

const mesh = scene.getObjectByName('myMesh')
await fireEvent(mesh, 'click', someOptionalCustomPayload)
expect(onClick).toHaveBeenCalledOnce()
expect(onclick).toHaveBeenCalledOnce()
```

Note that if you use the event object, you will have to design a mock payload.

### Setup

We recommend using `@threlte/test` with Vitest as your test runner. To get started, add the `threlteTesting` plugin to your Vite or Vitest config.
`@threlte/test` currently only supports vitest as your test runner. To get started, add the `threlteTesting` plugin to your Vite or Vitest config.

```ts
// vite.config.js
Expand All @@ -102,10 +98,8 @@ export default defineConfig({
});
```

Additionally, the [Vitest environment](https://vitest.dev/guide/environment.html) must be set to a DOM enviroment.
Additionally, the [Vitest environment](https://vitest.dev/guide/environment.html) must be set to a DOM enviroment, like happy-dom or vitest browser mode.

### Limitations

The test renderer runs in a node.js environment, and it does not attempt to mock a webgl canvas, which can become quite complicated. Instead, it creates a Threlte context and renders your component as a child of a Threlte `<SceneGraphObject>`. This means that testing `<Canvas>` or `WebGLRenderer` related configuration and behavior won't work.

This libary's primary purpose, however, is to allow you to test whether your component works in isolation as you intend it to work.
The test renderer runs in a node.js environment, unless if running in vite browser mode. It creates a Threlte context and renders your component with this context provided. This must be considered when testing `<Canvas>` or `WebGLRenderer` related configuration and behavior.
Loading