quake2ts 0.0.552 → 0.0.556
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/package.json +1 -1
- package/packages/engine/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/engine/dist/types/assets/index.d.ts +2 -0
- package/packages/engine/dist/types/assets/index.d.ts.map +1 -1
- package/packages/engine/dist/types/assets/interactionGraph.d.ts +21 -0
- package/packages/engine/dist/types/assets/interactionGraph.d.ts.map +1 -0
- package/packages/engine/dist/types/assets/visibilityAnalyzer.d.ts +9 -3
- package/packages/engine/dist/types/assets/visibilityAnalyzer.d.ts.map +1 -1
- package/packages/game/dist/tsconfig.tsbuildinfo +1 -1
- package/packages/game/dist/types/entities/target/speaker.d.ts.map +1 -1
- package/packages/test-utils/dist/index.cjs +353 -2
- package/packages/test-utils/dist/index.cjs.map +1 -1
- package/packages/test-utils/dist/index.d.cts +38 -1
- package/packages/test-utils/dist/index.d.ts +38 -1
- package/packages/test-utils/dist/index.js +346 -1
- package/packages/test-utils/dist/index.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"speaker.d.ts","sourceRoot":"","sources":["../../../../src/entities/target/speaker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiCjD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"speaker.d.ts","sourceRoot":"","sources":["../../../../src/entities/target/speaker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiCjD,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,aAAa,QAiC5D"}
|
|
@@ -20,6 +20,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
InputInjector: () => InputInjector,
|
|
24
|
+
MockPointerLock: () => MockPointerLock,
|
|
23
25
|
createBinaryStreamMock: () => createBinaryStreamMock,
|
|
24
26
|
createBinaryWriterMock: () => createBinaryWriterMock,
|
|
25
27
|
createEntity: () => createEntity,
|
|
@@ -27,6 +29,7 @@ __export(index_exports, {
|
|
|
27
29
|
createGameStateSnapshotFactory: () => createGameStateSnapshotFactory,
|
|
28
30
|
createMockEngine: () => createMockEngine,
|
|
29
31
|
createMockGame: () => createMockGame,
|
|
32
|
+
createMockWebGL2Context: () => createMockWebGL2Context,
|
|
30
33
|
createNetChanMock: () => createNetChanMock,
|
|
31
34
|
createPlayerStateFactory: () => createPlayerStateFactory,
|
|
32
35
|
createSpawnContext: () => createSpawnContext,
|
|
@@ -40,7 +43,10 @@ __export(index_exports, {
|
|
|
40
43
|
makeLeafModel: () => makeLeafModel,
|
|
41
44
|
makeNode: () => makeNode,
|
|
42
45
|
makePlane: () => makePlane,
|
|
43
|
-
|
|
46
|
+
setupBrowserEnvironment: () => setupBrowserEnvironment,
|
|
47
|
+
setupNodeEnvironment: () => setupNodeEnvironment,
|
|
48
|
+
stairTrace: () => import_shared3.stairTrace,
|
|
49
|
+
teardownBrowserEnvironment: () => teardownBrowserEnvironment
|
|
44
50
|
});
|
|
45
51
|
module.exports = __toCommonJS(index_exports);
|
|
46
52
|
|
|
@@ -433,8 +439,349 @@ function createSpawnContext() {
|
|
|
433
439
|
function createEntity() {
|
|
434
440
|
return new import_game.Entity(1);
|
|
435
441
|
}
|
|
442
|
+
|
|
443
|
+
// src/setup/browser.ts
|
|
444
|
+
var import_jsdom = require("jsdom");
|
|
445
|
+
var import_canvas = require("@napi-rs/canvas");
|
|
446
|
+
var import_auto = require("fake-indexeddb/auto");
|
|
447
|
+
function setupBrowserEnvironment(options = {}) {
|
|
448
|
+
const { url = "http://localhost", pretendToBeVisual = true } = options;
|
|
449
|
+
const dom = new import_jsdom.JSDOM("<!DOCTYPE html><html><head></head><body></body></html>", {
|
|
450
|
+
url,
|
|
451
|
+
pretendToBeVisual
|
|
452
|
+
});
|
|
453
|
+
global.window = dom.window;
|
|
454
|
+
global.document = dom.window.document;
|
|
455
|
+
global.navigator = dom.window.navigator;
|
|
456
|
+
global.location = dom.window.location;
|
|
457
|
+
global.HTMLElement = dom.window.HTMLElement;
|
|
458
|
+
global.Event = dom.window.Event;
|
|
459
|
+
global.CustomEvent = dom.window.CustomEvent;
|
|
460
|
+
global.DragEvent = dom.window.DragEvent;
|
|
461
|
+
global.MouseEvent = dom.window.MouseEvent;
|
|
462
|
+
global.KeyboardEvent = dom.window.KeyboardEvent;
|
|
463
|
+
global.FocusEvent = dom.window.FocusEvent;
|
|
464
|
+
global.WheelEvent = dom.window.WheelEvent;
|
|
465
|
+
global.InputEvent = dom.window.InputEvent;
|
|
466
|
+
global.UIEvent = dom.window.UIEvent;
|
|
467
|
+
try {
|
|
468
|
+
global.localStorage = dom.window.localStorage;
|
|
469
|
+
} catch (e) {
|
|
470
|
+
}
|
|
471
|
+
if (!global.localStorage) {
|
|
472
|
+
const storage = /* @__PURE__ */ new Map();
|
|
473
|
+
global.localStorage = {
|
|
474
|
+
getItem: (key) => storage.get(key) || null,
|
|
475
|
+
setItem: (key, value) => storage.set(key, value),
|
|
476
|
+
removeItem: (key) => storage.delete(key),
|
|
477
|
+
clear: () => storage.clear(),
|
|
478
|
+
key: (index) => Array.from(storage.keys())[index] || null,
|
|
479
|
+
get length() {
|
|
480
|
+
return storage.size;
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
const originalCreateElement = document.createElement.bind(document);
|
|
485
|
+
document.createElement = function(tagName, options2) {
|
|
486
|
+
if (tagName.toLowerCase() === "canvas") {
|
|
487
|
+
const napiCanvas = new import_canvas.Canvas(300, 150);
|
|
488
|
+
const domCanvas = originalCreateElement("canvas", options2);
|
|
489
|
+
Object.defineProperty(domCanvas, "width", {
|
|
490
|
+
get: () => napiCanvas.width,
|
|
491
|
+
set: (value) => {
|
|
492
|
+
napiCanvas.width = value;
|
|
493
|
+
},
|
|
494
|
+
enumerable: true,
|
|
495
|
+
configurable: true
|
|
496
|
+
});
|
|
497
|
+
Object.defineProperty(domCanvas, "height", {
|
|
498
|
+
get: () => napiCanvas.height,
|
|
499
|
+
set: (value) => {
|
|
500
|
+
napiCanvas.height = value;
|
|
501
|
+
},
|
|
502
|
+
enumerable: true,
|
|
503
|
+
configurable: true
|
|
504
|
+
});
|
|
505
|
+
const originalGetContext = domCanvas.getContext.bind(domCanvas);
|
|
506
|
+
domCanvas.getContext = function(contextId, options3) {
|
|
507
|
+
if (contextId === "2d") {
|
|
508
|
+
return napiCanvas.getContext("2d", options3);
|
|
509
|
+
}
|
|
510
|
+
if (contextId === "webgl" || contextId === "webgl2") {
|
|
511
|
+
return originalGetContext(contextId, options3);
|
|
512
|
+
}
|
|
513
|
+
return napiCanvas.getContext(contextId, options3);
|
|
514
|
+
};
|
|
515
|
+
domCanvas.__napiCanvas = napiCanvas;
|
|
516
|
+
return domCanvas;
|
|
517
|
+
}
|
|
518
|
+
return originalCreateElement(tagName, options2);
|
|
519
|
+
};
|
|
520
|
+
global.Image = import_canvas.Image;
|
|
521
|
+
global.ImageData = import_canvas.ImageData;
|
|
522
|
+
if (typeof global.createImageBitmap === "undefined") {
|
|
523
|
+
global.createImageBitmap = async function(image, _options) {
|
|
524
|
+
if (image && typeof image.width === "number" && typeof image.height === "number") {
|
|
525
|
+
const canvas2 = new import_canvas.Canvas(image.width, image.height);
|
|
526
|
+
const ctx = canvas2.getContext("2d");
|
|
527
|
+
if (image.data) {
|
|
528
|
+
ctx.putImageData(image, 0, 0);
|
|
529
|
+
}
|
|
530
|
+
return canvas2;
|
|
531
|
+
}
|
|
532
|
+
const canvas = new import_canvas.Canvas(100, 100);
|
|
533
|
+
return canvas;
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
if (typeof global.btoa === "undefined") {
|
|
537
|
+
global.btoa = function(str) {
|
|
538
|
+
return Buffer.from(str, "binary").toString("base64");
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
if (typeof global.atob === "undefined") {
|
|
542
|
+
global.atob = function(str) {
|
|
543
|
+
return Buffer.from(str, "base64").toString("binary");
|
|
544
|
+
};
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
function teardownBrowserEnvironment() {
|
|
548
|
+
delete global.window;
|
|
549
|
+
delete global.document;
|
|
550
|
+
delete global.navigator;
|
|
551
|
+
delete global.localStorage;
|
|
552
|
+
delete global.location;
|
|
553
|
+
delete global.HTMLElement;
|
|
554
|
+
delete global.Image;
|
|
555
|
+
delete global.ImageData;
|
|
556
|
+
delete global.createImageBitmap;
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
// src/setup/node.ts
|
|
560
|
+
function setupNodeEnvironment() {
|
|
561
|
+
if (typeof global.fetch === "undefined") {
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
// src/setup/webgl.ts
|
|
566
|
+
function createMockWebGL2Context(canvas) {
|
|
567
|
+
const gl = {
|
|
568
|
+
canvas,
|
|
569
|
+
drawingBufferWidth: canvas.width,
|
|
570
|
+
drawingBufferHeight: canvas.height,
|
|
571
|
+
// Constants
|
|
572
|
+
VERTEX_SHADER: 35633,
|
|
573
|
+
FRAGMENT_SHADER: 35632,
|
|
574
|
+
COMPILE_STATUS: 35713,
|
|
575
|
+
LINK_STATUS: 35714,
|
|
576
|
+
ARRAY_BUFFER: 34962,
|
|
577
|
+
ELEMENT_ARRAY_BUFFER: 34963,
|
|
578
|
+
STATIC_DRAW: 35044,
|
|
579
|
+
DYNAMIC_DRAW: 35048,
|
|
580
|
+
FLOAT: 5126,
|
|
581
|
+
DEPTH_TEST: 2929,
|
|
582
|
+
BLEND: 3042,
|
|
583
|
+
SRC_ALPHA: 770,
|
|
584
|
+
ONE_MINUS_SRC_ALPHA: 771,
|
|
585
|
+
TEXTURE_2D: 3553,
|
|
586
|
+
RGBA: 6408,
|
|
587
|
+
UNSIGNED_BYTE: 5121,
|
|
588
|
+
COLOR_BUFFER_BIT: 16384,
|
|
589
|
+
DEPTH_BUFFER_BIT: 256,
|
|
590
|
+
TRIANGLES: 4,
|
|
591
|
+
TRIANGLE_STRIP: 5,
|
|
592
|
+
TRIANGLE_FAN: 6,
|
|
593
|
+
// Methods
|
|
594
|
+
createShader: () => ({}),
|
|
595
|
+
shaderSource: () => {
|
|
596
|
+
},
|
|
597
|
+
compileShader: () => {
|
|
598
|
+
},
|
|
599
|
+
getShaderParameter: (_, param) => {
|
|
600
|
+
if (param === 35713) return true;
|
|
601
|
+
return true;
|
|
602
|
+
},
|
|
603
|
+
getShaderInfoLog: () => "",
|
|
604
|
+
createProgram: () => ({}),
|
|
605
|
+
attachShader: () => {
|
|
606
|
+
},
|
|
607
|
+
linkProgram: () => {
|
|
608
|
+
},
|
|
609
|
+
getProgramParameter: (_, param) => {
|
|
610
|
+
if (param === 35714) return true;
|
|
611
|
+
return true;
|
|
612
|
+
},
|
|
613
|
+
getProgramInfoLog: () => "",
|
|
614
|
+
useProgram: () => {
|
|
615
|
+
},
|
|
616
|
+
createBuffer: () => ({}),
|
|
617
|
+
bindBuffer: () => {
|
|
618
|
+
},
|
|
619
|
+
bufferData: () => {
|
|
620
|
+
},
|
|
621
|
+
enableVertexAttribArray: () => {
|
|
622
|
+
},
|
|
623
|
+
vertexAttribPointer: () => {
|
|
624
|
+
},
|
|
625
|
+
enable: () => {
|
|
626
|
+
},
|
|
627
|
+
disable: () => {
|
|
628
|
+
},
|
|
629
|
+
depthMask: () => {
|
|
630
|
+
},
|
|
631
|
+
blendFunc: () => {
|
|
632
|
+
},
|
|
633
|
+
viewport: () => {
|
|
634
|
+
},
|
|
635
|
+
clearColor: () => {
|
|
636
|
+
},
|
|
637
|
+
clear: () => {
|
|
638
|
+
},
|
|
639
|
+
createTexture: () => ({}),
|
|
640
|
+
bindTexture: () => {
|
|
641
|
+
},
|
|
642
|
+
texImage2D: () => {
|
|
643
|
+
},
|
|
644
|
+
texParameteri: () => {
|
|
645
|
+
},
|
|
646
|
+
activeTexture: () => {
|
|
647
|
+
},
|
|
648
|
+
uniform1i: () => {
|
|
649
|
+
},
|
|
650
|
+
uniform1f: () => {
|
|
651
|
+
},
|
|
652
|
+
uniform2f: () => {
|
|
653
|
+
},
|
|
654
|
+
uniform3f: () => {
|
|
655
|
+
},
|
|
656
|
+
uniform4f: () => {
|
|
657
|
+
},
|
|
658
|
+
uniformMatrix4fv: () => {
|
|
659
|
+
},
|
|
660
|
+
getUniformLocation: () => ({}),
|
|
661
|
+
getAttribLocation: () => 0,
|
|
662
|
+
drawArrays: () => {
|
|
663
|
+
},
|
|
664
|
+
drawElements: () => {
|
|
665
|
+
},
|
|
666
|
+
createVertexArray: () => ({}),
|
|
667
|
+
bindVertexArray: () => {
|
|
668
|
+
},
|
|
669
|
+
deleteShader: () => {
|
|
670
|
+
},
|
|
671
|
+
deleteProgram: () => {
|
|
672
|
+
},
|
|
673
|
+
deleteBuffer: () => {
|
|
674
|
+
},
|
|
675
|
+
deleteTexture: () => {
|
|
676
|
+
},
|
|
677
|
+
deleteVertexArray: () => {
|
|
678
|
+
},
|
|
679
|
+
// WebGL2 specific
|
|
680
|
+
texImage3D: () => {
|
|
681
|
+
},
|
|
682
|
+
uniformBlockBinding: () => {
|
|
683
|
+
},
|
|
684
|
+
getExtension: () => null
|
|
685
|
+
};
|
|
686
|
+
return gl;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
// src/e2e/input.ts
|
|
690
|
+
var MockPointerLock = class {
|
|
691
|
+
static setup(doc) {
|
|
692
|
+
let _pointerLockElement = null;
|
|
693
|
+
Object.defineProperty(doc, "pointerLockElement", {
|
|
694
|
+
get: () => _pointerLockElement,
|
|
695
|
+
configurable: true
|
|
696
|
+
});
|
|
697
|
+
doc.exitPointerLock = () => {
|
|
698
|
+
if (_pointerLockElement) {
|
|
699
|
+
_pointerLockElement = null;
|
|
700
|
+
doc.dispatchEvent(new Event("pointerlockchange"));
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
global.HTMLElement.prototype.requestPointerLock = function() {
|
|
704
|
+
_pointerLockElement = this;
|
|
705
|
+
doc.dispatchEvent(new Event("pointerlockchange"));
|
|
706
|
+
};
|
|
707
|
+
}
|
|
708
|
+
};
|
|
709
|
+
var InputInjector = class {
|
|
710
|
+
constructor(doc, win) {
|
|
711
|
+
this.doc = doc;
|
|
712
|
+
this.win = win;
|
|
713
|
+
}
|
|
714
|
+
keyDown(key, code) {
|
|
715
|
+
const event = new this.win.KeyboardEvent("keydown", {
|
|
716
|
+
key,
|
|
717
|
+
code: code || key,
|
|
718
|
+
bubbles: true,
|
|
719
|
+
cancelable: true,
|
|
720
|
+
view: this.win
|
|
721
|
+
});
|
|
722
|
+
this.doc.dispatchEvent(event);
|
|
723
|
+
}
|
|
724
|
+
keyUp(key, code) {
|
|
725
|
+
const event = new this.win.KeyboardEvent("keyup", {
|
|
726
|
+
key,
|
|
727
|
+
code: code || key,
|
|
728
|
+
bubbles: true,
|
|
729
|
+
cancelable: true,
|
|
730
|
+
view: this.win
|
|
731
|
+
});
|
|
732
|
+
this.doc.dispatchEvent(event);
|
|
733
|
+
}
|
|
734
|
+
mouseMove(movementX, movementY, clientX = 0, clientY = 0) {
|
|
735
|
+
const event = new this.win.MouseEvent("mousemove", {
|
|
736
|
+
bubbles: true,
|
|
737
|
+
cancelable: true,
|
|
738
|
+
view: this.win,
|
|
739
|
+
clientX,
|
|
740
|
+
clientY,
|
|
741
|
+
movementX,
|
|
742
|
+
// Note: JSDOM might not support this standard property fully on event init
|
|
743
|
+
movementY
|
|
744
|
+
});
|
|
745
|
+
Object.defineProperty(event, "movementX", { value: movementX });
|
|
746
|
+
Object.defineProperty(event, "movementY", { value: movementY });
|
|
747
|
+
const target = this.doc.pointerLockElement || this.doc;
|
|
748
|
+
target.dispatchEvent(event);
|
|
749
|
+
}
|
|
750
|
+
mouseDown(button = 0) {
|
|
751
|
+
const event = new this.win.MouseEvent("mousedown", {
|
|
752
|
+
button,
|
|
753
|
+
bubbles: true,
|
|
754
|
+
cancelable: true,
|
|
755
|
+
view: this.win
|
|
756
|
+
});
|
|
757
|
+
const target = this.doc.pointerLockElement || this.doc;
|
|
758
|
+
target.dispatchEvent(event);
|
|
759
|
+
}
|
|
760
|
+
mouseUp(button = 0) {
|
|
761
|
+
const event = new this.win.MouseEvent("mouseup", {
|
|
762
|
+
button,
|
|
763
|
+
bubbles: true,
|
|
764
|
+
cancelable: true,
|
|
765
|
+
view: this.win
|
|
766
|
+
});
|
|
767
|
+
const target = this.doc.pointerLockElement || this.doc;
|
|
768
|
+
target.dispatchEvent(event);
|
|
769
|
+
}
|
|
770
|
+
wheel(deltaY) {
|
|
771
|
+
const event = new this.win.WheelEvent("wheel", {
|
|
772
|
+
deltaY,
|
|
773
|
+
bubbles: true,
|
|
774
|
+
cancelable: true,
|
|
775
|
+
view: this.win
|
|
776
|
+
});
|
|
777
|
+
const target = this.doc.pointerLockElement || this.doc;
|
|
778
|
+
target.dispatchEvent(event);
|
|
779
|
+
}
|
|
780
|
+
};
|
|
436
781
|
// Annotate the CommonJS export names for ESM import in node:
|
|
437
782
|
0 && (module.exports = {
|
|
783
|
+
InputInjector,
|
|
784
|
+
MockPointerLock,
|
|
438
785
|
createBinaryStreamMock,
|
|
439
786
|
createBinaryWriterMock,
|
|
440
787
|
createEntity,
|
|
@@ -442,6 +789,7 @@ function createEntity() {
|
|
|
442
789
|
createGameStateSnapshotFactory,
|
|
443
790
|
createMockEngine,
|
|
444
791
|
createMockGame,
|
|
792
|
+
createMockWebGL2Context,
|
|
445
793
|
createNetChanMock,
|
|
446
794
|
createPlayerStateFactory,
|
|
447
795
|
createSpawnContext,
|
|
@@ -455,6 +803,9 @@ function createEntity() {
|
|
|
455
803
|
makeLeafModel,
|
|
456
804
|
makeNode,
|
|
457
805
|
makePlane,
|
|
458
|
-
|
|
806
|
+
setupBrowserEnvironment,
|
|
807
|
+
setupNodeEnvironment,
|
|
808
|
+
stairTrace,
|
|
809
|
+
teardownBrowserEnvironment
|
|
459
810
|
});
|
|
460
811
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/shared/mocks.ts","../src/shared/bsp.ts","../src/game/factories.ts","../src/game/helpers.ts"],"sourcesContent":["// Export all test utilities\nexport * from './shared/mocks.js';\nexport * from './shared/bsp.js';\nexport * from './game/factories.js';\nexport * from './game/helpers.js';\n","import { vi, type Mock } from 'vitest';\n\nexport interface BinaryWriterMock {\n writeByte: Mock<[number], void>;\n writeShort: Mock<[number], void>;\n writeLong: Mock<[number], void>;\n writeString: Mock<[string], void>;\n writeBytes: Mock<[Uint8Array], void>;\n getBuffer: Mock<[], Uint8Array>;\n reset: Mock<[], void>;\n writeInt8: Mock<[number], void>;\n writeUint8: Mock<[number], void>;\n writeInt16: Mock<[number], void>;\n writeUint16: Mock<[number], void>;\n writeInt32: Mock<[number], void>;\n writeUint32: Mock<[number], void>;\n writeFloat: Mock<[number], void>;\n getData: Mock<[], Uint8Array>;\n}\n\nexport const createBinaryWriterMock = (): BinaryWriterMock => ({\n writeByte: vi.fn(),\n writeShort: vi.fn(),\n writeLong: vi.fn(),\n writeString: vi.fn(),\n writeBytes: vi.fn(),\n getBuffer: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n reset: vi.fn(),\n // Legacy methods (if any)\n writeInt8: vi.fn(),\n writeUint8: vi.fn(),\n writeInt16: vi.fn(),\n writeUint16: vi.fn(),\n writeInt32: vi.fn(),\n writeUint32: vi.fn(),\n writeFloat: vi.fn(),\n getData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n});\n\nexport const createNetChanMock = () => ({\n qport: 1234,\n\n // Sequencing\n incomingSequence: 0,\n outgoingSequence: 0,\n incomingAcknowledged: 0,\n\n // Reliable messaging\n incomingReliableAcknowledged: false,\n incomingReliableSequence: 0,\n outgoingReliableSequence: 0,\n reliableMessage: createBinaryWriterMock(),\n reliableLength: 0,\n\n // Fragmentation\n fragmentSendOffset: 0,\n fragmentBuffer: null,\n fragmentLength: 0,\n fragmentReceived: 0,\n\n // Timing\n lastReceived: 0,\n lastSent: 0,\n\n remoteAddress: { type: 'IP', port: 1234 },\n\n // Methods\n setup: vi.fn(),\n reset: vi.fn(),\n transmit: vi.fn(),\n process: vi.fn(),\n canSendReliable: vi.fn(() => true),\n writeReliableByte: vi.fn(),\n writeReliableShort: vi.fn(),\n writeReliableLong: vi.fn(),\n writeReliableString: vi.fn(),\n getReliableData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n needsKeepalive: vi.fn(() => false),\n isTimedOut: vi.fn(() => false),\n});\n\nexport interface BinaryStreamMock {\n getPosition: Mock<[], number>;\n getReadPosition: Mock<[], number>;\n getLength: Mock<[], number>;\n getRemaining: Mock<[], number>;\n seek: Mock<[number], void>;\n setReadPosition: Mock<[number], void>;\n hasMore: Mock<[], boolean>;\n hasBytes: Mock<[number], boolean>;\n\n readChar: Mock<[], number>;\n readByte: Mock<[], number>;\n readShort: Mock<[], number>;\n readUShort: Mock<[], number>;\n readLong: Mock<[], number>;\n readULong: Mock<[], number>;\n readFloat: Mock<[], number>;\n\n readString: Mock<[], string>;\n readStringLine: Mock<[], string>;\n\n readCoord: Mock<[], number>;\n readAngle: Mock<[], number>;\n readAngle16: Mock<[], number>;\n\n readData: Mock<[number], Uint8Array>;\n\n readPos: Mock<[], any>; // Use proper type if available, e.g., Vec3\n readDir: Mock<[], any>;\n}\n\nexport const createBinaryStreamMock = (): BinaryStreamMock => ({\n getPosition: vi.fn(() => 0),\n getReadPosition: vi.fn(() => 0),\n getLength: vi.fn(() => 0),\n getRemaining: vi.fn(() => 0),\n seek: vi.fn(),\n setReadPosition: vi.fn(),\n hasMore: vi.fn(() => true),\n hasBytes: vi.fn((amount: number) => true),\n\n readChar: vi.fn(() => 0),\n readByte: vi.fn(() => 0),\n readShort: vi.fn(() => 0),\n readUShort: vi.fn(() => 0),\n readLong: vi.fn(() => 0),\n readULong: vi.fn(() => 0),\n readFloat: vi.fn(() => 0),\n\n readString: vi.fn(() => ''),\n readStringLine: vi.fn(() => ''),\n\n readCoord: vi.fn(() => 0),\n readAngle: vi.fn(() => 0),\n readAngle16: vi.fn(() => 0),\n\n readData: vi.fn<[number], Uint8Array>((length: number) => new Uint8Array(length)),\n\n readPos: vi.fn(),\n readDir: vi.fn(),\n});\n","import {\n computePlaneSignBits,\n type CollisionBrush,\n type CollisionModel,\n type CollisionPlane,\n type CollisionNode,\n type CollisionLeaf,\n CONTENTS_SOLID,\n type Vec3\n} from '@quake2ts/shared';\n\nexport function makePlane(normal: Vec3, dist: number): CollisionPlane {\n return {\n normal,\n dist,\n type: Math.abs(normal.x) === 1 ? 0 : Math.abs(normal.y) === 1 ? 1 : Math.abs(normal.z) === 1 ? 2 : 3,\n signbits: computePlaneSignBits(normal),\n };\n}\n\nexport function makeAxisBrush(size: number, contents = CONTENTS_SOLID): CollisionBrush {\n const half = size / 2;\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, half),\n makePlane({ x: -1, y: 0, z: 0 }, half),\n makePlane({ x: 0, y: 1, z: 0 }, half),\n makePlane({ x: 0, y: -1, z: 0 }, half),\n makePlane({ x: 0, y: 0, z: 1 }, half),\n makePlane({ x: 0, y: 0, z: -1 }, half),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n\nexport function makeNode(plane: CollisionPlane, children: [number, number]): CollisionNode {\n return { plane, children };\n}\n\nexport function makeBspModel(\n planes: CollisionPlane[],\n nodes: CollisionNode[],\n leaves: CollisionLeaf[],\n brushes: CollisionBrush[],\n leafBrushes: number[]\n): CollisionModel {\n return {\n planes,\n nodes,\n leaves,\n brushes,\n leafBrushes,\n bmodels: [],\n };\n}\n\nexport function makeLeaf(contents: number, firstLeafBrush: number, numLeafBrushes: number): CollisionLeaf {\n return { contents, cluster: 0, area: 0, firstLeafBrush, numLeafBrushes };\n}\n\nexport function makeLeafModel(brushes: CollisionBrush[]): CollisionModel {\n const planes = brushes.flatMap((brush) => brush.sides.map((side) => side.plane));\n\n return {\n planes,\n nodes: [],\n leaves: [makeLeaf(0, 0, brushes.length)],\n brushes,\n leafBrushes: brushes.map((_, i) => i),\n bmodels: [],\n };\n}\n\nexport function makeBrushFromMinsMaxs(mins: Vec3, maxs: Vec3, contents = CONTENTS_SOLID): CollisionBrush {\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, maxs.x),\n makePlane({ x: -1, y: 0, z: 0 }, -mins.x),\n makePlane({ x: 0, y: 1, z: 0 }, maxs.y),\n makePlane({ x: 0, y: -1, z: 0 }, -mins.y),\n makePlane({ x: 0, y: 0, z: 1 }, maxs.z),\n makePlane({ x: 0, y: 0, z: -1 }, -mins.z),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n","import type { PlayerState, EntityState } from '@quake2ts/shared';\nimport type { GameStateSnapshot } from '@quake2ts/game';\n\nexport const createPlayerStateFactory = (overrides?: Partial<PlayerState>): PlayerState => ({\n pm_type: 0,\n pm_time: 0,\n pm_flags: 0,\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewAngles: { x: 0, y: 0, z: 0 },\n onGround: false,\n waterLevel: 0,\n watertype: 0,\n mins: { x: 0, y: 0, z: 0 },\n maxs: { x: 0, y: 0, z: 0 },\n damageAlpha: 0,\n damageIndicators: [],\n blend: [0, 0, 0, 0],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n ...overrides,\n});\n\nexport const createEntityStateFactory = (overrides?: Partial<EntityState>): EntityState => ({\n number: 0,\n origin: { x: 0, y: 0, z: 0 },\n angles: { x: 0, y: 0, z: 0 },\n oldOrigin: { x: 0, y: 0, z: 0 },\n modelIndex: 0,\n modelIndex2: 0,\n modelIndex3: 0,\n modelIndex4: 0,\n frame: 0,\n skinNum: 0,\n effects: 0,\n renderfx: 0,\n solid: 0,\n sound: 0,\n event: 0,\n ...overrides,\n});\n\nexport const createGameStateSnapshotFactory = (overrides?: Partial<GameStateSnapshot>): GameStateSnapshot => ({\n gravity: { x: 0, y: 0, z: -800 },\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewangles: { x: 0, y: 0, z: 0 },\n level: { timeSeconds: 0, frameNumber: 0, previousTimeSeconds: 0, deltaSeconds: 0.1 },\n entities: {\n activeCount: 0,\n worldClassname: 'worldspawn',\n },\n packetEntities: [],\n pmFlags: 0,\n pmType: 0,\n waterlevel: 0,\n watertype: 0,\n deltaAngles: { x: 0, y: 0, z: 0 },\n health: 100,\n armor: 0,\n ammo: 0,\n blend: [0, 0, 0, 0],\n damageAlpha: 0,\n damageIndicators: [],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n pm_time: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n pm_flags: 0,\n pm_type: 0,\n ...overrides,\n});\n","import { vi, type Mock } from 'vitest';\nimport { Entity, SpawnRegistry, ScriptHookRegistry, type SpawnContext, type EntitySystem } from '@quake2ts/game';\nimport { createRandomGenerator, type Vec3 } from '@quake2ts/shared';\n\n// Re-export generic helpers from shared\nexport { intersects, stairTrace, ladderTrace } from '@quake2ts/shared';\n\n// -- Types --\n\nexport interface MockEngine {\n sound: Mock<[Entity, number, string, number, number, number], void>;\n soundIndex: Mock<[string], number>;\n modelIndex: Mock<[string], number>;\n centerprintf: Mock<[Entity, string], void>;\n}\n\nexport interface MockGame {\n random: ReturnType<typeof createRandomGenerator>;\n registerEntitySpawn: Mock<[string, (entity: Entity) => void], void>;\n unregisterEntitySpawn: Mock<[string], void>;\n getCustomEntities: Mock<[], string[]>;\n hooks: ScriptHookRegistry;\n registerHooks: Mock<[any], any>;\n spawnWorld: Mock<[], void>;\n clientBegin: Mock<[any], void>;\n damage: Mock<[number], void>;\n}\n\nexport interface TestContext extends SpawnContext {\n entities: EntitySystem;\n game: MockGame;\n engine: MockEngine;\n}\n\n// -- Factories --\n\nexport const createMockEngine = (): MockEngine => ({\n sound: vi.fn(),\n soundIndex: vi.fn((sound: string) => 0),\n modelIndex: vi.fn((model: string) => 0),\n centerprintf: vi.fn(),\n});\n\nexport const createMockGame = (seed: number = 12345): { game: MockGame, spawnRegistry: SpawnRegistry } => {\n const spawnRegistry = new SpawnRegistry();\n const hooks = new ScriptHookRegistry();\n\n const game: MockGame = {\n random: createRandomGenerator({ seed }),\n registerEntitySpawn: vi.fn((classname: string, spawnFunc: (entity: Entity) => void) => {\n spawnRegistry.register(classname, (entity) => spawnFunc(entity));\n }),\n unregisterEntitySpawn: vi.fn((classname: string) => {\n spawnRegistry.unregister(classname);\n }),\n getCustomEntities: vi.fn(() => Array.from(spawnRegistry.keys())),\n hooks,\n registerHooks: vi.fn((newHooks) => hooks.register(newHooks)),\n spawnWorld: vi.fn(() => {\n hooks.onMapLoad('q2dm1');\n }),\n clientBegin: vi.fn((client) => {\n hooks.onPlayerSpawn({} as any);\n }),\n damage: vi.fn((amount: number) => {\n hooks.onDamage({} as any, null, null, amount, 0, 0);\n })\n };\n\n return { game, spawnRegistry };\n};\n\nexport function createTestContext(options?: { seed?: number, initialEntities?: Entity[] }): TestContext {\n const engine = createMockEngine();\n const seed = options?.seed ?? 12345;\n const { game, spawnRegistry } = createMockGame(seed);\n\n const traceFn = vi.fn((start: Vec3, end: Vec3, mins?: Vec3, maxs?: Vec3) => ({\n fraction: 1.0,\n ent: null,\n allsolid: false,\n startsolid: false,\n endpos: end,\n plane: { normal: { x: 0, y: 0, z: 1 }, dist: 0 },\n surfaceFlags: 0,\n contents: 0\n }));\n\n const entityList: Entity[] = options?.initialEntities ? [...options.initialEntities] : [];\n\n // Create hooks helper that interacts with the entity list\n const hooks = game.hooks;\n\n const entities = {\n spawn: vi.fn(() => {\n const ent = new Entity(entityList.length + 1);\n entityList.push(ent);\n hooks.onEntitySpawn(ent);\n return ent;\n }),\n free: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n hooks.onEntityRemove(ent);\n }),\n finalizeSpawn: vi.fn(),\n freeImmediate: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n }),\n setSpawnRegistry: vi.fn(),\n timeSeconds: 10,\n deltaSeconds: 0.1,\n modelIndex: vi.fn(() => 0),\n scheduleThink: vi.fn((entity: Entity, time: number) => {\n entity.nextthink = time;\n }),\n linkentity: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n multicast: vi.fn(),\n unicast: vi.fn(),\n engine,\n game,\n sound: vi.fn((ent: Entity, chan: number, sound: string, vol: number, attn: number, timeofs: number) => {\n engine.sound(ent, chan, sound, vol, attn, timeofs);\n }),\n soundIndex: vi.fn((sound: string) => engine.soundIndex(sound)),\n useTargets: vi.fn((entity: Entity, activator: Entity | null) => {\n }),\n findByTargetName: vi.fn(() => []),\n pickTarget: vi.fn(() => null),\n killBox: vi.fn(),\n rng: createRandomGenerator({ seed }),\n imports: {\n configstring: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n },\n level: {\n intermission_angle: { x: 0, y: 0, z: 0 },\n intermission_origin: { x: 0, y: 0, z: 0 },\n next_auto_save: 0,\n health_bar_entities: null\n },\n targetNameIndex: new Map(),\n forEachEntity: vi.fn((callback: (ent: Entity) => void) => {\n entityList.forEach(callback);\n }),\n find: vi.fn((predicate: (ent: Entity) => boolean) => {\n return entityList.find(predicate);\n }),\n findByClassname: vi.fn((classname: string) => {\n return entityList.find(e => e.classname === classname);\n }),\n beginFrame: vi.fn((timeSeconds: number) => {\n (entities as any).timeSeconds = timeSeconds;\n }),\n targetAwareness: {\n timeSeconds: 10,\n frameNumber: 1,\n sightEntity: null,\n soundEntity: null,\n },\n // Adding missing properties to satisfy EntitySystem interface partially or fully\n // We cast to unknown first anyway, but filling these in makes it safer for consumers\n skill: 1,\n deathmatch: false,\n coop: false,\n activeCount: entityList.length,\n world: entityList.find(e => e.classname === 'worldspawn') || new Entity(0),\n // ... other EntitySystem properties would go here\n } as unknown as EntitySystem;\n\n return {\n keyValues: {},\n entities,\n game,\n engine,\n health_multiplier: 1,\n warn: vi.fn(),\n free: vi.fn(),\n // Mock precache functions if they are part of SpawnContext in future or TestContext extensions\n precacheModel: vi.fn(),\n precacheSound: vi.fn(),\n precacheImage: vi.fn(),\n } as unknown as TestContext;\n}\n\nexport function createSpawnContext(): SpawnContext {\n return createTestContext();\n}\n\nexport function createEntity(): Entity {\n return new Entity(1);\n}\n"],"mappings":"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","names":["import_vitest","import_shared"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/shared/mocks.ts","../src/shared/bsp.ts","../src/game/factories.ts","../src/game/helpers.ts","../src/setup/browser.ts","../src/setup/node.ts","../src/setup/webgl.ts","../src/e2e/input.ts"],"sourcesContent":["// Export all test utilities\nexport * from './shared/mocks.js';\nexport * from './shared/bsp.js';\nexport * from './game/factories.js';\nexport * from './game/helpers.js';\nexport * from './setup/browser.js';\nexport * from './setup/node.js';\nexport * from './setup/webgl.js';\nexport * from './e2e/input.js';\n","import { vi, type Mock } from 'vitest';\n\nexport interface BinaryWriterMock {\n writeByte: Mock<[number], void>;\n writeShort: Mock<[number], void>;\n writeLong: Mock<[number], void>;\n writeString: Mock<[string], void>;\n writeBytes: Mock<[Uint8Array], void>;\n getBuffer: Mock<[], Uint8Array>;\n reset: Mock<[], void>;\n writeInt8: Mock<[number], void>;\n writeUint8: Mock<[number], void>;\n writeInt16: Mock<[number], void>;\n writeUint16: Mock<[number], void>;\n writeInt32: Mock<[number], void>;\n writeUint32: Mock<[number], void>;\n writeFloat: Mock<[number], void>;\n getData: Mock<[], Uint8Array>;\n}\n\nexport const createBinaryWriterMock = (): BinaryWriterMock => ({\n writeByte: vi.fn(),\n writeShort: vi.fn(),\n writeLong: vi.fn(),\n writeString: vi.fn(),\n writeBytes: vi.fn(),\n getBuffer: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n reset: vi.fn(),\n // Legacy methods (if any)\n writeInt8: vi.fn(),\n writeUint8: vi.fn(),\n writeInt16: vi.fn(),\n writeUint16: vi.fn(),\n writeInt32: vi.fn(),\n writeUint32: vi.fn(),\n writeFloat: vi.fn(),\n getData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n});\n\nexport const createNetChanMock = () => ({\n qport: 1234,\n\n // Sequencing\n incomingSequence: 0,\n outgoingSequence: 0,\n incomingAcknowledged: 0,\n\n // Reliable messaging\n incomingReliableAcknowledged: false,\n incomingReliableSequence: 0,\n outgoingReliableSequence: 0,\n reliableMessage: createBinaryWriterMock(),\n reliableLength: 0,\n\n // Fragmentation\n fragmentSendOffset: 0,\n fragmentBuffer: null,\n fragmentLength: 0,\n fragmentReceived: 0,\n\n // Timing\n lastReceived: 0,\n lastSent: 0,\n\n remoteAddress: { type: 'IP', port: 1234 },\n\n // Methods\n setup: vi.fn(),\n reset: vi.fn(),\n transmit: vi.fn(),\n process: vi.fn(),\n canSendReliable: vi.fn(() => true),\n writeReliableByte: vi.fn(),\n writeReliableShort: vi.fn(),\n writeReliableLong: vi.fn(),\n writeReliableString: vi.fn(),\n getReliableData: vi.fn<[], Uint8Array>(() => new Uint8Array(0)),\n needsKeepalive: vi.fn(() => false),\n isTimedOut: vi.fn(() => false),\n});\n\nexport interface BinaryStreamMock {\n getPosition: Mock<[], number>;\n getReadPosition: Mock<[], number>;\n getLength: Mock<[], number>;\n getRemaining: Mock<[], number>;\n seek: Mock<[number], void>;\n setReadPosition: Mock<[number], void>;\n hasMore: Mock<[], boolean>;\n hasBytes: Mock<[number], boolean>;\n\n readChar: Mock<[], number>;\n readByte: Mock<[], number>;\n readShort: Mock<[], number>;\n readUShort: Mock<[], number>;\n readLong: Mock<[], number>;\n readULong: Mock<[], number>;\n readFloat: Mock<[], number>;\n\n readString: Mock<[], string>;\n readStringLine: Mock<[], string>;\n\n readCoord: Mock<[], number>;\n readAngle: Mock<[], number>;\n readAngle16: Mock<[], number>;\n\n readData: Mock<[number], Uint8Array>;\n\n readPos: Mock<[], any>; // Use proper type if available, e.g., Vec3\n readDir: Mock<[], any>;\n}\n\nexport const createBinaryStreamMock = (): BinaryStreamMock => ({\n getPosition: vi.fn(() => 0),\n getReadPosition: vi.fn(() => 0),\n getLength: vi.fn(() => 0),\n getRemaining: vi.fn(() => 0),\n seek: vi.fn(),\n setReadPosition: vi.fn(),\n hasMore: vi.fn(() => true),\n hasBytes: vi.fn((amount: number) => true),\n\n readChar: vi.fn(() => 0),\n readByte: vi.fn(() => 0),\n readShort: vi.fn(() => 0),\n readUShort: vi.fn(() => 0),\n readLong: vi.fn(() => 0),\n readULong: vi.fn(() => 0),\n readFloat: vi.fn(() => 0),\n\n readString: vi.fn(() => ''),\n readStringLine: vi.fn(() => ''),\n\n readCoord: vi.fn(() => 0),\n readAngle: vi.fn(() => 0),\n readAngle16: vi.fn(() => 0),\n\n readData: vi.fn<[number], Uint8Array>((length: number) => new Uint8Array(length)),\n\n readPos: vi.fn(),\n readDir: vi.fn(),\n});\n","import {\n computePlaneSignBits,\n type CollisionBrush,\n type CollisionModel,\n type CollisionPlane,\n type CollisionNode,\n type CollisionLeaf,\n CONTENTS_SOLID,\n type Vec3\n} from '@quake2ts/shared';\n\nexport function makePlane(normal: Vec3, dist: number): CollisionPlane {\n return {\n normal,\n dist,\n type: Math.abs(normal.x) === 1 ? 0 : Math.abs(normal.y) === 1 ? 1 : Math.abs(normal.z) === 1 ? 2 : 3,\n signbits: computePlaneSignBits(normal),\n };\n}\n\nexport function makeAxisBrush(size: number, contents = CONTENTS_SOLID): CollisionBrush {\n const half = size / 2;\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, half),\n makePlane({ x: -1, y: 0, z: 0 }, half),\n makePlane({ x: 0, y: 1, z: 0 }, half),\n makePlane({ x: 0, y: -1, z: 0 }, half),\n makePlane({ x: 0, y: 0, z: 1 }, half),\n makePlane({ x: 0, y: 0, z: -1 }, half),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n\nexport function makeNode(plane: CollisionPlane, children: [number, number]): CollisionNode {\n return { plane, children };\n}\n\nexport function makeBspModel(\n planes: CollisionPlane[],\n nodes: CollisionNode[],\n leaves: CollisionLeaf[],\n brushes: CollisionBrush[],\n leafBrushes: number[]\n): CollisionModel {\n return {\n planes,\n nodes,\n leaves,\n brushes,\n leafBrushes,\n bmodels: [],\n };\n}\n\nexport function makeLeaf(contents: number, firstLeafBrush: number, numLeafBrushes: number): CollisionLeaf {\n return { contents, cluster: 0, area: 0, firstLeafBrush, numLeafBrushes };\n}\n\nexport function makeLeafModel(brushes: CollisionBrush[]): CollisionModel {\n const planes = brushes.flatMap((brush) => brush.sides.map((side) => side.plane));\n\n return {\n planes,\n nodes: [],\n leaves: [makeLeaf(0, 0, brushes.length)],\n brushes,\n leafBrushes: brushes.map((_, i) => i),\n bmodels: [],\n };\n}\n\nexport function makeBrushFromMinsMaxs(mins: Vec3, maxs: Vec3, contents = CONTENTS_SOLID): CollisionBrush {\n const planes = [\n makePlane({ x: 1, y: 0, z: 0 }, maxs.x),\n makePlane({ x: -1, y: 0, z: 0 }, -mins.x),\n makePlane({ x: 0, y: 1, z: 0 }, maxs.y),\n makePlane({ x: 0, y: -1, z: 0 }, -mins.y),\n makePlane({ x: 0, y: 0, z: 1 }, maxs.z),\n makePlane({ x: 0, y: 0, z: -1 }, -mins.z),\n ];\n\n return {\n contents,\n sides: planes.map((plane) => ({ plane, surfaceFlags: 0 })),\n };\n}\n","import type { PlayerState, EntityState } from '@quake2ts/shared';\nimport type { GameStateSnapshot } from '@quake2ts/game';\n\nexport const createPlayerStateFactory = (overrides?: Partial<PlayerState>): PlayerState => ({\n pm_type: 0,\n pm_time: 0,\n pm_flags: 0,\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewAngles: { x: 0, y: 0, z: 0 },\n onGround: false,\n waterLevel: 0,\n watertype: 0,\n mins: { x: 0, y: 0, z: 0 },\n maxs: { x: 0, y: 0, z: 0 },\n damageAlpha: 0,\n damageIndicators: [],\n blend: [0, 0, 0, 0],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n ...overrides,\n});\n\nexport const createEntityStateFactory = (overrides?: Partial<EntityState>): EntityState => ({\n number: 0,\n origin: { x: 0, y: 0, z: 0 },\n angles: { x: 0, y: 0, z: 0 },\n oldOrigin: { x: 0, y: 0, z: 0 },\n modelIndex: 0,\n modelIndex2: 0,\n modelIndex3: 0,\n modelIndex4: 0,\n frame: 0,\n skinNum: 0,\n effects: 0,\n renderfx: 0,\n solid: 0,\n sound: 0,\n event: 0,\n ...overrides,\n});\n\nexport const createGameStateSnapshotFactory = (overrides?: Partial<GameStateSnapshot>): GameStateSnapshot => ({\n gravity: { x: 0, y: 0, z: -800 },\n origin: { x: 0, y: 0, z: 0 },\n velocity: { x: 0, y: 0, z: 0 },\n viewangles: { x: 0, y: 0, z: 0 },\n level: { timeSeconds: 0, frameNumber: 0, previousTimeSeconds: 0, deltaSeconds: 0.1 },\n entities: {\n activeCount: 0,\n worldClassname: 'worldspawn',\n },\n packetEntities: [],\n pmFlags: 0,\n pmType: 0,\n waterlevel: 0,\n watertype: 0,\n deltaAngles: { x: 0, y: 0, z: 0 },\n health: 100,\n armor: 0,\n ammo: 0,\n blend: [0, 0, 0, 0],\n damageAlpha: 0,\n damageIndicators: [],\n stats: [],\n kick_angles: { x: 0, y: 0, z: 0 },\n kick_origin: { x: 0, y: 0, z: 0 },\n gunoffset: { x: 0, y: 0, z: 0 },\n gunangles: { x: 0, y: 0, z: 0 },\n gunindex: 0,\n pm_time: 0,\n gun_frame: 0,\n rdflags: 0,\n fov: 90,\n renderfx: 0,\n pm_flags: 0,\n pm_type: 0,\n ...overrides,\n});\n","import { vi, type Mock } from 'vitest';\nimport { Entity, SpawnRegistry, ScriptHookRegistry, type SpawnContext, type EntitySystem } from '@quake2ts/game';\nimport { createRandomGenerator, type Vec3 } from '@quake2ts/shared';\n\n// Re-export generic helpers from shared\nexport { intersects, stairTrace, ladderTrace } from '@quake2ts/shared';\n\n// -- Types --\n\nexport interface MockEngine {\n sound: Mock<[Entity, number, string, number, number, number], void>;\n soundIndex: Mock<[string], number>;\n modelIndex: Mock<[string], number>;\n centerprintf: Mock<[Entity, string], void>;\n}\n\nexport interface MockGame {\n random: ReturnType<typeof createRandomGenerator>;\n registerEntitySpawn: Mock<[string, (entity: Entity) => void], void>;\n unregisterEntitySpawn: Mock<[string], void>;\n getCustomEntities: Mock<[], string[]>;\n hooks: ScriptHookRegistry;\n registerHooks: Mock<[any], any>;\n spawnWorld: Mock<[], void>;\n clientBegin: Mock<[any], void>;\n damage: Mock<[number], void>;\n}\n\nexport interface TestContext extends SpawnContext {\n entities: EntitySystem;\n game: MockGame;\n engine: MockEngine;\n}\n\n// -- Factories --\n\nexport const createMockEngine = (): MockEngine => ({\n sound: vi.fn(),\n soundIndex: vi.fn((sound: string) => 0),\n modelIndex: vi.fn((model: string) => 0),\n centerprintf: vi.fn(),\n});\n\nexport const createMockGame = (seed: number = 12345): { game: MockGame, spawnRegistry: SpawnRegistry } => {\n const spawnRegistry = new SpawnRegistry();\n const hooks = new ScriptHookRegistry();\n\n const game: MockGame = {\n random: createRandomGenerator({ seed }),\n registerEntitySpawn: vi.fn((classname: string, spawnFunc: (entity: Entity) => void) => {\n spawnRegistry.register(classname, (entity) => spawnFunc(entity));\n }),\n unregisterEntitySpawn: vi.fn((classname: string) => {\n spawnRegistry.unregister(classname);\n }),\n getCustomEntities: vi.fn(() => Array.from(spawnRegistry.keys())),\n hooks,\n registerHooks: vi.fn((newHooks) => hooks.register(newHooks)),\n spawnWorld: vi.fn(() => {\n hooks.onMapLoad('q2dm1');\n }),\n clientBegin: vi.fn((client) => {\n hooks.onPlayerSpawn({} as any);\n }),\n damage: vi.fn((amount: number) => {\n hooks.onDamage({} as any, null, null, amount, 0, 0);\n })\n };\n\n return { game, spawnRegistry };\n};\n\nexport function createTestContext(options?: { seed?: number, initialEntities?: Entity[] }): TestContext {\n const engine = createMockEngine();\n const seed = options?.seed ?? 12345;\n const { game, spawnRegistry } = createMockGame(seed);\n\n const traceFn = vi.fn((start: Vec3, end: Vec3, mins?: Vec3, maxs?: Vec3) => ({\n fraction: 1.0,\n ent: null,\n allsolid: false,\n startsolid: false,\n endpos: end,\n plane: { normal: { x: 0, y: 0, z: 1 }, dist: 0 },\n surfaceFlags: 0,\n contents: 0\n }));\n\n const entityList: Entity[] = options?.initialEntities ? [...options.initialEntities] : [];\n\n // Create hooks helper that interacts with the entity list\n const hooks = game.hooks;\n\n const entities = {\n spawn: vi.fn(() => {\n const ent = new Entity(entityList.length + 1);\n entityList.push(ent);\n hooks.onEntitySpawn(ent);\n return ent;\n }),\n free: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n hooks.onEntityRemove(ent);\n }),\n finalizeSpawn: vi.fn(),\n freeImmediate: vi.fn((ent: Entity) => {\n const idx = entityList.indexOf(ent);\n if (idx !== -1) {\n entityList.splice(idx, 1);\n }\n }),\n setSpawnRegistry: vi.fn(),\n timeSeconds: 10,\n deltaSeconds: 0.1,\n modelIndex: vi.fn(() => 0),\n scheduleThink: vi.fn((entity: Entity, time: number) => {\n entity.nextthink = time;\n }),\n linkentity: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n multicast: vi.fn(),\n unicast: vi.fn(),\n engine,\n game,\n sound: vi.fn((ent: Entity, chan: number, sound: string, vol: number, attn: number, timeofs: number) => {\n engine.sound(ent, chan, sound, vol, attn, timeofs);\n }),\n soundIndex: vi.fn((sound: string) => engine.soundIndex(sound)),\n useTargets: vi.fn((entity: Entity, activator: Entity | null) => {\n }),\n findByTargetName: vi.fn(() => []),\n pickTarget: vi.fn(() => null),\n killBox: vi.fn(),\n rng: createRandomGenerator({ seed }),\n imports: {\n configstring: vi.fn(),\n trace: traceFn,\n pointcontents: vi.fn(() => 0),\n },\n level: {\n intermission_angle: { x: 0, y: 0, z: 0 },\n intermission_origin: { x: 0, y: 0, z: 0 },\n next_auto_save: 0,\n health_bar_entities: null\n },\n targetNameIndex: new Map(),\n forEachEntity: vi.fn((callback: (ent: Entity) => void) => {\n entityList.forEach(callback);\n }),\n find: vi.fn((predicate: (ent: Entity) => boolean) => {\n return entityList.find(predicate);\n }),\n findByClassname: vi.fn((classname: string) => {\n return entityList.find(e => e.classname === classname);\n }),\n beginFrame: vi.fn((timeSeconds: number) => {\n (entities as any).timeSeconds = timeSeconds;\n }),\n targetAwareness: {\n timeSeconds: 10,\n frameNumber: 1,\n sightEntity: null,\n soundEntity: null,\n },\n // Adding missing properties to satisfy EntitySystem interface partially or fully\n // We cast to unknown first anyway, but filling these in makes it safer for consumers\n skill: 1,\n deathmatch: false,\n coop: false,\n activeCount: entityList.length,\n world: entityList.find(e => e.classname === 'worldspawn') || new Entity(0),\n // ... other EntitySystem properties would go here\n } as unknown as EntitySystem;\n\n return {\n keyValues: {},\n entities,\n game,\n engine,\n health_multiplier: 1,\n warn: vi.fn(),\n free: vi.fn(),\n // Mock precache functions if they are part of SpawnContext in future or TestContext extensions\n precacheModel: vi.fn(),\n precacheSound: vi.fn(),\n precacheImage: vi.fn(),\n } as unknown as TestContext;\n}\n\nexport function createSpawnContext(): SpawnContext {\n return createTestContext();\n}\n\nexport function createEntity(): Entity {\n return new Entity(1);\n}\n","import { JSDOM } from 'jsdom';\nimport { Canvas, Image, ImageData } from '@napi-rs/canvas';\nimport 'fake-indexeddb/auto';\n\nexport interface BrowserSetupOptions {\n url?: string;\n pretendToBeVisual?: boolean;\n}\n\n/**\n * Sets up a browser environment for testing using JSDOM and napi-rs/canvas.\n * This should be called in your vitest.setup.ts file.\n */\nexport function setupBrowserEnvironment(options: BrowserSetupOptions = {}) {\n const { url = 'http://localhost', pretendToBeVisual = true } = options;\n\n // Create a JSDOM instance\n const dom = new JSDOM('<!DOCTYPE html><html><head></head><body></body></html>', {\n url,\n pretendToBeVisual,\n });\n\n // Set up global variables\n global.window = dom.window as any;\n global.document = dom.window.document;\n global.navigator = dom.window.navigator;\n global.location = dom.window.location;\n global.HTMLElement = dom.window.HTMLElement;\n\n // Polyfill global Event constructors to match JSDOM's window\n global.Event = dom.window.Event;\n global.CustomEvent = dom.window.CustomEvent;\n global.DragEvent = dom.window.DragEvent as any;\n global.MouseEvent = dom.window.MouseEvent;\n global.KeyboardEvent = dom.window.KeyboardEvent;\n global.FocusEvent = dom.window.FocusEvent;\n global.WheelEvent = dom.window.WheelEvent;\n global.InputEvent = dom.window.InputEvent;\n global.UIEvent = dom.window.UIEvent;\n\n // Setup Storage mocks\n // First try to use JSDOM's localStorage\n try {\n global.localStorage = dom.window.localStorage;\n } catch (e) {\n // Ignore if it fails (e.g. strict mode)\n }\n\n // Fallback if not present\n if (!global.localStorage) {\n const storage = new Map<string, string>();\n global.localStorage = {\n getItem: (key: string) => storage.get(key) || null,\n setItem: (key: string, value: string) => storage.set(key, value),\n removeItem: (key: string) => storage.delete(key),\n clear: () => storage.clear(),\n key: (index: number) => Array.from(storage.keys())[index] || null,\n get length() { return storage.size; }\n } as Storage;\n }\n\n // Override document.createElement for canvas elements to use napi-rs/canvas\n const originalCreateElement = document.createElement.bind(document);\n document.createElement = function (tagName: string, options?: any) {\n if (tagName.toLowerCase() === 'canvas') {\n const napiCanvas = new Canvas(300, 150); // default canvas size\n\n // Create a wrapper that extends the DOM canvas element\n const domCanvas = originalCreateElement('canvas', options);\n\n // Copy properties and methods from napi-rs canvas to DOM canvas\n Object.defineProperty(domCanvas, 'width', {\n get: () => napiCanvas.width,\n set: (value) => { napiCanvas.width = value; },\n enumerable: true,\n configurable: true\n });\n\n Object.defineProperty(domCanvas, 'height', {\n get: () => napiCanvas.height,\n set: (value) => { napiCanvas.height = value; },\n enumerable: true,\n configurable: true\n });\n\n // Override getContext to return appropriate context\n const originalGetContext = domCanvas.getContext.bind(domCanvas);\n domCanvas.getContext = function(contextId: string, options?: any) {\n if (contextId === '2d') {\n return napiCanvas.getContext('2d', options);\n }\n // For webgl/webgl2, return jsdom's default context (null or mock)\n // or the original behavior if needed.\n if (contextId === 'webgl' || contextId === 'webgl2') {\n return originalGetContext(contextId, options);\n }\n return napiCanvas.getContext(contextId as any, options);\n } as any;\n\n // Store reference to napi canvas for direct access if needed\n (domCanvas as any).__napiCanvas = napiCanvas;\n\n return domCanvas;\n }\n return originalCreateElement(tagName, options);\n } as any;\n\n // Set up global Image constructor\n global.Image = Image as any;\n\n // Set up global ImageData constructor\n global.ImageData = ImageData as any;\n\n // Mock createImageBitmap if not available\n if (typeof global.createImageBitmap === 'undefined') {\n global.createImageBitmap = async function (\n image: any, // Relax type to allow passing different image sources\n _options?: ImageBitmapOptions\n ): Promise<any> {\n // Handle ImageData specially\n if (image && typeof image.width === 'number' && typeof image.height === 'number') {\n // For testing purposes, we can create a small canvas with the image data\n const canvas = new Canvas(image.width, image.height);\n const ctx = canvas.getContext('2d');\n // Only try to put data if it looks like ImageData\n if (image.data) {\n ctx.putImageData(image as any, 0, 0);\n }\n return canvas;\n }\n // Fallback for other sources (e.g. Image element) - return empty canvas of generic size\n const canvas = new Canvas(100, 100);\n return canvas;\n } as any;\n }\n\n // Mock btoa and atob if not available\n if (typeof global.btoa === 'undefined') {\n global.btoa = function (str: string): string {\n return Buffer.from(str, 'binary').toString('base64');\n };\n }\n\n if (typeof global.atob === 'undefined') {\n global.atob = function (str: string): string {\n return Buffer.from(str, 'base64').toString('binary');\n };\n }\n}\n\n/**\n * Cleans up the browser environment.\n */\nexport function teardownBrowserEnvironment() {\n // Optional cleanup if needed, though usually global scope cleanup is handled by test runner context\n // or by just overriding it again.\n // For strict cleanup, we could delete globals, but in Vitest environment, it might persist?\n // We'll leave it simple for now or just undefined them.\n\n // @ts-ignore\n delete global.window;\n // @ts-ignore\n delete global.document;\n // @ts-ignore\n delete global.navigator;\n // @ts-ignore\n delete global.localStorage;\n // @ts-ignore\n delete global.location;\n // @ts-ignore\n delete global.HTMLElement;\n // @ts-ignore\n delete global.Image;\n // @ts-ignore\n delete global.ImageData;\n // @ts-ignore\n delete global.createImageBitmap;\n\n // Note: btoa/atob might be native in newer Node versions, so be careful deleting them if they were original.\n // But here we only set them if undefined.\n}\n","/**\n * Sets up a Node.js environment for testing.\n * This is primarily for backend or shared logic that doesn't rely on browser APIs.\n */\nexport function setupNodeEnvironment() {\n // Add any Node-specific global setup here\n // For now, this is a placeholder or can be used for things like\n // polyfilling fetch if not present in older Node versions (though Quake2TS targets recent Node)\n\n if (typeof global.fetch === 'undefined') {\n // In a real scenario, we might import node-fetch here\n // global.fetch = ...\n }\n}\n","\nexport function createMockWebGL2Context(canvas: HTMLCanvasElement): WebGL2RenderingContext {\n const gl = {\n canvas,\n drawingBufferWidth: canvas.width,\n drawingBufferHeight: canvas.height,\n\n // Constants\n VERTEX_SHADER: 0x8B31,\n FRAGMENT_SHADER: 0x8B30,\n COMPILE_STATUS: 0x8B81,\n LINK_STATUS: 0x8B82,\n ARRAY_BUFFER: 0x8892,\n ELEMENT_ARRAY_BUFFER: 0x8893,\n STATIC_DRAW: 0x88E4,\n DYNAMIC_DRAW: 0x88E8,\n FLOAT: 0x1406,\n DEPTH_TEST: 0x0B71,\n BLEND: 0x0BE2,\n SRC_ALPHA: 0x0302,\n ONE_MINUS_SRC_ALPHA: 0x0303,\n TEXTURE_2D: 0x0DE1,\n RGBA: 0x1908,\n UNSIGNED_BYTE: 0x1401,\n COLOR_BUFFER_BIT: 0x4000,\n DEPTH_BUFFER_BIT: 0x0100,\n TRIANGLES: 0x0004,\n TRIANGLE_STRIP: 0x0005,\n TRIANGLE_FAN: 0x0006,\n\n // Methods\n createShader: () => ({}),\n shaderSource: () => {},\n compileShader: () => {},\n getShaderParameter: (_: any, param: number) => {\n if (param === 0x8B81) return true; // COMPILE_STATUS\n return true;\n },\n getShaderInfoLog: () => '',\n createProgram: () => ({}),\n attachShader: () => {},\n linkProgram: () => {},\n getProgramParameter: (_: any, param: number) => {\n if (param === 0x8B82) return true; // LINK_STATUS\n return true;\n },\n getProgramInfoLog: () => '',\n useProgram: () => {},\n createBuffer: () => ({}),\n bindBuffer: () => {},\n bufferData: () => {},\n enableVertexAttribArray: () => {},\n vertexAttribPointer: () => {},\n enable: () => {},\n disable: () => {},\n depthMask: () => {},\n blendFunc: () => {},\n viewport: () => {},\n clearColor: () => {},\n clear: () => {},\n createTexture: () => ({}),\n bindTexture: () => {},\n texImage2D: () => {},\n texParameteri: () => {},\n activeTexture: () => {},\n uniform1i: () => {},\n uniform1f: () => {},\n uniform2f: () => {},\n uniform3f: () => {},\n uniform4f: () => {},\n uniformMatrix4fv: () => {},\n getUniformLocation: () => ({}),\n getAttribLocation: () => 0,\n drawArrays: () => {},\n drawElements: () => {},\n createVertexArray: () => ({}),\n bindVertexArray: () => {},\n deleteShader: () => {},\n deleteProgram: () => {},\n deleteBuffer: () => {},\n deleteTexture: () => {},\n deleteVertexArray: () => {},\n\n // WebGL2 specific\n texImage3D: () => {},\n uniformBlockBinding: () => {},\n getExtension: () => null,\n } as unknown as WebGL2RenderingContext;\n\n return gl;\n}\n","\nexport class MockPointerLock {\n static setup(doc: Document) {\n // Mock pointerLockElement property\n let _pointerLockElement: Element | null = null;\n\n Object.defineProperty(doc, 'pointerLockElement', {\n get: () => _pointerLockElement,\n configurable: true\n });\n\n // Mock exitPointerLock\n doc.exitPointerLock = () => {\n if (_pointerLockElement) {\n _pointerLockElement = null;\n doc.dispatchEvent(new Event('pointerlockchange'));\n }\n };\n\n // Mock requestPointerLock on Element prototype\n // We need to extend the Element interface to make TS happy if we were strict,\n // but here we are modifying the prototype directly.\n // @ts-ignore\n (global.HTMLElement.prototype as any).requestPointerLock = function() {\n // In a real browser this is async and requires user gesture,\n // but for tests we make it immediate.\n _pointerLockElement = this;\n doc.dispatchEvent(new Event('pointerlockchange'));\n };\n }\n}\n\nexport class InputInjector {\n constructor(private doc: Document, private win: any) {}\n\n keyDown(key: string, code?: string) {\n const event = new this.win.KeyboardEvent('keydown', {\n key,\n code: code || key,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n this.doc.dispatchEvent(event);\n }\n\n keyUp(key: string, code?: string) {\n const event = new this.win.KeyboardEvent('keyup', {\n key,\n code: code || key,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n this.doc.dispatchEvent(event);\n }\n\n mouseMove(movementX: number, movementY: number, clientX = 0, clientY = 0) {\n const event = new this.win.MouseEvent('mousemove', {\n bubbles: true,\n cancelable: true,\n view: this.win,\n clientX,\n clientY,\n movementX, // Note: JSDOM might not support this standard property fully on event init\n movementY\n } as any);\n\n // Force movement properties if JSDOM doesn't handle them\n Object.defineProperty(event, 'movementX', { value: movementX });\n Object.defineProperty(event, 'movementY', { value: movementY });\n\n // Dispatch to pointer lock element if active, otherwise document\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n mouseDown(button: number = 0) {\n const event = new this.win.MouseEvent('mousedown', {\n button,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n mouseUp(button: number = 0) {\n const event = new this.win.MouseEvent('mouseup', {\n button,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n\n wheel(deltaY: number) {\n const event = new this.win.WheelEvent('wheel', {\n deltaY,\n bubbles: true,\n cancelable: true,\n view: this.win\n });\n // @ts-ignore\n const target = this.doc.pointerLockElement || this.doc;\n target.dispatchEvent(event);\n }\n}\n"],"mappings":"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","names":["import_vitest","import_shared","options","canvas"]}
|
|
@@ -127,4 +127,41 @@ declare function createTestContext(options?: {
|
|
|
127
127
|
declare function createSpawnContext(): SpawnContext;
|
|
128
128
|
declare function createEntity(): Entity;
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
interface BrowserSetupOptions {
|
|
131
|
+
url?: string;
|
|
132
|
+
pretendToBeVisual?: boolean;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Sets up a browser environment for testing using JSDOM and napi-rs/canvas.
|
|
136
|
+
* This should be called in your vitest.setup.ts file.
|
|
137
|
+
*/
|
|
138
|
+
declare function setupBrowserEnvironment(options?: BrowserSetupOptions): void;
|
|
139
|
+
/**
|
|
140
|
+
* Cleans up the browser environment.
|
|
141
|
+
*/
|
|
142
|
+
declare function teardownBrowserEnvironment(): void;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Sets up a Node.js environment for testing.
|
|
146
|
+
* This is primarily for backend or shared logic that doesn't rely on browser APIs.
|
|
147
|
+
*/
|
|
148
|
+
declare function setupNodeEnvironment(): void;
|
|
149
|
+
|
|
150
|
+
declare function createMockWebGL2Context(canvas: HTMLCanvasElement): WebGL2RenderingContext;
|
|
151
|
+
|
|
152
|
+
declare class MockPointerLock {
|
|
153
|
+
static setup(doc: Document): void;
|
|
154
|
+
}
|
|
155
|
+
declare class InputInjector {
|
|
156
|
+
private doc;
|
|
157
|
+
private win;
|
|
158
|
+
constructor(doc: Document, win: any);
|
|
159
|
+
keyDown(key: string, code?: string): void;
|
|
160
|
+
keyUp(key: string, code?: string): void;
|
|
161
|
+
mouseMove(movementX: number, movementY: number, clientX?: number, clientY?: number): void;
|
|
162
|
+
mouseDown(button?: number): void;
|
|
163
|
+
mouseUp(button?: number): void;
|
|
164
|
+
wheel(deltaY: number): void;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export { type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, InputInjector, type MockEngine, type MockGame, MockPointerLock, type TestContext, createBinaryStreamMock, createBinaryWriterMock, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockEngine, createMockGame, createMockWebGL2Context, createNetChanMock, createPlayerStateFactory, createSpawnContext, createTestContext, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, setupBrowserEnvironment, setupNodeEnvironment, teardownBrowserEnvironment };
|
|
@@ -127,4 +127,41 @@ declare function createTestContext(options?: {
|
|
|
127
127
|
declare function createSpawnContext(): SpawnContext;
|
|
128
128
|
declare function createEntity(): Entity;
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
interface BrowserSetupOptions {
|
|
131
|
+
url?: string;
|
|
132
|
+
pretendToBeVisual?: boolean;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Sets up a browser environment for testing using JSDOM and napi-rs/canvas.
|
|
136
|
+
* This should be called in your vitest.setup.ts file.
|
|
137
|
+
*/
|
|
138
|
+
declare function setupBrowserEnvironment(options?: BrowserSetupOptions): void;
|
|
139
|
+
/**
|
|
140
|
+
* Cleans up the browser environment.
|
|
141
|
+
*/
|
|
142
|
+
declare function teardownBrowserEnvironment(): void;
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Sets up a Node.js environment for testing.
|
|
146
|
+
* This is primarily for backend or shared logic that doesn't rely on browser APIs.
|
|
147
|
+
*/
|
|
148
|
+
declare function setupNodeEnvironment(): void;
|
|
149
|
+
|
|
150
|
+
declare function createMockWebGL2Context(canvas: HTMLCanvasElement): WebGL2RenderingContext;
|
|
151
|
+
|
|
152
|
+
declare class MockPointerLock {
|
|
153
|
+
static setup(doc: Document): void;
|
|
154
|
+
}
|
|
155
|
+
declare class InputInjector {
|
|
156
|
+
private doc;
|
|
157
|
+
private win;
|
|
158
|
+
constructor(doc: Document, win: any);
|
|
159
|
+
keyDown(key: string, code?: string): void;
|
|
160
|
+
keyUp(key: string, code?: string): void;
|
|
161
|
+
mouseMove(movementX: number, movementY: number, clientX?: number, clientY?: number): void;
|
|
162
|
+
mouseDown(button?: number): void;
|
|
163
|
+
mouseUp(button?: number): void;
|
|
164
|
+
wheel(deltaY: number): void;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export { type BinaryStreamMock, type BinaryWriterMock, type BrowserSetupOptions, InputInjector, type MockEngine, type MockGame, MockPointerLock, type TestContext, createBinaryStreamMock, createBinaryWriterMock, createEntity, createEntityStateFactory, createGameStateSnapshotFactory, createMockEngine, createMockGame, createMockWebGL2Context, createNetChanMock, createPlayerStateFactory, createSpawnContext, createTestContext, makeAxisBrush, makeBrushFromMinsMaxs, makeBspModel, makeLeaf, makeLeafModel, makeNode, makePlane, setupBrowserEnvironment, setupNodeEnvironment, teardownBrowserEnvironment };
|