6c7d95e
commit 6c7d95e
1 file changed
+156 -0
Showing 1 changed file+156-0
▼packages/renderer/src/index.test.ts
+156-0
| @@ -0,0 +1,156 @@ | ||
1 | +import { describe, it, expect, vi, beforeEach } from 'vitest'; | |
2 | +import { Canvas2DRenderer, WebGLRenderer, AutoRendererFactory } from './index.js'; | |
3 | + | |
4 | +// Mock HTMLCanvasElement | |
5 | +function createMockCanvas(contextType: string = '2d'): HTMLCanvasElement { | |
6 | + const canvas = { | |
7 | + width: 1920, | |
8 | + height: 1080, | |
9 | + getContext: vi.fn((type: string) => { | |
10 | + if (type === contextType || type === '2d') { | |
11 | + return { | |
12 | + clearRect: vi.fn(), | |
13 | + drawImage: vi.fn(), | |
14 | + fillRect: vi.fn(), | |
15 | + fillText: vi.fn(), | |
16 | + strokeText: vi.fn(), | |
17 | + measureText: vi.fn(() => ({ width: 100 })), | |
18 | + save: vi.fn(), | |
19 | + restore: vi.fn(), | |
20 | + createBuffer: vi.fn(() => ({})), | |
21 | + bindBuffer: vi.fn(), | |
22 | + bufferData: vi.fn(), | |
23 | + createTexture: vi.fn(() => ({})), | |
24 | + bindTexture: vi.fn(), | |
25 | + texParameteri: vi.fn(), | |
26 | + texImage2D: vi.fn(), | |
27 | + createProgram: vi.fn(() => ({})), | |
28 | + attachShader: vi.fn(), | |
29 | + linkProgram: vi.fn(), | |
30 | + getProgramParameter: vi.fn(() => true), | |
31 | + useProgram: vi.fn(), | |
32 | + getAttribLocation: vi.fn(() => 0), | |
33 | + enableVertexAttribArray: vi.fn(), | |
34 | + vertexAttribPointer: vi.fn(), | |
35 | + getUniformLocation: vi.fn(() => ({})), | |
36 | + uniform1i: vi.fn(), | |
37 | + drawArrays: vi.fn(), | |
38 | + viewport: vi.fn(), | |
39 | + clear: vi.fn(), | |
40 | + clearColor: vi.fn(), | |
41 | + deleteTexture: vi.fn(), | |
42 | + deleteProgram: vi.fn(), | |
43 | + deleteBuffer: vi.fn(), | |
44 | + createShader: vi.fn(() => ({})), | |
45 | + shaderSource: vi.fn(), | |
46 | + compileShader: vi.fn(), | |
47 | + getShaderParameter: vi.fn(() => true), | |
48 | + VERTEX_SHADER: 0x8B31, | |
49 | + FRAGMENT_SHADER: 0x8B30, | |
50 | + COMPILE_STATUS: 0x8B81, | |
51 | + LINK_STATUS: 0x8B82, | |
52 | + ARRAY_BUFFER: 0x8892, | |
53 | + STATIC_DRAW: 0x88E4, | |
54 | + FLOAT: 0x1406, | |
55 | + TEXTURE_2D: 0x0DE1, | |
56 | + RGBA: 0x1908, | |
57 | + UNSIGNED_BYTE: 0x1401, | |
58 | + TEXTURE_WRAP_S: 0x2802, | |
59 | + TEXTURE_WRAP_T: 0x2803, | |
60 | + TEXTURE_MIN_FILTER: 0x2801, | |
61 | + TEXTURE_MAG_FILTER: 0x2800, | |
62 | + CLAMP_TO_EDGE: 0x812F, | |
63 | + LINEAR: 0x2601, | |
64 | + COLOR_BUFFER_BIT: 0x4000, | |
65 | + TRIANGLE_STRIP: 0x0005 | |
66 | + }; | |
67 | + } | |
68 | + return null; | |
69 | + }), | |
70 | + style: {} | |
71 | + } as unknown as HTMLCanvasElement; | |
72 | + return canvas; | |
73 | +} | |
74 | + | |
75 | +describe('Canvas2DRenderer', () => { | |
76 | + it('should initialize with 2D context', () => { | |
77 | + const canvas = createMockCanvas('2d'); | |
78 | + const renderer = new Canvas2DRenderer(canvas); | |
79 | + expect(renderer.backendName).toBe('canvas2d'); | |
80 | + }); | |
81 | + | |
82 | + it('should throw if 2D context not available', () => { | |
83 | + const canvas = { | |
84 | + width: 1920, | |
85 | + height: 1080, | |
86 | + getContext: vi.fn(() => null), | |
87 | + style: {} | |
88 | + } as unknown as HTMLCanvasElement; | |
89 | + | |
90 | + expect(() => new Canvas2DRenderer(canvas)).toThrow('Failed to get 2D context'); | |
91 | + }); | |
92 | + | |
93 | + it('should resize canvas', () => { | |
94 | + const canvas = createMockCanvas('2d'); | |
95 | + const renderer = new Canvas2DRenderer(canvas); | |
96 | + | |
97 | + renderer.resize(1280, 720); | |
98 | + expect(canvas.width).toBe(1280); | |
99 | + expect(canvas.height).toBe(720); | |
100 | + }); | |
101 | + | |
102 | + it('should clear canvas on destroy', () => { | |
103 | + const canvas = createMockCanvas('2d'); | |
104 | + const renderer = new Canvas2DRenderer(canvas); | |
105 | + | |
106 | + renderer.destroy(); | |
107 | + // Destroy should not throw | |
108 | + expect(true).toBe(true); | |
109 | + }); | |
110 | +}); | |
111 | + | |
112 | +describe('WebGLRenderer', () => { | |
113 | + it('should initialize with WebGL context', () => { | |
114 | + const canvas = createMockCanvas('webgl'); | |
115 | + const renderer = new WebGLRenderer(canvas); | |
116 | + expect(renderer.backendName).toBe('webgl'); | |
117 | + }); | |
118 | + | |
119 | + it('should throw if WebGL not available', () => { | |
120 | + const canvas = { | |
121 | + width: 1920, | |
122 | + height: 1080, | |
123 | + getContext: vi.fn(() => null), | |
124 | + style: {} | |
125 | + } as unknown as HTMLCanvasElement; | |
126 | + | |
127 | + expect(() => new WebGLRenderer(canvas)).toThrow('WebGL not supported'); | |
128 | + }); | |
129 | + | |
130 | + it('should resize canvas', () => { | |
131 | + const canvas = createMockCanvas('webgl'); | |
132 | + const renderer = new WebGLRenderer(canvas); | |
133 | + | |
134 | + renderer.resize(1280, 720); | |
135 | + expect(canvas.width).toBe(1280); | |
136 | + expect(canvas.height).toBe(720); | |
137 | + }); | |
138 | + | |
139 | + it('should cleanup on destroy', () => { | |
140 | + const canvas = createMockCanvas('webgl'); | |
141 | + const renderer = new WebGLRenderer(canvas); | |
142 | + | |
143 | + renderer.destroy(); | |
144 | + // Should not throw | |
145 | + expect(true).toBe(true); | |
146 | + }); | |
147 | +}); | |
148 | + | |
149 | +describe('AutoRendererFactory', () => { | |
150 | + it('should create Canvas2DRenderer as fallback', async () => { | |
151 | + const canvas = createMockCanvas('2d'); | |
152 | + const renderer = await AutoRendererFactory.create(canvas); | |
153 | + expect(renderer).toBeDefined(); | |
154 | + expect(renderer.backendName).toBe('canvas2d'); | |
155 | + }); | |
156 | +}); | |
0 | 157 | |