]> git.proxmox.com Git - mirror_novnc.git/blob - tests/test.hextile.js
Test correct handling of alpha
[mirror_novnc.git] / tests / test.hextile.js
1 const expect = chai.expect;
2
3 import Websock from '../core/websock.js';
4 import Display from '../core/display.js';
5
6 import HextileDecoder from '../core/decoders/hextile.js';
7
8 import FakeWebSocket from './fake.websocket.js';
9
10 function testDecodeRect(decoder, x, y, width, height, data, display, depth) {
11 let sock;
12
13 sock = new Websock;
14 sock.open("ws://example.com");
15
16 sock.on('message', () => {
17 decoder.decodeRect(x, y, width, height, sock, display, depth);
18 });
19
20 sock._websocket._receiveData(new Uint8Array(data));
21
22 display.flip();
23 }
24
25 function push32(arr, num) {
26 arr.push((num >> 24) & 0xFF,
27 (num >> 16) & 0xFF,
28 (num >> 8) & 0xFF,
29 num & 0xFF);
30 }
31
32 describe('Hextile Decoder', function () {
33 let decoder;
34 let display;
35
36 before(FakeWebSocket.replace);
37 after(FakeWebSocket.restore);
38
39 beforeEach(function () {
40 decoder = new HextileDecoder();
41 display = new Display(document.createElement('canvas'));
42 display.resize(4, 4);
43 });
44
45 it('should handle a tile with fg, bg specified, normal subrects', function () {
46 let data = [];
47 data.push(0x02 | 0x04 | 0x08); // bg spec, fg spec, anysubrects
48 push32(data, 0x00ff0000); // becomes 00ff0000 --> #00FF00 bg color
49 data.push(0xff); // becomes ff000000 --> #0000FF fg color
50 data.push(0x00);
51 data.push(0x00);
52 data.push(0x00);
53 data.push(2); // 2 subrects
54 data.push(0); // x: 0, y: 0
55 data.push(1 | (1 << 4)); // width: 2, height: 2
56 data.push(2 | (2 << 4)); // x: 2, y: 2
57 data.push(1 | (1 << 4)); // width: 2, height: 2
58
59 testDecodeRect(decoder, 0, 0, 4, 4, data, display, 24);
60
61 let targetData = new Uint8Array([
62 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
63 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
64 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255,
65 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255
66 ]);
67
68 expect(display).to.have.displayed(targetData);
69 });
70
71 it('should handle a raw tile', function () {
72 let targetData = new Uint8Array([
73 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
74 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
75 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255,
76 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255
77 ]);
78
79 let data = [];
80 data.push(0x01); // raw
81 for (let i = 0; i < targetData.length; i += 4) {
82 data.push(targetData[i + 2]);
83 data.push(targetData[i + 1]);
84 data.push(targetData[i]);
85 // Last byte zero to test correct alpha handling
86 data.push(0);
87 }
88
89 testDecodeRect(decoder, 0, 0, 4, 4, data, display, 24);
90
91 expect(display).to.have.displayed(targetData);
92 });
93
94 it('should handle a tile with only bg specified (solid bg)', function () {
95 let data = [];
96 data.push(0x02);
97 push32(data, 0x00ff0000); // becomes 00ff0000 --> #00FF00 bg color
98
99 testDecodeRect(decoder, 0, 0, 4, 4, data, display, 24);
100
101 let expected = [];
102 for (let i = 0; i < 16; i++) {
103 push32(expected, 0x00ff00ff);
104 }
105
106 expect(display).to.have.displayed(new Uint8Array(expected));
107 });
108
109 it('should handle a tile with only bg specified and an empty frame afterwards', function () {
110 // set the width so we can have two tiles
111 display.resize(8, 4);
112
113 let data = [];
114
115 // send a bg frame
116 data.push(0x02);
117 push32(data, 0x00ff0000); // becomes 00ff0000 --> #00FF00 bg color
118
119 // send an empty frame
120 data.push(0x00);
121
122 testDecodeRect(decoder, 0, 0, 32, 4, data, display, 24);
123
124 let expected = [];
125 for (let i = 0; i < 16; i++) {
126 push32(expected, 0x00ff00ff); // rect 1: solid
127 }
128 for (let i = 0; i < 16; i++) {
129 push32(expected, 0x00ff00ff); // rect 2: same bkground color
130 }
131
132 expect(display).to.have.displayed(new Uint8Array(expected));
133 });
134
135 it('should handle a tile with bg and coloured subrects', function () {
136 let data = [];
137 data.push(0x02 | 0x08 | 0x10); // bg spec, anysubrects, colouredsubrects
138 push32(data, 0x00ff0000); // becomes 00ff0000 --> #00FF00 bg color
139 data.push(2); // 2 subrects
140 data.push(0xff); // becomes ff000000 --> #0000FF fg color
141 data.push(0x00);
142 data.push(0x00);
143 data.push(0x00);
144 data.push(0); // x: 0, y: 0
145 data.push(1 | (1 << 4)); // width: 2, height: 2
146 data.push(0xff); // becomes ff000000 --> #0000FF fg color
147 data.push(0x00);
148 data.push(0x00);
149 data.push(0x00);
150 data.push(2 | (2 << 4)); // x: 2, y: 2
151 data.push(1 | (1 << 4)); // width: 2, height: 2
152
153 testDecodeRect(decoder, 0, 0, 4, 4, data, display, 24);
154
155 let targetData = new Uint8Array([
156 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
157 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
158 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255,
159 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255
160 ]);
161
162 expect(display).to.have.displayed(targetData);
163 });
164
165 it('should carry over fg and bg colors from the previous tile if not specified', function () {
166 display.resize(4, 17);
167
168 let data = [];
169 data.push(0x02 | 0x04 | 0x08); // bg spec, fg spec, anysubrects
170 push32(data, 0xff00ff); // becomes 00ff00ff --> #00FF00 bg color
171 data.push(0xff); // becomes ff0000ff --> #0000FF fg color
172 data.push(0x00);
173 data.push(0x00);
174 data.push(0xff);
175 data.push(8); // 8 subrects
176 for (let i = 0; i < 4; i++) {
177 data.push((0 << 4) | (i * 4)); // x: 0, y: i*4
178 data.push(1 | (1 << 4)); // width: 2, height: 2
179 data.push((2 << 4) | (i * 4 + 2)); // x: 2, y: i * 4 + 2
180 data.push(1 | (1 << 4)); // width: 2, height: 2
181 }
182 data.push(0x08); // anysubrects
183 data.push(1); // 1 subrect
184 data.push(0); // x: 0, y: 0
185 data.push(1 | (1 << 4)); // width: 2, height: 2
186
187 testDecodeRect(decoder, 0, 0, 4, 17, data, display, 24);
188
189 let targetData = [
190 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
191 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255, 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255,
192 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255,
193 0x00, 0xff, 0x00, 255, 0x00, 0xff, 0x00, 255, 0x00, 0x00, 0xff, 255, 0x00, 0x00, 0xff, 255
194 ];
195
196 let expected = [];
197 for (let i = 0; i < 4; i++) {
198 expected = expected.concat(targetData);
199 }
200 expected = expected.concat(targetData.slice(0, 16));
201
202 expect(display).to.have.displayed(new Uint8Array(expected));
203 });
204
205 it('should fail on an invalid subencoding', function () {
206 let data = [45]; // an invalid subencoding
207 expect(() => testDecodeRect(decoder, 0, 0, 4, 4, data, display, 24)).to.throw();
208 });
209 });