Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,475 @@
/*global EventDispatcher,
Set
*/
'use strict';
require('/shared/js/event_dispatcher.js');
suite('EventDispatcher >', function() {
var originalObject = {
property: 3,
method: () => {}
};
var originalRestrictedObject = {
property: 3,
method: () => {}
};
var allowedEvents = ['allowed-event-1', 'allowed-event-2'];
var eventTarget = null,
restrictedEventTarget = null;
suiteSetup(function() {
eventTarget = EventDispatcher.mixin(originalObject);
restrictedEventTarget = EventDispatcher.mixin(
originalRestrictedObject,
allowedEvents
);
});
teardown(function() {
eventTarget.offAll();
});
suite('mixin >', function() {
test('throws if object to mix into is not valid object', function() {
assert.throws(() => EventDispatcher.mixin());
assert.throws(() => EventDispatcher.mixin(null));
assert.throws(() => EventDispatcher.mixin(() => {}));
assert.throws(() => EventDispatcher.mixin(3));
});
test('throws if object to mix into already has dispatcher methods',
function() {
var CustomClass = function() {};
EventDispatcher.mixin(CustomClass.prototype);
assert.throws(() => EventDispatcher.mixin({ on: () => {} }));
assert.throws(() => EventDispatcher.mixin({ on: null }));
assert.throws(() => EventDispatcher.mixin({ off: () => {} }));
assert.throws(() => EventDispatcher.mixin({ off: 'day off' }));
assert.throws(() => EventDispatcher.mixin({ offAll: () => {} }));
assert.throws(() => EventDispatcher.mixin({ emit: () => {} }));
assert.throws(() => EventDispatcher.mixin(new CustomClass()));
assert.throws(() => EventDispatcher.mixin(EventDispatcher.mixin({})));
});
test('throws if invalid array is passed for allowedEvents', function() {
assert.throws(() => EventDispatcher.mixin({}, null));
assert.throws(() => EventDispatcher.mixin({}, 'event'));
assert.throws(() => EventDispatcher.mixin({}, new Set()));
});
test('correctly adds methods to target object', function() {
assert.equal(typeof eventTarget.on, 'function');
assert.equal(typeof eventTarget.off, 'function');
assert.equal(typeof eventTarget.offAll, 'function');
assert.equal(typeof eventTarget.emit, 'function');
assert.strictEqual(eventTarget, originalObject);
assert.strictEqual(eventTarget.method, originalObject.method);
assert.strictEqual(eventTarget.property, originalObject.property);
});
});
suite('on >', function() {
test('throws if event name is not valid string', function() {
assert.throws(() => eventTarget.on());
assert.throws(() => eventTarget.on('', () => {}));
assert.throws(() => eventTarget.on(null, () => {}));
});
test('throws if handler is not function', function() {
assert.throws(() => eventTarget.on('event'));
assert.throws(() => eventTarget.on('event', null));
assert.throws(() => eventTarget.on('event', {}));
});
test('successfully registers handler', function() {
var expectedHandler = sinon.stub(),
unexpectedHandler = sinon.stub();
eventTarget.on('not-expected-event', unexpectedHandler);
eventTarget.on('event', expectedHandler);
eventTarget.emit('event');
sinon.assert.calledOnce(expectedHandler);
eventTarget.emit('event');
sinon.assert.calledTwice(expectedHandler);
sinon.assert.notCalled(unexpectedHandler);
});
test('successfully registers multiple handlers', function() {
var expectedHandler1 = sinon.stub(),
expectedHandler2 = sinon.stub(),
unexpectedHandler = sinon.stub();
eventTarget.on('not-expected-event', unexpectedHandler);
eventTarget.on('event', expectedHandler1);
eventTarget.on('event', expectedHandler2);
eventTarget.emit('event');
sinon.assert.notCalled(unexpectedHandler);
sinon.assert.calledOnce(expectedHandler1);
sinon.assert.calledOnce(expectedHandler2);
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
});
suite('with allowed events >', function() {
test('throws if event name is not allowed', function() {
assert.throws(() => restrictedEventTarget.on('event'));
});
test('successfully registers handler for allowed event', function() {
var expectedHandler = sinon.stub(),
unexpectedHandler = sinon.stub();
restrictedEventTarget.on('allowed-event-2', unexpectedHandler);
restrictedEventTarget.on('allowed-event-1', expectedHandler);
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledOnce(expectedHandler);
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledTwice(expectedHandler);
sinon.assert.notCalled(unexpectedHandler);
});
});
});
suite('once >', function() {
test('throws if event name is not valid string', function() {
assert.throws(() => eventTarget.once());
assert.throws(() => eventTarget.once('', () => {}));
assert.throws(() => eventTarget.once(null, () => {}));
});
test('throws if handler is not function', function() {
assert.throws(() => eventTarget.once('event'));
assert.throws(() => eventTarget.once('event', null));
assert.throws(() => eventTarget.once('event', {}));
});
test('successfully registers handler', function() {
var expectedHandler = sinon.stub(),
unexpectedHandler = sinon.stub();
eventTarget.once('not-expected-event', unexpectedHandler);
eventTarget.once('event', expectedHandler);
eventTarget.emit('event');
sinon.assert.calledOnce(expectedHandler);
// Should not call handler more than once.
eventTarget.emit('event');
sinon.assert.calledOnce(expectedHandler);
sinon.assert.notCalled(unexpectedHandler);
});
test('successfully registers multiple handlers', function() {
var expectedHandler1 = sinon.stub(),
expectedHandler2 = sinon.stub(),
unexpectedHandler = sinon.stub();
eventTarget.once('not-expected-event', unexpectedHandler);
eventTarget.once('event', expectedHandler1);
eventTarget.once('event', expectedHandler2);
eventTarget.emit('event');
sinon.assert.notCalled(unexpectedHandler);
sinon.assert.calledOnce(expectedHandler1);
sinon.assert.calledOnce(expectedHandler2);
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
});
test('correctly passes parameters', function() {
var handler = sinon.stub();
eventTarget.once('event', handler);
eventTarget.emit('event');
sinon.assert.calledOnce(handler);
sinon.assert.calledWithExactly(handler, undefined);
eventTarget.once('event', handler);
eventTarget.emit('event', { a: 'b' });
sinon.assert.calledTwice(handler);
sinon.assert.calledWithExactly(handler, { a: 'b' });
});
suite('with allowed events >', function() {
test('throws if event name is not allowed', function() {
assert.throws(() => restrictedEventTarget.once('event'));
});
test('successfully registers handler for allowed event', function() {
var expectedHandler = sinon.stub(),
unexpectedHandler = sinon.stub();
restrictedEventTarget.once('allowed-event-2', unexpectedHandler);
restrictedEventTarget.once('allowed-event-1', expectedHandler);
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledOnce(expectedHandler);
// Should not call handler more than once.
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledOnce(expectedHandler);
sinon.assert.notCalled(unexpectedHandler);
});
});
});
suite('off >', function() {
test('throws if event name is not valid string', function() {
assert.throws(() => eventTarget.off());
assert.throws(() => eventTarget.off('', () => {}));
assert.throws(() => eventTarget.off(null, () => {}));
});
test('throws if handler is not function', function() {
assert.throws(() => eventTarget.off('event'));
assert.throws(() => eventTarget.off('event', null));
assert.throws(() => eventTarget.off('event', {}));
});
test('successfully unregisters handler', function() {
var handler = sinon.stub();
eventTarget.on('event', handler);
eventTarget.emit('event');
sinon.assert.calledOnce(handler);
eventTarget.off('event', handler);
eventTarget.emit('event');
sinon.assert.calledOnce(handler);
});
test('unregisters correct handler', function() {
var handler1 = sinon.stub(),
handler2 = sinon.stub(),
handler3 = sinon.stub();
eventTarget.on('event', handler1);
eventTarget.on('event', handler2);
eventTarget.emit('event');
sinon.assert.calledOnce(handler1);
sinon.assert.calledOnce(handler2);
eventTarget.off('event', handler3);
eventTarget.emit('event');
sinon.assert.calledTwice(handler1);
sinon.assert.calledTwice(handler2);
eventTarget.off('event', handler1);
eventTarget.emit('event');
sinon.assert.calledTwice(handler1);
sinon.assert.calledThrice(handler2);
eventTarget.off('event', handler2);
eventTarget.emit('event');
sinon.assert.calledTwice(handler1);
sinon.assert.calledThrice(handler2);
});
suite('with allowed events >', function() {
test('throws if event name is not allowed', function() {
assert.throws(() => restrictedEventTarget.off('event'));
});
test('successfully unregisters handler for allowed event', function() {
var handler = sinon.stub();
restrictedEventTarget.on('allowed-event-1', handler);
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledOnce(handler);
restrictedEventTarget.off('allowed-event-1', handler);
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledOnce(handler);
});
});
});
suite('offAll >', function() {
test('throws if event name is not valid string', function() {
assert.throws(() => eventTarget.offAll(''));
assert.throws(() => eventTarget.offAll(null));
});
test('unregisters all handlers for a specific event', function() {
var handler1 = sinon.stub(),
handler2 = sinon.stub();
eventTarget.on('event', handler1);
eventTarget.on('event', handler2);
eventTarget.emit('event');
sinon.assert.calledOnce(handler1);
sinon.assert.calledOnce(handler2);
eventTarget.offAll('other-event');
eventTarget.emit('event');
sinon.assert.calledTwice(handler1);
sinon.assert.calledTwice(handler2);
eventTarget.offAll('event');
eventTarget.emit('event');
sinon.assert.calledTwice(handler1);
sinon.assert.calledTwice(handler2);
});
test('unregisters all handlers for all events', function() {
var handler1 = sinon.stub();
var handler2 = sinon.stub();
var handler3 = sinon.stub();
eventTarget.on('event-1', handler1);
eventTarget.on('event-1', handler2);
eventTarget.on('event-2', handler3);
eventTarget.offAll();
eventTarget.emit('event-1');
eventTarget.emit('event-2');
sinon.assert.notCalled(handler1);
sinon.assert.notCalled(handler2);
sinon.assert.notCalled(handler3);
});
suite('with allowed events >', function() {
test('throws if event name is not allowed', function() {
assert.throws(() => restrictedEventTarget.offAll('event'));
});
test('successfully unregisters all handlers for allowed event',
function() {
var handler1 = sinon.stub(),
handler2 = sinon.stub();
restrictedEventTarget.on('allowed-event-1', handler1);
restrictedEventTarget.on('allowed-event-1', handler2);
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledOnce(handler1);
sinon.assert.calledOnce(handler2);
restrictedEventTarget.offAll('allowed-event-2');
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledTwice(handler1);
sinon.assert.calledTwice(handler2);
restrictedEventTarget.offAll('allowed-event-1');
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.calledTwice(handler1);
sinon.assert.calledTwice(handler2);
});
});
});
suite('emit >', function() {
test('throws if event name is not valid string', function() {
assert.throws(() => eventTarget.emit());
assert.throws(() => eventTarget.emit('', {}));
assert.throws(() => eventTarget.emit(null, {}));
});
test('execute all handlers in the right order', function() {
var expectedHandler1 = sinon.stub(),
expectedHandler2 = sinon.stub(),
unexpectedHandler = sinon.stub();
eventTarget.on('event', expectedHandler1);
eventTarget.on('event', expectedHandler2);
eventTarget.on('other-event', unexpectedHandler);
eventTarget.emit('event');
sinon.assert.notCalled(unexpectedHandler);
sinon.assert.calledOnce(expectedHandler1);
sinon.assert.calledOnce(expectedHandler2);
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
});
test('passes correct parameters to the handlers', function() {
var handler1 = sinon.stub(),
handler2 = sinon.stub(),
handler3 = sinon.stub();
var parameters1 = {
id: 1
};
var parameters2 = 'hello!';
eventTarget.on('event', handler1);
eventTarget.on('event-1', handler2);
eventTarget.on('other-event', handler3);
eventTarget.emit('event', parameters1);
eventTarget.emit('event-1', parameters2);
eventTarget.emit('other-event');
sinon.assert.calledWith(handler1, parameters1);
sinon.assert.calledWith(handler2, parameters2);
sinon.assert.calledWith(handler3, undefined);
});
test('execute all handlers even if exception occurs', function() {
var handler1 = sinon.stub().throws('Type Error'),
handler2 = sinon.stub();
eventTarget.on('event', handler1);
eventTarget.on('event', handler2);
eventTarget.emit('event');
sinon.assert.calledOnce(handler1);
sinon.assert.calledOnce(handler2);
sinon.assert.callOrder(handler1, handler2);
});
suite('with allowed events >', function() {
test('throws if event name is not allowed', function() {
assert.throws(() => restrictedEventTarget.emit('event'));
});
test('execute all handlers for allowed event in the right order',
function() {
var expectedHandler1 = sinon.stub(),
expectedHandler2 = sinon.stub(),
unexpectedHandler = sinon.stub();
restrictedEventTarget.on('allowed-event-1', expectedHandler1);
restrictedEventTarget.on('allowed-event-1', expectedHandler2);
restrictedEventTarget.on('allowed-event-2', unexpectedHandler);
restrictedEventTarget.emit('allowed-event-1');
sinon.assert.notCalled(unexpectedHandler);
sinon.assert.calledOnce(expectedHandler1);
sinon.assert.calledOnce(expectedHandler2);
sinon.assert.callOrder(expectedHandler1, expectedHandler2);
});
});
});
});