@irtio/testing 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,66 @@
1
+ # @irtio/testing
2
+
3
+ Test room logic with real irtio clients and a controllable clock. Check synchronization, RPCs,
4
+ reconnection, and visibility without opening sockets.
5
+
6
+ ```bash
7
+ npm install --save-dev @irtio/testing vitest
8
+ ```
9
+
10
+ ## Test a player update
11
+
12
+ This test uses the room generated by `npx irtio init --tick --yes`.
13
+ Create or replace `irtio/room.test.ts`:
14
+
15
+ ```ts
16
+ import { expect, test } from 'vitest';
17
+ import { testRoom } from '@irtio/testing';
18
+ import '@irtio/testing/matchers';
19
+ import room from './room.js';
20
+
21
+ test('an owned write reaches another player', async () => {
22
+ const t = await testRoom(room);
23
+ try {
24
+ const [a, b] = await t.join(2, { role: 'player' });
25
+ const player = a.state.players.get(a.id);
26
+ expect(player).toBeDefined();
27
+ player!.x = 10;
28
+ a.flush();
29
+ await t.tick(2);
30
+
31
+ expect(t.state.players.get(a.id)?.x).toBe(10);
32
+ expect(b.state.players.get(a.id)?.x).toBe(10);
33
+ expect(t).toHaveConverged();
34
+ expect(t).toHaveNoVisibilityLeaks();
35
+ } finally {
36
+ t.stop();
37
+ }
38
+ });
39
+ ```
40
+
41
+ ```bash
42
+ npx vitest run irtio/room.test.ts
43
+ ```
44
+
45
+ ## Drive the clock
46
+
47
+ | Method | Behavior |
48
+ | --- | --- |
49
+ | `await t.join(spec?)` | Join one client |
50
+ | `await t.join(n, spec?)` | Join multiple clients |
51
+ | `await t.tick(n?)` | Advance server ticks; defaults to one |
52
+ | `await t.run(ms)` | Advance fake time in milliseconds |
53
+ | `await t.until(predicate, options?)` | Advance until a condition holds, or reject at the limit |
54
+ | `t.stop()` | Stop the room and its clients |
55
+
56
+ Await all clock operations. By default, awaiting client RPCs also advances the clock until they
57
+ settle, and a room handler error fails the test. Configure `autoPump` and `failOnHandlerError`
58
+ when testing those behaviors explicitly.
59
+
60
+ `testRelay()` tests schema-less relay messaging. Import `@irtio/testing/matchers` to register
61
+ Vitest matchers; the main entry point also exports assertion functions for other runners.
62
+ For physics rooms, await the corresponding `initPhysics`, `initRapier2d`, or `initMatter`
63
+ initializer before creating the test room.
64
+
65
+ See the [testing reference](https://irt.io/docs/reference/testing) for all options, matchers,
66
+ network conditions, and physics helpers.
@@ -1,4 +1,5 @@
1
1
  // src/compare.ts
2
+ import { isPerClient } from "@irtio/runtime";
2
3
  import {
3
4
  cloneValue,
4
5
  computeDirty,
@@ -46,7 +47,7 @@ function divergence(ext, authority, client, visible, memberships = /* @__PURE__
46
47
  for (const [name, cd] of computeDirty(ext, authority, client)) {
47
48
  if (!visible.has(name)) continue;
48
49
  const desc = ext.collection(name);
49
- const membership = desc.visibility === "spatial-grid" ? memberships.get(name) : void 0;
50
+ const membership = isPerClient(desc) ? memberships.get(name) : void 0;
50
51
  for (const id of cd.added) {
51
52
  if (!membership || !membership.has(id)) out.push(`${name}[${id}]: only in the client's view`);
52
53
  }
@@ -108,6 +109,7 @@ import {
108
109
  RoomCore,
109
110
  RoomFullError,
110
111
  createVisibilityPolicy,
112
+ isPerClient as isPerClient2,
111
113
  visibleNames
112
114
  } from "@irtio/runtime";
113
115
  import { FakeClock, HarnessHost, frameTypeName } from "@irtio/runtime/test";
@@ -874,16 +876,16 @@ var TestHarness = class {
874
876
  const seen = this.deliveredIds(link.clientId, dc.name);
875
877
  const leaked = dc.ops.filter((op) => {
876
878
  if (op.op === "remove") {
877
- if (keep.has(dc.name)) return desc.visibility === "spatial-grid" && !seen.has(op.id);
879
+ if (keep.has(dc.name)) return isPerClient2(desc) && !seen.has(op.id);
878
880
  return !seen.has(op.id);
879
881
  }
880
882
  if (!keep.has(dc.name)) return true;
881
- if (desc.visibility !== "spatial-grid") return false;
883
+ if (!isPerClient2(desc)) return false;
882
884
  return !policy.maySeeEntity(desc, op.id);
883
885
  });
884
886
  for (const op of dc.ops) {
885
887
  if (op.op === "remove") seen.delete(op.id);
886
- else if (desc.visibility !== "spatial-grid" || policy.maySeeEntity(desc, op.id)) {
888
+ else if (!isPerClient2(desc) || policy.maySeeEntity(desc, op.id)) {
887
889
  seen.add(op.id);
888
890
  }
889
891
  }
@@ -1205,7 +1207,7 @@ var TestHarness = class {
1205
1207
  const policy = createVisibilityPolicy(this.ext, this.plain, client.id, role);
1206
1208
  const view = client.view;
1207
1209
  for (const c of this.ext.collections) {
1208
- if (c.visibility === "spatial-grid") {
1210
+ if (isPerClient2(c)) {
1209
1211
  const coll = view[c.name];
1210
1212
  const ids = coll ? [...coll.ids()].filter((id) => !policy.maySeeEntity(c, id)) : [];
1211
1213
  if (ids.length > 0) {
package/dist/index.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  toHaveRejected,
13
13
  toStayUnderBandwidth,
14
14
  toStayWithinPrediction
15
- } from "./chunk-LQ5TGD2E.js";
15
+ } from "./chunk-7GS3V7QO.js";
16
16
 
17
17
  // src/relay-harness.ts
18
18
  import { joinRelay } from "@irtio/client";
package/dist/matchers.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  toHaveRejected,
6
6
  toStayUnderBandwidth,
7
7
  toStayWithinPrediction
8
- } from "./chunk-LQ5TGD2E.js";
8
+ } from "./chunk-7GS3V7QO.js";
9
9
 
10
10
  // src/matchers.ts
11
11
  import { expect } from "vitest";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@irtio/testing",
3
- "version": "4.0.0",
3
+ "version": "4.2.0",
4
4
  "description": "irtio's blessed test API: testRoom() in-process rooms with real client semantics, plus Vitest matchers",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -28,12 +28,12 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@irtio/bots": "^4.0.0",
32
- "@irtio/client": "^4.0.0",
33
- "@irtio/protocol": "^4.0.0",
34
- "@irtio/runtime": "^4.0.0",
35
- "@irtio/schema": "^4.0.0",
36
- "@irtio/server": "^4.0.0"
31
+ "@irtio/bots": "^4.2.0",
32
+ "@irtio/client": "^4.2.0",
33
+ "@irtio/protocol": "^4.2.0",
34
+ "@irtio/runtime": "^4.2.0",
35
+ "@irtio/schema": "^4.2.0",
36
+ "@irtio/server": "^4.2.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "vitest": ">=3"