dcs parser tests

This commit is contained in:
Jörg Breitbart
2019-07-26 15:07:24 +02:00
parent c9b7aefb88
commit 82aaef29f1
4 changed files with 183 additions and 3 deletions
+180
View File
@@ -0,0 +1,180 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { assert } from 'chai';
import { DcsParser, DcsHandlerFactory } from 'common/parser/DcsParser';
import { IDcsHandler, IParams } from 'common/parser/Types';
import { utf32ToString, StringToUtf32 } from 'common/input/TextDecoder';
import { Params } from 'common/parser/Params';
function toUtf32(s: string): Uint32Array {
const utf32 = new Uint32Array(s.length);
const decoder = new StringToUtf32();
const length = decoder.decode(s, utf32);
return utf32.subarray(0, length);
}
class TestHandler implements IDcsHandler {
constructor(public output: any[], public msg: string, public returnFalse: boolean = false) {}
hook(collect: string, params: IParams, flag: number): void {
this.output.push([this.msg, 'HOOK', params.toArray(), collect, flag]);
}
put(data: Uint32Array, start: number, end: number): void {
this.output.push([this.msg, 'PUT', utf32ToString(data, start, end)]);
}
unhook(success: boolean): void | boolean {
this.output.push([this.msg, 'UNHOOK', success]);
if (this.returnFalse) {
return false;
}
}
}
describe('DcsParser', () => {
let parser: DcsParser;
let reports: any[] = [];
beforeEach(() => {
reports = [];
parser = new DcsParser();
parser.setDcsHandlerFallback((id, action, data) => {
if (data.params) {
data.params = data.params.toArray();
}
reports.push([id, action, data]);
});
});
describe('handler registration', () => {
it('setDcsHandler', () => {
parser.setDcsHandler('+p', new TestHandler(reports, 'th'));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32('the mouse!');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [
// messages from TestHandler
['th', 'HOOK', [1, 2, 3], '+', 'p'.charCodeAt(0)],
['th', 'PUT', 'Here comes'],
['th', 'PUT', 'the mouse!'],
['th', 'UNHOOK', true]
]);
});
it('clearDcsHandler', () => {
parser.setDcsHandler('+p', new TestHandler(reports, 'th'));
parser.clearDcsHandler('+p');
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32('the mouse!');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [
// messages from fallback handler
['+p', 'HOOK', {collect: '+', params: [1, 2, 3], flag: 'p'.charCodeAt(0)}],
['+p', 'PUT', 'Here comes'],
['+p', 'PUT', 'the mouse!'],
['+p', 'UNHOOK', true]
]);
});
it('addDcsHandler', () => {
parser.setDcsHandler('+p', new TestHandler(reports, 'th1'));
parser.addDcsHandler('+p', new TestHandler(reports, 'th2'));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32('the mouse!');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [
['th2', 'HOOK', [1, 2, 3], '+', 'p'.charCodeAt(0)],
['th1', 'HOOK', [1, 2, 3], '+', 'p'.charCodeAt(0)],
['th2', 'PUT', 'Here comes'],
['th1', 'PUT', 'Here comes'],
['th2', 'PUT', 'the mouse!'],
['th1', 'PUT', 'the mouse!'],
['th2', 'UNHOOK', true],
['th1', 'UNHOOK', false] // false due being already handled by th2!
]);
});
it('addDcsHandler with return false', () => {
parser.setDcsHandler('+p', new TestHandler(reports, 'th1'));
parser.addDcsHandler('+p', new TestHandler(reports, 'th2', true));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32('the mouse!');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [
['th2', 'HOOK', [1, 2, 3], '+', 'p'.charCodeAt(0)],
['th1', 'HOOK', [1, 2, 3], '+', 'p'.charCodeAt(0)],
['th2', 'PUT', 'Here comes'],
['th1', 'PUT', 'Here comes'],
['th2', 'PUT', 'the mouse!'],
['th1', 'PUT', 'the mouse!'],
['th2', 'UNHOOK', true],
['th1', 'UNHOOK', true] // true since th2 indicated to keep bubbling
]);
});
it('dispose handlers', () => {
parser.setDcsHandler('+p', new TestHandler(reports, 'th1'));
const dispo = parser.addDcsHandler('+p', new TestHandler(reports, 'th2', true));
dispo.dispose();
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32('the mouse!');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [
['th1', 'HOOK', [1, 2, 3], '+', 'p'.charCodeAt(0)],
['th1', 'PUT', 'Here comes'],
['th1', 'PUT', 'the mouse!'],
['th1', 'UNHOOK', true]
]);
});
});
describe('DcsHandlerFactory', () => {
it('should be called once on end(true)', () => {
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push([params, data])));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32(' the mouse!');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [[[1, 2, 3], 'Here comes the mouse!']]);
});
it('should not be called on end(false)', () => {
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push([params, data])));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32(' the mouse!');
parser.put(data, 0, data.length);
parser.unhook(false);
assert.deepEqual(reports, []);
});
it('should be disposable', () => {
parser.setDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push(['one', params, data])));
const dispo = parser.addDcsHandler('+p', new DcsHandlerFactory((params, data) => reports.push(['two', params, data])));
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
let data = toUtf32('Here comes');
parser.put(data, 0, data.length);
data = toUtf32(' the mouse!');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [['two', [1, 2, 3], 'Here comes the mouse!']]);
dispo.dispose();
parser.hook('+', Params.fromArray([1, 2, 3]), 'p'.charCodeAt(0));
data = toUtf32('some other');
parser.put(data, 0, data.length);
data = toUtf32(' data');
parser.put(data, 0, data.length);
parser.unhook(true);
assert.deepEqual(reports, [['two', [1, 2, 3], 'Here comes the mouse!'], ['one', [1, 2, 3], 'some other data']]);
});
});
});
+1 -1
View File
@@ -43,7 +43,7 @@ export class DcsParser implements IDcsParser {
if (this._handlers[collectAndFlag]) delete this._handlers[collectAndFlag];
}
public setOscHandlerFallback(handler: DcsFallbackHandler): void {
public setDcsHandlerFallback(handler: DcsFallbackHandler): void {
this._handlerFb = handler;
}
+1 -1
View File
@@ -371,7 +371,7 @@ export class EscapeSequenceParser extends Disposable implements IEscapeSequenceP
this._dcsParser.clearDcsHandler(collectAndFlag);
}
setDcsHandlerFallback(handler: DcsFallbackHandler): void {
this._dcsParser.setOscHandlerFallback(handler);
this._dcsParser.setDcsHandlerFallback(handler);
}
setErrorHandler(callback: (state: IParsingState) => IParsingState): void {
+1 -1
View File
@@ -191,7 +191,7 @@ export interface IDcsParser extends IDisposable {
addDcsHandler(collectAndFlag: string, handler: IDcsHandler): IDisposable;
setDcsHandler(collectAndFlag: string, handler: IDcsHandler): void;
clearDcsHandler(collectAndFlag: string): void;
setOscHandlerFallback(handler: DcsFallbackHandler): void;
setDcsHandlerFallback(handler: DcsFallbackHandler): void;
reset(): void;
hook(collect: string, params: IParams, flag: number): void;
put(data: Uint32Array, start: number, end: number): void;