quake2ts 0.0.564 → 0.0.566
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/render/webgpu/context.d.ts +27 -0
- package/packages/engine/dist/types/render/webgpu/context.d.ts.map +1 -0
- package/packages/test-utils/dist/index.cjs +249 -178
- package/packages/test-utils/dist/index.cjs.map +1 -1
- package/packages/test-utils/dist/index.d.cts +46 -41
- package/packages/test-utils/dist/index.d.ts +46 -41
- package/packages/test-utils/dist/index.js +245 -178
- package/packages/test-utils/dist/index.js.map +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface WebGPUContextOptions {
|
|
2
|
+
powerPreference?: GPUPowerPreference;
|
|
3
|
+
requiredFeatures?: GPUFeatureName[];
|
|
4
|
+
requiredLimits?: Record<string, number>;
|
|
5
|
+
}
|
|
6
|
+
export interface WebGPUContextState {
|
|
7
|
+
adapter: GPUAdapter;
|
|
8
|
+
device: GPUDevice;
|
|
9
|
+
context?: GPUCanvasContext;
|
|
10
|
+
format: GPUTextureFormat;
|
|
11
|
+
features: Set<GPUFeatureName>;
|
|
12
|
+
limits: GPUSupportedLimits;
|
|
13
|
+
isHeadless: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Creates and initializes a WebGPU context.
|
|
17
|
+
*
|
|
18
|
+
* Handles adapter selection, device creation, and context configuration.
|
|
19
|
+
* Supports both browser (canvas) and headless environments.
|
|
20
|
+
*
|
|
21
|
+
* @param canvas - Optional canvas element for rendering. If omitted, assumes headless mode.
|
|
22
|
+
* @param options - Configuration options for device creation.
|
|
23
|
+
* @returns Initialized WebGPU context state.
|
|
24
|
+
* @throws Error if WebGPU is not supported or device creation fails.
|
|
25
|
+
*/
|
|
26
|
+
export declare function createWebGPUContext(canvas?: HTMLCanvasElement, options?: WebGPUContextOptions): Promise<WebGPUContextState>;
|
|
27
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../../../src/render/webgpu/context.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,eAAe,CAAC,EAAE,kBAAkB,CAAC;IACrC,gBAAgB,CAAC,EAAE,cAAc,EAAE,CAAC;IACpC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAGD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,EAAE,GAAG,CAAC,cAAc,CAAC,CAAC;IAC9B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,CAAC,EAAE,iBAAiB,EAC1B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CAsE7B"}
|
|
@@ -52,6 +52,9 @@ __export(index_exports, {
|
|
|
52
52
|
createMockCanvasContext2D: () => createMockCanvasContext2D,
|
|
53
53
|
createMockConnection: () => createMockConnection,
|
|
54
54
|
createMockEngine: () => createMockEngine,
|
|
55
|
+
createMockGPUAdapter: () => createMockGPUAdapter,
|
|
56
|
+
createMockGPUCanvasContext: () => createMockGPUCanvasContext,
|
|
57
|
+
createMockGPUDevice: () => createMockGPUDevice,
|
|
55
58
|
createMockGame: () => createMockGame,
|
|
56
59
|
createMockGameState: () => createMockGameState,
|
|
57
60
|
createMockHandshake: () => createMockHandshake,
|
|
@@ -93,6 +96,7 @@ __export(index_exports, {
|
|
|
93
96
|
setupBrowserEnvironment: () => setupBrowserEnvironment,
|
|
94
97
|
setupMockAudioContext: () => setupMockAudioContext,
|
|
95
98
|
setupNodeEnvironment: () => setupNodeEnvironment,
|
|
99
|
+
setupWebGPUMocks: () => setupWebGPUMocks,
|
|
96
100
|
simulateFrames: () => simulateFrames,
|
|
97
101
|
simulateFramesWithMock: () => simulateFramesWithMock,
|
|
98
102
|
simulateHandshake: () => simulateHandshake,
|
|
@@ -1397,193 +1401,67 @@ function createMockImage(width, height, src) {
|
|
|
1397
1401
|
return img;
|
|
1398
1402
|
}
|
|
1399
1403
|
|
|
1400
|
-
// src/
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
}
|
|
1404
|
-
}
|
|
1405
|
-
|
|
1406
|
-
// src/setup/storage.ts
|
|
1407
|
-
var import_auto2 = require("fake-indexeddb/auto");
|
|
1408
|
-
function createMockLocalStorage(initialData = {}) {
|
|
1409
|
-
const storage = new Map(Object.entries(initialData));
|
|
1404
|
+
// src/engine/mocks/webgpu.ts
|
|
1405
|
+
var import_vitest5 = require("vitest");
|
|
1406
|
+
function createMockGPUAdapter() {
|
|
1410
1407
|
return {
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
clear: () => storage.clear(),
|
|
1415
|
-
key: (index) => Array.from(storage.keys())[index] || null,
|
|
1416
|
-
get length() {
|
|
1417
|
-
return storage.size;
|
|
1418
|
-
}
|
|
1408
|
+
requestDevice: import_vitest5.vi.fn().mockResolvedValue(createMockGPUDevice()),
|
|
1409
|
+
features: /* @__PURE__ */ new Set(),
|
|
1410
|
+
limits: {}
|
|
1419
1411
|
};
|
|
1420
1412
|
}
|
|
1421
|
-
function
|
|
1422
|
-
return
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1413
|
+
function createMockGPUDevice() {
|
|
1414
|
+
return {
|
|
1415
|
+
features: /* @__PURE__ */ new Set(),
|
|
1416
|
+
limits: {},
|
|
1417
|
+
queue: {
|
|
1418
|
+
submit: import_vitest5.vi.fn(),
|
|
1419
|
+
writeBuffer: import_vitest5.vi.fn(),
|
|
1420
|
+
writeTexture: import_vitest5.vi.fn(),
|
|
1421
|
+
copyExternalImageToTexture: import_vitest5.vi.fn()
|
|
1422
|
+
},
|
|
1423
|
+
createCommandEncoder: import_vitest5.vi.fn().mockReturnValue({
|
|
1424
|
+
beginRenderPass: import_vitest5.vi.fn().mockReturnValue({
|
|
1425
|
+
setPipeline: import_vitest5.vi.fn(),
|
|
1426
|
+
draw: import_vitest5.vi.fn(),
|
|
1427
|
+
end: import_vitest5.vi.fn()
|
|
1428
|
+
}),
|
|
1429
|
+
finish: import_vitest5.vi.fn()
|
|
1430
|
+
}),
|
|
1431
|
+
createRenderPipeline: import_vitest5.vi.fn(),
|
|
1432
|
+
createShaderModule: import_vitest5.vi.fn(),
|
|
1433
|
+
createBindGroup: import_vitest5.vi.fn(),
|
|
1434
|
+
createBindGroupLayout: import_vitest5.vi.fn(),
|
|
1435
|
+
createBuffer: import_vitest5.vi.fn(),
|
|
1436
|
+
createTexture: import_vitest5.vi.fn(),
|
|
1437
|
+
createSampler: import_vitest5.vi.fn()
|
|
1438
|
+
};
|
|
1429
1439
|
}
|
|
1430
|
-
function
|
|
1431
|
-
if (storageType === "indexed") {
|
|
1432
|
-
const dbName = `test-db-${Math.random().toString(36).substring(7)}`;
|
|
1433
|
-
const storeName = "test-store";
|
|
1434
|
-
const storage2 = createMockIndexedDB();
|
|
1435
|
-
return {
|
|
1436
|
-
storage: storage2,
|
|
1437
|
-
populate: async (data) => {
|
|
1438
|
-
return new Promise((resolve, reject) => {
|
|
1439
|
-
const req = storage2.open(dbName, 1);
|
|
1440
|
-
req.onupgradeneeded = (e) => {
|
|
1441
|
-
const db = e.target.result;
|
|
1442
|
-
db.createObjectStore(storeName);
|
|
1443
|
-
};
|
|
1444
|
-
req.onsuccess = (e) => {
|
|
1445
|
-
const db = e.target.result;
|
|
1446
|
-
const tx = db.transaction(storeName, "readwrite");
|
|
1447
|
-
const store = tx.objectStore(storeName);
|
|
1448
|
-
Object.entries(data).forEach(([k, v]) => store.put(v, k));
|
|
1449
|
-
tx.oncomplete = () => {
|
|
1450
|
-
db.close();
|
|
1451
|
-
resolve();
|
|
1452
|
-
};
|
|
1453
|
-
tx.onerror = () => reject(tx.error);
|
|
1454
|
-
};
|
|
1455
|
-
req.onerror = () => reject(req.error);
|
|
1456
|
-
});
|
|
1457
|
-
},
|
|
1458
|
-
verify: async (key, value) => {
|
|
1459
|
-
return new Promise((resolve, reject) => {
|
|
1460
|
-
const req = storage2.open(dbName, 1);
|
|
1461
|
-
req.onsuccess = (e) => {
|
|
1462
|
-
const db = e.target.result;
|
|
1463
|
-
if (!db.objectStoreNames.contains(storeName)) {
|
|
1464
|
-
db.close();
|
|
1465
|
-
resolve(false);
|
|
1466
|
-
return;
|
|
1467
|
-
}
|
|
1468
|
-
const tx = db.transaction(storeName, "readonly");
|
|
1469
|
-
const store = tx.objectStore(storeName);
|
|
1470
|
-
const getReq = store.get(key);
|
|
1471
|
-
getReq.onsuccess = () => {
|
|
1472
|
-
const result = getReq.result === value;
|
|
1473
|
-
db.close();
|
|
1474
|
-
resolve(result);
|
|
1475
|
-
};
|
|
1476
|
-
getReq.onerror = () => {
|
|
1477
|
-
db.close();
|
|
1478
|
-
resolve(false);
|
|
1479
|
-
};
|
|
1480
|
-
};
|
|
1481
|
-
req.onerror = () => reject(req.error);
|
|
1482
|
-
});
|
|
1483
|
-
}
|
|
1484
|
-
};
|
|
1485
|
-
}
|
|
1486
|
-
const storage = storageType === "local" ? createMockLocalStorage() : createMockSessionStorage();
|
|
1440
|
+
function createMockGPUCanvasContext() {
|
|
1487
1441
|
return {
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
},
|
|
1492
|
-
verify(key, value) {
|
|
1493
|
-
return storage.getItem(key) === value;
|
|
1494
|
-
}
|
|
1442
|
+
configure: import_vitest5.vi.fn(),
|
|
1443
|
+
unconfigure: import_vitest5.vi.fn(),
|
|
1444
|
+
getCurrentTexture: import_vitest5.vi.fn()
|
|
1495
1445
|
};
|
|
1496
1446
|
}
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
connect: () => {
|
|
1503
|
-
},
|
|
1504
|
-
gain: { value: 1, setValueAtTime: () => {
|
|
1505
|
-
} }
|
|
1506
|
-
}),
|
|
1507
|
-
createOscillator: () => ({
|
|
1508
|
-
connect: () => {
|
|
1509
|
-
},
|
|
1510
|
-
start: () => {
|
|
1511
|
-
},
|
|
1512
|
-
stop: () => {
|
|
1513
|
-
},
|
|
1514
|
-
frequency: { value: 440 }
|
|
1515
|
-
}),
|
|
1516
|
-
createBufferSource: () => ({
|
|
1517
|
-
connect: () => {
|
|
1518
|
-
},
|
|
1519
|
-
start: () => {
|
|
1520
|
-
},
|
|
1521
|
-
stop: () => {
|
|
1522
|
-
},
|
|
1523
|
-
buffer: null,
|
|
1524
|
-
playbackRate: { value: 1 },
|
|
1525
|
-
loop: false
|
|
1526
|
-
}),
|
|
1527
|
-
destination: {},
|
|
1528
|
-
currentTime: 0,
|
|
1529
|
-
state: "running",
|
|
1530
|
-
resume: async () => {
|
|
1531
|
-
},
|
|
1532
|
-
suspend: async () => {
|
|
1533
|
-
},
|
|
1534
|
-
close: async () => {
|
|
1535
|
-
},
|
|
1536
|
-
decodeAudioData: async (buffer) => ({
|
|
1537
|
-
duration: 1,
|
|
1538
|
-
length: 44100,
|
|
1539
|
-
sampleRate: 44100,
|
|
1540
|
-
numberOfChannels: 2,
|
|
1541
|
-
getChannelData: () => new Float32Array(44100)
|
|
1542
|
-
}),
|
|
1543
|
-
createBuffer: (channels, length, sampleRate) => ({
|
|
1544
|
-
duration: length / sampleRate,
|
|
1545
|
-
length,
|
|
1546
|
-
sampleRate,
|
|
1547
|
-
numberOfChannels: channels,
|
|
1548
|
-
getChannelData: () => new Float32Array(length)
|
|
1549
|
-
}),
|
|
1550
|
-
// Helper to track events if needed
|
|
1551
|
-
_events: []
|
|
1447
|
+
function setupWebGPUMocks() {
|
|
1448
|
+
const mockAdapter = createMockGPUAdapter();
|
|
1449
|
+
const mockGpu = {
|
|
1450
|
+
requestAdapter: import_vitest5.vi.fn().mockResolvedValue(mockAdapter),
|
|
1451
|
+
getPreferredCanvasFormat: import_vitest5.vi.fn().mockReturnValue("bgra8unorm")
|
|
1552
1452
|
};
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
if (typeof value === "function") {
|
|
1558
|
-
return (...args) => {
|
|
1559
|
-
target._events.push({ type: String(prop), args });
|
|
1560
|
-
return Reflect.apply(value, target, args);
|
|
1561
|
-
};
|
|
1562
|
-
}
|
|
1563
|
-
return value;
|
|
1564
|
-
}
|
|
1453
|
+
Object.defineProperty(global.navigator, "gpu", {
|
|
1454
|
+
value: mockGpu,
|
|
1455
|
+
writable: true,
|
|
1456
|
+
configurable: true
|
|
1565
1457
|
});
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
};
|
|
1574
|
-
global.window.AudioContext = global.AudioContext;
|
|
1575
|
-
global.window.webkitAudioContext = global.AudioContext;
|
|
1576
|
-
}
|
|
1577
|
-
}
|
|
1578
|
-
function teardownMockAudioContext() {
|
|
1579
|
-
if (global.AudioContext && global.AudioContext.toString().includes("class")) {
|
|
1580
|
-
delete global.AudioContext;
|
|
1581
|
-
delete global.window.AudioContext;
|
|
1582
|
-
delete global.window.webkitAudioContext;
|
|
1583
|
-
}
|
|
1584
|
-
}
|
|
1585
|
-
function captureAudioEvents(context) {
|
|
1586
|
-
return context._events || [];
|
|
1458
|
+
global.GPUTextureUsage = {
|
|
1459
|
+
COPY_SRC: 1,
|
|
1460
|
+
COPY_DST: 2,
|
|
1461
|
+
TEXTURE_BINDING: 4,
|
|
1462
|
+
STORAGE_BINDING: 8,
|
|
1463
|
+
RENDER_ATTACHMENT: 16
|
|
1464
|
+
};
|
|
1587
1465
|
}
|
|
1588
1466
|
|
|
1589
1467
|
// src/setup/timing.ts
|
|
@@ -1770,6 +1648,195 @@ function simulateFramesWithMock(mock, count, frameTimeMs = 16.6, callback) {
|
|
|
1770
1648
|
}
|
|
1771
1649
|
}
|
|
1772
1650
|
|
|
1651
|
+
// src/setup/node.ts
|
|
1652
|
+
function setupNodeEnvironment(options = {}) {
|
|
1653
|
+
if (options.polyfillFetch && typeof global.fetch === "undefined") {
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
// src/setup/storage.ts
|
|
1658
|
+
var import_auto2 = require("fake-indexeddb/auto");
|
|
1659
|
+
function createMockLocalStorage(initialData = {}) {
|
|
1660
|
+
const storage = new Map(Object.entries(initialData));
|
|
1661
|
+
return {
|
|
1662
|
+
getItem: (key) => storage.get(key) || null,
|
|
1663
|
+
setItem: (key, value) => storage.set(key, value),
|
|
1664
|
+
removeItem: (key) => storage.delete(key),
|
|
1665
|
+
clear: () => storage.clear(),
|
|
1666
|
+
key: (index) => Array.from(storage.keys())[index] || null,
|
|
1667
|
+
get length() {
|
|
1668
|
+
return storage.size;
|
|
1669
|
+
}
|
|
1670
|
+
};
|
|
1671
|
+
}
|
|
1672
|
+
function createMockSessionStorage(initialData = {}) {
|
|
1673
|
+
return createMockLocalStorage(initialData);
|
|
1674
|
+
}
|
|
1675
|
+
function createMockIndexedDB() {
|
|
1676
|
+
if (typeof indexedDB === "undefined") {
|
|
1677
|
+
throw new Error("IndexedDB mock not found. Ensure fake-indexeddb is loaded.");
|
|
1678
|
+
}
|
|
1679
|
+
return indexedDB;
|
|
1680
|
+
}
|
|
1681
|
+
function createStorageTestScenario(storageType = "local") {
|
|
1682
|
+
if (storageType === "indexed") {
|
|
1683
|
+
const dbName = `test-db-${Math.random().toString(36).substring(7)}`;
|
|
1684
|
+
const storeName = "test-store";
|
|
1685
|
+
const storage2 = createMockIndexedDB();
|
|
1686
|
+
return {
|
|
1687
|
+
storage: storage2,
|
|
1688
|
+
populate: async (data) => {
|
|
1689
|
+
return new Promise((resolve, reject) => {
|
|
1690
|
+
const req = storage2.open(dbName, 1);
|
|
1691
|
+
req.onupgradeneeded = (e) => {
|
|
1692
|
+
const db = e.target.result;
|
|
1693
|
+
db.createObjectStore(storeName);
|
|
1694
|
+
};
|
|
1695
|
+
req.onsuccess = (e) => {
|
|
1696
|
+
const db = e.target.result;
|
|
1697
|
+
const tx = db.transaction(storeName, "readwrite");
|
|
1698
|
+
const store = tx.objectStore(storeName);
|
|
1699
|
+
Object.entries(data).forEach(([k, v]) => store.put(v, k));
|
|
1700
|
+
tx.oncomplete = () => {
|
|
1701
|
+
db.close();
|
|
1702
|
+
resolve();
|
|
1703
|
+
};
|
|
1704
|
+
tx.onerror = () => reject(tx.error);
|
|
1705
|
+
};
|
|
1706
|
+
req.onerror = () => reject(req.error);
|
|
1707
|
+
});
|
|
1708
|
+
},
|
|
1709
|
+
verify: async (key, value) => {
|
|
1710
|
+
return new Promise((resolve, reject) => {
|
|
1711
|
+
const req = storage2.open(dbName, 1);
|
|
1712
|
+
req.onsuccess = (e) => {
|
|
1713
|
+
const db = e.target.result;
|
|
1714
|
+
if (!db.objectStoreNames.contains(storeName)) {
|
|
1715
|
+
db.close();
|
|
1716
|
+
resolve(false);
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1719
|
+
const tx = db.transaction(storeName, "readonly");
|
|
1720
|
+
const store = tx.objectStore(storeName);
|
|
1721
|
+
const getReq = store.get(key);
|
|
1722
|
+
getReq.onsuccess = () => {
|
|
1723
|
+
const result = getReq.result === value;
|
|
1724
|
+
db.close();
|
|
1725
|
+
resolve(result);
|
|
1726
|
+
};
|
|
1727
|
+
getReq.onerror = () => {
|
|
1728
|
+
db.close();
|
|
1729
|
+
resolve(false);
|
|
1730
|
+
};
|
|
1731
|
+
};
|
|
1732
|
+
req.onerror = () => reject(req.error);
|
|
1733
|
+
});
|
|
1734
|
+
}
|
|
1735
|
+
};
|
|
1736
|
+
}
|
|
1737
|
+
const storage = storageType === "local" ? createMockLocalStorage() : createMockSessionStorage();
|
|
1738
|
+
return {
|
|
1739
|
+
storage,
|
|
1740
|
+
populate(data) {
|
|
1741
|
+
Object.entries(data).forEach(([k, v]) => storage.setItem(k, v));
|
|
1742
|
+
},
|
|
1743
|
+
verify(key, value) {
|
|
1744
|
+
return storage.getItem(key) === value;
|
|
1745
|
+
}
|
|
1746
|
+
};
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
// src/setup/audio.ts
|
|
1750
|
+
function createMockAudioContext() {
|
|
1751
|
+
const context = {
|
|
1752
|
+
createGain: () => ({
|
|
1753
|
+
connect: () => {
|
|
1754
|
+
},
|
|
1755
|
+
gain: { value: 1, setValueAtTime: () => {
|
|
1756
|
+
} }
|
|
1757
|
+
}),
|
|
1758
|
+
createOscillator: () => ({
|
|
1759
|
+
connect: () => {
|
|
1760
|
+
},
|
|
1761
|
+
start: () => {
|
|
1762
|
+
},
|
|
1763
|
+
stop: () => {
|
|
1764
|
+
},
|
|
1765
|
+
frequency: { value: 440 }
|
|
1766
|
+
}),
|
|
1767
|
+
createBufferSource: () => ({
|
|
1768
|
+
connect: () => {
|
|
1769
|
+
},
|
|
1770
|
+
start: () => {
|
|
1771
|
+
},
|
|
1772
|
+
stop: () => {
|
|
1773
|
+
},
|
|
1774
|
+
buffer: null,
|
|
1775
|
+
playbackRate: { value: 1 },
|
|
1776
|
+
loop: false
|
|
1777
|
+
}),
|
|
1778
|
+
destination: {},
|
|
1779
|
+
currentTime: 0,
|
|
1780
|
+
state: "running",
|
|
1781
|
+
resume: async () => {
|
|
1782
|
+
},
|
|
1783
|
+
suspend: async () => {
|
|
1784
|
+
},
|
|
1785
|
+
close: async () => {
|
|
1786
|
+
},
|
|
1787
|
+
decodeAudioData: async (buffer) => ({
|
|
1788
|
+
duration: 1,
|
|
1789
|
+
length: 44100,
|
|
1790
|
+
sampleRate: 44100,
|
|
1791
|
+
numberOfChannels: 2,
|
|
1792
|
+
getChannelData: () => new Float32Array(44100)
|
|
1793
|
+
}),
|
|
1794
|
+
createBuffer: (channels, length, sampleRate) => ({
|
|
1795
|
+
duration: length / sampleRate,
|
|
1796
|
+
length,
|
|
1797
|
+
sampleRate,
|
|
1798
|
+
numberOfChannels: channels,
|
|
1799
|
+
getChannelData: () => new Float32Array(length)
|
|
1800
|
+
}),
|
|
1801
|
+
// Helper to track events if needed
|
|
1802
|
+
_events: []
|
|
1803
|
+
};
|
|
1804
|
+
return new Proxy(context, {
|
|
1805
|
+
get(target, prop, receiver) {
|
|
1806
|
+
if (prop === "_events") return target._events;
|
|
1807
|
+
const value = Reflect.get(target, prop, receiver);
|
|
1808
|
+
if (typeof value === "function") {
|
|
1809
|
+
return (...args) => {
|
|
1810
|
+
target._events.push({ type: String(prop), args });
|
|
1811
|
+
return Reflect.apply(value, target, args);
|
|
1812
|
+
};
|
|
1813
|
+
}
|
|
1814
|
+
return value;
|
|
1815
|
+
}
|
|
1816
|
+
});
|
|
1817
|
+
}
|
|
1818
|
+
function setupMockAudioContext() {
|
|
1819
|
+
if (typeof global.AudioContext === "undefined" && typeof global.window !== "undefined") {
|
|
1820
|
+
global.AudioContext = class {
|
|
1821
|
+
constructor() {
|
|
1822
|
+
return createMockAudioContext();
|
|
1823
|
+
}
|
|
1824
|
+
};
|
|
1825
|
+
global.window.AudioContext = global.AudioContext;
|
|
1826
|
+
global.window.webkitAudioContext = global.AudioContext;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
function teardownMockAudioContext() {
|
|
1830
|
+
if (global.AudioContext && global.AudioContext.toString().includes("class")) {
|
|
1831
|
+
delete global.AudioContext;
|
|
1832
|
+
delete global.window.AudioContext;
|
|
1833
|
+
delete global.window.webkitAudioContext;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
function captureAudioEvents(context) {
|
|
1837
|
+
return context._events || [];
|
|
1838
|
+
}
|
|
1839
|
+
|
|
1773
1840
|
// src/e2e/playwright.ts
|
|
1774
1841
|
var import_playwright = require("playwright");
|
|
1775
1842
|
var import_http = require("http");
|
|
@@ -2009,6 +2076,9 @@ function createVisualTestScenario(page, sceneName) {
|
|
|
2009
2076
|
createMockCanvasContext2D,
|
|
2010
2077
|
createMockConnection,
|
|
2011
2078
|
createMockEngine,
|
|
2079
|
+
createMockGPUAdapter,
|
|
2080
|
+
createMockGPUCanvasContext,
|
|
2081
|
+
createMockGPUDevice,
|
|
2012
2082
|
createMockGame,
|
|
2013
2083
|
createMockGameState,
|
|
2014
2084
|
createMockHandshake,
|
|
@@ -2050,6 +2120,7 @@ function createVisualTestScenario(page, sceneName) {
|
|
|
2050
2120
|
setupBrowserEnvironment,
|
|
2051
2121
|
setupMockAudioContext,
|
|
2052
2122
|
setupNodeEnvironment,
|
|
2123
|
+
setupWebGPUMocks,
|
|
2053
2124
|
simulateFrames,
|
|
2054
2125
|
simulateFramesWithMock,
|
|
2055
2126
|
simulateHandshake,
|