1 | import DEMData from './dem_data';
|
2 | import {RGBAImage} from '../util/image';
|
3 | import {serialize, deserialize} from '../util/web_worker_transfer';
|
4 |
|
5 | function createMockImage(height, width) {
|
6 |
|
7 | height += 2;
|
8 | width += 2;
|
9 | const pixels = new Uint8Array(height * width * 4);
|
10 | for (let i = 0; i < pixels.length; i++) {
|
11 | pixels[i] = (i + 1) % 4 === 0 ? 1 : Math.floor(Math.random() * 256);
|
12 | }
|
13 | return new RGBAImage({height, width}, pixels);
|
14 | }
|
15 |
|
16 | function createMockClampImage(height, width) {
|
17 | const pixels = new Uint8ClampedArray(height * width * 4);
|
18 | for (let i = 0; i < pixels.length; i++) {
|
19 | pixels[i] = (i + 1) % 4 === 0 ? 1 : Math.floor(Math.random() * 256);
|
20 | }
|
21 | return new RGBAImage({height, width}, pixels);
|
22 | }
|
23 |
|
24 | describe('DEMData', () => {
|
25 | describe('constructor', () => {
|
26 | test('Uint8Array', () => {
|
27 | const imageData0 = createMockImage(4, 4);
|
28 | const dem = new DEMData('0', imageData0, 'mapbox');
|
29 | expect(dem.uid).toBe('0');
|
30 | expect(dem.dim).toBe(4);
|
31 | expect(dem.stride).toBe(6);
|
32 | });
|
33 |
|
34 | test('Uint8ClampedArray', () => {
|
35 | const imageData0 = createMockClampImage(4, 4);
|
36 | const dem = new DEMData('0', imageData0, 'mapbox');
|
37 | expect(dem).not.toBeNull();
|
38 | expect(dem['uid']).toBe('0');
|
39 | expect(dem['dim']).toBe(2);
|
40 | expect(dem['stride']).toBe(4);
|
41 | });
|
42 |
|
43 | test('otherEncoding', () => {
|
44 | const spyOnWarnConsole = jest.spyOn(console, 'warn').mockImplementation();
|
45 |
|
46 | const imageData0 = createMockImage(4, 4);
|
47 | new DEMData('0', imageData0, 'otherEncoding' as any);
|
48 |
|
49 | expect(spyOnWarnConsole).toHaveBeenCalledTimes(1);
|
50 | expect(spyOnWarnConsole.mock.calls).toEqual([['\"otherEncoding\" is not a valid encoding type. Valid types include \"mapbox\" and \"terrarium\".']]);
|
51 | });
|
52 | });
|
53 | });
|
54 |
|
55 | describe('DEMData#backfillBorder with encoding', () => {
|
56 | describe('mabox encoding', () => {
|
57 | const dem0 = new DEMData('0', createMockImage(4, 4), 'mapbox');
|
58 | const dem1 = new DEMData('1', createMockImage(4, 4), 'mapbox');
|
59 |
|
60 | test('border region is initially populated with neighboring data', () => {
|
61 | let nonempty = true;
|
62 | for (let x = -1; x < 5; x++) {
|
63 | for (let y = -1; y < 5; y++) {
|
64 | if (dem0.get(x, y) === -65536) {
|
65 | nonempty = false;
|
66 | break;
|
67 | }
|
68 | }
|
69 | }
|
70 | expect(nonempty).toBeTruthy();
|
71 |
|
72 | let verticalBorderMatch = true;
|
73 | for (const x of [-1, 4]) {
|
74 | for (let y = 0; y < 4; y++) {
|
75 | if (dem0.get(x, y) !== dem0.get(x < 0 ? x + 1 : x - 1, y)) {
|
76 | verticalBorderMatch = false;
|
77 | break;
|
78 | }
|
79 | }
|
80 | }
|
81 | expect(verticalBorderMatch).toBeTruthy();
|
82 |
|
83 |
|
84 | let horizontalBorderMatch = true;
|
85 | for (const y of [-1, 4]) {
|
86 | for (let x = 0; x < 4; x++) {
|
87 | if (dem0.get(x, y) !== dem0.get(x, y < 0 ? y + 1 : y - 1)) {
|
88 | horizontalBorderMatch = false;
|
89 | break;
|
90 | }
|
91 | }
|
92 | }
|
93 | expect(horizontalBorderMatch).toBeTruthy();
|
94 |
|
95 | expect(dem0.get(-1, 4) === dem0.get(0, 3)).toBeTruthy();
|
96 | expect(dem0.get(4, 4) === dem0.get(3, 3)).toBeTruthy();
|
97 | expect(dem0.get(-1, -1) === dem0.get(0, 0)).toBeTruthy();
|
98 | expect(dem0.get(4, -1) === dem0.get(3, 0)).toBeTruthy();
|
99 | });
|
100 |
|
101 | test('backfillBorder correctly populates borders with neighboring data', () => {
|
102 | dem0.backfillBorder(dem1, -1, 0);
|
103 | for (let y = 0; y < 4; y++) {
|
104 |
|
105 | expect(dem0.get(-1, y) === dem1.get(3, y)).toBeTruthy();
|
106 | }
|
107 |
|
108 | dem0.backfillBorder(dem1, 0, -1);
|
109 | for (let x = 0; x < 4; x++) {
|
110 | expect(dem0.get(x, -1) === dem1.get(x, 3)).toBeTruthy();
|
111 | }
|
112 |
|
113 | dem0.backfillBorder(dem1, 1, 0);
|
114 | for (let y = 0; y < 4; y++) {
|
115 | expect(dem0.get(4, y) === dem1.get(0, y)).toBeTruthy();
|
116 | }
|
117 |
|
118 | dem0.backfillBorder(dem1, 0, 1);
|
119 | for (let x = 0; x < 4; x++) {
|
120 | expect(dem0.get(x, 4) === dem1.get(x, 0)).toBeTruthy();
|
121 | }
|
122 |
|
123 | dem0.backfillBorder(dem1, -1, 1);
|
124 | expect(dem0.get(-1, 4) === dem1.get(3, 0)).toBeTruthy();
|
125 |
|
126 | dem0.backfillBorder(dem1, 1, 1);
|
127 | expect(dem0.get(4, 4) === dem1.get(0, 0)).toBeTruthy();
|
128 |
|
129 | dem0.backfillBorder(dem1, -1, -1);
|
130 | expect(dem0.get(-1, -1) === dem1.get(3, 3)).toBeTruthy();
|
131 |
|
132 | dem0.backfillBorder(dem1, 1, -1);
|
133 | expect(dem0.get(4, -1) === dem1.get(0, 3)).toBeTruthy();
|
134 | });
|
135 | });
|
136 |
|
137 | describe('terrarium encoding', () => {
|
138 | const dem0 = new DEMData('0', createMockImage(4, 4), 'terrarium');
|
139 | const dem1 = new DEMData('1', createMockImage(4, 4), 'terrarium');
|
140 |
|
141 | test('border region is initially populated with neighboring data', () => {
|
142 | let nonempty = true;
|
143 | for (let x = -1; x < 5; x++) {
|
144 | for (let y = -1; y < 5; y++) {
|
145 | if (dem0.get(x, y) === -65536) {
|
146 | nonempty = false;
|
147 | break;
|
148 | }
|
149 | }
|
150 | }
|
151 | expect(nonempty).toBeTruthy();
|
152 |
|
153 | let verticalBorderMatch = true;
|
154 | for (const x of [-1, 4]) {
|
155 | for (let y = 0; y < 4; y++) {
|
156 | if (dem0.get(x, y) !== dem0.get(x < 0 ? x + 1 : x - 1, y)) {
|
157 | verticalBorderMatch = false;
|
158 | break;
|
159 | }
|
160 | }
|
161 | }
|
162 | expect(verticalBorderMatch).toBeTruthy();
|
163 |
|
164 |
|
165 | let horizontalBorderMatch = true;
|
166 | for (const y of [-1, 4]) {
|
167 | for (let x = 0; x < 4; x++) {
|
168 | if (dem0.get(x, y) !== dem0.get(x, y < 0 ? y + 1 : y - 1)) {
|
169 | horizontalBorderMatch = false;
|
170 | break;
|
171 | }
|
172 | }
|
173 | }
|
174 | expect(horizontalBorderMatch).toBeTruthy();
|
175 |
|
176 | expect(dem0.get(-1, 4) === dem0.get(0, 3)).toBeTruthy();
|
177 | expect(dem0.get(4, 4) === dem0.get(3, 3)).toBeTruthy();
|
178 | expect(dem0.get(-1, -1) === dem0.get(0, 0)).toBeTruthy();
|
179 | expect(dem0.get(4, -1) === dem0.get(3, 0)).toBeTruthy();
|
180 | });
|
181 |
|
182 | test('backfillBorder correctly populates borders with neighboring data', () => {
|
183 | dem0.backfillBorder(dem1, -1, 0);
|
184 | for (let y = 0; y < 4; y++) {
|
185 |
|
186 | expect(dem0.get(-1, y) === dem1.get(3, y)).toBeTruthy();
|
187 | }
|
188 |
|
189 | dem0.backfillBorder(dem1, 0, -1);
|
190 | for (let x = 0; x < 4; x++) {
|
191 | expect(dem0.get(x, -1) === dem1.get(x, 3)).toBeTruthy();
|
192 | }
|
193 |
|
194 | dem0.backfillBorder(dem1, 1, 0);
|
195 | for (let y = 0; y < 4; y++) {
|
196 | expect(dem0.get(4, y) === dem1.get(0, y)).toBeTruthy();
|
197 | }
|
198 |
|
199 | dem0.backfillBorder(dem1, 0, 1);
|
200 | for (let x = 0; x < 4; x++) {
|
201 | expect(dem0.get(x, 4) === dem1.get(x, 0)).toBeTruthy();
|
202 | }
|
203 |
|
204 | dem0.backfillBorder(dem1, -1, 1);
|
205 | expect(dem0.get(-1, 4) === dem1.get(3, 0)).toBeTruthy();
|
206 |
|
207 | dem0.backfillBorder(dem1, 1, 1);
|
208 | expect(dem0.get(4, 4) === dem1.get(0, 0)).toBeTruthy();
|
209 |
|
210 | dem0.backfillBorder(dem1, -1, -1);
|
211 | expect(dem0.get(-1, -1) === dem1.get(3, 3)).toBeTruthy();
|
212 |
|
213 | dem0.backfillBorder(dem1, 1, -1);
|
214 | expect(dem0.get(4, -1) === dem1.get(0, 3)).toBeTruthy();
|
215 | });
|
216 | });
|
217 | });
|
218 |
|
219 | describe('DEMData is correctly serialized and deserialized', () => {
|
220 | test('serialized', () => {
|
221 | const imageData0 = createMockImage(4, 4);
|
222 | const dem0 = new DEMData('0', imageData0, 'mapbox');
|
223 | const serialized = serialize(dem0);
|
224 |
|
225 | expect(serialized).toEqual({
|
226 | $name: 'DEMData',
|
227 | uid: '0',
|
228 | dim: 4,
|
229 | stride: 6,
|
230 | data: dem0.data,
|
231 | encoding: 'mapbox'
|
232 | });
|
233 |
|
234 | const transferrables = [];
|
235 | serialize(dem0, transferrables);
|
236 | expect(new Uint32Array(transferrables[0])).toEqual(dem0.data);
|
237 | });
|
238 |
|
239 | test('deserialized', () => {
|
240 | const imageData0 = createMockImage(4, 4);
|
241 | const dem0 = new DEMData('0', imageData0, 'terrarium');
|
242 | const serialized = serialize(dem0);
|
243 |
|
244 | const deserialized = deserialize(serialized);
|
245 | expect(deserialized).toEqual(dem0);
|
246 | });
|
247 | });
|
248 |
|
249 | describe('UnpackVector is correctly returned', () => {
|
250 | test('terrarium and mapbox', () => {
|
251 | const imageData1 = createMockImage(4, 4);
|
252 | const dem1 = new DEMData('0', imageData1, 'terrarium');
|
253 |
|
254 | const imageData2 = createMockImage(4, 4);
|
255 | const dem2 = new DEMData('0', imageData2, 'mapbox');
|
256 |
|
257 | expect(dem1.getUnpackVector()).toEqual([256.0, 1.0, 1.0 / 256.0, 32768.0]);
|
258 | expect(dem2.getUnpackVector()).toEqual([6553.6, 25.6, 0.1, 10000.0]);
|
259 | });
|
260 | });
|
261 |
|
262 | describe('DEMData#getImage', () => {
|
263 | test('Image is correctly returned', () => {
|
264 | const imageData = createMockImage(4, 4);
|
265 | const dem = new DEMData('0', imageData, 'terrarium');
|
266 |
|
267 | expect(dem.getPixels()).toEqual(imageData);
|
268 | });
|
269 | });
|