@quake2ts/test-utils 0.0.828 → 0.0.830
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/dist/index.cjs +70 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -2
- package/dist/index.d.ts +23 -2
- package/dist/index.js +55 -5
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/game/helpers/spawn.ts +68 -0
- package/src/game/helpers.ts +27 -5
- package/src/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quake2ts/test-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.830",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"serve-handler": "^6.1.6",
|
|
56
56
|
"vitest": "^1.6.0",
|
|
57
57
|
"webgpu": "^0.3.8",
|
|
58
|
-
"@quake2ts/
|
|
59
|
-
"@quake2ts/
|
|
60
|
-
"@quake2ts/shared": "0.0.
|
|
61
|
-
"@quake2ts/
|
|
58
|
+
"@quake2ts/engine": "^0.0.830",
|
|
59
|
+
"@quake2ts/game": "0.0.830",
|
|
60
|
+
"@quake2ts/shared": "0.0.830",
|
|
61
|
+
"@quake2ts/server": "0.0.830"
|
|
62
62
|
},
|
|
63
63
|
"peerDependenciesMeta": {
|
|
64
64
|
"@quake2ts/engine": {
|
|
@@ -114,10 +114,10 @@
|
|
|
114
114
|
"typescript": "^5.9.3",
|
|
115
115
|
"vitest": "^4.0.16",
|
|
116
116
|
"webgpu": "^0.3.8",
|
|
117
|
-
"@quake2ts/engine": "^0.0.
|
|
118
|
-
"@quake2ts/game": "0.0.
|
|
119
|
-
"@quake2ts/shared": "0.0.
|
|
120
|
-
"@quake2ts/server": "0.0.
|
|
117
|
+
"@quake2ts/engine": "^0.0.830",
|
|
118
|
+
"@quake2ts/game": "0.0.830",
|
|
119
|
+
"@quake2ts/shared": "0.0.830",
|
|
120
|
+
"@quake2ts/server": "0.0.830"
|
|
121
121
|
},
|
|
122
122
|
"dependencies": {
|
|
123
123
|
"upng-js": "^2.1.0"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SpawnRegistry,
|
|
3
|
+
createDefaultSpawnRegistry,
|
|
4
|
+
type SpawnFunction,
|
|
5
|
+
type SpawnContext,
|
|
6
|
+
type SpawnOptions,
|
|
7
|
+
spawnEntityFromDictionary,
|
|
8
|
+
Entity
|
|
9
|
+
} from '@quake2ts/game';
|
|
10
|
+
import type { TestContext } from '../helpers.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Creates a configured SpawnRegistry for testing.
|
|
14
|
+
* Uses the default spawn registry but handles the game dependency if not provided.
|
|
15
|
+
*/
|
|
16
|
+
export function createSpawnRegistry(game?: any): SpawnRegistry {
|
|
17
|
+
// If game is not provided, we can pass a mock or empty object
|
|
18
|
+
// The default registry primarily uses game for registering items
|
|
19
|
+
const gameMock = game || {};
|
|
20
|
+
return createDefaultSpawnRegistry(gameMock);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Registers a custom spawn function for testing.
|
|
25
|
+
*/
|
|
26
|
+
export function registerTestSpawn(
|
|
27
|
+
registry: SpawnRegistry,
|
|
28
|
+
classname: string,
|
|
29
|
+
spawnFunc: SpawnFunction
|
|
30
|
+
): void {
|
|
31
|
+
registry.register(classname, spawnFunc);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface SpawnTestEntityOptions {
|
|
35
|
+
classname: string;
|
|
36
|
+
keyValues?: Record<string, string>;
|
|
37
|
+
registry?: SpawnRegistry;
|
|
38
|
+
onWarning?: (message: string) => void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Convenience function to spawn an entity using the spawn system.
|
|
43
|
+
*/
|
|
44
|
+
export function spawnTestEntity(
|
|
45
|
+
context: TestContext,
|
|
46
|
+
options: SpawnTestEntityOptions
|
|
47
|
+
): Entity | null {
|
|
48
|
+
const registry = options.registry || context.game?.entities?.spawnRegistry;
|
|
49
|
+
|
|
50
|
+
if (!registry) {
|
|
51
|
+
throw new Error('No spawn registry provided and none found on context.game.entities');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const keyValues = {
|
|
55
|
+
classname: options.classname,
|
|
56
|
+
...(options.keyValues || {})
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
const spawnOptions: SpawnOptions = {
|
|
60
|
+
registry,
|
|
61
|
+
entities: context.entities,
|
|
62
|
+
onWarning: options.onWarning
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// The type of spawnEntityFromDictionary might need validation based on exports
|
|
66
|
+
// but usually it accepts Record<string,string> which we provide.
|
|
67
|
+
return spawnEntityFromDictionary(keyValues, spawnOptions);
|
|
68
|
+
}
|
package/src/game/helpers.ts
CHANGED
|
@@ -27,6 +27,7 @@ export interface MockGame {
|
|
|
27
27
|
spawnWorld: LegacyMock<[], void>;
|
|
28
28
|
clientBegin: LegacyMock<[any], void>;
|
|
29
29
|
damage: LegacyMock<[number], void>;
|
|
30
|
+
entities: any;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export interface TestContext extends SpawnContext {
|
|
@@ -67,7 +68,10 @@ export const createMockGame = (seed: number = 12345): { game: MockGame, spawnReg
|
|
|
67
68
|
}),
|
|
68
69
|
damage: vi.fn((amount: number) => {
|
|
69
70
|
hooks.onDamage({} as any, null, null, amount, 0, 0);
|
|
70
|
-
})
|
|
71
|
+
}),
|
|
72
|
+
entities: {
|
|
73
|
+
spawnRegistry
|
|
74
|
+
}
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
return { game, spawnRegistry };
|
|
@@ -91,7 +95,11 @@ export function createTestContext(options?: { seed?: number, initialEntities?: E
|
|
|
91
95
|
const hooks = game.hooks;
|
|
92
96
|
|
|
93
97
|
// We need to store the registry reference to implement registerEntityClass/getSpawnFunction
|
|
94
|
-
let currentSpawnRegistry: SpawnRegistry | undefined;
|
|
98
|
+
let currentSpawnRegistry: SpawnRegistry | undefined = spawnRegistry;
|
|
99
|
+
|
|
100
|
+
const findByTargetName = (targetname: string) => {
|
|
101
|
+
return entityList.filter(e => e.targetname === targetname && e.inUse);
|
|
102
|
+
};
|
|
95
103
|
|
|
96
104
|
const entities = {
|
|
97
105
|
spawn: vi.fn(() => {
|
|
@@ -147,9 +155,20 @@ export function createTestContext(options?: { seed?: number, initialEntities?: E
|
|
|
147
155
|
}),
|
|
148
156
|
soundIndex: vi.fn((sound: string) => engine.soundIndex(sound)),
|
|
149
157
|
useTargets: vi.fn((entity: Entity, activator: Entity | null) => {
|
|
158
|
+
if (entity.target) {
|
|
159
|
+
const targets = findByTargetName(entity.target);
|
|
160
|
+
for (const t of targets) {
|
|
161
|
+
t.use?.(t, entity, activator);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}),
|
|
165
|
+
findByTargetName: vi.fn(findByTargetName),
|
|
166
|
+
pickTarget: vi.fn((targetname: string | undefined) => {
|
|
167
|
+
if (!targetname) return null;
|
|
168
|
+
const matches = findByTargetName(targetname);
|
|
169
|
+
if (matches.length === 0) return null;
|
|
170
|
+
return matches[0];
|
|
150
171
|
}),
|
|
151
|
-
findByTargetName: vi.fn(() => []),
|
|
152
|
-
pickTarget: vi.fn(() => null),
|
|
153
172
|
killBox: vi.fn(),
|
|
154
173
|
rng: createRandomGenerator({ seed }),
|
|
155
174
|
imports: {
|
|
@@ -171,7 +190,7 @@ export function createTestContext(options?: { seed?: number, initialEntities?: E
|
|
|
171
190
|
return entityList.find(predicate);
|
|
172
191
|
}),
|
|
173
192
|
findByClassname: vi.fn((classname: string) => {
|
|
174
|
-
return entityList.
|
|
193
|
+
return entityList.filter(e => e.classname === classname);
|
|
175
194
|
}),
|
|
176
195
|
beginFrame: vi.fn((timeSeconds: number) => {
|
|
177
196
|
(entities as any).timeSeconds = timeSeconds;
|
|
@@ -193,6 +212,9 @@ export function createTestContext(options?: { seed?: number, initialEntities?: E
|
|
|
193
212
|
world: entityList.find(e => e.classname === 'worldspawn') || new Entity(0),
|
|
194
213
|
} as unknown as EntitySystem;
|
|
195
214
|
|
|
215
|
+
// Fix circular reference
|
|
216
|
+
game.entities = entities;
|
|
217
|
+
|
|
196
218
|
return {
|
|
197
219
|
keyValues: {},
|
|
198
220
|
entities,
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './shared/collision.js';
|
|
|
7
7
|
export * from './shared/factories.js';
|
|
8
8
|
export * from './game/factories.js';
|
|
9
9
|
export * from './game/helpers.js';
|
|
10
|
+
export * from './game/helpers/spawn.js';
|
|
10
11
|
export * from './game/helpers/physics.js';
|
|
11
12
|
export * from './game/helpers/save.js';
|
|
12
13
|
export * from './game/mocks/ai.js';
|