Add .gitignore and .ratignore files for various directories
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
This commit is contained in:
141
guacamole-common-js/src/test/javascript/EventSpec.js
Normal file
141
guacamole-common-js/src/test/javascript/EventSpec.js
Normal file
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/* global Guacamole, jasmine, expect */
|
||||
|
||||
describe("Guacamole.Event", function EventSpec() {
|
||||
|
||||
/**
|
||||
* Test subclass of {@link Guacamole.Event} which provides a single
|
||||
* "value" property supports an "ontest" legacy event handler.
|
||||
*
|
||||
* @constructor
|
||||
* @augments Guacamole.Event
|
||||
* @param {object} value
|
||||
* An arbitrary value to expose to the handler of the event.
|
||||
*/
|
||||
var TestEvent = function TestEvent(value) {
|
||||
|
||||
Guacamole.Event.apply(this, [ 'test' ]);
|
||||
|
||||
/**
|
||||
* An arbitrary value to expose to the handler of this event.
|
||||
*
|
||||
* @type {object}
|
||||
*/
|
||||
this.value = value;
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
this.invokeLegacyHandler = function invokeLegacyHandler(target) {
|
||||
if (target.ontest)
|
||||
target.ontest(value);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Event target instance which will receive each fired {@link TestEvent}.
|
||||
*
|
||||
* @type {Guacamole.Event.Target}
|
||||
*/
|
||||
var eventTarget;
|
||||
|
||||
beforeEach(function() {
|
||||
eventTarget = new Guacamole.Event.Target();
|
||||
});
|
||||
|
||||
describe("when an event is dispatched", function(){
|
||||
|
||||
it("should invoke the legacy handler for matching events", function() {
|
||||
|
||||
eventTarget.ontest = jasmine.createSpy('ontest');
|
||||
eventTarget.dispatch(new TestEvent('event1'));
|
||||
expect(eventTarget.ontest).toHaveBeenCalledWith('event1');
|
||||
|
||||
});
|
||||
|
||||
it("should invoke all listeners for matching events", function() {
|
||||
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
eventTarget.on('test', listener1);
|
||||
eventTarget.on('test', listener2);
|
||||
|
||||
eventTarget.dispatch(new TestEvent('event2'));
|
||||
|
||||
expect(listener1).toHaveBeenCalledWith(jasmine.objectContaining({ type : 'test', value : 'event2' }), eventTarget);
|
||||
expect(listener2).toHaveBeenCalledWith(jasmine.objectContaining({ type : 'test', value : 'event2' }), eventTarget);
|
||||
|
||||
});
|
||||
|
||||
it("should not invoke any listeners for non-matching events", function() {
|
||||
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
eventTarget.on('test2', listener1);
|
||||
eventTarget.on('test2', listener2);
|
||||
|
||||
eventTarget.dispatch(new TestEvent('event3'));
|
||||
|
||||
expect(listener1).not.toHaveBeenCalled();
|
||||
expect(listener2).not.toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
it("should not invoke any listeners that have been removed", function() {
|
||||
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
eventTarget.on('test', listener1);
|
||||
eventTarget.on('test', listener2);
|
||||
eventTarget.off('test', listener1);
|
||||
|
||||
eventTarget.dispatch(new TestEvent('event4'));
|
||||
|
||||
expect(listener1).not.toHaveBeenCalled();
|
||||
expect(listener2).toHaveBeenCalledWith(jasmine.objectContaining({ type : 'test', value : 'event4' }), eventTarget);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe("when listeners are removed", function(){
|
||||
|
||||
it("should return whether a listener is successfully removed", function() {
|
||||
|
||||
var listener1 = jasmine.createSpy('listener1');
|
||||
var listener2 = jasmine.createSpy('listener2');
|
||||
|
||||
eventTarget.on('test', listener1);
|
||||
eventTarget.on('test', listener2);
|
||||
|
||||
expect(eventTarget.off('test', listener1)).toBe(true);
|
||||
expect(eventTarget.off('test', listener1)).toBe(false);
|
||||
expect(eventTarget.off('test', listener2)).toBe(true);
|
||||
expect(eventTarget.off('test', listener2)).toBe(false);
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
221
guacamole-common-js/src/test/javascript/ParserSpec.js
Normal file
221
guacamole-common-js/src/test/javascript/ParserSpec.js
Normal file
@@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/* global Guacamole, jasmine, expect */
|
||||
|
||||
describe('Guacamole.Parser', function ParserSpec() {
|
||||
|
||||
/**
|
||||
* A single Unicode high surrogate character (any character between U+D800
|
||||
* and U+DB7F).
|
||||
*
|
||||
* @constant
|
||||
* @type {!string}
|
||||
*/
|
||||
const HIGH_SURROGATE = '\uD802';
|
||||
|
||||
/**
|
||||
* A single Unicode low surrogate character (any character between U+DC00
|
||||
* and U+DFFF).
|
||||
*
|
||||
* @constant
|
||||
* @type {!string}
|
||||
*/
|
||||
const LOW_SURROGATE = '\uDF00';
|
||||
|
||||
/**
|
||||
* A Unicode surrogate pair, consisting of a high and low surrogate.
|
||||
*
|
||||
* @constant
|
||||
* @type {!string}
|
||||
*/
|
||||
const SURROGATE_PAIR = HIGH_SURROGATE + LOW_SURROGATE;
|
||||
|
||||
/**
|
||||
* A 4-character test string containing Unicode characters that require
|
||||
* multiple bytes when encoded as UTF-8, including at least one character
|
||||
* that is encoded as a surrogate pair in UTF-16.
|
||||
*
|
||||
* @constant
|
||||
* @type {!string}
|
||||
*/
|
||||
const UTF8_MULTIBYTE = '\u72AC' + SURROGATE_PAIR + 'z\u00C1';
|
||||
|
||||
/**
|
||||
* The Guacamole.Parser instance to test. This instance is (re)created prior
|
||||
* to each test via beforeEach().
|
||||
*
|
||||
* @type {Guacamole.Parser}
|
||||
*/
|
||||
var parser;
|
||||
|
||||
// Provide each test with a fresh parser
|
||||
beforeEach(function() {
|
||||
parser = new Guacamole.Parser();
|
||||
});
|
||||
|
||||
// Empty instruction
|
||||
describe('when an empty instruction is received', function() {
|
||||
|
||||
it('should parse the single empty opcode and invoke oninstruction', function() {
|
||||
parser.oninstruction = jasmine.createSpy('oninstruction');
|
||||
parser.receive('0.;');
|
||||
expect(parser.oninstruction).toHaveBeenCalledOnceWith('', [ ]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Instruction using basic Latin characters
|
||||
describe('when an instruction is containing only basic Latin characters', function() {
|
||||
|
||||
it('should correctly parse each element and invoke oninstruction', function() {
|
||||
parser.oninstruction = jasmine.createSpy('oninstruction');
|
||||
parser.receive('5.test2,'
|
||||
+ '10.hellohello,'
|
||||
+ '15.worldworldworld;'
|
||||
);
|
||||
expect(parser.oninstruction).toHaveBeenCalledOnceWith('test2', [
|
||||
'hellohello',
|
||||
'worldworldworld'
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Instruction using characters requiring multiple bytes in UTF-8 and
|
||||
// surrogate pairs in UTF-16, including an element ending with a surrogate
|
||||
// pair
|
||||
describe('when an instruction is received containing elements that '
|
||||
+ 'contain characters involving surrogate pairs', function() {
|
||||
|
||||
it('should correctly parse each element and invoke oninstruction', function() {
|
||||
parser.oninstruction = jasmine.createSpy('oninstruction');
|
||||
parser.receive('4.test,'
|
||||
+ '6.a' + UTF8_MULTIBYTE + 'b,'
|
||||
+ '5.1234' + SURROGATE_PAIR + ','
|
||||
+ '10.a' + UTF8_MULTIBYTE + UTF8_MULTIBYTE + 'c;'
|
||||
);
|
||||
expect(parser.oninstruction).toHaveBeenCalledOnceWith('test', [
|
||||
'a' + UTF8_MULTIBYTE + 'b',
|
||||
'1234' + SURROGATE_PAIR,
|
||||
'a' + UTF8_MULTIBYTE + UTF8_MULTIBYTE + 'c'
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Instruction with an element values ending with an incomplete surrogate
|
||||
// pair (high or low surrogate only)
|
||||
describe('when an instruction is received containing elements that end '
|
||||
+ 'with incomplete surrogate pairs', function() {
|
||||
|
||||
it('should correctly parse each element and invoke oninstruction', function() {
|
||||
parser.oninstruction = jasmine.createSpy('oninstruction');
|
||||
parser.receive('4.test,'
|
||||
+ '5.1234' + HIGH_SURROGATE + ','
|
||||
+ '5.4567' + LOW_SURROGATE + ';'
|
||||
);
|
||||
expect(parser.oninstruction).toHaveBeenCalledOnceWith('test', [
|
||||
'1234' + HIGH_SURROGATE,
|
||||
'4567' + LOW_SURROGATE
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Instruction with element values containing incomplete surrogate pairs,
|
||||
describe('when an instruction is received containing incomplete surrogate pairs', function() {
|
||||
|
||||
it('should correctly parse each element and invoke oninstruction', function() {
|
||||
parser.oninstruction = jasmine.createSpy('oninstruction');
|
||||
parser.receive('5.te' + LOW_SURROGATE + 'st,'
|
||||
+ '5.12' + HIGH_SURROGATE + '3' + LOW_SURROGATE + ','
|
||||
+ '6.5' + LOW_SURROGATE + LOW_SURROGATE + '4' + HIGH_SURROGATE + HIGH_SURROGATE + ','
|
||||
+ '10.' + UTF8_MULTIBYTE + HIGH_SURROGATE + UTF8_MULTIBYTE + HIGH_SURROGATE + ';',
|
||||
);
|
||||
expect(parser.oninstruction).toHaveBeenCalledOnceWith('te' + LOW_SURROGATE + 'st', [
|
||||
'12' + HIGH_SURROGATE + '3' + LOW_SURROGATE,
|
||||
'5' + LOW_SURROGATE + LOW_SURROGATE + '4' + HIGH_SURROGATE + HIGH_SURROGATE,
|
||||
UTF8_MULTIBYTE + HIGH_SURROGATE + UTF8_MULTIBYTE + HIGH_SURROGATE
|
||||
]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Instruction fed via blocks of characters that accumulate via an external
|
||||
// buffer
|
||||
describe('when an instruction is received via an external buffer', function() {
|
||||
|
||||
it('should correctly parse each element and invoke oninstruction once ready', function() {
|
||||
parser.oninstruction = jasmine.createSpy('oninstruction');
|
||||
parser.receive('5.test2,10.hello', true);
|
||||
expect(parser.oninstruction).not.toHaveBeenCalled();
|
||||
parser.receive('5.test2,10.hellohello,15', true);
|
||||
expect(parser.oninstruction).not.toHaveBeenCalled();
|
||||
parser.receive('5.test2,10.hellohello,15.worldworldworld;', true);
|
||||
expect(parser.oninstruction).toHaveBeenCalledOnceWith('test2', [ 'hellohello', 'worldworldworld' ]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Verify codePointCount() utility function correctly counts codepoints in
|
||||
// full strings
|
||||
describe('when a string is provided to codePointCount()', function() {
|
||||
|
||||
it('should return the number of codepoints in that string', function() {
|
||||
expect(Guacamole.Parser.codePointCount('')).toBe(0);
|
||||
expect(Guacamole.Parser.codePointCount('test string')).toBe(11);
|
||||
expect(Guacamole.Parser.codePointCount('surrogate' + SURROGATE_PAIR + 'pair')).toBe(14);
|
||||
expect(Guacamole.Parser.codePointCount('missing' + HIGH_SURROGATE + 'surrogates' + LOW_SURROGATE)).toBe(19);
|
||||
expect(Guacamole.Parser.codePointCount(HIGH_SURROGATE + LOW_SURROGATE + HIGH_SURROGATE)).toBe(2);
|
||||
expect(Guacamole.Parser.codePointCount(HIGH_SURROGATE + HIGH_SURROGATE + LOW_SURROGATE)).toBe(2);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Verify codePointCount() utility function correctly counts codepoints in
|
||||
// substrings
|
||||
describe('when a substring is provided to codePointCount()', function() {
|
||||
|
||||
it('should return the number of codepoints in that substring', function() {
|
||||
expect(Guacamole.Parser.codePointCount('test string', 0)).toBe(11);
|
||||
expect(Guacamole.Parser.codePointCount('surrogate' + SURROGATE_PAIR + 'pair', 5)).toBe(9);
|
||||
expect(Guacamole.Parser.codePointCount('missing' + HIGH_SURROGATE + 'surrogates' + LOW_SURROGATE, 2, 17)).toBe(15);
|
||||
expect(Guacamole.Parser.codePointCount(HIGH_SURROGATE + LOW_SURROGATE + HIGH_SURROGATE, 0, 2)).toBe(1);
|
||||
expect(Guacamole.Parser.codePointCount(HIGH_SURROGATE + HIGH_SURROGATE + LOW_SURROGATE, 1, 2)).toBe(1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
// Verify toInstruction() utility function correctly encodes instructions
|
||||
describe('when an array of elements is provided to toInstruction()', function() {
|
||||
|
||||
it('should return a correctly-encoded Guacamole instruction', function() {
|
||||
expect(Guacamole.Parser.toInstruction([ 'test', 'instruction' ])).toBe('4.test,11.instruction;');
|
||||
expect(Guacamole.Parser.toInstruction([ 'test' + SURROGATE_PAIR, 'instruction' ]))
|
||||
.toBe('5.test' + SURROGATE_PAIR + ',11.instruction;');
|
||||
expect(Guacamole.Parser.toInstruction([ UTF8_MULTIBYTE, HIGH_SURROGATE + 'xyz' + LOW_SURROGATE ]))
|
||||
.toBe('4.' + UTF8_MULTIBYTE + ',5.' + HIGH_SURROGATE + 'xyz' + LOW_SURROGATE + ';');
|
||||
expect(Guacamole.Parser.toInstruction([ UTF8_MULTIBYTE, LOW_SURROGATE + 'xyz' + HIGH_SURROGATE ]))
|
||||
.toBe('4.' + UTF8_MULTIBYTE + ',5.' + LOW_SURROGATE + 'xyz' + HIGH_SURROGATE + ';');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
/* global Guacamole, expect */
|
||||
|
||||
describe('Guacamole.SessionRecording', function() {
|
||||
|
||||
it('should create new SessionRecording instance from Blob', function() {
|
||||
|
||||
const blob = new Blob(['4.size,1.1,1.0,1.0;']);
|
||||
const recording = new Guacamole.SessionRecording(blob);
|
||||
expect(recording).not.toBeNull();
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
Reference in New Issue
Block a user