playable
Version:
Video player based on HTML5Video
270 lines (212 loc) • 6.5 kB
text/typescript
import 'jsdom-global/register';
import { expect } from 'chai';
import * as sinon from 'sinon';
import convertToDeviceRelatedConfig from './config';
import Player from './player-facade';
import DependencyContainer from './dependency-container';
import playerAPI from '../core/player-api-decorator';
describe("Player's instance", () => {
let container: any;
let player: any;
let defaultModules: any;
let additionalModules: any;
beforeEach(() => {
container = DependencyContainer.createContainer();
});
describe('rootNode and params', () => {
it('should be registered and resolved', () => {
const registerValueSpy: sinon.SinonSpy = sinon.spy(
container,
'registerValue',
);
const params = {};
player = new Player({}, container, []);
expect(
registerValueSpy.calledWith({
config: convertToDeviceRelatedConfig(params),
}),
).to.be.true;
});
it('should be resolved', () => {
const resolveSpy = sinon.spy(container, 'resolve');
player = new Player({}, container, []);
expect(resolveSpy.args).to.deep.equal([['config']]);
});
});
describe('default modules', () => {
it('should be resolved', () => {
class ClassA {}
const resolveSpy: sinon.SinonSpy = sinon.spy(container, 'resolve');
defaultModules = {
ClassA,
};
container.registerClass('ClassA', ClassA);
player = new Player({}, container, Object.keys(defaultModules));
expect(resolveSpy.calledWith('ClassA')).to.be.true;
});
it('should call destroy on player destroy', () => {
const destroySpy = sinon.spy();
class ClassA {
destroy() {
destroySpy();
}
}
defaultModules = {
ClassA,
};
container.registerClass('ClassA', ClassA);
player = new Player({}, container, Object.keys(defaultModules));
player.destroy();
expect(destroySpy.called).to.be.true;
});
});
describe('additional modules', () => {
it('should be resolved', () => {
class ClassB {}
const resolveSpy: sinon.SinonSpy = sinon.spy(container, 'resolve');
container.registerClass('ClassB', ClassB);
player = new Player({}, container, [], ['ClassB']);
expect(resolveSpy.calledWith('ClassB')).to.be.true;
});
it('should call destroy on player destroy', () => {
const destroySpy = sinon.spy();
class ClassA {
destroy() {
destroySpy();
}
}
container.registerClass('ClassA', ClassA);
player = new Player({}, container, [], ['ClassA']);
player.destroy();
expect(destroySpy.called).to.be.true;
});
});
describe('public API', () => {
let ClassA: any;
let ClassB: any;
let ClassC: any;
let methodASpy: any;
let methodBSpy: any;
beforeEach(() => {
methodASpy = sinon.spy();
methodBSpy = sinon.spy();
class A {
()
methodA() {
methodASpy();
}
()
get methodC() {
return;
}
set methodC(_) {}
destroy() {}
}
class B {
()
methodB() {
methodBSpy();
}
destroy() {}
}
class C {
('methodA')
methodA() {}
destroy() {}
}
ClassA = A;
ClassB = B;
ClassC = C;
});
it('should be constructed from default modules', () => {
container.registerClass('ClassA', ClassA);
defaultModules = {
ClassA,
};
player = new Player({}, container, Object.keys(defaultModules));
expect(Reflect.has(player, 'methodA')).to.be.true;
expect(Reflect.has(player, 'methodB')).to.be.false;
expect(Reflect.has(player, 'methodC')).to.be.true;
container.registerClass('ClassB', ClassB);
defaultModules = {
ClassA,
ClassB,
};
player = new Player({}, container, Object.keys(defaultModules));
expect(Reflect.has(player, 'methodA')).to.be.true;
expect(Reflect.has(player, 'methodB')).to.be.true;
});
it('should be constructed from additional modules', () => {
container.registerClass('ClassA', ClassA);
defaultModules = {
ClassA,
};
additionalModules = {
ClassA,
};
player = new Player(
{},
container,
Object.keys(defaultModules),
Object.keys(additionalModules),
);
expect(Reflect.has(player, 'methodA')).to.be.true;
expect(Reflect.has(player, 'methodC')).to.be.true;
});
it('methods should call proper methods from modules', () => {
defaultModules = {
ClassA,
};
additionalModules = {
ClassB,
};
container.registerClass('ClassA', ClassA);
container.registerClass('ClassB', ClassB);
player = new Player(
{},
container,
Object.keys(defaultModules),
Object.keys(additionalModules),
);
player.methodA();
player.methodB();
expect(methodASpy.called).to.be.true;
expect(methodBSpy.called).to.be.true;
});
it('should throw error on duplicate method in API', () => {
defaultModules = {
ClassA,
ClassC,
};
container.registerClass('ClassA', ClassA);
container.registerClass('ClassC', ClassC);
const getDuplicateAPIMethodPlayer = () => {
return new Player({}, container, Object.keys(defaultModules));
};
expect(getDuplicateAPIMethodPlayer).to.throw(
'API method methodA is already defined in Player facade',
);
});
describe('when instance destroyed', () => {
it('should clear instance', () => {
defaultModules = {
ClassA,
};
container.registerClass('ClassA', ClassA);
player = new Player({}, container, Object.keys(defaultModules));
player.destroy();
expect(Reflect.has(player, 'methodA')).to.be.false;
});
it('should not broadcast call methods of module', () => {
defaultModules = {
ClassA,
};
container.registerClass('ClassA', ClassA);
player = new Player({}, container, Object.keys(defaultModules));
const methodA = player.methodA;
player.destroy();
expect(methodA).to.throw('Player instance is destroyed');
});
});
});
});