1 |
|
2 |
|
3 |
|
4 |
|
5 | import test from "ava";
|
6 | import crypto from "crypto";
|
7 | import fs from "fs";
|
8 | import { Response } from "node-fetch";
|
9 | import * as sinon from "sinon";
|
10 | import { ImageSettings } from "../imageSettings";
|
11 | import { Parser } from "../parser";
|
12 | import { ScanSettings } from "../scanSettings";
|
13 | import { engine, Engine, Module } from "./engineWorker";
|
14 |
|
15 | declare interface MockModule extends Module {
|
16 | lengthBytesUTF8: sinon.SinonSpy<[any]>;
|
17 | UTF8ToString: sinon.SinonSpy<[any]>;
|
18 | stringToUTF8: sinon.SinonSpy<[any, any]>;
|
19 | _malloc: sinon.SinonSpy<[any]>;
|
20 | _free: sinon.SinonSpy;
|
21 | _create_context: sinon.SinonSpy;
|
22 | _scanner_settings_new_from_json: sinon.SinonSpy<[any]>;
|
23 | _scanner_image_settings_new: sinon.SinonSpy;
|
24 | _scanner_session_clear: sinon.SinonSpy;
|
25 | _can_hide_logo: sinon.SinonSpy<any>;
|
26 | _scanner_scan: sinon.SinonSpy<[any]>;
|
27 | _parser_parse_string: sinon.SinonSpy<[any]>;
|
28 | callMain: sinon.SinonSpy;
|
29 | }
|
30 |
|
31 | async function wait(ms: number): Promise<void> {
|
32 | return new Promise(resolve => {
|
33 | setTimeout(resolve, ms);
|
34 | });
|
35 | }
|
36 |
|
37 | function setupSpyModuleFunctions(m: MockModule): void {
|
38 | m.HEAPU8 = new Uint8Array(1);
|
39 | m.HEAPU8.set = (a: ArrayLike<number>, p: any) => {
|
40 | p.a = a;
|
41 | };
|
42 | m.lengthBytesUTF8 = sinon.spy((_: any) => {
|
43 | return 0;
|
44 | });
|
45 | m.UTF8ToString = sinon.spy((p: any) => {
|
46 | return p.s;
|
47 | });
|
48 | m.stringToUTF8 = sinon.spy((s: string, p: any) => {
|
49 | p.s = s;
|
50 | });
|
51 | m._malloc = sinon.spy((_: any) => {
|
52 | return {};
|
53 | });
|
54 | m._free = sinon.spy();
|
55 | m._create_context = sinon.spy();
|
56 | m._scanner_settings_new_from_json = sinon.spy((p: any) => {
|
57 |
|
58 | if (p.s === JSON.stringify({})) {
|
59 | return {
|
60 | s: ""
|
61 | };
|
62 | }
|
63 |
|
64 | return {
|
65 | s: JSON.stringify({})
|
66 | };
|
67 | });
|
68 | m._scanner_image_settings_new = sinon.spy();
|
69 | m._scanner_session_clear = sinon.spy();
|
70 | m._can_hide_logo = sinon.spy(() => {
|
71 | return 1;
|
72 | });
|
73 | m._scanner_scan = sinon.spy((imageData: { a: Uint8ClampedArray }) => {
|
74 |
|
75 | if (imageData.a[0] === 255) {
|
76 | return {
|
77 | s: JSON.stringify({
|
78 | error: {
|
79 | errorCode: 1,
|
80 | errorMessage: "Error."
|
81 | }
|
82 | })
|
83 | };
|
84 | }
|
85 |
|
86 | return {
|
87 | s: JSON.stringify({ scanResult: [] })
|
88 | };
|
89 | });
|
90 | m._parser_parse_string = sinon.spy((parserType: number) => {
|
91 |
|
92 | if (parserType >= 255) {
|
93 | return {
|
94 | s: JSON.stringify({
|
95 | error: {
|
96 | errorCode: parserType,
|
97 | errorMessage: "Error. This is a domain name."
|
98 | }
|
99 | })
|
100 | };
|
101 | }
|
102 |
|
103 | return {
|
104 | s: JSON.stringify({ result: { x: "y" } })
|
105 | };
|
106 | });
|
107 | m.callMain = sinon.spy();
|
108 | }
|
109 |
|
110 | declare const global: any;
|
111 |
|
112 | let moduleInstance: MockModule;
|
113 |
|
114 | Object.defineProperty(global, "self", {
|
115 | writable: true
|
116 | });
|
117 | Object.defineProperty(global, "postMessage", {
|
118 | writable: true
|
119 | });
|
120 | Object.defineProperty(global, "window", {
|
121 | writable: true
|
122 | });
|
123 | Object.defineProperty(global, "document", {
|
124 | writable: true
|
125 | });
|
126 |
|
127 | global.self = global;
|
128 |
|
129 | global.Module = {};
|
130 |
|
131 | global.crypto = {
|
132 | subtle: {
|
133 | digest: (_: string, data: ArrayBuffer) => {
|
134 | return Promise.resolve(
|
135 | crypto
|
136 | .createHash("sha256")
|
137 | .update(new DataView(data))
|
138 | .digest()
|
139 | );
|
140 | }
|
141 | }
|
142 | };
|
143 |
|
144 | global.fetch = (filePath: string) => {
|
145 | return new Promise((resolve, reject) => {
|
146 | filePath = filePath.split("?")[0];
|
147 |
|
148 | if (!fs.existsSync(filePath)) {
|
149 | reject(new Error(`File not found: ${filePath}`));
|
150 | }
|
151 | try {
|
152 |
|
153 | resolve(new Response(fs.readFileSync(filePath)));
|
154 | } catch (error) {
|
155 | reject(error);
|
156 | }
|
157 | });
|
158 | };
|
159 |
|
160 | global.importScripts = (filePath: string) => {
|
161 | filePath = filePath.split("?")[0];
|
162 |
|
163 | if (!fs.existsSync(filePath)) {
|
164 | throw new Error(`File not found: ${filePath}`);
|
165 | }
|
166 |
|
167 | moduleInstance = global.Module;
|
168 | setupSpyModuleFunctions(moduleInstance);
|
169 |
|
170 | return new Promise(resolve => {
|
171 |
|
172 |
|
173 | const readStream: fs.ReadStream = fs.createReadStream(filePath, { encoding: "utf8" });
|
174 | readStream.on("readable", () => {
|
175 | let dataString: string = "";
|
176 | let character: string = readStream.read(1);
|
177 | while (character !== ";") {
|
178 | dataString += character;
|
179 | character = readStream.read(1);
|
180 | }
|
181 | readStream.destroy();
|
182 | const regexMatch: RegExpMatchArray | null = dataString.match(/'(.+)'/);
|
183 | if (regexMatch != null) {
|
184 | (<any>self).wasmJSVersion = regexMatch[1];
|
185 | }
|
186 |
|
187 | moduleInstance.instantiateWasm({ env: {} }, () => {
|
188 | moduleInstance.preRun();
|
189 | moduleInstance.onRuntimeInitialized();
|
190 | resolve();
|
191 | });
|
192 | });
|
193 | });
|
194 | };
|
195 |
|
196 | global.FS = {
|
197 | mkdir: sinon.spy(),
|
198 | mount: sinon.spy(),
|
199 | syncfs: (_: boolean, callback: (e: any) => any) => {
|
200 | callback(undefined);
|
201 | }
|
202 | };
|
203 |
|
204 | global.IDBFS = null;
|
205 |
|
206 | global.WebAssembly.instantiate = global.WebAssembly.instantiateStreaming = () => {
|
207 | return Promise.resolve({
|
208 | module: "module",
|
209 | instance: "instance"
|
210 | });
|
211 | };
|
212 |
|
213 | global.OffscreenCanvas = () => {
|
214 | return;
|
215 | };
|
216 |
|
217 | const postMessageSpy: sinon.SinonSpy = sinon.spy();
|
218 | global.postMessage = postMessageSpy;
|
219 |
|
220 | test.serial("engine load", async t => {
|
221 | let engineInstance: Engine = engine();
|
222 |
|
223 |
|
224 | const importScriptsSpy: sinon.SinonSpy = sinon.spy(global, "importScripts");
|
225 | const consoleErrorSpy: sinon.SinonSpy = sinon.spy(console, "error");
|
226 | const originalSetTimeout: (handler: TimerHandler, timeout: number) => number = global.setTimeout;
|
227 | const setTimeoutStub: sinon.SinonSpy = sinon.stub(global, "setTimeout").callsFake((...args): number => {
|
228 | return originalSetTimeout(<TimerHandler>args[0], <number>args[1] / 100);
|
229 | });
|
230 |
|
231 | await engineInstance.loadLibrary("fakeDeviceId", "./wrong-path/", "fakePath", "fakeDevice", "fakeBrowserName");
|
232 | t.is(importScriptsSpy.callCount, 5);
|
233 | t.is(consoleErrorSpy.callCount, 2);
|
234 |
|
235 | const fetchStub: sinon.SinonStub = sinon.stub(global, "fetch").rejects();
|
236 | importScriptsSpy.resetHistory();
|
237 | consoleErrorSpy.resetHistory();
|
238 | engineInstance = engine();
|
239 |
|
240 | engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
241 | await wait(8500);
|
242 | t.is(importScriptsSpy.callCount, 1);
|
243 | t.is(consoleErrorSpy.callCount, 2);
|
244 | t.is(fetchStub.callCount, 5);
|
245 | t.false(moduleInstance.callMain.called);
|
246 | fetchStub.restore();
|
247 | importScriptsSpy.restore();
|
248 | setTimeoutStub.restore();
|
249 |
|
250 |
|
251 | consoleErrorSpy.resetHistory();
|
252 | const instantiateStreamingStub: sinon.SinonStub = sinon.stub(global.WebAssembly, "instantiateStreaming").rejects();
|
253 | const instantiateStub: sinon.SinonStub = sinon.stub(global.WebAssembly, "instantiate").rejects();
|
254 | engineInstance = engine();
|
255 |
|
256 | engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
257 | await wait(2000);
|
258 | t.is(consoleErrorSpy.callCount, 2);
|
259 | t.true(instantiateStreamingStub.called);
|
260 | t.true(instantiateStub.called);
|
261 | t.false(moduleInstance.callMain.called);
|
262 |
|
263 |
|
264 | consoleErrorSpy.resetHistory();
|
265 | instantiateStub.restore();
|
266 | postMessageSpy.resetHistory();
|
267 | engineInstance = engine();
|
268 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
269 | t.false(consoleErrorSpy.called);
|
270 | t.true(moduleInstance.callMain.called);
|
271 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
272 | instantiateStreamingStub.restore();
|
273 |
|
274 |
|
275 | consoleErrorSpy.resetHistory();
|
276 | const instantiateStreamingFunction: Function = global.WebAssembly.instantiateStreaming;
|
277 | global.WebAssembly.instantiateStreaming = null;
|
278 | postMessageSpy.resetHistory();
|
279 | engineInstance = engine();
|
280 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
281 | t.false(consoleErrorSpy.called);
|
282 | t.true(moduleInstance.callMain.called);
|
283 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
284 | global.WebAssembly.instantiateStreaming = instantiateStreamingFunction;
|
285 |
|
286 |
|
287 | consoleErrorSpy.resetHistory();
|
288 | postMessageSpy.resetHistory();
|
289 | engineInstance = engine();
|
290 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
291 | t.false(consoleErrorSpy.called);
|
292 | t.true(moduleInstance.callMain.called);
|
293 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
294 |
|
295 | engineInstance.workOnScanQueue();
|
296 | t.is(postMessageSpy.callCount, 1);
|
297 | engineInstance.createContext("");
|
298 | t.is(postMessageSpy.callCount, 2);
|
299 | engineInstance.setSettings(JSON.stringify({}));
|
300 | engineInstance.workOnScanQueue();
|
301 | t.is(postMessageSpy.callCount, 2);
|
302 | engineInstance.clearSession();
|
303 | engineInstance.setImageSettings({
|
304 | width: 1,
|
305 | height: 1,
|
306 | format: ImageSettings.Format.RGBA_8U
|
307 | });
|
308 | engineInstance.setImageSettings({
|
309 | width: 1,
|
310 | height: 1,
|
311 | format: ImageSettings.Format.RGBA_8U
|
312 | });
|
313 | engineInstance.addScanWorkUnit({
|
314 | requestId: 0,
|
315 | data: new Uint8ClampedArray([0, 0, 0, 0]),
|
316 | highQualitySingleFrameMode: true
|
317 | });
|
318 | engineInstance.setSettings(new ScanSettings().toJSONString());
|
319 | engineInstance.clearSession();
|
320 | consoleErrorSpy.restore();
|
321 | });
|
322 |
|
323 | test.serial("engine load - CDN", async t => {
|
324 | const originalSetTimeout: (handler: TimerHandler, timeout: number) => number = global.setTimeout;
|
325 | const setTimeoutStub: sinon.SinonSpy = sinon.stub(global, "setTimeout").callsFake((...args): number => {
|
326 | return originalSetTimeout(<TimerHandler>args[0], <number>args[1] / 100);
|
327 | });
|
328 | let engineInstance: Engine = engine();
|
329 | const importScriptsSpy: sinon.SinonSpy = sinon.spy(global, "importScripts");
|
330 | await engineInstance.loadLibrary(
|
331 | "fakeDeviceId",
|
332 | "https://cdn.jsdelivr.net/npm/scandit-sdk",
|
333 | "fakePath",
|
334 | "fakeDevice",
|
335 | "fakeBrowserName"
|
336 | );
|
337 | t.is(importScriptsSpy.callCount, 5);
|
338 | t.regex(
|
339 | importScriptsSpy.lastCall.args[0],
|
340 | /https:\/\/cdn.jsdelivr.net\/npm\/scandit-sdk@([1-9]+\.[0-9]+\.[0-9]+|%VER%)\/build\/scandit-engine-sdk.min.js/
|
341 | );
|
342 | engineInstance = engine();
|
343 | await engineInstance.loadLibrary(
|
344 | "fakeDeviceId",
|
345 |
|
346 | "http://cdn.jsdelivr.net/npm/scandit-sdk@0.0.1",
|
347 | "fakePath",
|
348 | "fakeDevice",
|
349 | "fakeBrowserName"
|
350 | );
|
351 | t.is(importScriptsSpy.callCount, 10);
|
352 | t.regex(
|
353 | importScriptsSpy.lastCall.args[0],
|
354 | /https:\/\/cdn.jsdelivr.net\/npm\/scandit-sdk@([1-9]+\.[0-9]+\.[0-9]+|%VER%)\/build\/scandit-engine-sdk.min.js/
|
355 | );
|
356 | engineInstance = engine();
|
357 | await engineInstance.loadLibrary(
|
358 | "fakeDeviceId",
|
359 | "https://unpkg.com/scandit-sdk@4.0.0",
|
360 | "fakePath",
|
361 | "fakeDevice",
|
362 | "fakeBrowserName"
|
363 | );
|
364 | t.is(importScriptsSpy.callCount, 15);
|
365 | t.regex(
|
366 | importScriptsSpy.lastCall.args[0],
|
367 | /https:\/\/unpkg.com\/scandit-sdk@([1-9]+\.[0-9]+\.[0-9]+|%VER%)\/build\/scandit-engine-sdk.min.js/
|
368 | );
|
369 | engineInstance = engine();
|
370 | await engineInstance.loadLibrary(
|
371 | "fakeDeviceId",
|
372 |
|
373 | "http://unpkg.com/scandit-sdk@0.0.1",
|
374 | "fakePath",
|
375 | "fakeDevice",
|
376 | "fakeBrowserName"
|
377 | );
|
378 | t.is(importScriptsSpy.callCount, 20);
|
379 | t.regex(
|
380 | importScriptsSpy.lastCall.args[0],
|
381 | /https:\/\/unpkg.com\/scandit-sdk@([1-9]+\.[0-9]+\.[0-9]+|%VER%)\/build\/scandit-engine-sdk.min.js/
|
382 | );
|
383 | engineInstance = engine();
|
384 | await engineInstance.loadLibrary("fakeDeviceId", "./wrong-path/", "fakePath", "fakeDevice", "fakeBrowserName");
|
385 | t.is(importScriptsSpy.callCount, 25);
|
386 | t.regex(importScriptsSpy.lastCall.args[0], /^\.\/wrong-path\//);
|
387 | setTimeoutStub.restore();
|
388 | importScriptsSpy.restore();
|
389 | });
|
390 |
|
391 | test.serial("engine license features", async t => {
|
392 | postMessageSpy.resetHistory();
|
393 | const engineInstance: Engine = engine();
|
394 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
395 | t.true(moduleInstance.callMain.called);
|
396 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
397 | engineInstance.createContext("");
|
398 | t.is(postMessageSpy.callCount, 2);
|
399 | t.deepEqual(postMessageSpy.getCall(1).args[0], [
|
400 | "license-features",
|
401 | {
|
402 | hiddenScanditLogoAllowed: true
|
403 | }
|
404 | ]);
|
405 | });
|
406 |
|
407 | test.serial("engine scan", async t => {
|
408 | function getWorkResult(requestId: number): [string, any] {
|
409 | return [
|
410 | "work-result",
|
411 | {
|
412 | result: {
|
413 | scanResult: []
|
414 | },
|
415 | requestId
|
416 | }
|
417 | ];
|
418 | }
|
419 | postMessageSpy.resetHistory();
|
420 | const engineInstance: Engine = engine();
|
421 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
422 | t.true(moduleInstance.callMain.called);
|
423 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
424 | engineInstance.createContext("");
|
425 | t.is(postMessageSpy.callCount, 2);
|
426 | engineInstance.addScanWorkUnit({
|
427 | requestId: 0,
|
428 | data: new Uint8ClampedArray([0, 0, 0, 0]),
|
429 | highQualitySingleFrameMode: true
|
430 | });
|
431 | t.is(postMessageSpy.callCount, 2);
|
432 | engineInstance.setSettings(new ScanSettings().toJSONString());
|
433 | engineInstance.setImageSettings({
|
434 | width: 1,
|
435 | height: 1,
|
436 | format: ImageSettings.Format.RGBA_8U
|
437 | });
|
438 | engineInstance.addScanWorkUnit({
|
439 | requestId: 1,
|
440 | data: new Uint8ClampedArray([0, 0, 0, 0]),
|
441 | highQualitySingleFrameMode: true
|
442 | });
|
443 | t.is(postMessageSpy.callCount, 4);
|
444 | t.deepEqual(postMessageSpy.getCall(2).args, [getWorkResult(0), undefined]);
|
445 | t.deepEqual(postMessageSpy.getCall(3).args, [getWorkResult(1), undefined]);
|
446 | engineInstance.setImageSettings({
|
447 | width: 1,
|
448 | height: 1,
|
449 | format: ImageSettings.Format.RGB_8U
|
450 | });
|
451 | engineInstance.addScanWorkUnit({
|
452 | requestId: 2,
|
453 | data: new Uint8ClampedArray([0, 0, 0]),
|
454 | highQualitySingleFrameMode: false
|
455 | });
|
456 | t.is(postMessageSpy.callCount, 5);
|
457 | t.deepEqual(postMessageSpy.getCall(4).args, [getWorkResult(2), undefined]);
|
458 | engineInstance.setImageSettings({
|
459 | width: 1,
|
460 | height: 1,
|
461 | format: ImageSettings.Format.GRAY_8U
|
462 | });
|
463 | engineInstance.addScanWorkUnit({
|
464 | requestId: 3,
|
465 | data: new Uint8ClampedArray([0]),
|
466 | highQualitySingleFrameMode: false
|
467 | });
|
468 | t.is(postMessageSpy.callCount, 6);
|
469 | t.deepEqual(postMessageSpy.getCall(5).args, [getWorkResult(3), undefined]);
|
470 |
|
471 | postMessageSpy.resetHistory();
|
472 | const engineInstance2: Engine = engine();
|
473 | await engineInstance2.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "Firefox");
|
474 | t.true(moduleInstance.callMain.called);
|
475 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
476 | engineInstance2.createContext("");
|
477 | t.is(postMessageSpy.callCount, 2);
|
478 | engineInstance2.setSettings(new ScanSettings().toJSONString());
|
479 | engineInstance2.setImageSettings({
|
480 | width: 1,
|
481 | height: 1,
|
482 | format: ImageSettings.Format.GRAY_8U
|
483 | });
|
484 | engineInstance2.addScanWorkUnit({
|
485 | requestId: 0,
|
486 | data: new Uint8ClampedArray([0]),
|
487 | highQualitySingleFrameMode: false
|
488 | });
|
489 | t.is(postMessageSpy.callCount, 3);
|
490 | t.deepEqual(postMessageSpy.getCall(2).args[0], getWorkResult(0));
|
491 | t.truthy(postMessageSpy.getCall(2).args[0]);
|
492 | });
|
493 |
|
494 | test.serial("engine scan error", async t => {
|
495 | postMessageSpy.resetHistory();
|
496 | const engineInstance: Engine = engine();
|
497 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
498 | engineInstance.createContext("");
|
499 | engineInstance.setSettings(new ScanSettings().toJSONString());
|
500 | engineInstance.setImageSettings({
|
501 | width: 1,
|
502 | height: 1,
|
503 | format: ImageSettings.Format.RGB_8U
|
504 | });
|
505 | engineInstance.addScanWorkUnit({
|
506 | requestId: 0,
|
507 | data: new Uint8ClampedArray([255, 255, 255]),
|
508 | highQualitySingleFrameMode: false
|
509 | });
|
510 | t.is(postMessageSpy.callCount, 3);
|
511 | t.deepEqual(postMessageSpy.getCall(2).args, [
|
512 | [
|
513 | "work-error",
|
514 | {
|
515 | error: {
|
516 | errorCode: 1,
|
517 | errorMessage: "Error."
|
518 | },
|
519 | requestId: 0
|
520 | }
|
521 | ],
|
522 | undefined
|
523 | ]);
|
524 |
|
525 | postMessageSpy.resetHistory();
|
526 | const engineInstance2: Engine = engine();
|
527 | await engineInstance2.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "Firefox");
|
528 | engineInstance2.createContext("");
|
529 | engineInstance2.setSettings(new ScanSettings().toJSONString());
|
530 | engineInstance2.setImageSettings({
|
531 | width: 1,
|
532 | height: 1,
|
533 | format: ImageSettings.Format.RGB_8U
|
534 | });
|
535 | engineInstance2.addScanWorkUnit({
|
536 | requestId: 0,
|
537 | data: new Uint8ClampedArray([255, 255, 255]),
|
538 | highQualitySingleFrameMode: false
|
539 | });
|
540 | t.is(postMessageSpy.callCount, 3);
|
541 | t.deepEqual(postMessageSpy.getCall(2).args[0], [
|
542 | "work-error",
|
543 | {
|
544 | error: {
|
545 | errorCode: 1,
|
546 | errorMessage: "Error."
|
547 | },
|
548 | requestId: 0
|
549 | }
|
550 | ]);
|
551 | t.truthy(postMessageSpy.getCall(2).args[1]);
|
552 | });
|
553 |
|
554 | test.serial("engine parse", async t => {
|
555 | postMessageSpy.resetHistory();
|
556 | const engineInstance: Engine = engine();
|
557 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
558 | t.true(moduleInstance.callMain.called);
|
559 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
560 | engineInstance.addParseWorkUnit({
|
561 | requestId: 0,
|
562 | dataFormat: Parser.DataFormat.DLID,
|
563 | dataString: "test",
|
564 | options: JSON.stringify({})
|
565 | });
|
566 | t.is(postMessageSpy.callCount, 1);
|
567 | engineInstance.createContext("");
|
568 | t.is(postMessageSpy.callCount, 2);
|
569 | engineInstance.addParseWorkUnit({
|
570 | requestId: 1,
|
571 | dataFormat: Parser.DataFormat.GS1_AI,
|
572 | dataString: "test",
|
573 | options: JSON.stringify({})
|
574 | });
|
575 | t.is(postMessageSpy.callCount, 4);
|
576 | t.deepEqual(postMessageSpy.getCall(2).args[0], [
|
577 | "parse-string-result",
|
578 | {
|
579 | result: {
|
580 | x: "y"
|
581 | },
|
582 | requestId: 0
|
583 | }
|
584 | ]);
|
585 | t.deepEqual(postMessageSpy.getCall(3).args[0], [
|
586 | "parse-string-result",
|
587 | {
|
588 | result: {
|
589 | x: "y"
|
590 | },
|
591 | requestId: 1
|
592 | }
|
593 | ]);
|
594 | engineInstance.addParseWorkUnit({
|
595 | requestId: 2,
|
596 | dataFormat: Parser.DataFormat.HIBC,
|
597 | dataString: "test",
|
598 | options: JSON.stringify({})
|
599 | });
|
600 | engineInstance.addParseWorkUnit({
|
601 | requestId: 3,
|
602 | dataFormat: Parser.DataFormat.MRTD,
|
603 | dataString: "test",
|
604 | options: JSON.stringify({})
|
605 | });
|
606 | engineInstance.addParseWorkUnit({
|
607 | requestId: 4,
|
608 | dataFormat: Parser.DataFormat.SWISSQR,
|
609 | dataString: "test",
|
610 | options: JSON.stringify({})
|
611 | });
|
612 | t.is(postMessageSpy.callCount, 7);
|
613 | });
|
614 |
|
615 | test.serial("engine parse error", async t => {
|
616 | postMessageSpy.resetHistory();
|
617 | const engineInstance: Engine = engine();
|
618 | await engineInstance.loadLibrary("fakeDeviceId", "./build/", "fakePath", "fakeDevice", "fakeBrowserName");
|
619 | t.true(moduleInstance.callMain.called);
|
620 | t.true(postMessageSpy.calledOnceWithExactly(["status", "ready"]));
|
621 | engineInstance.createContext("");
|
622 | t.is(postMessageSpy.callCount, 2);
|
623 | engineInstance.addParseWorkUnit({
|
624 | requestId: 0,
|
625 | dataFormat: 255,
|
626 | dataString: "test",
|
627 | options: JSON.stringify({})
|
628 | });
|
629 | t.is(postMessageSpy.callCount, 3);
|
630 | t.deepEqual(postMessageSpy.getCall(2).args[0], [
|
631 | "parse-string-error",
|
632 | {
|
633 | error: {
|
634 | errorCode: 255,
|
635 | errorMessage: "Error. This is a domain name."
|
636 | },
|
637 | requestId: 0
|
638 | }
|
639 | ]);
|
640 | engineInstance.addParseWorkUnit({
|
641 | requestId: 1,
|
642 | dataFormat: 260,
|
643 | dataString: "test",
|
644 | options: JSON.stringify({})
|
645 | });
|
646 | t.is(postMessageSpy.callCount, 4);
|
647 | t.deepEqual(postMessageSpy.getCall(3).args[0], [
|
648 | "parse-string-error",
|
649 | {
|
650 | error: {
|
651 | errorCode: 260,
|
652 | errorMessage: "Error. This is a domain name (example.com)."
|
653 | },
|
654 | requestId: 1
|
655 | }
|
656 | ]);
|
657 | });
|