1
0
mirror of https://github.com/videojs/video.js.git synced 2025-07-17 01:42:41 +02:00

@BrandonOCasey updates tests to pass linter

This commit is contained in:
Brandon Casey
2016-08-03 15:27:03 -04:00
committed by Gary Katsevman
parent e85c1c0391
commit 86068a5b45
29 changed files with 2168 additions and 1771 deletions

View File

@ -1,212 +1,231 @@
/* eslint-env qunit */
/**
* These tests run on the minified, window.videojs and ensure the needed
* APIs still exist
*/
import document from 'global/document';
import window from 'global/window';
const videojs = window.videojs;
(function(){
q.module('Player API');
test('videojs should exist on the window', function() {
ok(window.videojs, 'videojs exists on the window');
QUnit.module('Player API');
QUnit.test('videojs should exist on the window', function() {
QUnit.ok(window.videojs, 'videojs exists on the window');
});
test('should be able to access expected player API methods', function() {
var player = videojs.getComponent('Player').prototype;
QUnit.test('should be able to access expected player API methods', function() {
const player = videojs.getComponent('Player').prototype;
// Native HTML5 Methods
ok(player.error, 'error exists');
ok(player.src, 'src exists');
ok(player.currentSrc, 'currentSrc exists');
ok(player.buffered, 'buffered exists');
ok(player.load, 'load exists');
ok(player.seeking, 'seeking exists');
ok(player.currentTime, 'currentTime exists');
ok(player.duration, 'duration exists');
ok(player.paused, 'paused exists');
ok(player.ended, 'ended exists');
ok(player.autoplay, 'autoplay exists');
ok(player.loop, 'loop exists');
ok(player.play , 'play exists');
ok(player.pause , 'pause exists');
ok(player.controls, 'controls exists');
ok(player.volume, 'volume exists');
ok(player.muted, 'muted exists');
ok(player.width, 'width exists');
ok(player.height, 'height exists');
ok(player.poster, 'poster exists');
ok(player.textTracks, 'textTracks exists');
ok(player.requestFullscreen, 'requestFullscreen exists');
ok(player.exitFullscreen, 'exitFullscreen exists');
ok(player.playbackRate, 'playbackRate exists');
ok(player.networkState, 'networkState exists');
ok(player.readyState, 'readyState exists');
QUnit.ok(player.error, 'error exists');
QUnit.ok(player.src, 'src exists');
QUnit.ok(player.currentSrc, 'currentSrc exists');
QUnit.ok(player.buffered, 'buffered exists');
QUnit.ok(player.load, 'load exists');
QUnit.ok(player.seeking, 'seeking exists');
QUnit.ok(player.currentTime, 'currentTime exists');
QUnit.ok(player.duration, 'duration exists');
QUnit.ok(player.paused, 'paused exists');
QUnit.ok(player.ended, 'ended exists');
QUnit.ok(player.autoplay, 'autoplay exists');
QUnit.ok(player.loop, 'loop exists');
QUnit.ok(player.play, 'play exists');
QUnit.ok(player.pause, 'pause exists');
QUnit.ok(player.controls, 'controls exists');
QUnit.ok(player.volume, 'volume exists');
QUnit.ok(player.muted, 'muted exists');
QUnit.ok(player.width, 'width exists');
QUnit.ok(player.height, 'height exists');
QUnit.ok(player.poster, 'poster exists');
QUnit.ok(player.textTracks, 'textTracks exists');
QUnit.ok(player.requestFullscreen, 'requestFullscreen exists');
QUnit.ok(player.exitFullscreen, 'exitFullscreen exists');
QUnit.ok(player.playbackRate, 'playbackRate exists');
QUnit.ok(player.networkState, 'networkState exists');
QUnit.ok(player.readyState, 'readyState exists');
// Unsupported Native HTML5 Methods
// ok(player.canPlayType, 'canPlayType exists');
// ok(player.startTime, 'startTime exists');
// ok(player.defaultPlaybackRate, 'defaultPlaybackRate exists');
// ok(player.playbackRate, 'playbackRate exists');
// ok(player.played, 'played exists');
// ok(player.seekable, 'seekable exists');
// ok(player.videoWidth, 'videoWidth exists');
// ok(player.videoHeight, 'videoHeight exists');
// QUnit.ok(player.canPlayType, 'canPlayType exists');
// QUnit.ok(player.startTime, 'startTime exists');
// QUnit.ok(player.defaultPlaybackRate, 'defaultPlaybackRate exists');
// QUnit.ok(player.playbackRate, 'playbackRate exists');
// QUnit.ok(player.played, 'played exists');
// QUnit.ok(player.seekable, 'seekable exists');
// QUnit.ok(player.videoWidth, 'videoWidth exists');
// QUnit.ok(player.videoHeight, 'videoHeight exists');
// Additional player methods
ok(player.bufferedPercent, 'bufferedPercent exists');
ok(player.reportUserActivity, 'reportUserActivity exists');
ok(player.userActive, 'userActive exists');
ok(player.usingNativeControls, 'usingNativeControls exists');
ok(player.isFullscreen, 'isFullscreen exists');
QUnit.ok(player.bufferedPercent, 'bufferedPercent exists');
QUnit.ok(player.reportUserActivity, 'reportUserActivity exists');
QUnit.ok(player.userActive, 'userActive exists');
QUnit.ok(player.usingNativeControls, 'usingNativeControls exists');
QUnit.ok(player.isFullscreen, 'isFullscreen exists');
// Track methods
ok(player.audioTracks, 'audioTracks exists');
ok(player.videoTracks, 'videoTracks exists');
ok(player.textTracks, 'textTracks exists');
ok(player.remoteTextTrackEls, 'remoteTextTrackEls exists');
ok(player.remoteTextTracks, 'remoteTextTracks exists');
ok(player.addTextTrack, 'addTextTrack exists');
ok(player.addRemoteTextTrack, 'addRemoteTextTrack exists');
ok(player.removeRemoteTextTrack, 'removeRemoteTextTrack exists');
QUnit.ok(player.audioTracks, 'audioTracks exists');
QUnit.ok(player.videoTracks, 'videoTracks exists');
QUnit.ok(player.textTracks, 'textTracks exists');
QUnit.ok(player.remoteTextTrackEls, 'remoteTextTrackEls exists');
QUnit.ok(player.remoteTextTracks, 'remoteTextTracks exists');
QUnit.ok(player.addTextTrack, 'addTextTrack exists');
QUnit.ok(player.addRemoteTextTrack, 'addRemoteTextTrack exists');
QUnit.ok(player.removeRemoteTextTrack, 'removeRemoteTextTrack exists');
// Deprecated methods that should still exist
ok(player.requestFullScreen, 'requestFullScreen exists');
ok(player.isFullScreen, 'isFullScreen exists');
ok(player.cancelFullScreen, 'cancelFullScreen exists');
QUnit.ok(player.requestFullScreen, 'requestFullScreen exists');
QUnit.ok(player.isFullScreen, 'isFullScreen exists');
QUnit.ok(player.cancelFullScreen, 'cancelFullScreen exists');
});
test('should be able to access expected component API methods', function() {
var Component = videojs.getComponent('Component');
var comp = new Component({ id: function(){ return 1; }, reportUserActivity: function(){} });
QUnit.test('should be able to access expected component API methods', function() {
const Component = videojs.getComponent('Component');
const comp = new Component({
id() {
return 1;
},
reportUserActivity() {}
});
// Component methods
ok(comp.player, 'player exists');
ok(comp.options, 'options exists');
ok(comp.init, 'init exists');
ok(comp.dispose, 'dispose exists');
ok(comp.createEl, 'createEl exists');
ok(comp.contentEl, 'contentEl exists');
ok(comp.el, 'el exists');
ok(comp.addChild, 'addChild exists');
ok(comp.getChild, 'getChild exists');
ok(comp.getChildById, 'getChildById exists');
ok(comp.children, 'children exists');
ok(comp.initChildren, 'initChildren exists');
ok(comp.removeChild, 'removeChild exists');
ok(comp.on, 'on exists');
ok(comp.off, 'off exists');
ok(comp.one, 'one exists');
ok(comp.trigger, 'trigger exists');
ok(comp.triggerReady, 'triggerReady exists');
ok(comp.show, 'show exists');
ok(comp.hide, 'hide exists');
ok(comp.width, 'width exists');
ok(comp.height, 'height exists');
ok(comp.dimensions, 'dimensions exists');
ok(comp.ready, 'ready exists');
ok(comp.addClass, 'addClass exists');
ok(comp.removeClass, 'removeClass exists');
ok(comp.buildCSSClass, 'buildCSSClass exists');
ok(comp.setInterval, 'setInterval exists');
ok(comp.clearInterval, 'clearInterval exists');
ok(comp.setTimeout, 'setTimeout exists');
ok(comp.clearTimeout, 'clearTimeout exists');
QUnit.ok(comp.player, 'player exists');
QUnit.ok(comp.options, 'options exists');
QUnit.ok(comp.init, 'init exists');
QUnit.ok(comp.dispose, 'dispose exists');
QUnit.ok(comp.createEl, 'createEl exists');
QUnit.ok(comp.contentEl, 'contentEl exists');
QUnit.ok(comp.el, 'el exists');
QUnit.ok(comp.addChild, 'addChild exists');
QUnit.ok(comp.getChild, 'getChild exists');
QUnit.ok(comp.getChildById, 'getChildById exists');
QUnit.ok(comp.children, 'children exists');
QUnit.ok(comp.initChildren, 'initChildren exists');
QUnit.ok(comp.removeChild, 'removeChild exists');
QUnit.ok(comp.on, 'on exists');
QUnit.ok(comp.off, 'off exists');
QUnit.ok(comp.one, 'one exists');
QUnit.ok(comp.trigger, 'trigger exists');
QUnit.ok(comp.triggerReady, 'triggerReady exists');
QUnit.ok(comp.show, 'show exists');
QUnit.ok(comp.hide, 'hide exists');
QUnit.ok(comp.width, 'width exists');
QUnit.ok(comp.height, 'height exists');
QUnit.ok(comp.dimensions, 'dimensions exists');
QUnit.ok(comp.ready, 'ready exists');
QUnit.ok(comp.addClass, 'addClass exists');
QUnit.ok(comp.removeClass, 'removeClass exists');
QUnit.ok(comp.buildCSSClass, 'buildCSSClass exists');
QUnit.ok(comp.setInterval, 'setInterval exists');
QUnit.ok(comp.clearInterval, 'clearInterval exists');
QUnit.ok(comp.setTimeout, 'setTimeout exists');
QUnit.ok(comp.clearTimeout, 'clearTimeout exists');
});
test('should be able to access expected MediaTech API methods', function() {
var media = videojs.getComponent('Tech');
var mediaProto = media.prototype;
var html5 = videojs.getComponent('Html5');
var html5Proto = html5.prototype;
var flash = videojs.getComponent('Flash');
var flashProto = flash.prototype;
QUnit.test('should be able to access expected MediaTech API methods', function() {
const media = videojs.getComponent('Tech');
const mediaProto = media.prototype;
const html5 = videojs.getComponent('Html5');
const html5Proto = html5.prototype;
const flash = videojs.getComponent('Flash');
const flashProto = flash.prototype;
ok(mediaProto.setPoster, 'setPoster should exist on the Media tech');
ok(html5Proto.setPoster, 'setPoster should exist on the HTML5 tech');
ok(flashProto.setPoster, 'setPoster should exist on the Flash tech');
QUnit.ok(mediaProto.setPoster, 'setPoster should exist on the Media tech');
QUnit.ok(html5Proto.setPoster, 'setPoster should exist on the HTML5 tech');
QUnit.ok(flashProto.setPoster, 'setPoster should exist on the Flash tech');
ok(html5.patchCanPlayType, 'patchCanPlayType should exist for HTML5');
ok(html5.unpatchCanPlayType, 'unpatchCanPlayType should exist for HTML5');
QUnit.ok(html5.patchCanPlayType, 'patchCanPlayType should exist for HTML5');
QUnit.ok(html5.unpatchCanPlayType, 'unpatchCanPlayType should exist for HTML5');
// Source Handler Functions
ok(media.withSourceHandlers, 'withSourceHandlers should exist for Media Tech');
QUnit.ok(media.withSourceHandlers, 'withSourceHandlers should exist for Media Tech');
ok(html5.canPlaySource, 'canPlaySource should exist for HTML5');
ok(html5.registerSourceHandler, 'registerSourceHandler should exist for Html5');
ok(html5.selectSourceHandler, 'selectSourceHandler should exist for Html5');
ok(html5.prototype.setSource, 'setSource should exist for Html5');
ok(html5.prototype.disposeSourceHandler, 'disposeSourceHandler should exist for Html5');
QUnit.ok(html5.canPlaySource, 'canPlaySource should exist for HTML5');
QUnit.ok(html5.registerSourceHandler, 'registerSourceHandler should exist for Html5');
QUnit.ok(html5.selectSourceHandler, 'selectSourceHandler should exist for Html5');
QUnit.ok(html5.prototype.setSource, 'setSource should exist for Html5');
QUnit.ok(html5.prototype.disposeSourceHandler,
'disposeSourceHandler should exist for Html5');
ok(flash.canPlaySource, 'canPlaySource should exist for Flash');
ok(flash.registerSourceHandler, 'registerSourceHandler should exist for Flash');
ok(flash.selectSourceHandler, 'selectSourceHandler should exist for Flash');
ok(flash.prototype.setSource, 'setSource should exist for Flash');
ok(flash.prototype.disposeSourceHandler, 'disposeSourceHandler should exist for Flash');
QUnit.ok(flash.canPlaySource, 'canPlaySource should exist for Flash');
QUnit.ok(flash.registerSourceHandler, 'registerSourceHandler should exist for Flash');
QUnit.ok(flash.selectSourceHandler, 'selectSourceHandler should exist for Flash');
QUnit.ok(flash.prototype.setSource, 'setSource should exist for Flash');
QUnit.ok(flash.prototype.disposeSourceHandler,
'disposeSourceHandler should exist for Flash');
});
test('should export ready api call to public', function() {
var videoTag = testHelperMakeTag();
QUnit.test('should export ready api call to public', function() {
const videoTag = testHelperMakeTag();
const fixture = document.getElementById('qunit-fixture');
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
var player = videojs('example_1');
ok(player.ready !== undefined, 'ready callback is defined');
const player = videojs('example_1');
QUnit.ok(player.ready !== undefined, 'ready callback is defined');
player.dispose();
});
test('should export useful components to the public', function () {
ok(videojs.browser.TOUCH_ENABLED !== undefined, 'Touch detection should be public');
ok(videojs.getComponent('ControlBar'), 'ControlBar should be public');
ok(videojs.getComponent('Button'), 'Button should be public');
ok(videojs.getComponent('PlayToggle'), 'PlayToggle should be public');
ok(videojs.getComponent('FullscreenToggle'), 'FullscreenToggle should be public');
ok(videojs.getComponent('BigPlayButton'), 'BigPlayButton should be public');
ok(videojs.getComponent('LoadingSpinner'), 'LoadingSpinner should be public');
ok(videojs.getComponent('CurrentTimeDisplay'), 'CurrentTimeDisplay should be public');
ok(videojs.getComponent('DurationDisplay'), 'DurationDisplay should be public');
ok(videojs.getComponent('TimeDivider'), 'TimeDivider should be public');
ok(videojs.getComponent('RemainingTimeDisplay'), 'RemainingTimeDisplay should be public');
ok(videojs.getComponent('Slider'), 'Slider should be public');
ok(videojs.getComponent('ProgressControl'), 'ProgressControl should be public');
ok(videojs.getComponent('SeekBar'), 'SeekBar should be public');
ok(videojs.getComponent('LoadProgressBar'), 'LoadProgressBar should be public');
ok(videojs.getComponent('PlayProgressBar'), 'PlayProgressBar should be public');
ok(videojs.getComponent('VolumeControl'), 'VolumeControl should be public');
ok(videojs.getComponent('VolumeBar'), 'VolumeBar should be public');
ok(videojs.getComponent('VolumeLevel'), 'VolumeLevel should be public');
ok(videojs.getComponent('VolumeMenuButton'), 'VolumeMenuButton should be public');
ok(videojs.getComponent('MuteToggle'), 'MuteToggle should be public');
ok(videojs.getComponent('PosterImage'), 'PosterImage should be public');
ok(videojs.getComponent('Menu'), 'Menu should be public');
ok(videojs.getComponent('MenuItem'), 'MenuItem should be public');
ok(videojs.getComponent('MenuButton'), 'MenuButton should be public');
ok(videojs.getComponent('PlaybackRateMenuButton'), 'PlaybackRateMenuButton should be public');
QUnit.test('should export useful components to the public', function() {
QUnit.ok(videojs.browser.TOUCH_ENABLED !== undefined,
'Touch detection should be public');
QUnit.ok(videojs.getComponent('ControlBar'), 'ControlBar should be public');
QUnit.ok(videojs.getComponent('Button'), 'Button should be public');
QUnit.ok(videojs.getComponent('PlayToggle'), 'PlayToggle should be public');
QUnit.ok(videojs.getComponent('FullscreenToggle'), 'FullscreenToggle should be public');
QUnit.ok(videojs.getComponent('BigPlayButton'), 'BigPlayButton should be public');
QUnit.ok(videojs.getComponent('LoadingSpinner'), 'LoadingSpinner should be public');
QUnit.ok(videojs.getComponent('CurrentTimeDisplay'),
'CurrentTimeDisplay should be public');
QUnit.ok(videojs.getComponent('DurationDisplay'), 'DurationDisplay should be public');
QUnit.ok(videojs.getComponent('TimeDivider'), 'TimeDivider should be public');
QUnit.ok(videojs.getComponent('RemainingTimeDisplay'),
'RemainingTimeDisplay should be public');
QUnit.ok(videojs.getComponent('Slider'), 'Slider should be public');
QUnit.ok(videojs.getComponent('ProgressControl'), 'ProgressControl should be public');
QUnit.ok(videojs.getComponent('SeekBar'), 'SeekBar should be public');
QUnit.ok(videojs.getComponent('LoadProgressBar'), 'LoadProgressBar should be public');
QUnit.ok(videojs.getComponent('PlayProgressBar'), 'PlayProgressBar should be public');
QUnit.ok(videojs.getComponent('VolumeControl'), 'VolumeControl should be public');
QUnit.ok(videojs.getComponent('VolumeBar'), 'VolumeBar should be public');
QUnit.ok(videojs.getComponent('VolumeLevel'), 'VolumeLevel should be public');
QUnit.ok(videojs.getComponent('VolumeMenuButton'), 'VolumeMenuButton should be public');
QUnit.ok(videojs.getComponent('MuteToggle'), 'MuteToggle should be public');
QUnit.ok(videojs.getComponent('PosterImage'), 'PosterImage should be public');
QUnit.ok(videojs.getComponent('Menu'), 'Menu should be public');
QUnit.ok(videojs.getComponent('MenuItem'), 'MenuItem should be public');
QUnit.ok(videojs.getComponent('MenuButton'), 'MenuButton should be public');
QUnit.ok(videojs.getComponent('PlaybackRateMenuButton'),
'PlaybackRateMenuButton should be public');
ok(videojs.getComponent('CaptionSettingsMenuItem'), 'CaptionSettingsMenuItem should be public');
ok(videojs.getComponent('OffTextTrackMenuItem'), 'OffTextTrackMenuItem should be public');
ok(videojs.getComponent('TextTrackMenuItem'), 'TextTrackMenuItem should be public');
ok(videojs.getComponent('TextTrackDisplay'), 'TextTrackDisplay should be public');
ok(videojs.getComponent('TextTrackButton'), 'TextTrackButton should be public');
ok(videojs.getComponent('CaptionsButton'), 'CaptionsButton should be public');
ok(videojs.getComponent('SubtitlesButton'), 'SubtitlesButton should be public');
ok(videojs.getComponent('DescriptionsButton'), 'DescriptionsButton should be public');
ok(videojs.getComponent('ChaptersButton'), 'ChaptersButton should be public');
ok(videojs.getComponent('ChaptersTrackMenuItem'), 'ChaptersTrackMenuItem should be public');
QUnit.ok(videojs.getComponent('CaptionSettingsMenuItem'),
'CaptionSettingsMenuItem should be public');
QUnit.ok(videojs.getComponent('OffTextTrackMenuItem'),
'OffTextTrackMenuItem should be public');
QUnit.ok(videojs.getComponent('TextTrackMenuItem'),
'TextTrackMenuItem should be public');
QUnit.ok(videojs.getComponent('TextTrackDisplay'), 'TextTrackDisplay should be public');
QUnit.ok(videojs.getComponent('TextTrackButton'), 'TextTrackButton should be public');
QUnit.ok(videojs.getComponent('CaptionsButton'), 'CaptionsButton should be public');
QUnit.ok(videojs.getComponent('SubtitlesButton'), 'SubtitlesButton should be public');
QUnit.ok(videojs.getComponent('DescriptionsButton'),
'DescriptionsButton should be public');
QUnit.ok(videojs.getComponent('ChaptersButton'), 'ChaptersButton should be public');
QUnit.ok(videojs.getComponent('ChaptersTrackMenuItem'),
'ChaptersTrackMenuItem should be public');
ok(videojs.mergeOptions, 'mergeOptions should be public');
QUnit.ok(videojs.mergeOptions, 'mergeOptions should be public');
});
test('should be able to initialize player twice on the same tag using string reference', function() {
var videoTag = testHelperMakeTag();
var id = videoTag.id;
QUnit.test('should be able to initialize player twice on the same tag using string reference', function() {
const videoTag = testHelperMakeTag();
const id = videoTag.id;
const fixture = document.getElementById('qunit-fixture');
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
var player = videojs('example_1');
const player = videojs('example_1');
player.dispose();
ok(!document.getElementById(id), 'element is removed');
QUnit.ok(!document.getElementById(id), 'element is removed');
videoTag = testHelperMakeTag();
fixture.appendChild(videoTag);
@ -215,66 +234,68 @@ test('should be able to initialize player twice on the same tag using string ref
player.dispose();
});
test('videojs.getPlayers() should be available after minification', function() {
var videoTag = testHelperMakeTag();
var id = videoTag.id;
QUnit.test('videojs.getPlayers() should be available after minification', function() {
const videoTag = testHelperMakeTag();
const id = videoTag.id;
const fixture = document.getElementById('qunit-fixture');
var fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
var player = videojs(id);
ok(videojs.getPlayers()[id] === player, 'videojs.getPlayers() is available');
const player = videojs(id);
QUnit.ok(videojs.getPlayers()[id] === player, 'videojs.getPlayers() is available');
player.dispose();
});
test('component can be subclassed externally', function(){
var Component = videojs.getComponent('Component');
var ControlBar = videojs.getComponent('ControlBar');
QUnit.test('component can be subclassed externally', function() {
const Component = videojs.getComponent('Component');
const ControlBar = videojs.getComponent('ControlBar');
var player = new (videojs.extend(Component, {
reportUserActivity: function(){},
textTracks: function(){ return {
const player = new (videojs.extend(Component, {
reportUserActivity() {},
textTracks() {
return {
addEventListener: Function.prototype,
removeEventListener: Function.prototype
};
}
}))({
id: function(){},
reportUserActivity: function(){}
id() {},
reportUserActivity() {}
});
ok(new ControlBar(player), 'created a control bar without throwing');
QUnit.ok(new ControlBar(player), 'created a control bar without throwing');
});
function testHelperMakeTag(){
var videoTag = document.createElement('video');
function testHelperMakeTag() {
const videoTag = document.createElement('video');
videoTag.id = 'example_1';
videoTag.className = 'video-js vjs-default-skin';
return videoTag;
}
test('should extend Component', function(){
var Component = videojs.getComponent('Component');
var MyComponent = videojs.extend(Component, {
constructor: function() {
QUnit.test('should extend Component', function() {
const Component = videojs.getComponent('Component');
const MyComponent = videojs.extend(Component, {
constructor() {
this.bar = true;
},
foo: function() {
foo() {
return true;
}
});
var myComponent = new MyComponent();
ok(myComponent instanceof Component, 'creates an instance of Component');
ok(myComponent instanceof MyComponent, 'creates an instance of MyComponent');
ok(myComponent.bar, 'the constructor function is used');
ok(myComponent.foo(), 'instance methods are applied');
const myComponent = new MyComponent();
var NoMethods = videojs.extend(Component);
var noMethods = new NoMethods({});
ok(noMethods.on, 'should extend component with no methods or constructor');
QUnit.ok(myComponent instanceof Component, 'creates an instance of Component');
QUnit.ok(myComponent instanceof MyComponent, 'creates an instance of MyComponent');
QUnit.ok(myComponent.bar, 'the constructor function is used');
QUnit.ok(myComponent.foo(), 'instance methods are applied');
const NoMethods = videojs.extend(Component);
const noMethods = new NoMethods({});
QUnit.ok(noMethods.on, 'should extend component with no methods or constructor');
});
})();

View File

@ -1,3 +1,4 @@
/* eslint-env qunit */
import 'es6-shim';
import document from 'global/document';
import window from 'global/window';

View File

@ -1,27 +1,29 @@
/* eslint-env qunit */
import {IE_VERSION} from '../../src/js/utils/browser';
import registerPlugin from '../../src/js/plugins.js';
import Player from '../../src/js/player.js';
import TestHelpers from './test-helpers.js';
import window from 'global/window';
import sinon from 'sinon';
q.module('Plugins');
QUnit.module('Plugins');
test('Plugin should get initialized and receive options', function(){
expect(2);
QUnit.test('Plugin should get initialized and receive options', function() {
QUnit.expect(2);
registerPlugin('myPlugin1', function(options){
ok(true, 'Plugin initialized');
ok(options['test'], 'Option passed through');
registerPlugin('myPlugin1', function(options) {
QUnit.ok(true, 'Plugin initialized');
QUnit.ok(options.test, 'Option passed through');
});
registerPlugin('myPlugin2', function(options){
ok(false, 'Plugin initialized and should not have been');
registerPlugin('myPlugin2', function(options) {
QUnit.ok(false, 'Plugin initialized and should not have been');
});
var player = TestHelpers.makePlayer({
'plugins': {
'myPlugin1': {
'test': true
const player = TestHelpers.makePlayer({
plugins: {
myPlugin1: {
test: true
}
}
});
@ -29,121 +31,122 @@ test('Plugin should get initialized and receive options', function(){
player.dispose();
});
test('Plugin should have the option of being initilized outside of player init', function(){
expect(3);
QUnit.test('Plugin should have the option of being initilized outside of player init', function() {
QUnit.expect(3);
registerPlugin('myPlugin3', function(options){
ok(true, 'Plugin initialized after player init');
ok(options['test'], 'Option passed through');
registerPlugin('myPlugin3', function(options) {
QUnit.ok(true, 'Plugin initialized after player init');
QUnit.ok(options.test, 'Option passed through');
});
var player = TestHelpers.makePlayer({});
const player = TestHelpers.makePlayer({});
ok(player['myPlugin3'], 'Plugin has direct access on player instance');
QUnit.ok(player.myPlugin3, 'Plugin has direct access on player instance');
player['myPlugin3']({
'test': true
player.myPlugin3({
test: true
});
player.dispose();
});
test('Plugin should be able to add a UI component', function(){
expect(2);
QUnit.test('Plugin should be able to add a UI component', function() {
QUnit.expect(2);
registerPlugin('myPlugin4', function(options){
ok((this instanceof Player), 'Plugin executed in player scope by default');
registerPlugin('myPlugin4', function(options) {
QUnit.ok((this instanceof Player), 'Plugin executed in player scope by default');
this.addChild('component');
});
var player = TestHelpers.makePlayer({});
player['myPlugin4']({
'test': true
const player = TestHelpers.makePlayer({});
player.myPlugin4({
test: true
});
var comp = player.getChild('component');
ok(comp, 'Plugin added a component to the player');
const comp = player.getChild('component');
QUnit.ok(comp, 'Plugin added a component to the player');
player.dispose();
});
test('Plugin should overwrite plugin of same name', function(){
var v1Called = 0,
v2Called = 0,
v3Called = 0;
QUnit.test('Plugin should overwrite plugin of same name', function() {
let v1Called = 0;
let v2Called = 0;
let v3Called = 0;
// Create initial plugin
registerPlugin('myPlugin5', function(options){
registerPlugin('myPlugin5', function(options) {
v1Called++;
});
var player = TestHelpers.makePlayer({});
player['myPlugin5']({});
const player = TestHelpers.makePlayer({});
player.myPlugin5({});
// Overwrite and create new player
registerPlugin('myPlugin5', function(options){
registerPlugin('myPlugin5', function(options) {
v2Called++;
});
var player2 = TestHelpers.makePlayer({});
player2['myPlugin5']({});
const player2 = TestHelpers.makePlayer({});
player2.myPlugin5({});
// Overwrite and init new version on existing player
registerPlugin('myPlugin5', function(options){
registerPlugin('myPlugin5', function(options) {
v3Called++;
});
player2['myPlugin5']({});
player2.myPlugin5({});
var comp = player.getChild('component');
ok(v1Called === 1, 'First version of plugin called once');
ok(v2Called === 1, 'Plugin overwritten for new player');
ok(v3Called === 1, 'Plugin overwritten for existing player');
QUnit.ok(v1Called === 1, 'First version of plugin called once');
QUnit.ok(v2Called === 1, 'Plugin overwritten for new player');
QUnit.ok(v3Called === 1, 'Plugin overwritten for existing player');
player.dispose();
player2.dispose();
});
test('Plugins should get events in registration order', function() {
var order = [];
var expectedOrder = [];
var pluginName = 'orderPlugin';
var i = 0;
var name;
var player = TestHelpers.makePlayer({});
var plugin = function (name) {
registerPlugin(name, function (opts) {
this.on('test', function (event) {
QUnit.test('Plugins should get events in registration order', function() {
const order = [];
const expectedOrder = [];
const pluginName = 'orderPlugin';
const player = TestHelpers.makePlayer({});
const plugin = function(name) {
registerPlugin(name, function(opts) {
this.on('test', function(event) {
order.push(name);
});
});
player[name]({});
};
for (; i < 3; i++ ) {
name = pluginName + i;
for (let i = 0; i < 3; i++) {
const name = pluginName + i;
expectedOrder.push(name);
plugin(name);
}
registerPlugin('testerPlugin', function (opts) {
registerPlugin('testerPlugin', function(opts) {
this.trigger('test');
});
player['testerPlugin']({});
player.testerPlugin({});
deepEqual(order, expectedOrder, 'plugins should receive events in order of initialization');
QUnit.deepEqual(order,
expectedOrder,
'plugins should receive events in order of initialization');
player.dispose();
});
test('Plugins should not get events after stopImmediatePropagation is called', function () {
var order = [];
var expectedOrder = [];
var pluginName = 'orderPlugin';
var i = 0;
var name;
var player = TestHelpers.makePlayer({});
var plugin = function (name) {
registerPlugin(name, function (opts) {
this.on('test', function (event) {
QUnit.test('Plugins should not get events after stopImmediatePropagation is called', function() {
const order = [];
const expectedOrder = [];
const pluginName = 'orderPlugin';
const player = TestHelpers.makePlayer({});
const plugin = function(name) {
registerPlugin(name, function(opts) {
this.on('test', function(event) {
order.push(name);
event.stopImmediatePropagation();
});
@ -151,56 +154,57 @@ test('Plugins should not get events after stopImmediatePropagation is called', f
player[name]({});
};
for (; i < 3; i++ ) {
name = pluginName + i;
for (let i = 0; i < 3; i++) {
const name = pluginName + i;
expectedOrder.push(name);
plugin(name);
}
registerPlugin('testerPlugin', function (opts) {
registerPlugin('testerPlugin', function(opts) {
this.trigger('test');
});
player['testerPlugin']({});
player.testerPlugin({});
deepEqual(order, expectedOrder.slice(0, order.length), 'plugins should receive events in order of initialization, until stopImmediatePropagation');
QUnit.deepEqual(order,
expectedOrder.slice(0, order.length),
'plugins should receive events in order of ' +
'initialization, until stopImmediatePropagation');
equal(order.length, 1, 'only one event listener should have triggered');
QUnit.equal(order.length, 1, 'only one event listener should have triggered');
player.dispose();
});
test('Plugin that does not exist logs an error', function() {
QUnit.test('Plugin that does not exist logs an error', function() {
// stub the global log functions
var console, log, error, origConsole;
origConsole = window.console;
console = window.console = {
log: function(){},
warn: function(){},
error: function(){}
const console = window.console = {
log() {},
warn() {},
error() {}
};
log = sinon.stub(console, 'log');
error = sinon.stub(console, 'error');
const log = sinon.stub(console, 'log');
const error = sinon.stub(console, 'error');
const origConsole = window.console;
// enable a non-existing plugin
TestHelpers.makePlayer({
plugins: {
'nonExistingPlugin': {
'foo': 'bar'
nonExistingPlugin: {
foo: 'bar'
}
}
});
ok(error.called, 'error was called');
QUnit.ok(error.called, 'error was called');
if (IE_VERSION && IE_VERSION < 11) {
equal(error.firstCall.args[0], 'VIDEOJS: ERROR: Unable to find plugin: nonExistingPlugin');
QUnit.equal(error.firstCall.args[0],
'VIDEOJS: ERROR: Unable to find plugin: nonExistingPlugin');
} else {
equal(error.firstCall.args[2], 'Unable to find plugin:');
equal(error.firstCall.args[3], 'nonExistingPlugin');
QUnit.equal(error.firstCall.args[2], 'Unable to find plugin:');
QUnit.equal(error.firstCall.args[3], 'nonExistingPlugin');
}
// tear down logging stubs

View File

@ -1,10 +1,11 @@
/* eslint-env qunit */
import PosterImage from '../../src/js/poster-image.js';
import * as browser from '../../src/js/utils/browser.js';
import TestHelpers from './test-helpers.js';
import document from 'global/document';
q.module('PosterImage', {
'setup': function(){
QUnit.module('PosterImage', {
setup() {
// Store the original background support so we can test different vals
this.origVal = browser.BACKGROUND_SIZE_SUPPORTED;
this.poster1 = '#poster1';
@ -13,69 +14,80 @@ q.module('PosterImage', {
// Create a mock player object that responds as a player would
this.mockPlayer = {
poster_: this.poster1,
poster: function(){
poster() {
return this.poster_;
},
handler_: null,
on: function(type, handler){
on(type, handler) {
this.handler_ = handler;
},
trigger: function(type){
trigger(type) {
this.handler_.call();
}
};
},
'teardown': function(){
teardown() {
browser.BACKGROUND_SIZE_SUPPORTED = this.origVal;
}
});
test('should create and update a poster image', function(){
QUnit.test('should create and update a poster image', function() {
browser.BACKGROUND_SIZE_SUPPORTED = true;
let posterImage = new PosterImage(this.mockPlayer);
const posterImage = new PosterImage(this.mockPlayer);
let backgroundImage = posterImage.el().style.backgroundImage;
notEqual(backgroundImage.indexOf(this.poster1), -1, 'Background image used');
QUnit.notEqual(backgroundImage.indexOf(this.poster1), -1, 'Background image used');
// Update with a new poster source and check the new value
this.mockPlayer.poster_ = this.poster2;
this.mockPlayer.trigger('posterchange');
backgroundImage = posterImage.el().style.backgroundImage;
notEqual(backgroundImage.indexOf(this.poster2), -1, 'Background image updated');
QUnit.notEqual(backgroundImage.indexOf(this.poster2), -1, 'Background image updated');
});
test('should create and update a fallback image in older browsers', function(){
QUnit.test('should create and update a fallback image in older browsers', function() {
browser.BACKGROUND_SIZE_SUPPORTED = false;
let posterImage = new PosterImage(this.mockPlayer);
notEqual(posterImage.fallbackImg_.src.indexOf(this.poster1), -1, 'Fallback image created');
const posterImage = new PosterImage(this.mockPlayer);
QUnit.notEqual(posterImage.fallbackImg_.src.indexOf(this.poster1),
-1,
'Fallback image created');
// Update with a new poster source and check the new value
this.mockPlayer.poster_ = this.poster2;
this.mockPlayer.trigger('posterchange');
notEqual(posterImage.fallbackImg_.src.indexOf(this.poster2), -1, 'Fallback image updated');
QUnit.notEqual(posterImage.fallbackImg_.src.indexOf(this.poster2),
-1,
'Fallback image updated');
});
test('should remove itself from the document flow when there is no poster', function(){
let posterImage = new PosterImage(this.mockPlayer);
equal(posterImage.el().style.display, '', 'Poster image shows by default');
QUnit.test('should remove itself from the document flow when there is no poster', function() {
const posterImage = new PosterImage(this.mockPlayer);
QUnit.equal(posterImage.el().style.display, '', 'Poster image shows by default');
// Update with an empty string
this.mockPlayer.poster_ = '';
this.mockPlayer.trigger('posterchange');
equal(posterImage.hasClass('vjs-hidden'), true, 'Poster image hides with an empty source');
QUnit.equal(posterImage.hasClass('vjs-hidden'),
true,
'Poster image hides with an empty source');
// Updated with a valid source
this.mockPlayer.poster_ = this.poster2;
this.mockPlayer.trigger('posterchange');
equal(posterImage.hasClass('vjs-hidden'), false, 'Poster image shows again when there is a source');
QUnit.equal(posterImage.hasClass('vjs-hidden'),
false,
'Poster image shows again when there is a source');
});
test('should hide the poster in the appropriate player states', function(){
var posterImage = new PosterImage(this.mockPlayer);
var playerDiv = document.createElement('div');
var fixture = document.getElementById('qunit-fixture');
var el = posterImage.el();
QUnit.test('should hide the poster in the appropriate player states', function() {
const posterImage = new PosterImage(this.mockPlayer);
const playerDiv = document.createElement('div');
const fixture = document.getElementById('qunit-fixture');
const el = posterImage.el();
// Remove the source so when we add to the DOM it doesn't throw an error
// We want to poster to still think it has a real source so it doesn't hide itself
@ -86,8 +98,12 @@ test('should hide the poster in the appropriate player states', function(){
fixture.appendChild(playerDiv);
playerDiv.className = 'video-js vjs-has-started';
equal(TestHelpers.getComputedStyle(el, 'display'), 'none', 'The poster hides when the video has started (CSS may not be loaded)');
QUnit.equal(TestHelpers.getComputedStyle(el, 'display'),
'none',
'The poster hides when the video has started (CSS may not be loaded)');
playerDiv.className = 'video-js vjs-has-started vjs-audio';
equal(TestHelpers.getComputedStyle(el, 'display'), 'block', 'The poster continues to show when playing audio');
QUnit.equal(TestHelpers.getComputedStyle(el, 'display'),
'block',
'The poster continues to show when playing audio');
});

View File

@ -1,14 +1,17 @@
/* eslint-env qunit */
import TestHelpers from './test-helpers.js';
q.module('Setup');
QUnit.module('Setup');
test('should set options from data-setup even if autoSetup is not called before initialisation', function(){
var el = TestHelpers.makeTag();
el.setAttribute('data-setup', '{"controls": true, "autoplay": false, "preload": "auto"}');
QUnit.test('should set options from data-setup even if autoSetup is not called before initialisation', function() {
const el = TestHelpers.makeTag();
var player = TestHelpers.makePlayer({}, el);
el.setAttribute('data-setup',
'{"controls": true, "autoplay": false, "preload": "auto"}');
ok(player.options_['controls'] === true);
ok(player.options_['autoplay'] === false);
ok(player.options_['preload'] === 'auto');
const player = TestHelpers.makePlayer({}, el);
QUnit.ok(player.options_.controls === true);
QUnit.ok(player.options_.autoplay === false);
QUnit.ok(player.options_.preload === 'auto');
});

View File

@ -1,54 +1,58 @@
/* eslint-env qunit */
import Flash from '../../../src/js/tech/flash.js';
q.module('Flash RTMP');
QUnit.module('Flash RTMP');
const streamToPartsAndBack = function(url) {
const parts = Flash.streamToParts(url);
var streamToPartsAndBack = function(url) {
var parts = Flash.streamToParts(url);
return Flash.streamFromParts(parts.connection, parts.stream);
};
test('test using both streamToParts and streamFromParts', function() {
ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/isthis'));
ok('rtmp://myurl.com/&isthis' === streamToPartsAndBack('rtmp://myurl.com/&isthis'));
ok('rtmp://myurl.com/isthis/&andthis' === streamToPartsAndBack('rtmp://myurl.com/isthis/andthis'));
QUnit.test('test using both streamToParts and streamFromParts', function() {
QUnit.ok(streamToPartsAndBack('rtmp://myurl.com/isthis') === 'rtmp://myurl.com/&isthis');
QUnit.ok(streamToPartsAndBack('rtmp://myurl.com/&isthis') === 'rtmp://myurl.com/&isthis');
QUnit.ok(streamToPartsAndBack('rtmp://myurl.com/isthis/andthis') === 'rtmp://myurl.com/isthis/&andthis');
});
test('test streamToParts', function() {
var parts = Flash.streamToParts('http://myurl.com/streaming&/is/fun');
ok(parts.connection === 'http://myurl.com/streaming');
ok(parts.stream === '/is/fun');
QUnit.test('test streamToParts', function() {
let parts = Flash.streamToParts('http://myurl.com/streaming&/is/fun');
QUnit.ok(parts.connection === 'http://myurl.com/streaming');
QUnit.ok(parts.stream === '/is/fun');
parts = Flash.streamToParts('http://myurl.com/&streaming&/is/fun');
ok(parts.connection === 'http://myurl.com/');
ok(parts.stream === 'streaming&/is/fun');
QUnit.ok(parts.connection === 'http://myurl.com/');
QUnit.ok(parts.stream === 'streaming&/is/fun');
parts = Flash.streamToParts('http://myurl.com/really?streaming=fun&really=fun');
ok(parts.connection === 'http://myurl.com/');
ok(parts.stream === 'really?streaming=fun&really=fun');
QUnit.ok(parts.connection === 'http://myurl.com/');
QUnit.ok(parts.stream === 'really?streaming=fun&really=fun');
parts = Flash.streamToParts('http://myurl.com/streaming/is/fun');
ok(parts.connection === 'http://myurl.com/streaming/is/');
ok(parts.stream === 'fun');
QUnit.ok(parts.connection === 'http://myurl.com/streaming/is/');
QUnit.ok(parts.stream === 'fun');
parts = Flash.streamToParts('whatisgoingonhere');
ok(parts.connection === 'whatisgoingonhere');
ok(parts.stream === '');
QUnit.ok(parts.connection === 'whatisgoingonhere');
QUnit.ok(parts.stream === '');
parts = Flash.streamToParts();
ok(parts.connection === '');
ok(parts.stream === '');
QUnit.ok(parts.connection === '');
QUnit.ok(parts.stream === '');
});
test('test isStreamingSrc', function() {
var isStreamingSrc = Flash.isStreamingSrc;
ok(isStreamingSrc('rtmp://streaming.is/fun'));
ok(isStreamingSrc('rtmps://streaming.is/fun'));
ok(isStreamingSrc('rtmpe://streaming.is/fun'));
ok(isStreamingSrc('rtmpt://streaming.is/fun'));
QUnit.test('test isStreamingSrc', function() {
const isStreamingSrc = Flash.isStreamingSrc;
QUnit.ok(isStreamingSrc('rtmp://streaming.is/fun'));
QUnit.ok(isStreamingSrc('rtmps://streaming.is/fun'));
QUnit.ok(isStreamingSrc('rtmpe://streaming.is/fun'));
QUnit.ok(isStreamingSrc('rtmpt://streaming.is/fun'));
// test invalid protocols
ok(!isStreamingSrc('rtmp:streaming.is/fun'));
ok(!isStreamingSrc('rtmpz://streaming.is/fun'));
ok(!isStreamingSrc('http://streaming.is/fun'));
ok(!isStreamingSrc('https://streaming.is/fun'));
ok(!isStreamingSrc('file://streaming.is/fun'));
QUnit.ok(!isStreamingSrc('rtmp:streaming.is/fun'));
QUnit.ok(!isStreamingSrc('rtmpz://streaming.is/fun'));
QUnit.ok(!isStreamingSrc('http://streaming.is/fun'));
QUnit.ok(!isStreamingSrc('https://streaming.is/fun'));
QUnit.ok(!isStreamingSrc('file://streaming.is/fun'));
});

View File

@ -1,28 +1,38 @@
/* eslint-env qunit */
import Flash from '../../../src/js/tech/flash.js';
import { createTimeRange } from '../../../src/js/utils/time-ranges.js';
import document from 'global/document';
import sinon from 'sinon';
q.module('Flash');
// fake out the <object> interaction but leave all the other logic intact
class MockFlash extends Flash {
constructor() {
super({});
}
}
test('Flash.canPlaySource', function() {
var canPlaySource = Flash.canPlaySource;
QUnit.module('Flash');
QUnit.test('Flash.canPlaySource', function() {
const canPlaySource = Flash.canPlaySource;
// Supported
ok(canPlaySource({ type: 'video/mp4; codecs=avc1.42E01E,mp4a.40.2' }, {}), 'codecs supported');
ok(canPlaySource({ type: 'video/mp4' }, {}), 'video/mp4 supported');
ok(canPlaySource({ type: 'video/x-flv' }, {}), 'video/x-flv supported');
ok(canPlaySource({ type: 'video/flv' }, {}), 'video/flv supported');
ok(canPlaySource({ type: 'video/m4v' }, {}), 'video/m4v supported');
ok(canPlaySource({ type: 'VIDEO/FLV' }, {}), 'capitalized mime type');
QUnit.ok(canPlaySource({type: 'video/mp4; codecs=avc1.42E01E,mp4a.40.2' }, {}),
'codecs supported');
QUnit.ok(canPlaySource({type: 'video/mp4' }, {}), 'video/mp4 supported');
QUnit.ok(canPlaySource({type: 'video/x-flv' }, {}), 'video/x-flv supported');
QUnit.ok(canPlaySource({type: 'video/flv' }, {}), 'video/flv supported');
QUnit.ok(canPlaySource({type: 'video/m4v' }, {}), 'video/m4v supported');
QUnit.ok(canPlaySource({type: 'VIDEO/FLV' }, {}), 'capitalized mime type');
// Not supported
ok(!canPlaySource({ type: 'video/webm; codecs="vp8, vorbis"' }, {}));
ok(!canPlaySource({ type: 'video/webm' }, {}));
QUnit.ok(!canPlaySource({ type: 'video/webm; codecs="vp8, vorbis"' }, {}));
QUnit.ok(!canPlaySource({ type: 'video/webm' }, {}));
});
test('currentTime', function() {
let getCurrentTime = Flash.prototype.currentTime;
let setCurrentTime = Flash.prototype.setCurrentTime;
QUnit.test('currentTime', function() {
const getCurrentTime = Flash.prototype.currentTime;
const setCurrentTime = Flash.prototype.setCurrentTime;
let seekingCount = 0;
let seeking = false;
let setPropVal;
@ -30,24 +40,26 @@ test('currentTime', function() {
let result;
// Mock out a Flash instance to avoid creating the swf object
let mockFlash = {
const mockFlash = {
el_: {
vjs_setProperty(prop, val){
/* eslint-disable camelcase */
vjs_setProperty(prop, val) {
setPropVal = val;
},
vjs_getProperty(){
vjs_getProperty() {
return getPropVal;
}
/* eslint-enable camelcase */
},
seekable(){
seekable() {
return createTimeRange(5, 1000);
},
trigger(event){
trigger(event) {
if (event === 'seeking') {
seekingCount++;
}
},
seeking(){
seeking() {
return seeking;
}
};
@ -55,39 +67,43 @@ test('currentTime', function() {
// Test the currentTime getter
getPropVal = 3;
result = getCurrentTime.call(mockFlash);
equal(result, 3, 'currentTime is retreived from the swf element');
QUnit.equal(result, 3, 'currentTime is retreived from the swf element');
// Test the currentTime setter
setCurrentTime.call(mockFlash, 10);
equal(setPropVal, 10, 'currentTime is set on the swf element');
equal(seekingCount, 1, 'triggered seeking');
QUnit.equal(setPropVal, 10, 'currentTime is set on the swf element');
QUnit.equal(seekingCount, 1, 'triggered seeking');
// Test current time while seeking
setCurrentTime.call(mockFlash, 20);
seeking = true;
result = getCurrentTime.call(mockFlash);
equal(result, 20, 'currentTime is retrieved from the lastSeekTarget while seeking');
notEqual(result, getPropVal, 'currentTime is not retrieved from the element while seeking');
equal(seekingCount, 2, 'triggered seeking');
QUnit.equal(result,
20,
'currentTime is retrieved from the lastSeekTarget while seeking');
QUnit.notEqual(result,
getPropVal,
'currentTime is not retrieved from the element while seeking');
QUnit.equal(seekingCount, 2, 'triggered seeking');
// clamp seeks to seekable
setCurrentTime.call(mockFlash, 1001);
result = getCurrentTime.call(mockFlash);
equal(result, mockFlash.seekable().end(0), 'clamped to the seekable end');
equal(seekingCount, 3, 'triggered seeking');
QUnit.equal(result, mockFlash.seekable().end(0), 'clamped to the seekable end');
QUnit.equal(seekingCount, 3, 'triggered seeking');
setCurrentTime.call(mockFlash, 1);
result = getCurrentTime.call(mockFlash);
equal(result, mockFlash.seekable().start(0), 'clamped to the seekable start');
equal(seekingCount, 4, 'triggered seeking');
QUnit.equal(result, mockFlash.seekable().start(0), 'clamped to the seekable start');
QUnit.equal(seekingCount, 4, 'triggered seeking');
});
test('dispose removes the object element even before ready fires', function() {
QUnit.test('dispose removes the object element even before ready fires', function() {
// This test appears to test bad functionaly that was fixed
// so it's debateable whether or not it's useful
let dispose = Flash.prototype.dispose;
let mockFlash = new MockFlash();
let noop = function(){};
const dispose = Flash.prototype.dispose;
const mockFlash = new MockFlash();
const noop = function() {};
// Mock required functions for dispose
mockFlash.off = noop;
@ -95,14 +111,14 @@ test('dispose removes the object element even before ready fires', function() {
mockFlash.el_ = {};
dispose.call(mockFlash);
strictEqual(mockFlash.el_, null, 'swf el is nulled');
QUnit.strictEqual(mockFlash.el_, null, 'swf el is nulled');
});
test('ready triggering before and after disposing the tech', function() {
let checkReady = sinon.stub(Flash, 'checkReady');
let fixtureDiv = document.getElementById('qunit-fixture');
let playerDiv = document.createElement('div');
let techEl = document.createElement('div');
QUnit.test('ready triggering before and after disposing the tech', function() {
const checkReady = sinon.stub(Flash, 'checkReady');
const fixtureDiv = document.getElementById('qunit-fixture');
const playerDiv = document.createElement('div');
const techEl = document.createElement('div');
techEl.id = 'foo1234';
playerDiv.appendChild(techEl);
@ -110,7 +126,7 @@ test('ready triggering before and after disposing the tech', function() {
// Mock the swf element
techEl.tech = {
el: function() {
el() {
return techEl;
}
};
@ -120,44 +136,55 @@ test('ready triggering before and after disposing the tech', function() {
};
Flash.onReady(techEl.id);
ok(checkReady.called, 'checkReady should be called before the tech is disposed');
QUnit.ok(checkReady.called, 'checkReady should be called before the tech is disposed');
// remove the tech el from the player div to simulate being disposed
playerDiv.removeChild(techEl);
Flash.onReady(techEl.id);
ok(!checkReady.calledTwice, 'checkReady should not be called after the tech is disposed');
QUnit.ok(!checkReady.calledTwice,
'checkReady should not be called after the tech is disposed');
Flash.checkReady.restore();
});
test('should have the source handler interface', function() {
ok(Flash.registerSourceHandler, 'has the registerSourceHandler function');
QUnit.test('should have the source handler interface', function() {
QUnit.ok(Flash.registerSourceHandler, 'has the registerSourceHandler function');
});
test('canPlayType should select the correct types to play', function () {
let canPlayType = Flash.nativeSourceHandler.canPlayType;
QUnit.test('canPlayType should select the correct types to play', function() {
const canPlayType = Flash.nativeSourceHandler.canPlayType;
equal(canPlayType('video/flv'), 'maybe', 'should be able to play FLV files');
equal(canPlayType('video/x-flv'), 'maybe', 'should be able to play x-FLV files');
equal(canPlayType('video/mp4'), 'maybe', 'should be able to play MP4 files');
equal(canPlayType('video/m4v'), 'maybe', 'should be able to play M4V files');
equal(canPlayType('video/ogg'), '', 'should return empty string if it can not play the video');
QUnit.equal(canPlayType('video/flv'), 'maybe', 'should be able to play FLV files');
QUnit.equal(canPlayType('video/x-flv'), 'maybe', 'should be able to play x-FLV files');
QUnit.equal(canPlayType('video/mp4'), 'maybe', 'should be able to play MP4 files');
QUnit.equal(canPlayType('video/m4v'), 'maybe', 'should be able to play M4V files');
QUnit.equal(canPlayType('video/ogg'),
'',
'should return empty string if it can not play the video');
});
test('canHandleSource should be able to work with src objects without a type', function () {
let canHandleSource = Flash.nativeSourceHandler.canHandleSource;
QUnit.test('canHandleSource should be able to work with src objects without a type', function() {
const canHandleSource = Flash.nativeSourceHandler.canHandleSource;
equal('maybe', canHandleSource({ src: 'test.video.mp4' }, {}), 'should guess that it is a mp4 video');
equal('maybe', canHandleSource({ src: 'test.video.m4v' }, {}), 'should guess that it is a m4v video');
equal('maybe', canHandleSource({ src: 'test.video.flv' }, {}), 'should guess that it is a flash video');
equal('', canHandleSource({ src: 'test.video.wgg' }, {}), 'should return empty string if it can not play the video');
QUnit.equal('maybe',
canHandleSource({ src: 'test.video.mp4' }, {}),
'should guess that it is a mp4 video');
QUnit.equal('maybe',
canHandleSource({ src: 'test.video.m4v' }, {}),
'should guess that it is a m4v video');
QUnit.equal('maybe',
canHandleSource({ src: 'test.video.flv' }, {}),
'should guess that it is a flash video');
QUnit.equal('',
canHandleSource({ src: 'test.video.wgg' }, {}),
'should return empty string if it can not play the video');
});
test('seekable', function() {
let seekable = Flash.prototype.seekable;
QUnit.test('seekable', function() {
const seekable = Flash.prototype.seekable;
let result;
let mockFlash = {
duration: function() {
const mockFlash = {
duration() {
return this.duration_;
}
};
@ -165,24 +192,28 @@ test('seekable', function() {
// Test a normal duration
mockFlash.duration_ = 23;
result = seekable.call(mockFlash);
equal(result.length, 1, 'seekable is non-empty');
equal(result.start(0), 0, 'starts at zero');
equal(result.end(0), mockFlash.duration_, 'ends at the duration');
QUnit.equal(result.length, 1, 'seekable is non-empty');
QUnit.equal(result.start(0), 0, 'starts at zero');
QUnit.equal(result.end(0), mockFlash.duration_, 'ends at the duration');
// Test a zero duration
mockFlash.duration_ = 0;
result = seekable.call(mockFlash);
equal(result.length, mockFlash.duration_, 'seekable is empty with a zero duration');
QUnit.equal(result.length, mockFlash.duration_,
'seekable is empty with a zero duration');
});
test('play after ended seeks to the beginning', function() {
let plays = 0, seeks = [];
QUnit.test('play after ended seeks to the beginning', function() {
let plays = 0;
const seeks = [];
Flash.prototype.play.call({
el_: {
/* eslint-disable camelcase */
vjs_play() {
plays++;
}
/* eslint-enable camelcase */
},
ended() {
return true;
@ -192,41 +223,41 @@ test('play after ended seeks to the beginning', function() {
}
});
equal(plays, 1, 'called play on the SWF');
equal(seeks.length, 1, 'seeked on play');
equal(seeks[0], 0, 'seeked to the beginning');
QUnit.equal(plays, 1, 'called play on the SWF');
QUnit.equal(seeks.length, 1, 'seeked on play');
QUnit.equal(seeks[0], 0, 'seeked to the beginning');
});
test('duration returns NaN, Infinity or duration according to the HTML standard', function() {
let duration = Flash.prototype.duration;
QUnit.test('duration returns NaN, Infinity or duration according to the HTML standard', function() {
const duration = Flash.prototype.duration;
let mockedDuration = -1;
let mockedReadyState = 0;
let result;
let mockFlash = {
const mockFlash = {
el_: {
/* eslint-disable camelcase */
vjs_getProperty() {
return mockedDuration;
}
/* eslint-enable camelcase */
},
readyState: function() {
readyState() {
return mockedReadyState;
}
};
result = duration.call(mockFlash);
ok(Number.isNaN(result), 'duration returns NaN when readyState equals 0');
QUnit.ok(Number.isNaN(result), 'duration returns NaN when readyState equals 0');
mockedReadyState = 1;
result = duration.call(mockFlash);
ok(!Number.isFinite(result), 'duration returns Infinity when duration property is less then 0');
QUnit.ok(!Number.isFinite(result),
'duration returns Infinity when duration property is less then 0');
mockedDuration = 1;
result = duration.call(mockFlash);
equal(result, 1, 'duration returns duration property when readeyState and duration property are both higher than 0');
QUnit.equal(result,
1,
'duration returns duration property when readyState' +
' and duration property are both higher than 0');
});
// fake out the <object> interaction but leave all the other logic intact
class MockFlash extends Flash {
constructor() {
super({});
}
}

View File

@ -1,381 +1,449 @@
var player, tech, el;
/* eslint-env qunit */
let player;
let tech;
import Html5 from '../../../src/js/tech/html5.js';
import * as browser from '../../../src/js/utils/browser.js';
import document from 'global/document';
q.module('HTML5', {
'setup': function() {
QUnit.module('HTML5', {
setup() {
const el = document.createElement('div');
el = document.createElement('div');
el.innerHTML = '<div />';
player = {
id: function(){ return 'id'; },
el: function(){ return el; },
id() {
return 'id';
},
el() {
return el;
},
options_: {},
options: function(){ return this.options_; },
bufferedPercent: function() { return 0; },
controls: function(){ return false; },
usingNativeControls: function(){ return false; },
on: function(){ return this; },
off: function() { return this; },
ready: function(){},
addChild: function(){},
trigger: function(){}
options() {
return this.options_;
},
bufferedPercent() {
return 0;
},
controls() {
return false;
},
usingNativeControls() {
return false;
},
on() {
return this;
},
off() {
return this;
},
ready() {},
addChild() {},
trigger() {}
};
tech = new Html5({});
},
'teardown': function() {
teardown() {
tech.dispose();
el = null;
player = null;
tech = null;
}
});
test('should detect whether the volume can be changed', function(){
var testVid, ConstVolumeVideo;
if (!{}['__defineSetter__']) {
ok(true, 'your browser does not support this test, skipping it');
QUnit.test('should detect whether the volume can be changed', function() {
if (!{}.__defineSetter__) {
QUnit.ok(true, 'your browser does not support this test, skipping it');
return;
}
testVid = Html5.TEST_VID;
ConstVolumeVideo = function(){
const testVid = Html5.TEST_VID;
const ConstVolumeVideo = function() {
this.volume = 1;
this.__defineSetter__('volume', function(){});
this.__defineSetter__('volume', function() {});
};
Html5.TEST_VID = new ConstVolumeVideo();
ok(!Html5.canControlVolume());
QUnit.ok(!Html5.canControlVolume());
Html5.TEST_VID = testVid;
});
test('test playbackRate', function() {
var playbackRate;
QUnit.test('test playbackRate', function() {
// Android 2.3 always returns 0 for playback rate
if (!Html5.canControlPlaybackRate()) {
ok('Playback rate is not supported');
QUnit.ok('Playback rate is not supported');
return;
}
tech.createEl();
tech.el().playbackRate = 1.25;
strictEqual(tech.playbackRate(), 1.25);
QUnit.strictEqual(tech.playbackRate(), 1.25);
tech['setPlaybackRate'](0.75);
strictEqual(tech.playbackRate(), 0.75);
tech.setPlaybackRate(0.75);
QUnit.strictEqual(tech.playbackRate(), 0.75);
});
test('should export played', function() {
QUnit.test('should export played', function() {
tech.createEl();
deepEqual(tech.played(), tech.el().played, 'returns the played attribute');
QUnit.deepEqual(tech.played(), tech.el().played, 'returns the played attribute');
});
test('should remove the controls attribute when recreating the element', function() {
var el;
QUnit.test('should remove the controls attribute when recreating the element', function() {
player.tagAttributes = {
controls: true
};
// force custom controls so the test environment is equivalent on iOS
player.options_['nativeControlsForTouch'] = false;
el = tech.createEl();
player.options_.nativeControlsForTouch = false;
const el = tech.createEl();
// On the iPhone controls are always true
if (!browser.IS_IPHONE) {
ok(!el.controls, 'controls attribute is absent');
QUnit.ok(!el.controls, 'controls attribute is absent');
}
ok(player.tagAttributes.controls, 'tag attribute is still present');
QUnit.ok(player.tagAttributes.controls, 'tag attribute is still present');
});
test('patchCanPlayType patches canplaytype with our function, conditionally', function() {
QUnit.test('patchCanPlayType patches canplaytype with our function, conditionally', function() {
// the patch runs automatically so we need to first unpatch
Html5.unpatchCanPlayType();
var oldAV = browser.ANDROID_VERSION,
video = document.createElement('video'),
canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType,
patchedCanPlayType,
unpatchedCanPlayType;
const oldAV = browser.ANDROID_VERSION;
const video = document.createElement('video');
const canPlayType = Html5.TEST_VID.constructor.prototype.canPlayType;
browser.ANDROID_VERSION = 4.0;
Html5.patchCanPlayType();
notStrictEqual(video.canPlayType, canPlayType, 'original canPlayType and patched canPlayType should not be equal');
QUnit.notStrictEqual(video.canPlayType,
canPlayType,
'original canPlayType and patched canPlayType should not be equal');
patchedCanPlayType = video.canPlayType;
unpatchedCanPlayType = Html5.unpatchCanPlayType();
const patchedCanPlayType = video.canPlayType;
const unpatchedCanPlayType = Html5.unpatchCanPlayType();
strictEqual(canPlayType, Html5.TEST_VID.constructor.prototype.canPlayType, 'original canPlayType and unpatched canPlayType should be equal');
strictEqual(patchedCanPlayType, unpatchedCanPlayType, 'patched canPlayType and function returned from unpatch are equal');
QUnit.strictEqual(canPlayType,
Html5.TEST_VID.constructor.prototype.canPlayType,
'original canPlayType and unpatched canPlayType should be equal');
QUnit.strictEqual(patchedCanPlayType,
unpatchedCanPlayType,
'patched canPlayType and function returned from unpatch are equal');
browser.ANDROID_VERSION = oldAV;
Html5.unpatchCanPlayType();
});
test('should return maybe for HLS urls on Android 4.0 or above', function() {
var oldAV = browser.ANDROID_VERSION,
video = document.createElement('video');
QUnit.test('should return maybe for HLS urls on Android 4.0 or above', function() {
const oldAV = browser.ANDROID_VERSION;
const video = document.createElement('video');
browser.ANDROID_VERSION = 4.0;
Html5.patchCanPlayType();
strictEqual(video.canPlayType('application/x-mpegurl'), 'maybe', 'android version 4.0 or above should be a maybe for x-mpegurl');
strictEqual(video.canPlayType('application/x-mpegURL'), 'maybe', 'android version 4.0 or above should be a maybe for x-mpegURL');
strictEqual(video.canPlayType('application/vnd.apple.mpegurl'), 'maybe', 'android version 4.0 or above should be a maybe for vnd.apple.mpegurl');
strictEqual(video.canPlayType('application/vnd.apple.mpegURL'), 'maybe', 'android version 4.0 or above should be a maybe for vnd.apple.mpegurl');
QUnit.strictEqual(video.canPlayType('application/x-mpegurl'),
'maybe',
'android version 4.0 or above should be a maybe for x-mpegurl');
QUnit.strictEqual(video.canPlayType('application/x-mpegURL'),
'maybe',
'android version 4.0 or above should be a maybe for x-mpegURL');
QUnit.strictEqual(video.canPlayType('application/vnd.apple.mpegurl'),
'maybe',
'android version 4.0 or above should be a ' +
'maybe for vnd.apple.mpegurl');
QUnit.strictEqual(video.canPlayType('application/vnd.apple.mpegURL'),
'maybe',
'android version 4.0 or above should be a ' +
'maybe for vnd.apple.mpegurl');
browser.ANDROID_VERSION = oldAV;
Html5.unpatchCanPlayType();
});
test('should return a maybe for mp4 on OLD ANDROID', function() {
var isOldAndroid = browser.IS_OLD_ANDROID,
video = document.createElement('video');
QUnit.test('should return a maybe for mp4 on OLD ANDROID', function() {
const isOldAndroid = browser.IS_OLD_ANDROID;
const video = document.createElement('video');
browser.IS_OLD_ANDROID = true;
Html5.patchCanPlayType();
strictEqual(video.canPlayType('video/mp4'), 'maybe', 'old android should return a maybe for video/mp4');
QUnit.strictEqual(video.canPlayType('video/mp4'),
'maybe',
'old android should return a maybe for video/mp4');
browser.IS_OLD_ANDROID = isOldAndroid;
Html5.unpatchCanPlayType();
});
test('error events may not set the errors property', function() {
equal(tech.error(), undefined, 'no tech-level error');
QUnit.test('error events may not set the errors property', function() {
QUnit.equal(tech.error(), undefined, 'no tech-level error');
tech.trigger('error');
ok(true, 'no error was thrown');
QUnit.ok(true, 'no error was thrown');
});
test('should have the source handler interface', function() {
ok(Html5.registerSourceHandler, 'has the registerSourceHandler function');
QUnit.test('should have the source handler interface', function() {
QUnit.ok(Html5.registerSourceHandler, 'has the registerSourceHandler function');
});
test('native source handler canPlayType', function(){
var result;
QUnit.test('native source handler canPlayType', function() {
// Stub the test video canPlayType (used in canPlayType) to control results
var origCPT = Html5.TEST_VID.canPlayType;
Html5.TEST_VID.canPlayType = function(type){
const origCPT = Html5.TEST_VID.canPlayType;
Html5.TEST_VID.canPlayType = function(type) {
if (type === 'video/mp4') {
return 'maybe';
}
return '';
};
var canPlayType = Html5.nativeSourceHandler.canPlayType;
const canPlayType = Html5.nativeSourceHandler.canPlayType;
equal(canPlayType('video/mp4'), 'maybe', 'Native source handler reported type support');
equal(canPlayType('foo'), '', 'Native source handler handled bad type');
QUnit.equal(canPlayType('video/mp4'),
'maybe',
'Native source handler reported type support');
QUnit.equal(canPlayType('foo'), '', 'Native source handler handled bad type');
// Reset test video canPlayType
Html5.TEST_VID.canPlayType = origCPT;
});
test('native source handler canHandleSource', function(){
var result;
QUnit.test('native source handler canHandleSource', function() {
// Stub the test video canPlayType (used in canHandleSource) to control results
var origCPT = Html5.TEST_VID.canPlayType;
Html5.TEST_VID.canPlayType = function(type){
const origCPT = Html5.TEST_VID.canPlayType;
Html5.TEST_VID.canPlayType = function(type) {
if (type === 'video/mp4') {
return 'maybe';
}
return '';
};
var canHandleSource = Html5.nativeSourceHandler.canHandleSource;
const canHandleSource = Html5.nativeSourceHandler.canHandleSource;
equal(canHandleSource({ type: 'video/mp4', src: 'video.flv' }, {}), 'maybe', 'Native source handler reported type support');
equal(canHandleSource({ src: 'http://www.example.com/video.mp4' }, {}), 'maybe', 'Native source handler reported extension support');
equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo&token=bar' }, {}), 'maybe', 'Native source handler reported extension support');
equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo' }, {}), 'maybe', 'Native source handler reported extension support');
QUnit.equal(canHandleSource({ type: 'video/mp4', src: 'video.flv' }, {}),
'maybe',
'Native source handler reported type support');
QUnit.equal(canHandleSource({ src: 'http://www.example.com/video.mp4' }, {}),
'maybe',
'Native source handler reported extension support');
QUnit.equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo&token=bar' }, {}),
'maybe',
'Native source handler reported extension support');
QUnit.equal(canHandleSource({ src: 'https://example.com/video.sd.mp4?s=foo' }, {}),
'maybe',
'Native source handler reported extension support');
// Test for issue videojs/video.js#1785 and other potential failures
equal(canHandleSource({ src: '' }, {}), '', 'Native source handler handled empty src');
equal(canHandleSource({}, {}), '', 'Native source handler handled empty object');
equal(canHandleSource({ src: 'foo' }, {}), '', 'Native source handler handled bad src');
equal(canHandleSource({ type: 'foo' }, {}), '', 'Native source handler handled bad type');
QUnit.equal(canHandleSource({ src: '' }, {}),
'',
'Native source handler handled empty src');
QUnit.equal(canHandleSource({}, {}),
'',
'Native source handler handled empty object');
QUnit.equal(canHandleSource({ src: 'foo' }, {}),
'',
'Native source handler handled bad src');
QUnit.equal(canHandleSource({ type: 'foo' }, {}),
'',
'Native source handler handled bad type');
// Reset test video canPlayType
Html5.TEST_VID.canPlayType = origCPT;
});
if (Html5.supportsNativeTextTracks()) {
test('add native textTrack listeners on startup', function() {
let adds = [];
let rems = [];
let tt = {
QUnit.test('add native textTrack listeners on startup', function() {
const adds = [];
const rems = [];
const tt = {
length: 0,
addEventListener: (type, fn) => adds.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn])
};
let el = document.createElement('div');
const el = document.createElement('div');
el.textTracks = tt;
let htmlTech = new Html5({el});
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el});
/* eslint-enable no-unused-vars */
equal(adds[0][0], 'change', 'change event handler added');
equal(adds[1][0], 'addtrack', 'addtrack event handler added');
equal(adds[2][0], 'removetrack', 'removetrack event handler added');
QUnit.equal(adds[0][0], 'change', 'change event handler added');
QUnit.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
QUnit.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
});
test('remove all tracks from emulated list on dispose', function() {
let adds = [];
let rems = [];
let tt = {
QUnit.test('remove all tracks from emulated list on dispose', function() {
const adds = [];
const rems = [];
const tt = {
length: 0,
addEventListener: (type, fn) => adds.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn])
};
let el = document.createElement('div');
const el = document.createElement('div');
el.textTracks = tt;
let htmlTech = new Html5({el});
const htmlTech = new Html5({el});
htmlTech.dispose();
equal(adds[0][0], 'change', 'change event handler added');
equal(adds[1][0], 'addtrack', 'addtrack event handler added');
equal(adds[2][0], 'removetrack', 'removetrack event handler added');
equal(rems[0][0], 'change', 'change event handler removed');
equal(rems[1][0], 'addtrack', 'addtrack event handler removed');
equal(rems[2][0], 'removetrack', 'removetrack event handler removed');
equal(adds[0][0], rems[0][0], 'change event handler removed');
equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
QUnit.equal(adds[0][0], 'change', 'change event handler added');
QUnit.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
QUnit.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
QUnit.equal(rems[0][0], 'change', 'change event handler removed');
QUnit.equal(rems[1][0], 'addtrack', 'addtrack event handler removed');
QUnit.equal(rems[2][0], 'removetrack', 'removetrack event handler removed');
QUnit.equal(adds[0][0], rems[0][0], 'change event handler removed');
QUnit.equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
QUnit.equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
});
}
if (Html5.supportsNativeAudioTracks()) {
test('add native audioTrack listeners on startup', function() {
let adds = [];
let rems = [];
let at = {
QUnit.test('add native audioTrack listeners on startup', function() {
const adds = [];
const rems = [];
const at = {
length: 0,
addEventListener: (type, fn) => adds.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn])
};
let el = document.createElement('div');
const el = document.createElement('div');
el.audioTracks = at;
let htmlTech = new Html5({el});
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el});
/* eslint-enable no-unused-vars */
equal(adds[0][0], 'change', 'change event handler added');
equal(adds[1][0], 'addtrack', 'addtrack event handler added');
equal(adds[2][0], 'removetrack', 'removetrack event handler added');
QUnit.equal(adds[0][0], 'change', 'change event handler added');
QUnit.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
QUnit.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
});
test('remove all tracks from emulated list on dispose', function() {
let adds = [];
let rems = [];
let at = {
QUnit.test('remove all tracks from emulated list on dispose', function() {
const adds = [];
const rems = [];
const at = {
length: 0,
addEventListener: (type, fn) => adds.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn])
};
let el = document.createElement('div');
const el = document.createElement('div');
el.audioTracks = at;
let htmlTech = new Html5({el});
const htmlTech = new Html5({el});
htmlTech.dispose();
equal(adds[0][0], 'change', 'change event handler added');
equal(adds[1][0], 'addtrack', 'addtrack event handler added');
equal(adds[2][0], 'removetrack', 'removetrack event handler added');
equal(rems[0][0], 'change', 'change event handler removed');
equal(rems[1][0], 'addtrack', 'addtrack event handler removed');
equal(rems[2][0], 'removetrack', 'removetrack event handler removed');
equal(adds[0][0], rems[0][0], 'change event handler removed');
equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
QUnit.equal(adds[0][0], 'change', 'change event handler added');
QUnit.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
QUnit.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
QUnit.equal(rems[0][0], 'change', 'change event handler removed');
QUnit.equal(rems[1][0], 'addtrack', 'addtrack event handler removed');
QUnit.equal(rems[2][0], 'removetrack', 'removetrack event handler removed');
QUnit.equal(adds[0][0], rems[0][0], 'change event handler removed');
QUnit.equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
QUnit.equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
});
}
if (Html5.supportsNativeVideoTracks()) {
test('add native videoTrack listeners on startup', function() {
let adds = [];
let rems = [];
let vt = {
QUnit.test('add native videoTrack listeners on startup', function() {
const adds = [];
const rems = [];
const vt = {
length: 0,
addEventListener: (type, fn) => adds.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn])
};
let el = document.createElement('div');
const el = document.createElement('div');
el.videoTracks = vt;
let htmlTech = new Html5({el});
/* eslint-disable no-unused-vars */
const htmlTech = new Html5({el});
/* eslint-enable no-unused-vars */
equal(adds[0][0], 'change', 'change event handler added');
equal(adds[1][0], 'addtrack', 'addtrack event handler added');
equal(adds[2][0], 'removetrack', 'removetrack event handler added');
QUnit.equal(adds[0][0], 'change', 'change event handler added');
QUnit.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
QUnit.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
});
test('remove all tracks from emulated list on dispose', function() {
let adds = [];
let rems = [];
let vt = {
QUnit.test('remove all tracks from emulated list on dispose', function() {
const adds = [];
const rems = [];
const vt = {
length: 0,
addEventListener: (type, fn) => adds.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn]),
removeEventListener: (type, fn) => rems.push([type, fn])
};
let el = document.createElement('div');
const el = document.createElement('div');
el.videoTracks = vt;
let htmlTech = new Html5({el});
const htmlTech = new Html5({el});
htmlTech.dispose();
equal(adds[0][0], 'change', 'change event handler added');
equal(adds[1][0], 'addtrack', 'addtrack event handler added');
equal(adds[2][0], 'removetrack', 'removetrack event handler added');
equal(rems[0][0], 'change', 'change event handler removed');
equal(rems[1][0], 'addtrack', 'addtrack event handler removed');
equal(rems[2][0], 'removetrack', 'removetrack event handler removed');
equal(adds[0][0], rems[0][0], 'change event handler removed');
equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
QUnit.equal(adds[0][0], 'change', 'change event handler added');
QUnit.equal(adds[1][0], 'addtrack', 'addtrack event handler added');
QUnit.equal(adds[2][0], 'removetrack', 'removetrack event handler added');
QUnit.equal(rems[0][0], 'change', 'change event handler removed');
QUnit.equal(rems[1][0], 'addtrack', 'addtrack event handler removed');
QUnit.equal(rems[2][0], 'removetrack', 'removetrack event handler removed');
QUnit.equal(adds[0][0], rems[0][0], 'change event handler removed');
QUnit.equal(adds[1][0], rems[1][0], 'addtrack event handler removed');
QUnit.equal(adds[2][0], rems[2][0], 'removetrack event handler removed');
});
}
test('should always return currentSource_ if set', function(){
let currentSrc = Html5.prototype.currentSrc;
equal(currentSrc.call({el_: {currentSrc:'test1'}}), 'test1', 'sould return source from element if nothing else set');
equal(currentSrc.call({currentSource_:{src: 'test2'}}), 'test2', 'sould return source from currentSource_, if nothing else set');
equal(currentSrc.call({currentSource_:{src: 'test2'}, el_:{currentSrc:'test1'}}), 'test2', 'sould return source from source set, not from element');
QUnit.test('should always return currentSource_ if set', function() {
const currentSrc = Html5.prototype.currentSrc;
QUnit.equal(currentSrc.call({el_: {currentSrc: 'test1'}}),
'test1',
'sould return source from element if nothing else set');
QUnit.equal(currentSrc.call({currentSource_: {src: 'test2'}}),
'test2',
'sould return source from currentSource_, if nothing else set');
QUnit.equal(currentSrc.call({currentSource_: {src: 'test2'},
el_: {currentSrc: 'test1'}}),
'test2',
'sould return source from source set, not from element');
});
test('should fire makeup events when a video tag is initialized late', function(){
let lateInit = Html5.prototype.handleLateInit_;
QUnit.test('should fire makeup events when a video tag is initialized late', function() {
const lateInit = Html5.prototype.handleLateInit_;
let triggeredEvents = [];
let mockHtml5 = {
const mockHtml5 = {
readyListeners: [],
ready(listener){
ready(listener) {
this.readyListeners.push(listener);
},
triggerReady(){
this.readyListeners.forEach(function(listener){
triggerReady() {
this.readyListeners.forEach(function(listener) {
listener.call(this);
}, this);
},
trigger(type){
trigger(type) {
triggeredEvents.push(type);
},
on: function(){},
off: function(){}
on() {},
off() {}
};
function resetMock() {
triggeredEvents = {};
mockHtml5.readyListeners = [];
}
function testStates(statesObject, expectedEvents) {
lateInit.call(mockHtml5, statesObject);
mockHtml5.triggerReady();
deepEqual(triggeredEvents, expectedEvents, `wrong events triggered for networkState:${statesObject.networkState} and readyState:${statesObject.readyState || 'no readyState'}`);
QUnit.deepEqual(triggeredEvents,
expectedEvents,
'wrong events triggered for ' +
`networkState:${statesObject.networkState} ` +
`and readyState:${statesObject.readyState || 'no readyState'}`);
// reset mock
triggeredEvents = [];
@ -391,19 +459,21 @@ test('should fire makeup events when a video tag is initialized late', function(
// Ready States
testStates({ networkState: 1, readyState: 0 }, ['loadstart']);
testStates({ networkState: 1, readyState: 1 }, ['loadstart', 'loadedmetadata']);
testStates({ networkState: 1, readyState: 2 }, ['loadstart', 'loadedmetadata', 'loadeddata']);
testStates({ networkState: 1, readyState: 3 }, ['loadstart', 'loadedmetadata', 'loadeddata', 'canplay']);
testStates({ networkState: 1, readyState: 4 }, ['loadstart', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough']);
testStates({ networkState: 1, readyState: 2 },
['loadstart', 'loadedmetadata', 'loadeddata']);
testStates({ networkState: 1, readyState: 3 },
['loadstart', 'loadedmetadata', 'loadeddata', 'canplay']);
testStates({ networkState: 1, readyState: 4 },
['loadstart', 'loadedmetadata', 'loadeddata', 'canplay', 'canplaythrough']);
});
test('Html5.resetMediaElement should remove sources and call load', function() {
QUnit.test('Html5.resetMediaElement should remove sources and call load', function() {
let selector;
let removedChildren = [];
const removedChildren = [];
let removedAttribute;
let loaded;
let children = ['source1', 'source2', 'source3'];
let testEl = {
const children = ['source1', 'source2', 'source3'];
const testEl = {
querySelectorAll(input) {
selector = input;
return children;
@ -423,22 +493,27 @@ test('Html5.resetMediaElement should remove sources and call load', function() {
};
Html5.resetMediaElement(testEl);
equal(selector, 'source', 'we got the source elements from the test el');
deepEqual(removedChildren, children.reverse(), 'we removed the children that were present');
equal(removedAttribute, 'src', 'we removed the src attribute');
ok(loaded, 'we called load on the element');
QUnit.equal(selector, 'source', 'we got the source elements from the test el');
QUnit.deepEqual(removedChildren,
children.reverse(),
'we removed the children that were present');
QUnit.equal(removedAttribute, 'src', 'we removed the src attribute');
QUnit.ok(loaded, 'we called load on the element');
});
test('Html5#reset calls Html5.resetMediaElement when called', function() {
let oldResetMedia = Html5.resetMediaElement;
QUnit.test('Html5#reset calls Html5.resetMediaElement when called', function() {
const oldResetMedia = Html5.resetMediaElement;
let resetEl;
Html5.resetMediaElement = (el) => resetEl = el;
Html5.resetMediaElement = (el) => {
resetEl = el;
};
const el = {};
let el = {};
Html5.prototype.reset.call({el_: el});
equal(resetEl, el, 'we called resetMediaElement with the tech\'s el');
QUnit.equal(resetEl, el, 'we called resetMediaElement with the tech\'s el');
Html5.resetMediaElement = oldResetMedia;
});

View File

@ -1,6 +1,5 @@
// Fake a media playback tech controller so that player tests
// can run without HTML5 or Flash, of which PhantomJS supports neither.
import Tech from '../../../src/js/tech/tech.js';
/**
@ -8,49 +7,82 @@ import Tech from '../../../src/js/tech/tech.js';
*/
class TechFaker extends Tech {
constructor(options, handleReady){
constructor(options, handleReady) {
super(options, handleReady);
this.triggerReady();
}
createEl() {
var el = super.createEl('div', {
const el = super.createEl('div', {
className: 'vjs-tech'
});
/*if (this.player().poster()) {
// transfer the poster image to mimic HTML
el.poster = this.player().poster();
}*/
return el;
}
// fake a poster attribute to mimic the video element
poster() { return this.el().poster; }
setPoster(val) { this.el().poster = val; }
poster() {
return this.el().poster;
}
setPoster(val) {
this.el().poster = val;
}
setControls(val) {}
currentTime() { return 0; }
seeking() { return false; }
src() { return 'movie.mp4'; }
volume() { return 0; }
muted() { return false; }
pause() { return false; }
paused() { return true; }
play() { this.trigger('play'); }
supportsFullScreen() { return false; }
buffered() { return {}; }
duration() { return {}; }
networkState() { return 0; }
readyState() { return 0; }
controls() { return false; }
currentTime() {
return 0;
}
seeking() {
return false;
}
src() {
return 'movie.mp4';
}
volume() {
return 0;
}
muted() {
return false;
}
pause() {
return false;
}
paused() {
return true;
}
play() {
this.trigger('play');
}
supportsFullScreen() {
return false;
}
buffered() {
return {};
}
duration() {
return {};
}
networkState() {
return 0;
}
readyState() {
return 0;
}
controls() {
return false;
}
// Support everything except for "video/unsupported-format"
static isSupported() { return true; }
static canPlayType(type) { return (type !== 'video/unsupported-format' ? 'maybe' : ''); }
static canPlaySource(srcObj) { return srcObj.type !== 'video/unsupported-format'; }
static isSupported() {
return true;
}
static canPlayType(type) {
return (type !== 'video/unsupported-format' ? 'maybe' : '');
}
static canPlaySource(srcObj) {
return srcObj.type !== 'video/unsupported-format';
}
}
Tech.registerTech('TechFaker', TechFaker);

View File

@ -1,5 +1,4 @@
var noop = function() {}, clock, oldTextTracks;
/* eslint-env qunit */
import Tech from '../../../src/js/tech/tech.js';
import Html5 from '../../../src/js/tech/html5.js';
import Flash from '../../../src/js/tech/flash.js';
@ -13,24 +12,25 @@ import TextTrack from '../../../src/js/tracks/text-track';
import AudioTrackList from '../../../src/js/tracks/audio-track-list';
import VideoTrackList from '../../../src/js/tracks/video-track-list';
import TextTrackList from '../../../src/js/tracks/text-track-list';
import sinon from 'sinon';
q.module('Media Tech', {
'setup': function() {
QUnit.module('Media Tech', {
setup() {
this.noop = function() {};
this.clock = sinon.useFakeTimers();
this.featuresProgessEvents = Tech.prototype['featuresProgessEvents'];
Tech.prototype['featuresProgressEvents'] = false;
this.featuresProgessEvents = Tech.prototype.featuresProgessEvents;
Tech.prototype.featuresProgressEvents = false;
},
'teardown': function() {
teardown() {
this.clock.restore();
Tech.prototype['featuresProgessEvents'] = this.featuresProgessEvents;
Tech.prototype.featuresProgessEvents = this.featuresProgessEvents;
}
});
test('should synthesize timeupdate events by default', function() {
var timeupdates = 0, tech;
QUnit.test('should synthesize timeupdate events by default', function() {
let timeupdates = 0;
const tech = new Tech();
tech = new Tech();
tech.on('timeupdate', function() {
timeupdates++;
});
@ -38,33 +38,36 @@ test('should synthesize timeupdate events by default', function() {
tech.trigger('play');
this.clock.tick(250);
equal(timeupdates, 1, 'triggered at least one timeupdate');
QUnit.equal(timeupdates, 1, 'triggered at least one timeupdate');
});
test('stops manual timeupdates while paused', function() {
var timeupdates = 0, tech, expected;
tech = new Tech();
QUnit.test('stops manual timeupdates while paused', function() {
let timeupdates = 0;
const tech = new Tech();
tech.on('timeupdate', function() {
timeupdates++;
});
tech.trigger('play');
this.clock.tick(10 * 250);
ok(timeupdates > 0, 'timeupdates fire during playback');
QUnit.ok(timeupdates > 0, 'timeupdates fire during playback');
tech.trigger('pause');
timeupdates = 0;
this.clock.tick(10 * 250);
equal(timeupdates, 0, 'timeupdates do not fire when paused');
QUnit.equal(timeupdates, 0, 'timeupdates do not fire when paused');
tech.trigger('play');
this.clock.tick(10 * 250);
ok(timeupdates > 0, 'timeupdates fire when playback resumes');
QUnit.ok(timeupdates > 0, 'timeupdates fire when playback resumes');
});
test('should synthesize progress events by default', function() {
var progresses = 0, bufferedPercent = 0.5, tech;
tech = new Tech();
QUnit.test('should synthesize progress events by default', function() {
let progresses = 0;
let bufferedPercent = 0.5;
const tech = new Tech();
tech.on('progress', function() {
progresses++;
});
@ -73,20 +76,21 @@ test('should synthesize progress events by default', function() {
};
this.clock.tick(500);
equal(progresses, 0, 'waits until ready');
QUnit.equal(progresses, 0, 'waits until ready');
tech.trigger('ready');
this.clock.tick(500);
equal(progresses, 1, 'triggered one event');
QUnit.equal(progresses, 1, 'triggered one event');
tech.trigger('ready');
bufferedPercent = 0.75;
this.clock.tick(500);
equal(progresses, 2, 'repeated readies are ok');
QUnit.equal(progresses, 2, 'repeated readies are ok');
});
test('dispose() should stop time tracking', function() {
var tech = new Tech();
QUnit.test('dispose() should stop time tracking', function() {
const tech = new Tech();
tech.dispose();
// progress and timeupdate events will throw exceptions after the
@ -94,34 +98,42 @@ test('dispose() should stop time tracking', function() {
try {
this.clock.tick(10 * 1000);
} catch (e) {
return equal(e, undefined, 'threw an exception');
return QUnit.equal(e, undefined, 'threw an exception');
}
ok(true, 'no exception was thrown');
QUnit.ok(true, 'no exception was thrown');
});
test('dispose() should clear all tracks that are passed when its created', function() {
var audioTracks = new AudioTrackList([new AudioTrack(), new AudioTrack()]);
var videoTracks = new VideoTrackList([new VideoTrack(), new VideoTrack()]);
var textTracks = new TextTrackList([new TextTrack({tech: {}}), new TextTrack({tech: {}})]);
QUnit.test('dispose() should clear all tracks that are passed when its created', function() {
const audioTracks = new AudioTrackList([new AudioTrack(), new AudioTrack()]);
const videoTracks = new VideoTrackList([new VideoTrack(), new VideoTrack()]);
const textTracks = new TextTrackList([new TextTrack({tech: {}}),
new TextTrack({tech: {}})]);
equal(audioTracks.length, 2, 'should have two audio tracks at the start');
equal(videoTracks.length, 2, 'should have two video tracks at the start');
equal(textTracks.length, 2, 'should have two text tracks at the start');
QUnit.equal(audioTracks.length, 2, 'should have two audio tracks at the start');
QUnit.equal(videoTracks.length, 2, 'should have two video tracks at the start');
QUnit.equal(textTracks.length, 2, 'should have two text tracks at the start');
var tech = new Tech({audioTracks, videoTracks, textTracks});
equal(tech.videoTracks().length, videoTracks.length, 'should hold video tracks that we passed');
equal(tech.audioTracks().length, audioTracks.length, 'should hold audio tracks that we passed');
equal(tech.textTracks().length, textTracks.length, 'should hold text tracks that we passed');
const tech = new Tech({audioTracks, videoTracks, textTracks});
QUnit.equal(tech.videoTracks().length,
videoTracks.length,
'should hold video tracks that we passed');
QUnit.equal(tech.audioTracks().length,
audioTracks.length,
'should hold audio tracks that we passed');
QUnit.equal(tech.textTracks().length,
textTracks.length,
'should hold text tracks that we passed');
tech.dispose();
equal(audioTracks.length, 0, 'should have zero audio tracks after dispose');
equal(videoTracks.length, 0, 'should have zero video tracks after dispose');
equal(textTracks.length, 0, 'should have zero text tracks after dispose');
QUnit.equal(audioTracks.length, 0, 'should have zero audio tracks after dispose');
QUnit.equal(videoTracks.length, 0, 'should have zero video tracks after dispose');
QUnit.equal(textTracks.length, 0, 'should have zero text tracks after dispose');
});
test('dispose() should clear all tracks that are added after creation', function() {
var tech = new Tech();
QUnit.test('dispose() should clear all tracks that are added after creation', function() {
const tech = new Tech();
tech.addRemoteTextTrack({});
tech.addRemoteTextTrack({});
@ -132,103 +144,140 @@ test('dispose() should clear all tracks that are added after creation', function
tech.videoTracks().addTrack_(new VideoTrack());
tech.videoTracks().addTrack_(new VideoTrack());
equal(tech.audioTracks().length, 2, 'should have two audio tracks at the start');
equal(tech.videoTracks().length, 2, 'should have two video tracks at the start');
equal(tech.textTracks().length, 2, 'should have two video tracks at the start');
equal(tech.remoteTextTrackEls().length, 2, 'should have two remote text tracks els');
equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
QUnit.equal(tech.audioTracks().length, 2, 'should have two audio tracks at the start');
QUnit.equal(tech.videoTracks().length, 2, 'should have two video tracks at the start');
QUnit.equal(tech.textTracks().length, 2, 'should have two video tracks at the start');
QUnit.equal(tech.remoteTextTrackEls().length,
2,
'should have two remote text tracks els');
QUnit.equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
tech.dispose();
equal(tech.audioTracks().length, 0, 'should have zero audio tracks after dispose');
equal(tech.videoTracks().length, 0, 'should have zero video tracks after dispose');
equal(tech.remoteTextTrackEls().length, 0, 'should have zero remote text tracks els');
equal(tech.remoteTextTracks().length, 0, 'should have zero remote text tracks');
equal(tech.textTracks().length, 0, 'should have zero video tracks after dispose');
QUnit.equal(tech.audioTracks().length,
0,
'should have zero audio tracks after dispose');
QUnit.equal(tech.videoTracks().length,
0,
'should have zero video tracks after dispose');
QUnit.equal(tech.remoteTextTrackEls().length,
0,
'should have zero remote text tracks els');
QUnit.equal(tech.remoteTextTracks().length, 0, 'should have zero remote text tracks');
QUnit.equal(tech.textTracks().length, 0, 'should have zero video tracks after dispose');
});
test('should add the source handler interface to a tech', function(){
var sourceA = { src: 'foo.mp4', type: 'video/mp4' };
var sourceB = { src: 'no-support', type: 'no-support' };
QUnit.test('should add the source handler interface to a tech', function() {
const sourceA = { src: 'foo.mp4', type: 'video/mp4' };
const sourceB = { src: 'no-support', type: 'no-support' };
// Define a new tech class
var MyTech = extendFn(Tech);
const MyTech = extendFn(Tech);
// Extend Tech with source handlers
Tech.withSourceHandlers(MyTech);
// Check for the expected class methods
ok(MyTech.registerSourceHandler, 'added a registerSourceHandler function to the Tech');
ok(MyTech.selectSourceHandler, 'added a selectSourceHandler function to the Tech');
QUnit.ok(MyTech.registerSourceHandler,
'added a registerSourceHandler function to the Tech');
QUnit.ok(MyTech.selectSourceHandler,
'added a selectSourceHandler function to the Tech');
// Create an instance of Tech
var tech = new MyTech();
const tech = new MyTech();
// Check for the expected instance methods
ok(tech.setSource, 'added a setSource function to the tech instance');
QUnit.ok(tech.setSource, 'added a setSource function to the tech instance');
// Create an internal state class for the source handler
// The internal class would be used by a source handler to maintain state
// and provde a dispose method for the handler.
// This is optional for source handlers
var disposeCalled = false;
var handlerInternalState = function(){};
handlerInternalState.prototype.dispose = function(){
let disposeCalled = false;
const HandlerInternalState = function() {};
HandlerInternalState.prototype.dispose = function() {
disposeCalled = true;
};
// Create source handlers
var handlerOne = {
canPlayType: function(type){
if (type !=='no-support') {
const handlerOne = {
canPlayType(type) {
if (type !== 'no-support') {
return 'probably';
}
return '';
},
canHandleSource: function(source, options){
strictEqual(tech.options_, options, 'the tech options were passed to the source handler canHandleSource');
if (source.type !=='no-support') {
canHandleSource(source, options) {
QUnit.strictEqual(tech.options_,
options,
'tech options passed to canHandleSource');
if (source.type !== 'no-support') {
return 'probably';
}
return '';
},
handleSource: function(s, t, o){
strictEqual(tech, t, 'the tech instance was passed to the source handler');
strictEqual(sourceA, s, 'the tech instance was passed to the source handler');
strictEqual(tech.options_, o, 'the tech options were passed to the source handler handleSource');
return new handlerInternalState();
handleSource(s, t, o) {
QUnit.strictEqual(tech,
t,
'tech instance passed to source handler');
QUnit.strictEqual(sourceA,
s,
'tech instance passed to the source handler');
QUnit.strictEqual(tech.options_,
o,
'tech options passed to the source handler handleSource');
return new HandlerInternalState();
}
};
var handlerTwo = {
canPlayType: function(type){
return ''; // no support
const handlerTwo = {
canPlayType(type) {
// no support
return '';
},
canHandleSource: function(source, options){
return ''; // no support
canHandleSource(source, options) {
// no support
return '';
},
handleSource: function(source, tech, options){
ok(false, 'handlerTwo supports nothing and should never be called');
handleSource(source, tech_, options) {
QUnit.ok(false, 'handlerTwo supports nothing and should never be called');
}
};
// Test registering source handlers
MyTech.registerSourceHandler(handlerOne);
strictEqual(MyTech.sourceHandlers[0], handlerOne, 'handlerOne was added to the source handler array');
QUnit.strictEqual(MyTech.sourceHandlers[0],
handlerOne,
'handlerOne was added to the source handler array');
MyTech.registerSourceHandler(handlerTwo, 0);
strictEqual(MyTech.sourceHandlers[0], handlerTwo, 'handlerTwo was registered at the correct index (0)');
QUnit.strictEqual(MyTech.sourceHandlers[0],
handlerTwo,
'handlerTwo was registered at the correct index (0)');
// Test handler selection
strictEqual(MyTech.selectSourceHandler(sourceA, tech.options_), handlerOne, 'handlerOne was selected to handle the valid source');
strictEqual(MyTech.selectSourceHandler(sourceB, tech.options_), null, 'no handler was selected to handle the invalid source');
QUnit.strictEqual(MyTech.selectSourceHandler(sourceA, tech.options_),
handlerOne,
'handlerOne was selected to handle the valid source');
QUnit.strictEqual(MyTech.selectSourceHandler(sourceB, tech.options_),
null,
'no handler was selected to handle the invalid source');
// Test canPlayType return values
strictEqual(MyTech.canPlayType(sourceA.type), 'probably', 'the Tech returned probably for the valid source');
strictEqual(MyTech.canPlayType(sourceB.type), '', 'the Tech returned an empty string for the invalid source');
QUnit.strictEqual(MyTech.canPlayType(sourceA.type),
'probably',
'the Tech returned probably for the valid source');
QUnit.strictEqual(MyTech.canPlayType(sourceB.type),
'',
'the Tech returned an empty string for the invalid source');
// Test canPlaySource return values
strictEqual(MyTech.canPlaySource(sourceA, tech.options_), 'probably', 'the Tech returned probably for the valid source');
strictEqual(MyTech.canPlaySource(sourceB, tech.options_), '', 'the Tech returned an empty string for the invalid source');
QUnit.strictEqual(MyTech.canPlaySource(sourceA, tech.options_),
'probably',
'the Tech returned probably for the valid source');
QUnit.strictEqual(MyTech.canPlaySource(sourceB, tech.options_),
'',
'the Tech returned an empty string for the invalid source');
tech.addRemoteTextTrack({});
tech.addRemoteTextTrack({});
@ -239,155 +288,169 @@ test('should add the source handler interface to a tech', function(){
tech.videoTracks().addTrack_(new VideoTrack());
tech.videoTracks().addTrack_(new VideoTrack());
equal(tech.audioTracks().length, 2, 'should have two audio tracks at the start');
equal(tech.videoTracks().length, 2, 'should have two video tracks at the start');
equal(tech.textTracks().length, 2, 'should have two video tracks at the start');
equal(tech.remoteTextTrackEls().length, 2, 'should have two remote text tracks els');
equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
QUnit.equal(tech.audioTracks().length, 2, 'should have two audio tracks at the start');
QUnit.equal(tech.videoTracks().length, 2, 'should have two video tracks at the start');
QUnit.equal(tech.textTracks().length, 2, 'should have two video tracks at the start');
QUnit.equal(tech.remoteTextTrackEls().length,
2,
'should have two remote text tracks els');
QUnit.equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
// Pass a source through the source handler process of a tech instance
tech.setSource(sourceA);
// verify that the Tracks are still there
equal(tech.audioTracks().length, 2, 'should have two audio tracks at the start');
equal(tech.videoTracks().length, 2, 'should have two video tracks at the start');
equal(tech.textTracks().length, 2, 'should have two video tracks at the start');
equal(tech.remoteTextTrackEls().length, 2, 'should have two remote text tracks els');
equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
QUnit.equal(tech.audioTracks().length, 2, 'should have two audio tracks at the start');
QUnit.equal(tech.videoTracks().length, 2, 'should have two video tracks at the start');
QUnit.equal(tech.textTracks().length, 2, 'should have two video tracks at the start');
QUnit.equal(tech.remoteTextTrackEls().length,
2,
'should have two remote text tracks els');
QUnit.equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
strictEqual(tech.currentSource_, sourceA, 'sourceA was handled and stored');
ok(tech.sourceHandler_.dispose, 'the handlerOne state instance was stored');
QUnit.strictEqual(tech.currentSource_, sourceA, 'sourceA was handled and stored');
QUnit.ok(tech.sourceHandler_.dispose, 'the handlerOne state instance was stored');
// Pass a second source
tech.setSource(sourceA);
strictEqual(tech.currentSource_, sourceA, 'sourceA was handled and stored');
ok(tech.sourceHandler_.dispose, 'the handlerOne state instance was stored');
QUnit.strictEqual(tech.currentSource_, sourceA, 'sourceA was handled and stored');
QUnit.ok(tech.sourceHandler_.dispose, 'the handlerOne state instance was stored');
// verify that all the tracks were removed as we got a new source
equal(tech.audioTracks().length, 0, 'should have zero audio tracks');
equal(tech.videoTracks().length, 0, 'should have zero video tracks');
equal(tech.textTracks().length, 2, 'should have two text tracks');
equal(tech.remoteTextTrackEls().length, 2, 'should have two remote text tracks els');
equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
QUnit.equal(tech.audioTracks().length, 0, 'should have zero audio tracks');
QUnit.equal(tech.videoTracks().length, 0, 'should have zero video tracks');
QUnit.equal(tech.textTracks().length, 2, 'should have two text tracks');
QUnit.equal(tech.remoteTextTrackEls().length,
2,
'should have two remote text tracks els');
QUnit.equal(tech.remoteTextTracks().length, 2, 'should have two remote text tracks');
// Check that the handler dipose method works
ok(disposeCalled, 'dispose has been called for the handler yet');
QUnit.ok(disposeCalled, 'dispose has been called for the handler yet');
disposeCalled = false;
tech.dispose();
ok(disposeCalled, 'the handler dispose method was called when the tech was disposed');
QUnit.ok(disposeCalled,
'the handler dispose method was called when the tech was disposed');
});
test('should handle unsupported sources with the source handler API', function(){
QUnit.test('should handle unsupported sources with the source handler API', function() {
// Define a new tech class
var MyTech = extendFn(Tech);
const MyTech = extendFn(Tech);
// Extend Tech with source handlers
Tech.withSourceHandlers(MyTech);
// Create an instance of Tech
var tech = new MyTech();
const tech = new MyTech();
let usedNative;
var usedNative;
MyTech.nativeSourceHandler = {
handleSource: function(){ usedNative = true; }
handleSource() {
usedNative = true;
}
};
tech.setSource('');
ok(usedNative, 'native source handler was used when an unsupported source was set');
QUnit.ok(usedNative,
'native source handler was used when an unsupported source was set');
});
test('should allow custom error events to be set', function() {
let tech = new Tech();
let errors = [];
QUnit.test('should allow custom error events to be set', function() {
const tech = new Tech();
const errors = [];
tech.on('error', function() {
errors.push(tech.error());
});
equal(tech.error(), null, 'error is null by default');
QUnit.equal(tech.error(), null, 'error is null by default');
tech.error(new MediaError(1));
equal(errors.length, 1, 'triggered an error event');
equal(errors[0].code, 1, 'set the proper code');
QUnit.equal(errors.length, 1, 'triggered an error event');
QUnit.equal(errors[0].code, 1, 'set the proper code');
tech.error(2);
equal(errors.length, 2, 'triggered an error event');
equal(errors[1].code, 2, 'wrapped the error code');
QUnit.equal(errors.length, 2, 'triggered an error event');
QUnit.equal(errors[1].code, 2, 'wrapped the error code');
});
test('should track whether a video has played', function() {
let tech = new Tech();
QUnit.test('should track whether a video has played', function() {
const tech = new Tech();
equal(tech.played().length, 0, 'starts with zero length');
QUnit.equal(tech.played().length, 0, 'starts with zero length');
tech.trigger('playing');
equal(tech.played().length, 1, 'has length after playing');
QUnit.equal(tech.played().length, 1, 'has length after playing');
});
test('delegates seekable to the source handler', function(){
let MyTech = extendFn(Tech, {
seekable: function() {
QUnit.test('delegates seekable to the source handler', function() {
const MyTech = extendFn(Tech, {
seekable() {
throw new Error('You should not be calling me!');
}
});
Tech.withSourceHandlers(MyTech);
let seekableCount = 0;
let handler = {
seekable: function() {
const handler = {
seekable() {
seekableCount++;
return createTimeRange(0, 0);
}
};
MyTech.registerSourceHandler({
canPlayType: function() {
canPlayType() {
return true;
},
canHandleSource: function() {
canHandleSource() {
return true;
},
handleSource: function(source, tech, options) {
handleSource(source, tech, options) {
return handler;
}
});
let tech = new MyTech();
const tech = new MyTech();
tech.setSource({
src: 'example.mp4',
type: 'video/mp4'
});
tech.seekable();
equal(seekableCount, 1, 'called the source handler');
QUnit.equal(seekableCount, 1, 'called the source handler');
});
test('Tech.isTech returns correct answers for techs and components', function() {
let isTech = Tech.isTech;
QUnit.test('Tech.isTech returns correct answers for techs and components', function() {
const isTech = Tech.isTech;
ok(isTech(Tech), 'Tech is a Tech');
ok(isTech(Html5), 'Html5 is a Tech');
ok(isTech(new Html5({}, {})), 'An html5 instance is a Tech');
ok(isTech(Flash), 'Flash is a Tech');
ok(!isTech(5), 'A number is not a Tech');
ok(!isTech('this is a tech'), 'A string is not a Tech');
ok(!isTech(Button), 'A Button is not a Tech');
ok(!isTech(new Button({}, {})), 'A Button instance is not a Tech');
ok(!isTech(isTech), 'A function is not a Tech');
QUnit.ok(isTech(Tech), 'Tech is a Tech');
QUnit.ok(isTech(Html5), 'Html5 is a Tech');
QUnit.ok(isTech(new Html5({}, {})), 'An html5 instance is a Tech');
QUnit.ok(isTech(Flash), 'Flash is a Tech');
QUnit.ok(!isTech(5), 'A number is not a Tech');
QUnit.ok(!isTech('this is a tech'), 'A string is not a Tech');
QUnit.ok(!isTech(Button), 'A Button is not a Tech');
QUnit.ok(!isTech(new Button({}, {})), 'A Button instance is not a Tech');
QUnit.ok(!isTech(isTech), 'A function is not a Tech');
});
test('Tech#setSource clears currentSource_ after repeated loadstart', function() {
QUnit.test('Tech#setSource clears currentSource_ after repeated loadstart', function() {
let disposed = false;
let MyTech = extendFn(Tech);
const MyTech = extendFn(Tech);
Tech.withSourceHandlers(MyTech);
let tech = new MyTech();
const tech = new MyTech();
var sourceHandler = {
canPlayType: function(type) {
const sourceHandler = {
canPlayType(type) {
return true;
},
canHandleSource: function(source, options) {
canHandleSource(source, options) {
return true;
},
handleSource: function(source, tech, options) {
handleSource(source, tech_, options) {
return {
dispose: function() {
dispose() {
disposed = true;
}
};
@ -401,95 +464,98 @@ test('Tech#setSource clears currentSource_ after repeated loadstart', function()
tech.setSource('test');
tech.currentSource_ = 'test';
tech.trigger('loadstart');
equal(tech.currentSource_, 'test', 'Current source is test');
QUnit.equal(tech.currentSource_, 'test', 'Current source is test');
// Second loadstart
tech.trigger('loadstart');
equal(tech.currentSource_, null, 'Current source is null');
equal(disposed, true, 'disposed is true');
QUnit.equal(tech.currentSource_, null, 'Current source is null');
QUnit.equal(disposed, true, 'disposed is true');
// Third loadstart
tech.currentSource_ = 'test';
tech.trigger('loadstart');
equal(tech.currentSource_, null, 'Current source is still null');
QUnit.equal(tech.currentSource_, null, 'Current source is still null');
});
test('setSource after tech dispose should dispose source handler once', function(){
let MyTech = extendFn(Tech);
QUnit.test('setSource after tech dispose should dispose source handler once', function() {
const MyTech = extendFn(Tech);
Tech.withSourceHandlers(MyTech);
let disposeCount = 0;
let handler = {
const handler = {
dispose() {
disposeCount++;
}
};
MyTech.registerSourceHandler({
canPlayType: function() {
canPlayType() {
return true;
},
canHandleSource: function() {
canHandleSource() {
return true;
},
handleSource: function(source, tech, options) {
handleSource(source, tech, options) {
return handler;
}
});
let tech = new MyTech();
const tech = new MyTech();
tech.setSource('test');
equal(disposeCount, 0, 'did not call sourceHandler_ dispose for initial dispose');
QUnit.equal(disposeCount, 0, 'did not call sourceHandler_ dispose for initial dispose');
tech.dispose();
ok(!tech.sourceHandler_, 'sourceHandler should be unset');
equal(disposeCount, 1, 'called the source handler dispose');
QUnit.ok(!tech.sourceHandler_, 'sourceHandler should be unset');
QUnit.equal(disposeCount, 1, 'called the source handler dispose');
// this would normally be done above tech on src after dispose
tech.el_ = tech.createEl();
tech.setSource('test');
equal(disposeCount, 1, 'did not dispose after initial setSource');
QUnit.equal(disposeCount, 1, 'did not dispose after initial setSource');
tech.setSource('test');
equal(disposeCount, 2, 'did dispose on second setSource');
QUnit.equal(disposeCount, 2, 'did dispose on second setSource');
});
test('setSource after previous setSource should dispose source handler once', function(){
let MyTech = extendFn(Tech);
QUnit.test('setSource after previous setSource should dispose source handler once', function() {
const MyTech = extendFn(Tech);
Tech.withSourceHandlers(MyTech);
let disposeCount = 0;
let handler = {
const handler = {
dispose() {
disposeCount++;
}
};
MyTech.registerSourceHandler({
canPlayType: function() {
canPlayType() {
return true;
},
canHandleSource: function() {
canHandleSource() {
return true;
},
handleSource: function(source, tech, options) {
handleSource(source, tech, options) {
return handler;
}
});
let tech = new MyTech();
const tech = new MyTech();
tech.setSource('test');
equal(disposeCount, 0, 'did not call dispose for initial setSource');
QUnit.equal(disposeCount, 0, 'did not call dispose for initial setSource');
tech.setSource('test');
equal(disposeCount, 1, 'did dispose for second setSource');
QUnit.equal(disposeCount, 1, 'did dispose for second setSource');
tech.setSource('test');
equal(disposeCount, 2, 'did dispose for third setSource');
QUnit.equal(disposeCount, 2, 'did dispose for third setSource');
});

View File

@ -1,32 +1,30 @@
import * as Dom from '../../src/js/utils/dom';
import Player from '../../src/js/player.js';
import TechFaker from './tech/tech-faker.js';
import window from 'global/window';
import document from 'global/document';
var TestHelpers = {
makeTag: function(){
var videoTag = document.createElement('video');
const TestHelpers = {
makeTag() {
const videoTag = document.createElement('video');
videoTag.id = 'example_1';
videoTag.className = 'video-js vjs-default-skin';
return videoTag;
},
makePlayer: function(playerOptions, videoTag){
var player;
makePlayer(playerOptions, videoTag) {
videoTag = videoTag || TestHelpers.makeTag();
var fixture = document.getElementById('qunit-fixture');
const fixture = document.getElementById('qunit-fixture');
fixture.appendChild(videoTag);
playerOptions = playerOptions || {};
playerOptions['techOrder'] = playerOptions['techOrder'] || ['techFaker'];
playerOptions.techOrder = playerOptions.techOrder || ['techFaker'];
return player = new Player(videoTag, playerOptions);
return new Player(videoTag, playerOptions);
},
getComputedStyle: function(el, rule){
getComputedStyle(el, rule) {
if (document.defaultView && document.defaultView.getComputedStyle) {
return document.defaultView.getComputedStyle(el, null).getPropertyValue(rule);
}
@ -37,9 +35,8 @@ var TestHelpers = {
// return clientWidth or clientHeight instead for better accuracy
rule = 'client' + rule.substr(0, 1).toUpperCase() + rule.substr(1);
return el[rule] + 'px';
} else {
return el.currentStyle[rule];
}
return el.currentStyle[rule];
}
},
@ -73,45 +70,53 @@ var TestHelpers = {
* reference how many assertions will be run (e.g. for use
* with `assert.expect()`).
*/
assertEl: function(assert, el, spec) {
let attrs = spec.attrs ? Object.keys(spec.attrs) : [];
let classes = spec.classes || [];
let innerHTML = spec.innerHTML ? spec.innerHTML.trim() : '';
let props = spec.props ? Object.keys(spec.props) : [];
let tagName = spec.tagName ? spec.tagName.toLowerCase() : '';
assertEl(assert, el, spec) {
const attrs = spec.attrs ? Object.keys(spec.attrs) : [];
const classes = spec.classes || [];
const innerHTML = spec.innerHTML ? spec.innerHTML.trim() : '';
const props = spec.props ? Object.keys(spec.props) : [];
const tagName = spec.tagName ? spec.tagName.toLowerCase() : '';
// Return value is a function, which runs through all the combined
// assertions. This is done so that the count can be attached dynamically
// and run whenever desired.
let run = () => {
const run = () => {
if (tagName) {
let elTagName = el.tagName.toLowerCase();
let msg = `el should have been a <${tagName}> and was a <${elTagName}>`;
const elTagName = el.tagName.toLowerCase();
const msg = `el should have been a <${tagName}> and was a <${elTagName}>`;
assert.strictEqual(elTagName, tagName, msg);
}
if (innerHTML) {
let elInnerHTML = el.innerHTML.trim();
let msg = `el should have expected HTML content`;
const elInnerHTML = el.innerHTML.trim();
const msg = 'el should have expected HTML content';
assert.strictEqual(elInnerHTML, innerHTML, msg);
}
attrs.forEach(a => {
let actual = el.getAttribute(a);
let expected = spec.attrs[a];
let msg = `el should have the "${a}" attribute with the value "${expected}" and it was "${actual}"`;
const actual = el.getAttribute(a);
const expected = spec.attrs[a];
const msg = `el should have the "${a}" attribute with ` +
`the value "${expected}" and it was "${actual}"`;
assert.strictEqual(actual, expected, msg);
});
classes.forEach(c => {
let msg = `el should have the "${c}" class in its className, which is "${el.className}"`;
const msg = `el should have the "${c}" class in its ` +
`className, which is "${el.className}"`;
assert.ok(Dom.hasElClass(el, c), msg);
});
props.forEach(p => {
let actual = el[p];
let expected = spec.props[p];
let msg = `el should have the "${p}" property with the value "${expected}" and it was "${actual}"`;
const actual = el[p];
const expected = spec.props[p];
const msg = `el should have the "${p}" property with the ` +
`value "${expected}" and it was "${actual}"`;
assert.strictEqual(actual, expected, msg);
});
};

View File

@ -7,13 +7,13 @@ import document from 'global/document';
QUnit.module('Text Track List Converter', {});
let clean = (item) => {
const clean = (item) => {
delete item.id;
delete item.inBandMetadataTrackDispatchType;
delete item.cues;
};
let cleanup = (item) => {
const cleanup = (item) => {
if (Array.isArray(item)) {
item.forEach(clean);
} else {
@ -25,7 +25,7 @@ let cleanup = (item) => {
if (Html5.supportsNativeTextTracks()) {
QUnit.test('trackToJson_ produces correct representation for native track object', function(a) {
let track = document.createElement('track');
const track = document.createElement('track');
track.src = 'example.com/english.vtt';
track.kind = 'captions';
@ -41,25 +41,25 @@ if (Html5.supportsNativeTextTracks()) {
});
QUnit.test('textTracksToJson produces good json output', function(a) {
let emulatedTrack = new TextTrack({
const emulatedTrack = new TextTrack({
kind: 'captions',
label: 'English',
language: 'en',
tech: {}
});
let nativeTrack = document.createElement('track');
const nativeTrack = document.createElement('track');
nativeTrack.kind = 'captions';
nativeTrack.srclang = 'es';
nativeTrack.label = 'Spanish';
let tt = new TextTrackList();
const tt = new TextTrackList();
tt.addTrack_(nativeTrack.track);
tt.addTrack_(emulatedTrack);
let tech = {
const tech = {
$$() {
return [nativeTrack];
},
@ -90,7 +90,7 @@ if (Html5.supportsNativeTextTracks()) {
});
QUnit.test('jsonToTextTracks calls addRemoteTextTrack on the tech with mixed tracks', function(a) {
let emulatedTrack = new TextTrack({
const emulatedTrack = new TextTrack({
kind: 'captions',
label: 'English',
language: 'en',
@ -98,20 +98,20 @@ if (Html5.supportsNativeTextTracks()) {
tech: {}
});
let nativeTrack = document.createElement('track');
const nativeTrack = document.createElement('track');
nativeTrack.src = 'example.com/spanish.vtt';
nativeTrack.kind = 'captions';
nativeTrack.srclang = 'es';
nativeTrack.label = 'Spanish';
let tt = new TextTrackList();
const tt = new TextTrackList();
tt.addTrack_(nativeTrack.track);
tt.addTrack_(emulatedTrack);
let addRemotes = 0;
let tech = {
const tech = {
$$() {
return [nativeTrack];
},
@ -141,7 +141,7 @@ if (Html5.supportsNativeTextTracks()) {
}
QUnit.test('trackToJson_ produces correct representation for emulated track object', function(a) {
let track = new TextTrack({
const track = new TextTrack({
kind: 'captions',
label: 'English',
language: 'en',
@ -159,7 +159,7 @@ QUnit.test('trackToJson_ produces correct representation for emulated track obje
});
QUnit.test('textTracksToJson produces good json output for emulated only', function(a) {
let emulatedTrack = new TextTrack({
const emulatedTrack = new TextTrack({
kind: 'captions',
label: 'English',
language: 'en',
@ -167,7 +167,7 @@ QUnit.test('textTracksToJson produces good json output for emulated only', funct
tech: {}
});
let anotherTrack = new TextTrack({
const anotherTrack = new TextTrack({
src: 'example.com/spanish.vtt',
kind: 'captions',
srclang: 'es',
@ -175,12 +175,12 @@ QUnit.test('textTracksToJson produces good json output for emulated only', funct
tech: {}
});
let tt = new TextTrackList();
const tt = new TextTrackList();
tt.addTrack_(anotherTrack);
tt.addTrack_(emulatedTrack);
let tech = {
const tech = {
$$() {
return [];
},
@ -213,7 +213,7 @@ QUnit.test('textTracksToJson produces good json output for emulated only', funct
});
QUnit.test('jsonToTextTracks calls addRemoteTextTrack on the tech with emulated tracks only', function(a) {
let emulatedTrack = new TextTrack({
const emulatedTrack = new TextTrack({
kind: 'captions',
label: 'English',
language: 'en',
@ -221,7 +221,7 @@ QUnit.test('jsonToTextTracks calls addRemoteTextTrack on the tech with emulated
tech: {}
});
let anotherTrack = new TextTrack({
const anotherTrack = new TextTrack({
src: 'example.com/spanish.vtt',
kind: 'captions',
srclang: 'es',
@ -229,13 +229,13 @@ QUnit.test('jsonToTextTracks calls addRemoteTextTrack on the tech with emulated
tech: {}
});
let tt = new TextTrackList();
const tt = new TextTrackList();
tt.addTrack_(anotherTrack);
tt.addTrack_(emulatedTrack);
let addRemotes = 0;
let tech = {
const tech = {
$$() {
return [];
},

View File

@ -1,21 +1,22 @@
/* eslint-env qunit */
import window from 'global/window';
import EventTarget from '../../../src/js/event-target.js';
import TrackBaseline from './track-baseline';
import TechFaker from '../tech/tech-faker';
import TextTrack from '../../../src/js/tracks/text-track.js';
import TestHelpers from '../test-helpers.js';
import log from '../../../src/js/utils/log.js';
import proxyquireify from 'proxyquireify';
import sinon from 'sinon';
const proxyquire = proxyquireify(require);
const defaultTech = {
textTracks() {},
on() {},
off() {},
currentTime() {}
};
q.module('Text Track');
QUnit.module('Text Track');
// do baseline track testing
TrackBaseline(TextTrack, {
@ -27,193 +28,189 @@ TrackBaseline(TextTrack, {
tech: defaultTech
});
test('requires a tech', function() {
let error = new Error('A tech was not provided.');
QUnit.test('requires a tech', function() {
const error = new Error('A tech was not provided.');
q.throws(() => new TextTrack({}), error, 'a tech is required');
q.throws(() => new TextTrack({tech: null}), error, 'a tech is required');
QUnit.throws(() => new TextTrack({}), error, 'a tech is required');
QUnit.throws(() => new TextTrack({tech: null}), error, 'a tech is required');
});
test('can create a TextTrack with a mode property', function() {
let mode = 'disabled';
let tt = new TextTrack({
QUnit.test('can create a TextTrack with a mode property', function() {
const mode = 'disabled';
const tt = new TextTrack({
mode,
tech: defaultTech
});
equal(tt.mode, mode, 'we have a mode');
QUnit.equal(tt.mode, mode, 'we have a mode');
});
test('defaults when items not provided', function() {
let tt = new TextTrack({
QUnit.test('defaults when items not provided', function() {
const tt = new TextTrack({
tech: TechFaker
});
equal(tt.kind, 'subtitles', 'kind defaulted to subtitles');
equal(tt.mode, 'disabled', 'mode defaulted to disabled');
equal(tt.label, '', 'label defaults to empty string');
equal(tt.language, '', 'language defaults to empty string');
QUnit.equal(tt.kind, 'subtitles', 'kind defaulted to subtitles');
QUnit.equal(tt.mode, 'disabled', 'mode defaulted to disabled');
QUnit.equal(tt.label, '', 'label defaults to empty string');
QUnit.equal(tt.language, '', 'language defaults to empty string');
});
test('kind can only be one of several options, defaults to subtitles', function() {
QUnit.test('kind can only be one of several options, defaults to subtitles', function() {
let tt = new TextTrack({
tech: defaultTech,
kind: 'foo'
});
equal(tt.kind, 'subtitles', 'the kind is set to subtitles, not foo');
notEqual(tt.kind, 'foo', 'the kind is set to subtitles, not foo');
QUnit.equal(tt.kind, 'subtitles', 'the kind is set to subtitles, not foo');
QUnit.notEqual(tt.kind, 'foo', 'the kind is set to subtitles, not foo');
tt = new TextTrack({
tech: defaultTech,
kind: 'subtitles'
});
equal(tt.kind, 'subtitles', 'the kind is set to subtitles');
QUnit.equal(tt.kind, 'subtitles', 'the kind is set to subtitles');
tt = new TextTrack({
tech: defaultTech,
kind: 'captions'
});
equal(tt.kind, 'captions', 'the kind is set to captions');
QUnit.equal(tt.kind, 'captions', 'the kind is set to captions');
tt = new TextTrack({
tech: defaultTech,
kind: 'descriptions'
});
equal(tt.kind, 'descriptions', 'the kind is set to descriptions');
QUnit.equal(tt.kind, 'descriptions', 'the kind is set to descriptions');
tt = new TextTrack({
tech: defaultTech,
kind: 'chapters'
});
equal(tt.kind, 'chapters', 'the kind is set to chapters');
QUnit.equal(tt.kind, 'chapters', 'the kind is set to chapters');
tt = new TextTrack({
tech: defaultTech,
kind: 'metadata'
});
equal(tt.kind, 'metadata', 'the kind is set to metadata');
QUnit.equal(tt.kind, 'metadata', 'the kind is set to metadata');
});
test('mode can only be one of several options, defaults to disabled', function() {
QUnit.test('mode can only be one of several options, defaults to disabled', function() {
let tt = new TextTrack({
tech: defaultTech,
mode: 'foo'
});
equal(tt.mode, 'disabled', 'the mode is set to disabled, not foo');
notEqual(tt.mode, 'foo', 'the mode is set to disabld, not foo');
QUnit.equal(tt.mode, 'disabled', 'the mode is set to disabled, not foo');
QUnit.notEqual(tt.mode, 'foo', 'the mode is set to disabld, not foo');
tt = new TextTrack({
tech: defaultTech,
mode: 'disabled'
});
equal(tt.mode, 'disabled', 'the mode is set to disabled');
QUnit.equal(tt.mode, 'disabled', 'the mode is set to disabled');
tt = new TextTrack({
tech: defaultTech,
mode: 'hidden'
});
equal(tt.mode, 'hidden', 'the mode is set to hidden');
QUnit.equal(tt.mode, 'hidden', 'the mode is set to hidden');
tt = new TextTrack({
tech: defaultTech,
mode: 'showing'
});
equal(tt.mode, 'showing', 'the mode is set to showing');
QUnit.equal(tt.mode, 'showing', 'the mode is set to showing');
});
test('cue and activeCues are read only', function() {
let mode = 'disabled';
let tt = new TextTrack({
QUnit.test('cue and activeCues are read only', function() {
const mode = 'disabled';
const tt = new TextTrack({
mode,
tech: defaultTech,
tech: defaultTech
});
tt.cues = 'foo';
tt.activeCues = 'bar';
notEqual(tt.cues, 'foo', 'cues is still original value');
notEqual(tt.activeCues, 'bar', 'activeCues is still original value');
QUnit.notEqual(tt.cues, 'foo', 'cues is still original value');
QUnit.notEqual(tt.activeCues, 'bar', 'activeCues is still original value');
});
test('mode can only be set to a few options', function() {
let tt = new TextTrack({
QUnit.test('mode can only be set to a few options', function() {
const tt = new TextTrack({
tech: defaultTech
});
tt.mode = 'foo';
notEqual(tt.mode, 'foo', 'the mode is still the old value, disabled');
equal(tt.mode, 'disabled', 'still on the default mode, disabled');
QUnit.notEqual(tt.mode, 'foo', 'the mode is still the old value, disabled');
QUnit.equal(tt.mode, 'disabled', 'still on the default mode, disabled');
tt.mode = 'hidden';
equal(tt.mode, 'hidden', 'mode set to hidden');
QUnit.equal(tt.mode, 'hidden', 'mode set to hidden');
tt.mode = 'bar';
notEqual(tt.mode, 'bar', 'the mode is still the old value, hidden');
equal(tt.mode, 'hidden', 'still on the previous mode, hidden');
QUnit.notEqual(tt.mode, 'bar', 'the mode is still the old value, hidden');
QUnit.equal(tt.mode, 'hidden', 'still on the previous mode, hidden');
tt.mode = 'showing';
equal(tt.mode, 'showing', 'mode set to showing');
QUnit.equal(tt.mode, 'showing', 'mode set to showing');
tt.mode = 'baz';
notEqual(tt.mode, 'baz', 'the mode is still the old value, showing');
equal(tt.mode, 'showing', 'still on the previous mode, showing');
QUnit.notEqual(tt.mode, 'baz', 'the mode is still the old value, showing');
QUnit.equal(tt.mode, 'showing', 'still on the previous mode, showing');
});
test('cues and activeCues return a TextTrackCueList', function() {
let tt = new TextTrack({
QUnit.test('cues and activeCues return a TextTrackCueList', function() {
const tt = new TextTrack({
tech: defaultTech
});
ok(tt.cues.getCueById, 'cues are a TextTrackCueList');
ok(tt.activeCues.getCueById, 'activeCues are a TextTrackCueList');
QUnit.ok(tt.cues.getCueById, 'cues are a TextTrackCueList');
QUnit.ok(tt.activeCues.getCueById, 'activeCues are a TextTrackCueList');
});
test('cues can be added and removed from a TextTrack', function() {
let tt = new TextTrack({
QUnit.test('cues can be added and removed from a TextTrack', function() {
const tt = new TextTrack({
tech: defaultTech
});
let cues;
const cues = tt.cues;
cues = tt.cues;
equal(cues.length, 0, 'start with zero cues');
QUnit.equal(cues.length, 0, 'start with zero cues');
tt.addCue({id: '1'});
equal(cues.length, 1, 'we have one cue');
QUnit.equal(cues.length, 1, 'we have one cue');
tt.removeCue(cues.getCueById('1'));
equal(cues.length, 0, 'we have removed our one cue');
QUnit.equal(cues.length, 0, 'we have removed our one cue');
tt.addCue({id: '1'});
tt.addCue({id: '2'});
tt.addCue({id: '3'});
equal(cues.length, 3, 'we now have 3 cues');
QUnit.equal(cues.length, 3, 'we now have 3 cues');
});
test('fires cuechange when cues become active and inactive', function() {
let player = TestHelpers.makePlayer();
QUnit.test('fires cuechange when cues become active and inactive', function() {
const player = TestHelpers.makePlayer();
let changes = 0;
let cuechangeHandler;
let tt = new TextTrack({
const tt = new TextTrack({
tech: player.tech_,
mode: 'showing'
});
cuechangeHandler = function() {
const cuechangeHandler = function() {
changes++;
};
@ -232,7 +229,7 @@ test('fires cuechange when cues become active and inactive', function() {
player.tech_.trigger('timeupdate');
equal(changes, 2, 'a cuechange event trigger addEventListener and oncuechange');
QUnit.equal(changes, 2, 'a cuechange event trigger addEventListener and oncuechange');
player.tech_.currentTime = function() {
return 7;
@ -240,12 +237,12 @@ test('fires cuechange when cues become active and inactive', function() {
player.tech_.trigger('timeupdate');
equal(changes, 4, 'a cuechange event trigger addEventListener and oncuechange');
QUnit.equal(changes, 4, 'a cuechange event trigger addEventListener and oncuechange');
player.dispose();
});
test('tracks are parsed if vttjs is loaded', function() {
QUnit.test('tracks are parsed if vttjs is loaded', function() {
const clock = sinon.useFakeTimers();
const oldVTT = window.WebVTT;
let parserCreated = false;
@ -265,34 +262,35 @@ test('tracks are parsed if vttjs is loaded', function() {
// use proxyquire to stub xhr module because IE8s XDomainRequest usage
let xhrHandler;
let TextTrack = proxyquire('../../../src/js/tracks/text-track.js', {
const TextTrack_ = proxyquire('../../../src/js/tracks/text-track.js', {
xhr(options, fn) {
xhrHandler = fn;
}
});
let tt = new TextTrack({
/* eslint-disable no-unused-vars */
const tt = new TextTrack_({
tech: defaultTech,
src: 'http://example.com'
});
/* eslint-enable no-unused-vars */
xhrHandler(null, {}, 'WEBVTT\n');
ok(parserCreated, 'WebVTT is loaded, so we can just parse');
QUnit.ok(parserCreated, 'WebVTT is loaded, so we can just parse');
clock.restore();
window.WebVTT = oldVTT;
TextTrack = proxyquire('../../../src/js/tracks/text-track.js', {});
});
test('tracks are parsed once vttjs is loaded', function() {
QUnit.test('tracks are parsed once vttjs is loaded', function() {
const clock = sinon.useFakeTimers();
const oldVTT = window.WebVTT;
let parserCreated = false;
// use proxyquire to stub xhr module because IE8s XDomainRequest usage
let xhrHandler;
let TextTrack = proxyquire('../../../src/js/tracks/text-track.js', {
const TextTrack_ = proxyquire('../../../src/js/tracks/text-track.js', {
xhr(options, fn) {
xhrHandler = fn;
}
@ -300,21 +298,24 @@ test('tracks are parsed once vttjs is loaded', function() {
window.WebVTT = true;
let testTech = new EventTarget();
const testTech = new EventTarget();
testTech.textTracks = () => {};
testTech.currentTime = () => {};
let tt = new TextTrack({
/* eslint-disable no-unused-vars */
const tt = new TextTrack_({
tech: testTech,
src: 'http://example.com'
});
/* eslint-enable no-unused-vars */
xhrHandler(null, {}, 'WEBVTT\n');
ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');
QUnit.ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');
clock.tick(100);
ok(!parserCreated, 'WebVTT still not loaded, do not try to parse yet');
QUnit.ok(!parserCreated, 'WebVTT still not loaded, do not try to parse yet');
window.WebVTT = () => {};
window.WebVTT.StringDecoder = () => {};
@ -330,61 +331,63 @@ test('tracks are parsed once vttjs is loaded', function() {
};
testTech.trigger('vttjsloaded');
ok(parserCreated, 'WebVTT is loaded, so we can parse now');
QUnit.ok(parserCreated, 'WebVTT is loaded, so we can parse now');
clock.restore();
window.WebVTT = oldVTT;
TextTrack = proxyquire('../../../src/js/tracks/text-track.js', {});
});
test('stops processing if vttjs loading errored out', function() {
QUnit.test('stops processing if vttjs loading errored out', function() {
const clock = sinon.useFakeTimers();
const errorSpy = sinon.spy();
const oldVTT = window.WebVTT;
let parserCreated = false;
const parserCreated = false;
window.WebVTT = true;
// use proxyquire to stub xhr module because IE8s XDomainRequest usage
let xhrHandler;
let TextTrack = proxyquire('../../../src/js/tracks/text-track.js', {
const TextTrack_ = proxyquire('../../../src/js/tracks/text-track.js', {
xhr(options, fn) {
xhrHandler = fn;
},
'../utils/log.js': {
'default': {
default: {
error: errorSpy
}
}
});
let testTech = new EventTarget();
const testTech = new EventTarget();
testTech.textTracks = () => {};
testTech.currentTime = () => {};
sinon.stub(testTech, 'off');
testTech.off.withArgs('vttjsloaded');
let tt = new TextTrack({
/* eslint-disable no-unused-vars */
const tt = new TextTrack_({
tech: testTech,
src: 'http://example.com'
});
/* eslint-enable no-unused-vars */
xhrHandler(null, {}, 'WEBVTT\n');
ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');
QUnit.ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');
testTech.trigger('vttjserror');
let offSpyCall = testTech.off.getCall(0);
const offSpyCall = testTech.off.getCall(0);
ok(errorSpy.called, 'vttjs failed to load, so log.error was called');
QUnit.ok(errorSpy.called, 'vttjs failed to load, so log.error was called');
if (errorSpy.called) {
ok(/^vttjs failed to load, stopping trying to process/.test(errorSpy.getCall(0).args[0]),
QUnit.ok(/^vttjs failed to load, stopping trying to process/.test(errorSpy.getCall(0).args[0]),
'log.error was called with the expected message');
}
ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');
ok(offSpyCall, 'tech.off was called');
QUnit.ok(!parserCreated, 'WebVTT is not loaded, do not try to parse yet');
QUnit.ok(offSpyCall, 'tech.off was called');
clock.restore();
window.WebVTT = oldVTT;
TextTrack = proxyquire('../../../src/js/tracks/text-track.js', {});
});

View File

@ -1,3 +1,4 @@
/* eslint-env qunit */
import ChaptersButton from '../../../src/js/control-bar/text-track-controls/chapters-button.js';
import DescriptionsButton from '../../../src/js/control-bar/text-track-controls/descriptions-button.js';
import SubtitlesButton from '../../../src/js/control-bar/text-track-controls/subtitles-button.js';
@ -12,8 +13,9 @@ import Component from '../../../src/js/component.js';
import * as browser from '../../../src/js/utils/browser.js';
import TestHelpers from '../test-helpers.js';
import document from 'global/document';
import sinon from 'sinon';
q.module('Tracks', {
QUnit.module('Tracks', {
setup() {
this.clock = sinon.useFakeTimers();
},
@ -22,28 +24,22 @@ q.module('Tracks', {
}
});
test('should place title list item into ul', function() {
let player;
let chaptersButton;
QUnit.test('should place title list item into ul', function() {
const player = TestHelpers.makePlayer();
const chaptersButton = new ChaptersButton(player);
player = TestHelpers.makePlayer();
const menuContentElement = chaptersButton.el().getElementsByTagName('UL')[0];
const titleElement = menuContentElement.children[0];
chaptersButton = new ChaptersButton(player);
let menuContentElement = chaptersButton.el().getElementsByTagName('UL')[0];
let titleElement = menuContentElement.children[0];
ok(titleElement.innerHTML === 'Chapters', 'title element placed in ul');
QUnit.ok(titleElement.innerHTML === 'Chapters', 'title element placed in ul');
player.dispose();
});
test('Player track methods call the tech', function() {
let player;
QUnit.test('Player track methods call the tech', function() {
const player = TestHelpers.makePlayer();
let calls = 0;
player = TestHelpers.makePlayer();
player.tech_.textTracks = function() {
calls++;
};
@ -54,14 +50,15 @@ test('Player track methods call the tech', function() {
player.addTextTrack();
player.textTracks();
equal(calls, 2, 'both textTrack and addTextTrack defer to the tech');
QUnit.equal(calls, 2, 'both textTrack and addTextTrack defer to the tech');
player.dispose();
});
test('TextTrackDisplay initializes tracks on player ready', function() {
QUnit.test('TextTrackDisplay initializes tracks on player ready', function() {
let calls = 0;
let ttd = new TextTrackDisplay({
/* eslint-disable no-unused-vars */
const ttd = new TextTrackDisplay({
on() {},
addTextTracks() {
calls--;
@ -73,17 +70,15 @@ test('TextTrackDisplay initializes tracks on player ready', function() {
calls++;
}
}, {});
/* eslint-enable no-unused-vars */
equal(calls, 1, 'only a player.ready call was made');
QUnit.equal(calls, 1, 'only a player.ready call was made');
});
test('listen to remove and add track events in native text tracks', function() {
let oldTestVid = Html5.TEST_VID;
let player;
let options;
let oldTextTracks = Html5.prototype.textTracks;
let events = {};
let html;
QUnit.test('listen to remove and add track events in native text tracks', function() {
const oldTestVid = Html5.TEST_VID;
const oldTextTracks = Html5.prototype.textTracks;
const events = {};
Html5.prototype.textTracks = function() {
return {
@ -97,7 +92,7 @@ test('listen to remove and add track events in native text tracks', function() {
textTracks: []
};
player = {
const player = {
// Function.prototype is a built-in no-op function.
controls() {},
ready() {},
@ -113,35 +108,29 @@ test('listen to remove and add track events in native text tracks', function() {
};
}
};
player.player_ = player;
player.options_ = options = {};
player.options_ = {};
html = new Html5(options);
/* eslint-disable no-unused-vars */
const html = new Html5({});
/* eslint-enable no-unused-vars */
ok(events.removetrack, 'removetrack listener was added');
ok(events.addtrack, 'addtrack listener was added');
QUnit.ok(events.removetrack, 'removetrack listener was added');
QUnit.ok(events.addtrack, 'addtrack listener was added');
Html5.TEST_VID = oldTestVid;
Html5.prototype.textTracks = oldTextTracks;
});
test('update texttrack buttons on removetrack or addtrack', function() {
QUnit.test('update texttrack buttons on removetrack or addtrack', function() {
let update = 0;
let i;
let player;
let tag;
let track;
let oldTextTracks;
let events = {};
let oldCaptionsUpdate;
let oldSubsUpdate;
let oldChaptersUpdate;
let oldDescriptionsUpdate;
const events = {};
const oldCaptionsUpdate = CaptionsButton.prototype.update;
const oldSubsUpdate = SubtitlesButton.prototype.update;
const oldDescriptionsUpdate = DescriptionsButton.prototype.update;
const oldChaptersUpdate = ChaptersButton.prototype.update;
oldCaptionsUpdate = CaptionsButton.prototype.update;
oldSubsUpdate = SubtitlesButton.prototype.update;
oldDescriptionsUpdate = DescriptionsButton.prototype.update;
oldChaptersUpdate = ChaptersButton.prototype.update;
CaptionsButton.prototype.update = function() {
update++;
oldCaptionsUpdate.call(this);
@ -160,7 +149,9 @@ test('update texttrack buttons on removetrack or addtrack', function() {
};
Tech.prototype.featuresNativeTextTracks = true;
oldTextTracks = Tech.prototype.textTracks;
const oldTextTracks = Tech.prototype.textTracks;
Tech.prototype.textTracks = function() {
return {
length: 0,
@ -175,37 +166,39 @@ test('update texttrack buttons on removetrack or addtrack', function() {
};
};
tag = document.createElement('video');
track = document.createElement('track');
track.kind = 'captions';
track.label = 'en';
track.language = 'English';
track.src = '#en.vtt';
tag.appendChild(track);
track = document.createElement('track');
track.kind = 'captions';
track.label = 'es';
track.language = 'Spanish';
track.src = '#es.vtt';
tag.appendChild(track);
const tag = document.createElement('video');
const track1 = document.createElement('track');
const track2 = document.createElement('track');
player = TestHelpers.makePlayer({}, tag);
track1.kind = 'captions';
track1.label = 'en';
track1.language = 'English';
track1.src = '#en.vtt';
tag.appendChild(track1);
track2.kind = 'captions';
track2.label = 'es';
track2.language = 'Spanish';
track2.src = '#es.vtt';
tag.appendChild(track2);
const player = TestHelpers.makePlayer({}, tag);
player.player_ = player;
equal(update, 4, 'update was called on the four buttons during init');
QUnit.equal(update, 4, 'update was called on the four buttons during init');
for (i = 0; i < events.removetrack.length; i++) {
for (let i = 0; i < events.removetrack.length; i++) {
events.removetrack[i]();
}
equal(update, 8, 'update was called on the four buttons for remove track');
QUnit.equal(update, 8, 'update was called on the four buttons for remove track');
for (i = 0; i < events.addtrack.length; i++) {
for (let i = 0; i < events.addtrack.length; i++) {
events.addtrack[i]();
}
equal(update, 12, 'update was called on the four buttons for remove track');
QUnit.equal(update, 12, 'update was called on the four buttons for remove track');
Tech.prototype.textTracks = oldTextTracks;
Tech.prototype.featuresNativeTextTracks = false;
@ -216,28 +209,26 @@ test('update texttrack buttons on removetrack or addtrack', function() {
player.dispose();
});
test('if native text tracks are not supported, create a texttrackdisplay', function() {
let oldTestVid = Html5.TEST_VID;
let oldIsFirefox = browser.IS_FIREFOX;
let oldTextTrackDisplay = Component.getComponent('TextTrackDisplay');
QUnit.test('if native text tracks are not supported, create a texttrackdisplay', function() {
const oldTestVid = Html5.TEST_VID;
const oldIsFirefox = browser.IS_FIREFOX;
const oldTextTrackDisplay = Component.getComponent('TextTrackDisplay');
let called = false;
let player;
let tag;
let track;
const tag = document.createElement('video');
const track1 = document.createElement('track');
const track2 = document.createElement('track');
tag = document.createElement('video');
track = document.createElement('track');
track.kind = 'captions';
track.label = 'en';
track.language = 'English';
track.src = 'en.vtt';
tag.appendChild(track);
track = document.createElement('track');
track.kind = 'captions';
track.label = 'es';
track.language = 'Spanish';
track.src = 'es.vtt';
tag.appendChild(track);
track1.kind = 'captions';
track1.label = 'en';
track1.language = 'English';
track1.src = 'en.vtt';
tag.appendChild(track1);
track2.kind = 'captions';
track2.label = 'es';
track2.language = 'Spanish';
track2.src = 'es.vtt';
tag.appendChild(track2);
Html5.TEST_VID = {
textTracks: []
@ -248,9 +239,9 @@ test('if native text tracks are not supported, create a texttrackdisplay', funct
called = true;
});
player = TestHelpers.makePlayer({}, tag);
const player = TestHelpers.makePlayer({}, tag);
ok(called, 'text track display was created');
QUnit.ok(called, 'text track display was created');
Html5.TEST_VID = oldTestVid;
browser.IS_FIREFOX = oldIsFirefox;
@ -259,8 +250,8 @@ test('if native text tracks are not supported, create a texttrackdisplay', funct
player.dispose();
});
test('html5 tech supports native text tracks if the video supports it, unless mode is a number', function() {
let oldTestVid = Html5.TEST_VID;
QUnit.test('html5 tech supports native text tracks if the video supports it, unless mode is a number', function() {
const oldTestVid = Html5.TEST_VID;
Html5.TEST_VID = {
textTracks: [{
@ -268,14 +259,15 @@ test('html5 tech supports native text tracks if the video supports it, unless mo
}]
};
ok(!Html5.supportsNativeTextTracks(), 'native text tracks are not supported if mode is a number');
QUnit.ok(!Html5.supportsNativeTextTracks(),
'native text tracks are not supported if mode is a number');
Html5.TEST_VID = oldTestVid;
});
test('html5 tech supports native text tracks if the video supports it, unless it is firefox', function() {
let oldTestVid = Html5.TEST_VID;
let oldIsFirefox = browser.IS_FIREFOX;
QUnit.test('html5 tech supports native text tracks if the video supports it, unless it is firefox', function() {
const oldTestVid = Html5.TEST_VID;
const oldIsFirefox = browser.IS_FIREFOX;
Html5.TEST_VID = {
textTracks: []
@ -283,39 +275,41 @@ test('html5 tech supports native text tracks if the video supports it, unless it
browser.IS_FIREFOX = true;
ok(!Html5.supportsNativeTextTracks(), 'if textTracks are available on video element, native text tracks are supported');
QUnit.ok(!Html5.supportsNativeTextTracks(),
'if textTracks are available on video element,' +
' native text tracks are supported');
Html5.TEST_VID = oldTestVid;
browser.IS_FIREFOX = oldIsFirefox;
});
test('when switching techs, we should not get a new text track', function() {
let player = TestHelpers.makePlayer();
QUnit.test('when switching techs, we should not get a new text track', function() {
const player = TestHelpers.makePlayer();
player.loadTech_('TechFaker');
let firstTracks = player.textTracks();
const firstTracks = player.textTracks();
player.loadTech_('TechFaker');
let secondTracks = player.textTracks();
const secondTracks = player.textTracks();
ok(firstTracks === secondTracks, 'the tracks are equal');
QUnit.ok(firstTracks === secondTracks, 'the tracks are equal');
});
if (Html5.supportsNativeTextTracks()) {
test('listen to native remove and add track events in native text tracks', function(assert) {
let done = assert.async();
QUnit.test('listen to native remove and add track events in native text tracks', function(assert) {
const done = assert.async();
let el = document.createElement('video');
let html = new Html5({el});
let tt = el.textTracks;
let emulatedTt = html.textTracks();
let track = document.createElement('track');
const el = document.createElement('video');
const html = new Html5({el});
const tt = el.textTracks;
const emulatedTt = html.textTracks();
const track = document.createElement('track');
el.appendChild(track);
let addtrack = function() {
equal(emulatedTt.length, tt.length, 'we have matching tracks length');
equal(emulatedTt.length, 1, 'we have one text track');
const addtrack = function() {
QUnit.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
QUnit.equal(emulatedTt.length, 1, 'we have one text track');
emulatedTt.off('addtrack', addtrack);
el.removeChild(track);
@ -323,32 +317,32 @@ if (Html5.supportsNativeTextTracks()) {
emulatedTt.on('addtrack', addtrack);
emulatedTt.on('removetrack', function() {
equal(emulatedTt.length, tt.length, 'we have matching tracks length');
equal(emulatedTt.length, 0, 'we have no more text tracks');
QUnit.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
QUnit.equal(emulatedTt.length, 0, 'we have no more text tracks');
done();
});
});
test('should have removed tracks on dispose', function(assert) {
let done = assert.async();
QUnit.test('should have removed tracks on dispose', function(assert) {
const done = assert.async();
let el = document.createElement('video');
let html = new Html5({el});
let tt = el.textTracks;
let emulatedTt = html.textTracks();
let track = document.createElement('track');
const el = document.createElement('video');
const html = new Html5({el});
const tt = el.textTracks;
const emulatedTt = html.textTracks();
const track = document.createElement('track');
el.appendChild(track);
let addtrack = function() {
equal(emulatedTt.length, tt.length, 'we have matching tracks length');
equal(emulatedTt.length, 1, 'we have one text track');
const addtrack = function() {
QUnit.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
QUnit.equal(emulatedTt.length, 1, 'we have one text track');
emulatedTt.off('addtrack', addtrack);
html.dispose();
equal(emulatedTt.length, tt.length, 'we have matching tracks length');
equal(emulatedTt.length, 0, 'we have no more text tracks');
QUnit.equal(emulatedTt.length, tt.length, 'we have matching tracks length');
QUnit.equal(emulatedTt.length, 0, 'we have no more text tracks');
done();
};
@ -357,20 +351,20 @@ if (Html5.supportsNativeTextTracks()) {
});
}
test('should check for text track changes when emulating text tracks', function() {
let tech = new Tech();
QUnit.test('should check for text track changes when emulating text tracks', function() {
const tech = new Tech();
let numTextTrackChanges = 0;
tech.on('texttrackchange', function() {
numTextTrackChanges++;
});
tech.emulateTextTracks();
equal(numTextTrackChanges, 1, 'we got a texttrackchange event');
QUnit.equal(numTextTrackChanges, 1, 'we got a texttrackchange event');
});
test('removes cuechange event when text track is hidden for emulated tracks', function() {
let player = TestHelpers.makePlayer();
let tt = new TextTrack({
QUnit.test('removes cuechange event when text track is hidden for emulated tracks', function() {
const player = TestHelpers.makePlayer();
const tt = new TextTrack({
tech: player.tech_,
mode: 'showing'
});
@ -390,34 +384,34 @@ test('removes cuechange event when text track is hidden for emulated tracks', fu
});
tt.mode = 'showing';
equal(numTextTrackChanges, 1,
QUnit.equal(numTextTrackChanges, 1,
'texttrackchange should be called once for mode change');
tt.mode = 'showing';
equal(numTextTrackChanges, 2,
QUnit.equal(numTextTrackChanges, 2,
'texttrackchange should be called once for mode change');
player.tech_.currentTime = function() {
return 3;
};
player.tech_.trigger('timeupdate');
equal(numTextTrackChanges, 3,
QUnit.equal(numTextTrackChanges, 3,
'texttrackchange should be triggered once for the cuechange');
tt.mode = 'hidden';
equal(numTextTrackChanges, 4,
QUnit.equal(numTextTrackChanges, 4,
'texttrackchange should be called once for the mode change');
player.tech_.currentTime = function() {
return 7;
};
player.tech_.trigger('timeupdate');
equal(numTextTrackChanges, 4,
QUnit.equal(numTextTrackChanges, 4,
'texttrackchange should be not be called since mode is hidden');
});
test('should return correct remote text track values', function() {
let fixture = document.getElementById('qunit-fixture');
let html = `
QUnit.test('should return correct remote text track values', function() {
const fixture = document.getElementById('qunit-fixture');
const html = `
<video id="example_1" class="video-js" autoplay preload="none">
<source src="http://google.com" type="video/mp4">
<source src="http://google.com" type="video/webm">
@ -426,33 +420,35 @@ test('should return correct remote text track values', function() {
`;
fixture.innerHTML += html;
let tag = document.getElementById('example_1');
let player = TestHelpers.makePlayer({}, tag);
const tag = document.getElementById('example_1');
const player = TestHelpers.makePlayer({}, tag);
this.clock.tick(1);
equal(player.remoteTextTracks().length, 1, 'add text track via html');
equal(player.remoteTextTrackEls().length, 1, 'add html track element via html');
QUnit.equal(player.remoteTextTracks().length, 1, 'add text track via html');
QUnit.equal(player.remoteTextTrackEls().length, 1, 'add html track element via html');
let htmlTrackElement = player.addRemoteTextTrack({
const htmlTrackElement = player.addRemoteTextTrack({
kind: 'captions',
label: 'label'
});
equal(player.remoteTextTracks().length, 2, 'add text track via method');
equal(player.remoteTextTrackEls().length, 2, 'add html track element via method');
QUnit.equal(player.remoteTextTracks().length, 2, 'add text track via method');
QUnit.equal(player.remoteTextTrackEls().length, 2, 'add html track element via method');
player.removeRemoteTextTrack(htmlTrackElement.track);
equal(player.remoteTextTracks().length, 1, 'remove text track via method');
equal(player.remoteTextTrackEls().length, 1, 'remove html track element via method');
QUnit.equal(player.remoteTextTracks().length, 1, 'remove text track via method');
QUnit.equal(player.remoteTextTrackEls().length,
1,
'remove html track element via method');
player.dispose();
});
test('should uniformly create html track element when adding text track', function() {
let player = TestHelpers.makePlayer();
let track = {
QUnit.test('should uniformly create html track element when adding text track', function() {
const player = TestHelpers.makePlayer();
const track = {
kind: 'kind',
src: 'src',
language: 'language',
@ -460,32 +456,44 @@ test('should uniformly create html track element when adding text track', functi
default: 'default'
};
equal(player.remoteTextTrackEls().length, 0, 'no html text tracks');
QUnit.equal(player.remoteTextTrackEls().length, 0, 'no html text tracks');
let htmlTrackElement = player.addRemoteTextTrack(track);
const htmlTrackElement = player.addRemoteTextTrack(track);
equal(htmlTrackElement.kind, htmlTrackElement.track.kind, 'verify html track element kind');
equal(htmlTrackElement.src, htmlTrackElement.track.src, 'verify html track element src');
equal(htmlTrackElement.srclang, htmlTrackElement.track.language, 'verify html track element language');
equal(htmlTrackElement.label, htmlTrackElement.track.label, 'verify html track element label');
equal(htmlTrackElement.default, htmlTrackElement.track.default, 'verify html track element default');
QUnit.equal(htmlTrackElement.kind,
htmlTrackElement.track.kind,
'verify html track element kind');
QUnit.equal(htmlTrackElement.src,
htmlTrackElement.track.src,
'verify html track element src');
QUnit.equal(htmlTrackElement.srclang,
htmlTrackElement.track.language,
'verify html track element language');
QUnit.equal(htmlTrackElement.label,
htmlTrackElement.track.label,
'verify html track element label');
QUnit.equal(htmlTrackElement.default,
htmlTrackElement.track.default,
'verify html track element default');
equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
equal(player.remoteTextTrackEls().getTrackElementByTrack_(htmlTrackElement.track), htmlTrackElement, 'verify same html track element');
QUnit.equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
QUnit.equal(player.remoteTextTrackEls().getTrackElementByTrack_(htmlTrackElement.track),
htmlTrackElement,
'verify same html track element');
player.dispose();
});
test('default text tracks should show by default', function() {
let tag = TestHelpers.makeTag();
let capt = document.createElement('track');
QUnit.test('default text tracks should show by default', function() {
const tag = TestHelpers.makeTag();
const capt = document.createElement('track');
capt.setAttribute('kind', 'captions');
capt.setAttribute('default', 'default');
tag.appendChild(capt);
let player = TestHelpers.makePlayer({
const player = TestHelpers.makePlayer({
html5: {
nativeTextTracks: false
}
@ -494,16 +502,16 @@ test('default text tracks should show by default', function() {
// native tracks are initialized after the player is ready
this.clock.tick(1);
let tracks = player.textTracks();
const tracks = player.textTracks();
equal(tracks[0].kind, 'captions', 'the captions track is present');
equal(tracks[0].mode, 'showing', 'the captions track is showing');
QUnit.equal(tracks[0].kind, 'captions', 'the captions track is present');
QUnit.equal(tracks[0].mode, 'showing', 'the captions track is showing');
});
test('default captions take precedence over default descriptions', function() {
let tag = TestHelpers.makeTag();
let desc = document.createElement('track');
let capt = document.createElement('track');
QUnit.test('default captions take precedence over default descriptions', function() {
const tag = TestHelpers.makeTag();
const desc = document.createElement('track');
const capt = document.createElement('track');
desc.setAttribute('kind', 'descriptions');
desc.setAttribute('default', 'default');
@ -513,7 +521,7 @@ test('default captions take precedence over default descriptions', function() {
tag.appendChild(desc);
tag.appendChild(capt);
let player = TestHelpers.makePlayer({
const player = TestHelpers.makePlayer({
html5: {
nativeTextTracks: false
}
@ -522,17 +530,17 @@ test('default captions take precedence over default descriptions', function() {
// native tracks are initialized after the player is ready
this.clock.tick(1);
let tracks = player.textTracks();
const tracks = player.textTracks();
equal(tracks[0].kind, 'descriptions', 'the descriptions track is first');
equal(tracks[0].mode, 'disabled', 'the descriptions track is disabled');
equal(tracks[1].kind, 'captions', 'the captions track is second');
equal(tracks[1].mode, 'showing', 'the captions track is showing');
QUnit.equal(tracks[0].kind, 'descriptions', 'the descriptions track is first');
QUnit.equal(tracks[0].mode, 'disabled', 'the descriptions track is disabled');
QUnit.equal(tracks[1].kind, 'captions', 'the captions track is second');
QUnit.equal(tracks[1].mode, 'showing', 'the captions track is showing');
});
test('removeRemoteTextTrack should be able to take both a track and the response from addRemoteTextTrack', function() {
let player = TestHelpers.makePlayer();
let track = {
QUnit.test('removeRemoteTextTrack should be able to take both a track and the response from addRemoteTextTrack', function() {
const player = TestHelpers.makePlayer();
const track = {
kind: 'kind',
src: 'src',
language: 'language',
@ -541,15 +549,19 @@ test('removeRemoteTextTrack should be able to take both a track and the response
};
let htmlTrackElement = player.addRemoteTextTrack(track);
equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
QUnit.equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
player.removeRemoteTextTrack(htmlTrackElement);
equal(player.remoteTextTrackEls().length, 0, 'the track element was removed correctly');
QUnit.equal(player.remoteTextTrackEls().length,
0,
'the track element was removed correctly');
htmlTrackElement = player.addRemoteTextTrack(track);
equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
QUnit.equal(player.remoteTextTrackEls().length, 1, 'html track element exist');
player.removeRemoteTextTrack(htmlTrackElement.track);
equal(player.remoteTextTrackEls().length, 0, 'the track element was removed correctly');
QUnit.equal(player.remoteTextTrackEls().length,
0,
'the track element was removed correctly');
});

View File

@ -1,5 +1,5 @@
/* eslint-env qunit */
import * as browser from '../../../src/js/utils/browser.js';
import document from 'global/document';
/**
* Tests baseline functionality for all tracks
@ -9,34 +9,37 @@ import document from 'global/document';
*/
const TrackBaseline = function(TrackClass, options) {
test('is setup with id, kind, label, and language', function() {
let track = new TrackClass(options);
equal(track.kind, options.kind, 'we have a kind');
equal(track.label, options.label, 'we have a label');
equal(track.language, options.language, 'we have a language');
equal(track.id, options.id, 'we have a id');
QUnit.test('is setup with id, kind, label, and language', function() {
const track = new TrackClass(options);
QUnit.equal(track.kind, options.kind, 'we have a kind');
QUnit.equal(track.label, options.label, 'we have a label');
QUnit.equal(track.language, options.language, 'we have a language');
QUnit.equal(track.id, options.id, 'we have a id');
});
test('kind, label, language, id, are read only', function() {
let track = new TrackClass(options);
QUnit.test('kind, label, language, id, are read only', function() {
const track = new TrackClass(options);
track.kind = 'subtitles';
track.label = 'Spanish';
track.language = 'es';
track.id = '2';
equal(track.kind, options.kind, 'we have a kind');
equal(track.label, options.label, 'we have a label');
equal(track.language, options.language, 'we have a language');
equal(track.id, options.id, 'we have an id');
QUnit.equal(track.kind, options.kind, 'we have a kind');
QUnit.equal(track.label, options.label, 'we have a label');
QUnit.equal(track.language, options.language, 'we have a language');
QUnit.equal(track.id, options.id, 'we have an id');
});
test('returns an instance of itself on non ie8 browsers', function() {
let track = new TrackClass(options);
QUnit.test('returns an instance of itself on non ie8 browsers', function() {
const track = new TrackClass(options);
if (browser.IS_IE8) {
ok(track, 'returns an object on ie8');
QUnit.ok(track, 'returns an object on ie8');
return;
}
ok(track instanceof TrackClass, 'returns an instance');
QUnit.ok(track instanceof TrackClass, 'returns an instance');
});
};

View File

@ -1,103 +1,113 @@
/* eslint-env qunit */
import TrackList from '../../../src/js/tracks/track-list.js';
import EventTarget from '../../../src/js/event-target.js';
const newTrack = function(id) {
return {
id,
addEventListener() {},
off() {},
off() {}
};
};
q.module('Track List', {
QUnit.module('Track List', {
beforeEach() {
this.tracks = [newTrack('1'), newTrack('2'), newTrack('3')];
}
});
test('TrackList\'s length is set correctly', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('TrackList\'s length is set correctly', function() {
const trackList = new TrackList(this.tracks);
equal(trackList.length, this.tracks.length, 'length is ' + this.tracks.length);
QUnit.equal(trackList.length, this.tracks.length, 'length is ' + this.tracks.length);
});
test('can get tracks by int and string id', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('can get tracks by int and string id', function() {
const trackList = new TrackList(this.tracks);
equal(trackList.getTrackById('1').id, '1', 'id "1" has id of "1"');
equal(trackList.getTrackById('2').id, '2', 'id "2" has id of "2"');
equal(trackList.getTrackById('3').id, '3', 'id "3" has id of "3"');
QUnit.equal(trackList.getTrackById('1').id, '1', 'id "1" has id of "1"');
QUnit.equal(trackList.getTrackById('2').id, '2', 'id "2" has id of "2"');
QUnit.equal(trackList.getTrackById('3').id, '3', 'id "3" has id of "3"');
});
test('length is updated when new tracks are added or removed', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('length is updated when new tracks are added or removed', function() {
const trackList = new TrackList(this.tracks);
trackList.addTrack_(newTrack('100'));
equal(trackList.length, this.tracks.length + 1, 'the length is ' + (this.tracks.length + 1));
QUnit.equal(trackList.length,
this.tracks.length + 1,
'the length is ' + (this.tracks.length + 1));
trackList.addTrack_(newTrack('101'));
equal(trackList.length, this.tracks.length + 2, 'the length is ' + (this.tracks.length + 2));
QUnit.equal(trackList.length,
this.tracks.length + 2,
'the length is ' + (this.tracks.length + 2));
trackList.removeTrack_(trackList.getTrackById('101'));
equal(trackList.length, this.tracks.length + 1, 'the length is ' + (this.tracks.length + 1));
QUnit.equal(trackList.length,
this.tracks.length + 1,
'the length is ' + (this.tracks.length + 1));
trackList.removeTrack_(trackList.getTrackById('100'));
equal(trackList.length, this.tracks.length, 'the length is ' + this.tracks.length);
QUnit.equal(trackList.length,
this.tracks.length,
'the length is ' + this.tracks.length);
});
test('can access items by index', function() {
let trackList = new TrackList(this.tracks);
let length = trackList.length;
QUnit.test('can access items by index', function() {
const trackList = new TrackList(this.tracks);
const length = trackList.length;
expect(length);
QUnit.expect(length);
for (let i = 0; i < length; i++) {
equal(trackList[i].id, String(i + 1), 'the id of a track matches the index + 1');
QUnit.equal(trackList[i].id,
String(i + 1),
'the id of a track matches the index + 1');
}
});
test('can access new items by index', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('can access new items by index', function() {
const trackList = new TrackList(this.tracks);
trackList.addTrack_(newTrack('100'));
equal(trackList[3].id, '100', 'id of item at index 3 is 100');
QUnit.equal(trackList[3].id, '100', 'id of item at index 3 is 100');
trackList.addTrack_(newTrack('101'));
equal(trackList[4].id, '101', 'id of item at index 4 is 101');
QUnit.equal(trackList[4].id, '101', 'id of item at index 4 is 101');
});
test('cannot access removed items by index', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('cannot access removed items by index', function() {
const trackList = new TrackList(this.tracks);
trackList.addTrack_(newTrack('100'));
trackList.addTrack_(newTrack('101'));
equal(trackList[3].id, '100', 'id of item at index 3 is 100');
equal(trackList[4].id, '101', 'id of item at index 4 is 101');
QUnit.equal(trackList[3].id, '100', 'id of item at index 3 is 100');
QUnit.equal(trackList[4].id, '101', 'id of item at index 4 is 101');
trackList.removeTrack_(trackList.getTrackById('101'));
trackList.removeTrack_(trackList.getTrackById('100'));
ok(!trackList[3], 'nothing at index 3');
ok(!trackList[4], 'nothing at index 4');
QUnit.ok(!trackList[3], 'nothing at index 3');
QUnit.ok(!trackList[4], 'nothing at index 4');
});
test('new item available at old index', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('new item available at old index', function() {
const trackList = new TrackList(this.tracks);
trackList.addTrack_(newTrack('100'));
equal(trackList[3].id, '100', 'id of item at index 3 is 100');
QUnit.equal(trackList[3].id, '100', 'id of item at index 3 is 100');
trackList.removeTrack_(trackList.getTrackById('100'));
ok(!trackList[3], 'nothing at index 3');
QUnit.ok(!trackList[3], 'nothing at index 3');
trackList.addTrack_(newTrack('101'));
equal(trackList[3].id, '101', 'id of new item at index 3 is now 101');
QUnit.equal(trackList[3].id, '101', 'id of new item at index 3 is now 101');
});
test('a "addtrack" event is triggered when new tracks are added', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('a "addtrack" event is triggered when new tracks are added', function() {
const trackList = new TrackList(this.tracks);
let tracks = 0;
let adds = 0;
let addHandler = (e) => {
const addHandler = (e) => {
if (e.track) {
tracks++;
}
@ -115,15 +125,15 @@ test('a "addtrack" event is triggered when new tracks are added', function() {
trackList.addTrack_(newTrack('102'));
trackList.addTrack_(newTrack('103'));
equal(adds, 4, 'we got ' + adds + ' "addtrack" events');
equal(tracks, 4, 'we got a track with every event');
QUnit.equal(adds, 4, 'we got ' + adds + ' "addtrack" events');
QUnit.equal(tracks, 4, 'we got a track with every event');
});
test('a "removetrack" event is triggered when tracks are removed', function() {
let trackList = new TrackList(this.tracks);
QUnit.test('a "removetrack" event is triggered when tracks are removed', function() {
const trackList = new TrackList(this.tracks);
let tracks = 0;
let rms = 0;
let rmHandler = (e) => {
const rmHandler = (e) => {
if (e.track) {
tracks++;
}
@ -138,6 +148,6 @@ test('a "removetrack" event is triggered when tracks are removed', function() {
trackList.onremovetrack = rmHandler;
trackList.removeTrack_(trackList.getTrackById('3'));
equal(rms, 3, 'we got ' + rms + ' "removetrack" events');
equal(tracks, 3, 'we got a track with every event');
QUnit.equal(rms, 3, 'we got ' + rms + ' "removetrack" events');
QUnit.equal(tracks, 3, 'we got a track with every event');
});

View File

@ -1,7 +1,7 @@
/* eslint-env qunit */
import TechFaker from '../tech/tech-faker';
import TrackBaseline from './track-baseline';
import Track from '../../../src/js/tracks/track.js';
import * as browser from '../../../src/js/utils/browser.js';
const defaultTech = {
textTracks() {},
@ -11,7 +11,7 @@ const defaultTech = {
};
// do baseline track testing
q.module('Track');
QUnit.module('Track');
TrackBaseline(Track, {
id: '1',
@ -22,13 +22,13 @@ TrackBaseline(Track, {
tech: new TechFaker()
});
test('defaults when items not provided', function() {
let track = new Track({
QUnit.test('defaults when items not provided', function() {
const track = new Track({
tech: defaultTech
});
equal(track.kind, '', 'kind defaulted to empty string');
equal(track.label, '', 'label defaults to empty string');
equal(track.language, '', 'language defaults to empty string');
ok(track.id.match(/vjs_track_\d{5}/), 'id defaults to vjs_track_GUID');
QUnit.equal(track.kind, '', 'kind defaulted to empty string');
QUnit.equal(track.label, '', 'label defaults to empty string');
QUnit.equal(track.language, '', 'language defaults to empty string');
QUnit.ok(track.id.match(/vjs_track_\d{5}/), 'id defaults to vjs_track_GUID');
});

View File

@ -1,96 +1,103 @@
/* eslint-env qunit */
import VideoTrackList from '../../../src/js/tracks/video-track-list.js';
import VideoTrack from '../../../src/js/tracks/video-track.js';
import EventTarget from '../../../src/js/event-target.js';
q.module('Video Track List');
QUnit.module('Video Track List');
QUnit.test('trigger "change" when "selectedchange" is fired on a track', function() {
const track = new EventTarget();
test('trigger "change" when "selectedchange" is fired on a track', function() {
let track = new EventTarget();
track.loaded_ = true;
let audioTrackList = new VideoTrackList([track]);
const videoTrackList = new VideoTrackList([track]);
let changes = 0;
let changeHandler = function() {
const changeHandler = function() {
changes++;
};
audioTrackList.on('change', changeHandler);
track.trigger('selectedchange');
equal(changes, 1, 'one change events for trigger');
audioTrackList.off('change', changeHandler);
audioTrackList.onchange = changeHandler;
videoTrackList.on('change', changeHandler);
track.trigger('selectedchange');
QUnit.equal(changes, 1, 'one change events for trigger');
videoTrackList.off('change', changeHandler);
videoTrackList.onchange = changeHandler;
track.trigger('selectedchange');
equal(changes, 2, 'one change events for another trigger');
QUnit.equal(changes, 2, 'one change events for another trigger');
});
test('only one track is ever selected', function() {
let track = new VideoTrack({selected: true});
let track2 = new VideoTrack({selected: true});
let track3 = new VideoTrack({selected: true});
let track4 = new VideoTrack();
let list = new VideoTrackList([track, track2]);
equal(track.selected, false, 'track is unselected');
equal(track2.selected, true, 'track2 is selected');
QUnit.test('only one track is ever selected', function() {
const track = new VideoTrack({selected: true});
const track2 = new VideoTrack({selected: true});
const track3 = new VideoTrack({selected: true});
const track4 = new VideoTrack();
const list = new VideoTrackList([track, track2]);
QUnit.equal(track.selected, false, 'track is unselected');
QUnit.equal(track2.selected, true, 'track2 is selected');
track.selected = true;
equal(track.selected, true, 'track is selected');
equal(track2.selected, false, 'track2 is unselected');
QUnit.equal(track.selected, true, 'track is selected');
QUnit.equal(track2.selected, false, 'track2 is unselected');
list.addTrack_(track3);
equal(track.selected, false, 'track is unselected');
equal(track2.selected, false, 'track2 is unselected');
equal(track3.selected, true, 'track3 is selected');
QUnit.equal(track.selected, false, 'track is unselected');
QUnit.equal(track2.selected, false, 'track2 is unselected');
QUnit.equal(track3.selected, true, 'track3 is selected');
track.selected = true;
equal(track.selected, true, 'track is unselected');
equal(track2.selected, false, 'track2 is unselected');
equal(track3.selected, false, 'track3 is unselected');
QUnit.equal(track.selected, true, 'track is unselected');
QUnit.equal(track2.selected, false, 'track2 is unselected');
QUnit.equal(track3.selected, false, 'track3 is unselected');
list.addTrack_(track4);
equal(track.selected, true, 'track is selected');
equal(track2.selected, false, 'track2 is unselected');
equal(track3.selected, false, 'track3 is unselected');
equal(track4.selected, false, 'track4 is unselected');
QUnit.equal(track.selected, true, 'track is selected');
QUnit.equal(track2.selected, false, 'track2 is unselected');
QUnit.equal(track3.selected, false, 'track3 is unselected');
QUnit.equal(track4.selected, false, 'track4 is unselected');
});
test('all tracks can be unselected', function() {
let track = new VideoTrack();
let track2 = new VideoTrack();
let list = new VideoTrackList([track, track2]);
equal(track.selected, false, 'track is unselected');
equal(track2.selected, false, 'track2 is unselected');
QUnit.test('all tracks can be unselected', function() {
const track = new VideoTrack();
const track2 = new VideoTrack();
/* eslint-disable no-unused-vars */
const list = new VideoTrackList([track, track2]);
/* eslint-enable no-unused-vars */
QUnit.equal(track.selected, false, 'track is unselected');
QUnit.equal(track2.selected, false, 'track2 is unselected');
track.selected = true;
equal(track.selected, true, 'track is selected');
equal(track2.selected, false, 'track2 is unselected');
QUnit.equal(track.selected, true, 'track is selected');
QUnit.equal(track2.selected, false, 'track2 is unselected');
track.selected = false;
equal(track.selected, false, 'track is unselected');
equal(track2.selected, false, 'track2 is unselected');
QUnit.equal(track.selected, false, 'track is unselected');
QUnit.equal(track2.selected, false, 'track2 is unselected');
});
test('trigger a change event per selected change', function() {
let track = new VideoTrack({selected: true});
let track2 = new VideoTrack({selected: true});
let track3 = new VideoTrack({selected: true});
let track4 = new VideoTrack();
let list = new VideoTrackList([track, track2]);
QUnit.test('trigger a change event per selected change', function() {
const track = new VideoTrack({selected: true});
const track2 = new VideoTrack({selected: true});
const track3 = new VideoTrack({selected: true});
const track4 = new VideoTrack();
const list = new VideoTrackList([track, track2]);
let change = 0;
list.on('change', () => change++);
track.selected = true;
equal(change, 1, 'one change triggered');
QUnit.equal(change, 1, 'one change triggered');
list.addTrack_(track3);
equal(change, 2, 'another change triggered by adding an selected track');
QUnit.equal(change, 2, 'another change triggered by adding an selected track');
track.selected = true;
equal(change, 3, 'another change trigger by changing selected');
QUnit.equal(change, 3, 'another change trigger by changing selected');
track.selected = false;
equal(change, 4, 'another change trigger by changing selected');
QUnit.equal(change, 4, 'another change trigger by changing selected');
list.addTrack_(track4);
equal(change, 4, 'no change triggered by adding a unselected track');
QUnit.equal(change, 4, 'no change triggered by adding a unselected track');
});

View File

@ -1,96 +1,101 @@
/* eslint-env qunit */
import VideoTrack from '../../../src/js/tracks/video-track';
import VideoTrackList from '../../../src/js/tracks/video-track-list';
import {VideoTrackKind} from '../../../src/js/tracks/track-enums';
import TrackBaseline from './track-baseline';
q.module('Video Track');
QUnit.module('Video Track');
// do baseline track testing
TrackBaseline(VideoTrack, {
id: '1',
language: 'en',
label: 'English',
kind: 'main',
kind: 'main'
});
test('can create an VideoTrack a selected property', function() {
let selected = true;
let track = new VideoTrack({
selected,
QUnit.test('can create an VideoTrack a selected property', function() {
const selected = true;
const track = new VideoTrack({
selected
});
equal(track.selected, selected, 'selected value matches what we passed in');
QUnit.equal(track.selected, selected, 'selected value matches what we passed in');
});
test('defaults when items not provided', function() {
let track = new VideoTrack();
QUnit.test('defaults when items not provided', function() {
const track = new VideoTrack();
equal(track.kind, '', 'kind defaulted to empty string');
equal(track.selected, false, 'selected defaulted to true since there is one track');
equal(track.label, '', 'label defaults to empty string');
equal(track.language, '', 'language defaults to empty string');
ok(track.id.match(/vjs_track_\d{5}/), 'id defaults to vjs_track_GUID');
QUnit.equal(track.kind, '', 'kind defaulted to empty string');
QUnit.equal(track.selected,
false,
'selected defaulted to true since there is one track');
QUnit.equal(track.label, '', 'label defaults to empty string');
QUnit.equal(track.language, '', 'language defaults to empty string');
QUnit.ok(track.id.match(/vjs_track_\d{5}/), 'id defaults to vjs_track_GUID');
});
test('kind can only be one of several options, defaults to empty string', function() {
let track = new VideoTrack({
QUnit.test('kind can only be one of several options, defaults to empty string', function() {
const track1 = new VideoTrack({
kind: 'foo'
});
equal(track.kind, '', 'the kind is set to empty string, not foo');
notEqual(track.kind, 'foo', 'the kind is set to empty string, not foo');
QUnit.equal(track1.kind, '', 'the kind is set to empty string, not foo');
QUnit.notEqual(track1.kind, 'foo', 'the kind is set to empty string, not foo');
// loop through all possible kinds to verify
for (let key in VideoTrackKind) {
let currentKind = VideoTrackKind[key];
let track = new VideoTrack({kind: currentKind});
equal(track.kind, currentKind, 'the kind is set to ' + currentKind);
for (const key in VideoTrackKind) {
const currentKind = VideoTrackKind[key];
const track = new VideoTrack({kind: currentKind});
QUnit.equal(track.kind, currentKind, 'the kind is set to ' + currentKind);
}
});
test('selected can only be instantiated to true or false, defaults to false', function() {
QUnit.test('selected can only be instantiated to true or false, defaults to false', function() {
let track = new VideoTrack({
selected: 'foo'
});
equal(track.selected, false, 'the selected value is set to false, not foo');
notEqual(track.selected, 'foo', 'the selected value is not set to foo');
QUnit.equal(track.selected, false, 'the selected value is set to false, not foo');
QUnit.notEqual(track.selected, 'foo', 'the selected value is not set to foo');
track = new VideoTrack({
selected: true
});
equal(track.selected, true, 'the selected value is set to true');
QUnit.equal(track.selected, true, 'the selected value is set to true');
track = new VideoTrack({
selected: false
});
equal(track.selected, false, 'the selected value is set to false');
QUnit.equal(track.selected, false, 'the selected value is set to false');
});
test('selected can only be changed to true or false', function() {
let track = new VideoTrack();
QUnit.test('selected can only be changed to true or false', function() {
const track = new VideoTrack();
track.selected = 'foo';
notEqual(track.selected, 'foo', 'selected not set to invalid value, foo');
equal(track.selected, false, 'selected remains on the old value, false');
QUnit.notEqual(track.selected, 'foo', 'selected not set to invalid value, foo');
QUnit.equal(track.selected, false, 'selected remains on the old value, false');
track.selected = true;
equal(track.selected, true, 'selected was set to true');
QUnit.equal(track.selected, true, 'selected was set to true');
track.selected = 'baz';
notEqual(track.selected, 'baz', 'selected not set to invalid value, baz');
equal(track.selected, true, 'selected remains on the old value, true');
QUnit.notEqual(track.selected, 'baz', 'selected not set to invalid value, baz');
QUnit.equal(track.selected, true, 'selected remains on the old value, true');
track.selected = false;
equal(track.selected, false, 'selected was set to false');
QUnit.equal(track.selected, false, 'selected was set to false');
});
test('when selected is changed selectedchange event is fired', function() {
let track = new VideoTrack({
QUnit.test('when selected is changed selectedchange event is fired', function() {
const track = new VideoTrack({
selected: false
});
let eventsTriggered = 0;
track.addEventListener('selectedchange', () => {
eventsTriggered++;
});
@ -98,14 +103,14 @@ test('when selected is changed selectedchange event is fired', function() {
// two events
track.selected = true;
track.selected = false;
equal(eventsTriggered, 2, 'two selected changes');
QUnit.equal(eventsTriggered, 2, 'two selected changes');
// no event here
track.selected = false;
track.selected = false;
equal(eventsTriggered, 2, 'still two selected changes');
QUnit.equal(eventsTriggered, 2, 'still two selected changes');
// one event
track.selected = true;
equal(eventsTriggered, 3, 'three selected changes');
QUnit.equal(eventsTriggered, 3, 'three selected changes');
});

View File

@ -1,13 +1,9 @@
import VideoTrack from '../../../src/js/tracks/video-track.js';
/* eslint-env qunit */
import Html5 from '../../../src/js/tech/html5.js';
import Tech from '../../../src/js/tech/tech.js';
import Component from '../../../src/js/component.js';
import * as browser from '../../../src/js/utils/browser.js';
import TestHelpers from '../test-helpers.js';
import document from 'global/document';
import sinon from 'sinon';
q.module('Video Tracks', {
QUnit.module('Video Tracks', {
setup() {
this.clock = sinon.useFakeTimers();
},
@ -16,11 +12,9 @@ q.module('Video Tracks', {
}
});
test('Player track methods call the tech', function() {
let player;
QUnit.test('Player track methods call the tech', function() {
let calls = 0;
player = TestHelpers.makePlayer();
const player = TestHelpers.makePlayer();
player.tech_.videoTracks = function() {
calls++;
@ -28,17 +22,14 @@ test('Player track methods call the tech', function() {
player.videoTracks();
equal(calls, 1, 'videoTrack defers to the tech');
QUnit.equal(calls, 1, 'videoTrack defers to the tech');
player.dispose();
});
test('listen to remove and add track events in native video tracks', function() {
let oldTestVid = Html5.TEST_VID;
let player;
let options;
let oldVideoTracks = Html5.prototype.videoTracks;
let events = {};
let html;
QUnit.test('listen to remove and add track events in native video tracks', function() {
const oldTestVid = Html5.TEST_VID;
const oldVideoTracks = Html5.prototype.videoTracks;
const events = {};
Html5.prototype.videoTracks = function() {
return {
@ -52,7 +43,7 @@ test('listen to remove and add track events in native video tracks', function()
videoTracks: []
};
player = {
const player = {
// Function.prototype is a built-in no-op function.
controls() {},
ready() {},
@ -68,47 +59,51 @@ test('listen to remove and add track events in native video tracks', function()
};
}
};
player.player_ = player;
player.options_ = options = {};
player.options_ = {};
html = new Html5(options);
/* eslint-disable no-unused-vars */
const html = new Html5({});
/* eslint-enable no-unused-vars */
ok(events.removetrack, 'removetrack listener was added');
ok(events.addtrack, 'addtrack listener was added');
QUnit.ok(events.removetrack, 'removetrack listener was added');
QUnit.ok(events.addtrack, 'addtrack listener was added');
Html5.TEST_VID = oldTestVid;
Html5.prototype.videoTracks = oldVideoTracks;
});
test('html5 tech supports native video tracks if the video supports it', function() {
let oldTestVid = Html5.TEST_VID;
QUnit.test('html5 tech supports native video tracks if the video supports it', function() {
const oldTestVid = Html5.TEST_VID;
Html5.TEST_VID = {
videoTracks: []
};
ok(Html5.supportsNativeVideoTracks(), 'native video tracks are supported');
QUnit.ok(Html5.supportsNativeVideoTracks(), 'native video tracks are supported');
Html5.TEST_VID = oldTestVid;
});
test('html5 tech does not support native video tracks if the video does not supports it', function() {
let oldTestVid = Html5.TEST_VID;
QUnit.test('html5 tech does not support native video tracks if the video does not supports it', function() {
const oldTestVid = Html5.TEST_VID;
Html5.TEST_VID = {};
ok(!Html5.supportsNativeVideoTracks(), 'native video tracks are not supported');
QUnit.ok(!Html5.supportsNativeVideoTracks(), 'native video tracks are not supported');
Html5.TEST_VID = oldTestVid;
});
test('when switching techs, we should not get a new video track', function() {
let player = TestHelpers.makePlayer();
QUnit.test('when switching techs, we should not get a new video track', function() {
const player = TestHelpers.makePlayer();
player.loadTech_('TechFaker');
let firstTracks = player.videoTracks();
const firstTracks = player.videoTracks();
player.loadTech_('TechFaker');
let secondTracks = player.videoTracks();
const secondTracks = player.videoTracks();
ok(firstTracks === secondTracks, 'the tracks are equal');
QUnit.ok(firstTracks === secondTracks, 'the tracks are equal');
});

View File

@ -1,13 +1,13 @@
/* eslint-env qunit */
import document from 'global/document';
import * as Dom from '../../../src/js/utils/dom.js';
import TestHelpers from '../test-helpers.js';
q.module('dom');
QUnit.module('dom');
test('should return the element with the ID', function(){
var el1 = document.createElement('div');
var el2 = document.createElement('div');
var fixture = document.getElementById('qunit-fixture');
QUnit.test('should return the element with the ID', function() {
const el1 = document.createElement('div');
const el2 = document.createElement('div');
const fixture = document.getElementById('qunit-fixture');
fixture.appendChild(el1);
fixture.appendChild(el2);
@ -15,121 +15,128 @@ test('should return the element with the ID', function(){
el1.id = 'test_id1';
el2.id = 'test_id2';
ok(Dom.getEl('test_id1') === el1, 'found element for ID');
ok(Dom.getEl('#test_id2') === el2, 'found element for CSS ID');
QUnit.ok(Dom.getEl('test_id1') === el1, 'found element for ID');
QUnit.ok(Dom.getEl('#test_id2') === el2, 'found element for CSS ID');
});
test('should create an element', function(){
let div = Dom.createEl();
let span = Dom.createEl('span', {
QUnit.test('should create an element', function() {
const div = Dom.createEl();
const span = Dom.createEl('span', {
innerHTML: 'fdsa'
}, {
'data-test': 'asdf'
});
ok(div.nodeName === 'DIV');
ok(span.nodeName === 'SPAN');
ok(span.getAttribute('data-test') === 'asdf');
ok(span.innerHTML === 'fdsa');
QUnit.ok(div.nodeName === 'DIV');
QUnit.ok(span.nodeName === 'SPAN');
QUnit.ok(span.getAttribute('data-test') === 'asdf');
QUnit.ok(span.innerHTML === 'fdsa');
});
test('should insert an element first in another', function(){
var el1 = document.createElement('div');
var el2 = document.createElement('div');
var parent = document.createElement('div');
QUnit.test('should insert an element first in another', function() {
const el1 = document.createElement('div');
const el2 = document.createElement('div');
const parent = document.createElement('div');
Dom.insertElFirst(el1, parent);
ok(parent.firstChild === el1, 'inserts first into empty parent');
QUnit.ok(parent.firstChild === el1, 'inserts first into empty parent');
Dom.insertElFirst(el2, parent);
ok(parent.firstChild === el2, 'inserts first into parent with child');
QUnit.ok(parent.firstChild === el2, 'inserts first into parent with child');
});
test('should get and remove data from an element', function(){
var el = document.createElement('div');
var data = Dom.getElData(el);
QUnit.test('should get and remove data from an element', function() {
const el = document.createElement('div');
const data = Dom.getElData(el);
ok(typeof data === 'object', 'data object created');
QUnit.ok(typeof data === 'object', 'data object created');
// Add data
var testData = { asdf: 'fdsa' };
const testData = { asdf: 'fdsa' };
data.test = testData;
ok(Dom.getElData(el).test === testData, 'data added');
QUnit.ok(Dom.getElData(el).test === testData, 'data added');
// Remove all data
Dom.removeElData(el);
ok(!Dom.hasElData(el), 'cached item emptied');
QUnit.ok(!Dom.hasElData(el), 'cached item emptied');
});
test('addElClass()', function(){
var el = document.createElement('div');
QUnit.test('addElClass()', function() {
const el = document.createElement('div');
expect(5);
QUnit.expect(5);
Dom.addElClass(el, 'test-class');
strictEqual(el.className, 'test-class', 'adds a single class');
QUnit.strictEqual(el.className, 'test-class', 'adds a single class');
Dom.addElClass(el, 'test-class');
strictEqual(el.className, 'test-class', 'does not duplicate classes');
QUnit.strictEqual(el.className, 'test-class', 'does not duplicate classes');
throws(function(){
QUnit.throws(function() {
Dom.addElClass(el, 'foo foo-bar');
}, 'throws when attempting to add a class with whitespace');
Dom.addElClass(el, 'test2_className');
strictEqual(el.className, 'test-class test2_className', 'adds second class');
QUnit.strictEqual(el.className, 'test-class test2_className', 'adds second class');
Dom.addElClass(el, 'FOO');
strictEqual(el.className, 'test-class test2_className FOO', 'adds third class');
QUnit.strictEqual(el.className, 'test-class test2_className FOO', 'adds third class');
});
test('removeElClass()', function() {
var el = document.createElement('div');
QUnit.test('removeElClass()', function() {
const el = document.createElement('div');
el.className = 'test-class foo foo test2_className FOO bar';
expect(5);
QUnit.expect(5);
Dom.removeElClass(el, 'test-class');
strictEqual(el.className, 'foo foo test2_className FOO bar', 'removes one class');
QUnit.strictEqual(el.className, 'foo foo test2_className FOO bar', 'removes one class');
Dom.removeElClass(el, 'foo');
strictEqual(el.className, 'test2_className FOO bar', 'removes all instances of a class');
QUnit.strictEqual(el.className,
'test2_className FOO bar',
'removes all instances of a class');
throws(function(){
QUnit.throws(function() {
Dom.removeElClass(el, 'test2_className bar');
}, 'throws when attempting to remove a class with whitespace');
Dom.removeElClass(el, 'test2_className');
strictEqual(el.className, 'FOO bar', 'removes another class');
QUnit.strictEqual(el.className, 'FOO bar', 'removes another class');
Dom.removeElClass(el, 'FOO');
strictEqual(el.className, 'bar', 'removes another class');
QUnit.strictEqual(el.className, 'bar', 'removes another class');
});
test('hasElClass()', function(){
var el = document.createElement('div');
QUnit.test('hasElClass()', function() {
const el = document.createElement('div');
el.className = 'test-class foo foo test2_className FOO bar';
strictEqual(Dom.hasElClass(el, 'test-class'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'foo'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'test2_className'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'FOO'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'bar'), true, 'class detected');
strictEqual(Dom.hasElClass(el, 'test2'), false, 'valid substring - but not a class - correctly not detected');
strictEqual(Dom.hasElClass(el, 'className'), false, 'valid substring - but not a class - correctly not detected');
QUnit.strictEqual(Dom.hasElClass(el, 'test-class'), true, 'class detected');
QUnit.strictEqual(Dom.hasElClass(el, 'foo'), true, 'class detected');
QUnit.strictEqual(Dom.hasElClass(el, 'test2_className'), true, 'class detected');
QUnit.strictEqual(Dom.hasElClass(el, 'FOO'), true, 'class detected');
QUnit.strictEqual(Dom.hasElClass(el, 'bar'), true, 'class detected');
QUnit.strictEqual(Dom.hasElClass(el, 'test2'),
false,
'valid substring - but not a class - correctly not detected');
QUnit.strictEqual(Dom.hasElClass(el, 'className'),
false,
'valid substring - but not a class - correctly not detected');
throws(function(){
QUnit.throws(function() {
Dom.hasElClass(el, 'FOO bar');
}, 'throws when attempting to detect a class with whitespace');
});
test('toggleElClass()', function() {
let el = Dom.createEl('div', {className: 'foo bar'});
QUnit.test('toggleElClass()', function() {
const el = Dom.createEl('div', {className: 'foo bar'});
let predicateToggles = [
const predicateToggles = [
{
toggle: 'foo',
predicate: true,
@ -158,151 +165,162 @@ test('toggleElClass()', function() {
toggle: 'bar',
predicate: () => true,
className: 'bar baz',
message: 'if a predicate function returns `true`, matching the state of the element, do nothing'
message: 'if a predicate function returns `true`, ' +
'matching the state of the element, do nothing'
},
{
toggle: 'foo',
predicate: () => false,
className: 'bar baz',
message: 'if a predicate function returns `false`, matching the state of the element, do nothing'
message: 'if a predicate function returns `false`, matching ' +
'the state of the element, do nothing'
},
{
toggle: 'foo',
predicate: () => true,
className: 'bar baz foo',
message: 'if a predicate function returns `true`, differing from state of the element, add the class'
message: 'if a predicate function returns `true`, ' +
'differing from state of the element, add the class'
},
{
toggle: 'foo',
predicate: () => false,
className: 'bar baz',
message: 'if a predicate function returns `false`, differing from state of the element, remove the class'
message: 'if a predicate function returns `false`, differing ' +
'from state of the element, remove the class'
},
{
toggle: 'foo',
predicate: Function.prototype,
className: 'bar baz foo',
message: 'if a predicate function returns `undefined` and the element does not have the class, add the class'
message: 'if a predicate function returns `undefined` and ' +
'the element does not have the class, add the class'
},
{
toggle: 'bar',
predicate: Function.prototype,
className: 'baz foo',
message: 'if a predicate function returns `undefined` and the element has the class, remove the class'
message: 'if a predicate function returns `undefined` and the ' +
'element has the class, remove the class'
},
{
toggle: 'bar',
predicate: () => [],
className: 'baz foo bar',
message: 'if a predicate function returns a defined non-boolean value and the element does not have the class, add the class'
message: 'if a predicate function returns a defined non-boolean ' +
'value and the element does not have the class, add the class'
},
{
toggle: 'baz',
predicate: () => 'this is incorrect',
className: 'foo bar',
message: 'if a predicate function returns a defined non-boolean value and the element has the class, remove the class'
},
message: 'if a predicate function returns a defined non-boolean value ' +
'and the element has the class, remove the class'
}
];
expect(3 + predicateToggles.length);
QUnit.expect(3 + predicateToggles.length);
Dom.toggleElClass(el, 'bar');
strictEqual(el.className, 'foo', 'toggles a class off, if present');
QUnit.strictEqual(el.className, 'foo', 'toggles a class off, if present');
Dom.toggleElClass(el, 'bar');
strictEqual(el.className, 'foo bar', 'toggles a class on, if absent');
QUnit.strictEqual(el.className, 'foo bar', 'toggles a class on, if absent');
throws(function(){
QUnit.throws(function() {
Dom.toggleElClass(el, 'foo bar');
}, 'throws when attempting to toggle a class with whitespace');
predicateToggles.forEach(x => {
Dom.toggleElClass(el, x.toggle, x.predicate);
strictEqual(el.className, x.className, x.message);
QUnit.strictEqual(el.className, x.className, x.message);
});
});
test('should set element attributes from object', function(){
var el, vid1Vals;
QUnit.test('should set element attributes from object', function() {
const el = document.createElement('div');
el = document.createElement('div');
el.id = 'el1';
Dom.setElAttributes(el, {'controls': true, 'data-test': 'asdf'});
Dom.setElAttributes(el, { controls: true, 'data-test': 'asdf' });
equal(el.getAttribute('id'), 'el1');
equal(el.getAttribute('controls'), '');
equal(el.getAttribute('data-test'), 'asdf');
QUnit.equal(el.getAttribute('id'), 'el1');
QUnit.equal(el.getAttribute('controls'), '');
QUnit.equal(el.getAttribute('data-test'), 'asdf');
});
test('should read tag attributes from elements, including HTML5 in all browsers', function(){
QUnit.test('should read tag attributes from elements, including HTML5 in all browsers', function() {
// Creating the source/track tags outside of the video tag prevents log errors
let tags = `
const tags = `
<video id="vid1" controls autoplay loop muted preload="none" src="http://google.com" poster="http://www2.videojs.com/img/video-js-html5-video-player.png" data-test="asdf" data-empty-string="">
<source id="source" src="http://google.com" type="video/mp4" media="fdsa" title="test" >
</video>
<track id="track" default src="http://google.com" kind="captions" srclang="en" label="testlabel" title="test" >
`;
let fixture = document.getElementById('qunit-fixture');
const fixture = document.getElementById('qunit-fixture');
// Have to use innerHTML to append for IE8. AppendChild doesn't work.
// Also it must be added to the page body, not just in memory.
fixture.innerHTML += tags;
let vid1Vals = Dom.getElAttributes(fixture.getElementsByTagName('video')[0]);
let sourceVals = Dom.getElAttributes(fixture.getElementsByTagName('source')[0]);
let trackVals = Dom.getElAttributes(fixture.getElementsByTagName('track')[0]);
const vid1Vals = Dom.getElAttributes(fixture.getElementsByTagName('video')[0]);
const sourceVals = Dom.getElAttributes(fixture.getElementsByTagName('source')[0]);
const trackVals = Dom.getElAttributes(fixture.getElementsByTagName('track')[0]);
// vid1
// was using deepEqual, but ie8 would send all properties as attributes
equal(vid1Vals['autoplay'], true);
equal(vid1Vals['controls'], true);
equal(vid1Vals['data-test'], 'asdf');
equal(vid1Vals['data-empty-string'], '');
equal(vid1Vals['id'], 'vid1');
equal(vid1Vals['loop'], true);
equal(vid1Vals['muted'], true);
equal(vid1Vals['poster'], 'http://www2.videojs.com/img/video-js-html5-video-player.png');
equal(vid1Vals['preload'], 'none');
equal(vid1Vals['src'], 'http://google.com');
QUnit.equal(vid1Vals.autoplay, true);
QUnit.equal(vid1Vals.controls, true);
QUnit.equal(vid1Vals['data-test'], 'asdf');
QUnit.equal(vid1Vals['data-empty-string'], '');
QUnit.equal(vid1Vals.id, 'vid1');
QUnit.equal(vid1Vals.loop, true);
QUnit.equal(vid1Vals.muted, true);
QUnit.equal(vid1Vals.poster, 'http://www2.videojs.com/img/video-js-html5-video-player.png');
QUnit.equal(vid1Vals.preload, 'none');
QUnit.equal(vid1Vals.src, 'http://google.com');
// sourceVals
equal(sourceVals['title'], 'test');
equal(sourceVals['media'], 'fdsa');
equal(sourceVals['type'], 'video/mp4');
equal(sourceVals['src'], 'http://google.com');
equal(sourceVals['id'], 'source');
QUnit.equal(sourceVals.title, 'test');
QUnit.equal(sourceVals.media, 'fdsa');
QUnit.equal(sourceVals.type, 'video/mp4');
QUnit.equal(sourceVals.src, 'http://google.com');
QUnit.equal(sourceVals.id, 'source');
// trackVals
equal(trackVals['default'], true);
equal(trackVals['id'], 'track');
equal(trackVals['kind'], 'captions');
equal(trackVals['label'], 'testlabel');
equal(trackVals['src'], 'http://google.com');
equal(trackVals['srclang'], 'en');
equal(trackVals['title'], 'test');
QUnit.equal(trackVals.default, true);
QUnit.equal(trackVals.id, 'track');
QUnit.equal(trackVals.kind, 'captions');
QUnit.equal(trackVals.label, 'testlabel');
QUnit.equal(trackVals.src, 'http://google.com');
QUnit.equal(trackVals.srclang, 'en');
QUnit.equal(trackVals.title, 'test');
});
test('Dom.findElPosition should find top and left position', function() {
QUnit.test('Dom.findElPosition should find top and left position', function() {
const d = document.createElement('div');
let position = Dom.findElPosition(d);
d.style.top = '10px';
d.style.left = '20px';
d.style.position = 'absolute';
deepEqual(position, {left: 0, top: 0}, 'If element isn\'t in the DOM, we should get zeros');
QUnit.deepEqual(position,
{left: 0, top: 0},
'If element isn\'t in the DOM, we should get zeros');
document.body.appendChild(d);
position = Dom.findElPosition(d);
deepEqual(position, {left: 20, top: 10}, 'The position was not correct');
QUnit.deepEqual(position, {left: 20, top: 10}, 'The position was not correct');
d.getBoundingClientRect = null;
position = Dom.findElPosition(d);
deepEqual(position, {left: 0, top: 0}, 'If there is no gBCR, we should get zeros');
QUnit.deepEqual(position,
{left: 0, top: 0},
'If there is no gBCR, we should get zeros');
});
test('Dom.isEl', function(assert) {
QUnit.test('Dom.isEl', function(assert) {
assert.expect(7);
assert.notOk(Dom.isEl(), 'undefined is not an element');
assert.notOk(Dom.isEl(true), 'booleans are not elements');
@ -313,19 +331,20 @@ test('Dom.isEl', function(assert) {
assert.ok(Dom.isEl({nodeType: 1}), 'duck typing is imperfect');
});
test('Dom.isTextNode', function(assert) {
QUnit.test('Dom.isTextNode', function(assert) {
assert.expect(7);
assert.notOk(Dom.isTextNode(), 'undefined is not a text node');
assert.notOk(Dom.isTextNode(true), 'booleans are not text nodes');
assert.notOk(Dom.isTextNode({}), 'objects are not text nodes');
assert.notOk(Dom.isTextNode([]), 'arrays are not text nodes');
assert.notOk(Dom.isTextNode('hola mundo'), 'strings are not text nodes');
assert.ok(Dom.isTextNode(document.createTextNode('hello, world!')), 'text nodes are text nodes');
assert.ok(Dom.isTextNode(document.createTextNode('hello, world!')),
'text nodes are text nodes');
assert.ok(Dom.isTextNode({nodeType: 3}), 'duck typing is imperfect');
});
test('Dom.emptyEl', function(assert) {
let el = Dom.createEl();
QUnit.test('Dom.emptyEl', function(assert) {
const el = Dom.createEl();
el.appendChild(Dom.createEl('span'));
el.appendChild(Dom.createEl('span'));
@ -338,16 +357,19 @@ test('Dom.emptyEl', function(assert) {
assert.notOk(el.firstChild, 'the element was emptied');
});
test('Dom.normalizeContent: strings and elements/nodes', function(assert) {
QUnit.test('Dom.normalizeContent: strings and elements/nodes', function(assert) {
assert.expect(8);
let str = Dom.normalizeContent('hello');
const str = Dom.normalizeContent('hello');
assert.strictEqual(str[0].data, 'hello', 'single string becomes a text node');
let elem = Dom.normalizeContent(Dom.createEl());
const elem = Dom.normalizeContent(Dom.createEl());
assert.ok(Dom.isEl(elem[0]), 'an element is passed through');
let node = Dom.normalizeContent(document.createTextNode('goodbye'));
const node = Dom.normalizeContent(document.createTextNode('goodbye'));
assert.strictEqual(node[0].data, 'goodbye', 'a text node is passed through');
assert.strictEqual(Dom.normalizeContent(null).length, 0, 'falsy values are ignored');
@ -357,30 +379,47 @@ test('Dom.normalizeContent: strings and elements/nodes', function(assert) {
assert.strictEqual(Dom.normalizeContent({}).length, 0, 'objects are ignored');
});
test('Dom.normalizeContent: functions returning strings and elements/nodes', function(assert) {
QUnit.test('Dom.normalizeContent: functions returning strings and elements/nodes', function(assert) {
assert.expect(9);
let str = Dom.normalizeContent(() => 'hello');
assert.strictEqual(str[0].data, 'hello', 'a function can return a string, which becomes a text node');
const str = Dom.normalizeContent(() => 'hello');
assert.strictEqual(str[0].data,
'hello',
'a function can return a string, which becomes a text node');
const elem = Dom.normalizeContent(() => Dom.createEl());
let elem = Dom.normalizeContent(() => Dom.createEl());
assert.ok(Dom.isEl(elem[0]), 'a function can return an element');
let node = Dom.normalizeContent(() => document.createTextNode('goodbye'));
const node = Dom.normalizeContent(() => document.createTextNode('goodbye'));
assert.strictEqual(node[0].data, 'goodbye', 'a function can return a text node');
assert.strictEqual(Dom.normalizeContent(() => null).length, 0, 'a function CANNOT return falsy values');
assert.strictEqual(Dom.normalizeContent(() => false).length, 0, 'a function CANNOT return falsy values');
assert.strictEqual(Dom.normalizeContent(() => undefined).length, 0, 'a function CANNOT return falsy values');
assert.strictEqual(Dom.normalizeContent(() => 123).length, 0, 'a function CANNOT return numbers');
assert.strictEqual(Dom.normalizeContent(() => {}).length, 0, 'a function CANNOT return objects');
assert.strictEqual(Dom.normalizeContent(() => (() => null)).length, 0, 'a function CANNOT return a function');
assert.strictEqual(Dom.normalizeContent(() => null).length,
0,
'a function CANNOT return falsy values');
assert.strictEqual(Dom.normalizeContent(() => false).length,
0,
'a function CANNOT return falsy values');
assert.strictEqual(Dom.normalizeContent(() => undefined).length,
0,
'a function CANNOT return falsy values');
assert.strictEqual(Dom.normalizeContent(() => 123).length,
0,
'a function CANNOT return numbers');
assert.strictEqual(Dom.normalizeContent(() => {}).length,
0,
'a function CANNOT return objects');
assert.strictEqual(Dom.normalizeContent(() => (() => null)).length,
0,
'a function CANNOT return a function');
});
test('Dom.normalizeContent: arrays of strings and objects', function(assert) {
QUnit.test('Dom.normalizeContent: arrays of strings and objects', function(assert) {
assert.expect(7);
let source = [
const source = [
'hello',
{},
Dom.createEl(),
@ -389,43 +428,52 @@ test('Dom.normalizeContent: arrays of strings and objects', function(assert) {
document.createTextNode('goodbye'),
() => 'it works'
];
const result = Dom.normalizeContent(source);
let result = Dom.normalizeContent(source);
assert.strictEqual(result[0].data, 'hello', 'an array can include a string normalized to a text node');
assert.strictEqual(result[0].data,
'hello',
'an array can include a string normalized to a text node');
assert.ok(Dom.isEl(result[1]), 'an array can include an element');
assert.strictEqual(result[2].data, 'goodbye', 'an array can include a text node');
assert.strictEqual(result[3].data, 'it works', 'an array can include a function, which is invoked');
assert.strictEqual(result[3].data,
'it works',
'an array can include a function, which is invoked');
assert.strictEqual(result.indexOf(source[1]), -1, 'an array CANNOT include an object');
assert.strictEqual(result.indexOf(source[3]), -1, 'an array CANNOT include an array');
assert.strictEqual(result.indexOf(source[4]), -1, 'an array CANNOT include falsy values');
assert.strictEqual(result.indexOf(source[4]),
-1,
'an array CANNOT include falsy values');
});
test('Dom.normalizeContent: functions returning arrays', function(assert) {
QUnit.test('Dom.normalizeContent: functions returning arrays', function(assert) {
assert.expect(3);
let arr = [];
let result = Dom.normalizeContent(() => ['hello', Function.prototype, arr]);
const arr = [];
const result = Dom.normalizeContent(() => ['hello', Function.prototype, arr]);
assert.strictEqual(result[0].data, 'hello', 'a function can return an array');
assert.strictEqual(result.indexOf(Function.prototype), -1, 'a function can return an array, but it CANNOT include a function');
assert.strictEqual(result.indexOf(arr), -1, 'a function can return an array, but it CANNOT include an array');
assert.strictEqual(result.indexOf(Function.prototype),
-1,
'a function can return an array, but it CANNOT include a function');
assert.strictEqual(result.indexOf(arr),
-1,
'a function can return an array, but it CANNOT include an array');
});
test('Dom.insertContent', function(assert) {
let p = Dom.createEl('p');
let text = document.createTextNode('hello');
let el = Dom.insertContent(Dom.createEl(), [p, text]);
QUnit.test('Dom.insertContent', function(assert) {
const p = Dom.createEl('p');
const text = document.createTextNode('hello');
const el = Dom.insertContent(Dom.createEl(), [p, text]);
assert.expect(2);
assert.strictEqual(el.firstChild, p, 'the paragraph was inserted first');
assert.strictEqual(el.firstChild.nextSibling, text, 'the text node was inserted last');
});
test('Dom.appendContent', function(assert) {
let p1 = Dom.createEl('p');
let p2 = Dom.createEl('p');
let el = Dom.insertContent(Dom.createEl(), [p1]);
QUnit.test('Dom.appendContent', function(assert) {
const p1 = Dom.createEl('p');
const p2 = Dom.createEl('p');
const el = Dom.insertContent(Dom.createEl(), [p1]);
Dom.appendContent(el, p2);
@ -434,37 +482,59 @@ test('Dom.appendContent', function(assert) {
assert.strictEqual(el.firstChild.nextSibling, p2, 'the second paragraph was appended');
});
test('$() and $$()', function() {
let fixture = document.getElementById('qunit-fixture');
let container = document.createElement('div');
let children = [
document.createElement('div'),
QUnit.test('$() and $$()', function() {
const fixture = document.getElementById('qunit-fixture');
const container = document.createElement('div');
const children = [
document.createElement('div'),
document.createElement('div'),
document.createElement('div')
];
children.forEach(child => container.appendChild(child));
fixture.appendChild(container);
let totalDivCount = document.getElementsByTagName('div').length;
const totalDivCount = document.getElementsByTagName('div').length;
expect(12);
QUnit.expect(12);
strictEqual(Dom.$('#qunit-fixture'), fixture, 'can find an element in the document context');
strictEqual(Dom.$$('div').length, totalDivCount, 'finds elements in the document context');
QUnit.strictEqual(Dom.$('#qunit-fixture'),
fixture,
'can find an element in the document context');
QUnit.strictEqual(Dom.$$('div').length,
totalDivCount,
'finds elements in the document context');
strictEqual(Dom.$('div', container), children[0], 'can find an element in a DOM element context');
strictEqual(Dom.$$('div', container).length, children.length, 'finds elements in a DOM element context');
QUnit.strictEqual(Dom.$('div', container),
children[0],
'can find an element in a DOM element context');
QUnit.strictEqual(Dom.$$('div', container).length,
children.length,
'finds elements in a DOM element context');
strictEqual(Dom.$('#qunit-fixture', document.querySelector('unknown')), fixture, 'falls back to document given a bad context element');
strictEqual(Dom.$$('div', document.querySelector('unknown')).length, totalDivCount, 'falls back to document given a bad context element');
QUnit.strictEqual(Dom.$('#qunit-fixture', document.querySelector('unknown')),
fixture,
'falls back to document given a bad context element');
QUnit.strictEqual(Dom.$$('div', document.querySelector('unknown')).length,
totalDivCount,
'falls back to document given a bad context element');
strictEqual(Dom.$('#qunit-fixture', 'body'), fixture, 'can find an element in a selector context');
strictEqual(Dom.$$('div', '#qunit-fixture').length, 1 + children.length, 'finds elements in a selector context');
QUnit.strictEqual(Dom.$('#qunit-fixture', 'body'),
fixture,
'can find an element in a selector context');
QUnit.strictEqual(Dom.$$('div', '#qunit-fixture').length,
1 + children.length,
'finds elements in a selector context');
strictEqual(Dom.$('#qunit-fixture', 'unknown'), fixture, 'falls back to document given a bad context selector');
strictEqual(Dom.$$('div', 'unknown').length, totalDivCount, 'falls back to document given a bad context selector');
QUnit.strictEqual(Dom.$('#qunit-fixture', 'unknown'),
fixture,
'falls back to document given a bad context selector');
QUnit.strictEqual(Dom.$$('div', 'unknown').length,
totalDivCount,
'falls back to document given a bad context selector');
strictEqual(Dom.$('div', children[0]), null, 'returns null for missing elements');
strictEqual(Dom.$$('div', children[0]).length, 0, 'returns 0 for missing elements');
QUnit.strictEqual(Dom.$('div', children[0]), null, 'returns null for missing elements');
QUnit.strictEqual(Dom.$$('div', children[0]).length,
0,
'returns 0 for missing elements');
});

View File

@ -1,13 +1,14 @@
/* eslint-env qunit */
import * as Fn from '../../../src/js/utils/fn.js';
q.module('fn');
QUnit.module('fn');
test('should add context to a function', function(){
var newContext = { test: 'obj'};
var asdf = function(){
ok(this === newContext);
QUnit.test('should add context to a function', function() {
const newContext = { test: 'obj'};
const asdf = function() {
QUnit.ok(this === newContext);
};
var fdsa = Fn.bind(newContext, asdf);
const fdsa = Fn.bind(newContext, asdf);
fdsa();
});

View File

@ -1,35 +1,35 @@
/* eslint-env qunit */
import formatTime from '../../../src/js/utils/format-time.js';
q.module('format-time');
QUnit.module('format-time');
test('should format time as a string', function(){
ok(formatTime(1) === '0:01');
ok(formatTime(10) === '0:10');
ok(formatTime(60) === '1:00');
ok(formatTime(600) === '10:00');
ok(formatTime(3600) === '1:00:00');
ok(formatTime(36000) === '10:00:00');
ok(formatTime(360000) === '100:00:00');
QUnit.test('should format time as a string', function() {
QUnit.ok(formatTime(1) === '0:01');
QUnit.ok(formatTime(10) === '0:10');
QUnit.ok(formatTime(60) === '1:00');
QUnit.ok(formatTime(600) === '10:00');
QUnit.ok(formatTime(3600) === '1:00:00');
QUnit.ok(formatTime(36000) === '10:00:00');
QUnit.ok(formatTime(360000) === '100:00:00');
// Using guide should provide extra leading zeros
ok(formatTime(1,1) === '0:01');
ok(formatTime(1,10) === '0:01');
ok(formatTime(1,60) === '0:01');
ok(formatTime(1,600) === '00:01');
ok(formatTime(1,3600) === '0:00:01');
QUnit.ok(formatTime(1, 1) === '0:01');
QUnit.ok(formatTime(1, 10) === '0:01');
QUnit.ok(formatTime(1, 60) === '0:01');
QUnit.ok(formatTime(1, 600) === '00:01');
QUnit.ok(formatTime(1, 3600) === '0:00:01');
// Don't do extra leading zeros for hours
ok(formatTime(1,36000) === '0:00:01');
ok(formatTime(1,360000) === '0:00:01');
QUnit.ok(formatTime(1, 36000) === '0:00:01');
QUnit.ok(formatTime(1, 360000) === '0:00:01');
// Do not display negative time
ok(formatTime(-1) === '0:00');
ok(formatTime(-1,3600) === '0:00:00');
QUnit.ok(formatTime(-1) === '0:00');
QUnit.ok(formatTime(-1, 3600) === '0:00:00');
});
test('should format invalid times as dashes', function(){
equal(formatTime(Infinity, 90), '-:-');
equal(formatTime(NaN), '-:-');
// equal(formatTime(NaN, 216000), '-:--:--');
equal(formatTime(10, Infinity), '0:00:10');
equal(formatTime(90, NaN), '1:30');
QUnit.test('should format invalid times as dashes', function() {
QUnit.equal(formatTime(Infinity, 90), '-:-');
QUnit.equal(formatTime(NaN), '-:-');
QUnit.equal(formatTime(10, Infinity), '0:00:10');
QUnit.equal(formatTime(90, NaN), '1:30');
});

View File

@ -1,9 +1,11 @@
/* eslint-env qunit */
import {IE_VERSION} from '../../../src/js/utils/browser';
import log from '../../../src/js/utils/log.js';
import {logByType} from '../../../src/js/utils/log.js';
import window from 'global/window';
import sinon from 'sinon';
q.module('log', {
QUnit.module('log', {
beforeEach() {
@ -35,7 +37,7 @@ q.module('log', {
const getConsoleArgs = (...arr) =>
IE_VERSION && IE_VERSION < 11 ? [arr.join(' ')] : arr;
test('logging functions should work', function() {
QUnit.test('logging functions should work', function() {
// Need to reset history here because there are extra messages logged
// when running via Karma.
@ -45,28 +47,28 @@ test('logging functions should work', function() {
log.warn('warn1', 'warn2');
log.error('error1', 'error2');
ok(window.console.log.called, 'log was called');
deepEqual(
QUnit.ok(window.console.log.called, 'log was called');
QUnit.deepEqual(
window.console.log.firstCall.args,
getConsoleArgs('VIDEOJS:', 'log1', 'log2')
);
ok(window.console.warn.called, 'warn was called');
deepEqual(
QUnit.ok(window.console.warn.called, 'warn was called');
QUnit.deepEqual(
window.console.warn.firstCall.args,
getConsoleArgs('VIDEOJS:', 'WARN:', 'warn1', 'warn2')
);
ok(window.console.error.called, 'error was called');
deepEqual(
QUnit.ok(window.console.error.called, 'error was called');
QUnit.deepEqual(
window.console.error.firstCall.args,
getConsoleArgs('VIDEOJS:', 'ERROR:', 'error1', 'error2')
);
equal(log.history.length, 3, 'there should be three messages in the log history');
QUnit.equal(log.history.length, 3, 'there should be three messages in the log history');
});
test('in IE pre-11 (or when requested) objects and arrays are stringified', function() {
QUnit.test('in IE pre-11 (or when requested) objects and arrays are stringified', function() {
// Run a custom log call, explicitly requesting object/array stringification.
logByType('log', [
@ -78,7 +80,7 @@ test('in IE pre-11 (or when requested) objects and arrays are stringified', func
null
], true);
ok(window.console.log.called, 'log was called');
deepEqual(window.console.log.firstCall.args,
QUnit.ok(window.console.log.called, 'log was called');
QUnit.deepEqual(window.console.log.firstCall.args,
['VIDEOJS: test {"foo":"bar"} [1,2,3] 0 false null']);
});

View File

@ -1,17 +1,15 @@
/* eslint-env qunit */
import mergeOptions from '../../../src/js/utils/merge-options.js';
q.module('merge-options');
test('should merge options objects', function(){
var ob1, ob2, ob3;
ob1 = {
QUnit.module('merge-options');
QUnit.test('should merge options objects', function() {
const ob1 = {
a: true,
b: { b1: true, b2: true, b3: true },
c: true
};
ob2 = {
const ob2 = {
// override value
a: false,
// merge sub-option values
@ -20,9 +18,9 @@ test('should merge options objects', function(){
d: true
};
ob3 = mergeOptions(ob1, ob2);
const ob3 = mergeOptions(ob1, ob2);
deepEqual(ob3, {
QUnit.deepEqual(ob3, {
a: false,
b: { b1: true, b2: false, b3: true, b4: true },
c: true,

View File

@ -1,30 +1,45 @@
/* eslint-env qunit */
import { createTimeRanges, createTimeRange } from '../../../src/js/utils/time-ranges.js';
q.module('time-ranges');
QUnit.module('time-ranges');
test('should export the deprecated createTimeRange function', function(){
equal(createTimeRange, createTimeRanges, 'createTimeRange is an alias to createTimeRanges');
QUnit.test('should export the deprecated createTimeRange function', function() {
QUnit.equal(createTimeRange,
createTimeRanges,
'createTimeRange is an alias to createTimeRanges');
});
test('should create a fake single timerange', function(assert){
var tr = createTimeRanges(0, 10);
QUnit.test('should create a fake single timerange', function(assert) {
const tr = createTimeRanges(0, 10);
equal(tr.length, 1, 'length should be 1');
equal(tr.start(0), 0, 'works if start is called with valid index');
equal(tr.end(0), 10, 'works if end is called with with valid index');
assert.throws(()=>tr.start(1), /Failed to execute 'start'/, 'fails if start is called with an invalid index');
assert.throws(()=>tr.end(1), /Failed to execute 'end'/, 'fails if end is called with with an invalid index');
QUnit.equal(tr.length, 1, 'length should be 1');
QUnit.equal(tr.start(0),
0,
'works if start is called with valid index');
QUnit.equal(tr.end(0),
10,
'works if end is called with with valid index');
assert.throws(()=>tr.start(1),
/Failed to execute 'start'/,
'fails if start is called with an invalid index');
assert.throws(()=>tr.end(1),
/Failed to execute 'end'/,
'fails if end is called with with an invalid index');
});
test('should create a fake multiple timerange', function(assert){
var tr = createTimeRanges([
QUnit.test('should create a fake multiple timerange', function(assert) {
const tr = createTimeRanges([
[0, 10],
[11, 20]
]);
equal(tr.length, 2, 'length should equal 2');
equal(tr.start(1), 11, 'works if start is called with valid index');
equal(tr.end(1), 20, 'works if end is called with with valid index');
assert.throws(()=>tr.start(-1), /Failed to execute 'start'/, 'fails if start is called with an invalid index');
assert.throws(()=>tr.end(-1), /Failed to execute 'end'/, 'fails if end is called with with an invalid index');
QUnit.equal(tr.length, 2, 'length should equal 2');
QUnit.equal(tr.start(1), 11, 'works if start is called with valid index');
QUnit.equal(tr.end(1), 20, 'works if end is called with with valid index');
assert.throws(()=>tr.start(-1),
/Failed to execute 'start'/,
'fails if start is called with an invalid index');
assert.throws(()=>tr.end(-1),
/Failed to execute 'end'/,
'fails if end is called with with an invalid index');
});

View File

@ -1,8 +1,10 @@
/* eslint-env qunit */
import toTitleCase from '../../../src/js/utils/to-title-case.js';
q.module('to-title-case');
QUnit.module('to-title-case');
test('should make a string start with an uppercase letter', function(){
var foo = toTitleCase('bar');
ok(foo === 'Bar');
QUnit.test('should make a string start with an uppercase letter', function() {
const foo = toTitleCase('bar');
QUnit.ok(foo === 'Bar');
});

View File

@ -1,24 +1,25 @@
/* eslint-env qunit */
import document from 'global/document';
import window from 'global/window';
import * as Url from '../../../src/js/utils/url.js';
import proxyquireify from 'proxyquireify';
const proxyquire = proxyquireify(require);
q.module('url');
QUnit.module('url');
QUnit.test('should parse the details of a url correctly', function() {
QUnit.equal(Url.parseUrl('#').protocol,
window.location.protocol,
'parsed relative url protocol');
QUnit.equal(Url.parseUrl('#').host, window.location.host, 'parsed relative url host');
test('should parse the details of a url correctly', function(){
equal(Url.parseUrl('#').protocol, window.location.protocol, 'parsed relative url protocol');
equal(Url.parseUrl('#').host, window.location.host, 'parsed relative url host');
QUnit.equal(Url.parseUrl('http://example.com').protocol, 'http:', 'parsed example url protocol');
QUnit.equal(Url.parseUrl('http://example.com').hostname, 'example.com', 'parsed example url hostname');
equal(Url.parseUrl('http://example.com').protocol, 'http:', 'parsed example url protocol');
equal(Url.parseUrl('http://example.com').hostname, 'example.com', 'parsed example url hostname');
equal(Url.parseUrl('http://example.com:1234').port, '1234', 'parsed example url port');
QUnit.equal(Url.parseUrl('http://example.com:1234').port, '1234', 'parsed example url port');
});
test('should strip port from hosts using http or https', function() {
var url;
var origDocCreate = document.createElement;
QUnit.test('should strip port from hosts using http or https', function() {
const origDocCreate = document.createElement;
// attempts to create elements will return an anchor tag that
// misbehaves like IE9
@ -33,67 +34,67 @@ test('should strip port from hosts using http or https', function() {
};
};
url = Url.parseUrl('/domain/relative/url');
const url = Url.parseUrl('/domain/relative/url');
document.createElement = origDocCreate;
ok(!(/.*:80$/).test(url.host), ':80 is not appended to the host');
QUnit.ok(!(/.*:80$/).test(url.host), ':80 is not appended to the host');
});
test('should get an absolute URL', function(){
QUnit.test('should get an absolute URL', function() {
// Errors on compiled tests that don't use unit.html. Need a better solution.
// ok(Url.getAbsoluteURL('unit.html') === window.location.href);
ok(Url.getAbsoluteURL('http://asdf.com') === 'http://asdf.com');
ok(Url.getAbsoluteURL('https://asdf.com/index.html') === 'https://asdf.com/index.html');
// QUnit.ok(Url.getAbsoluteURL('unit.html') === window.location.href);
QUnit.ok(Url.getAbsoluteURL('http://asdf.com') === 'http://asdf.com');
QUnit.ok(Url.getAbsoluteURL('https://asdf.com/index.html') === 'https://asdf.com/index.html');
});
//getFileExtension tests
test('should get the file extension of the passed path', function() {
equal(Url.getFileExtension('/foo/bar/test.video.wgg'), 'wgg');
equal(Url.getFileExtension('test./video.mp4'), 'mp4');
equal(Url.getFileExtension('.bar/test.video.m4v'), 'm4v');
equal(Url.getFileExtension('foo/.bar/test.video.flv'), 'flv');
equal(Url.getFileExtension('foo/.bar/test.video.flv?foo=bar'), 'flv');
equal(Url.getFileExtension('http://www.test.com/video.mp4'), 'mp4');
equal(Url.getFileExtension('http://foo/bar/test.video.wgg'), 'wgg');
// getFileExtension tests
QUnit.test('should get the file extension of the passed path', function() {
QUnit.equal(Url.getFileExtension('/foo/bar/test.video.wgg'), 'wgg');
QUnit.equal(Url.getFileExtension('test./video.mp4'), 'mp4');
QUnit.equal(Url.getFileExtension('.bar/test.video.m4v'), 'm4v');
QUnit.equal(Url.getFileExtension('foo/.bar/test.video.flv'), 'flv');
QUnit.equal(Url.getFileExtension('foo/.bar/test.video.flv?foo=bar'), 'flv');
QUnit.equal(Url.getFileExtension('http://www.test.com/video.mp4'), 'mp4');
QUnit.equal(Url.getFileExtension('http://foo/bar/test.video.wgg'), 'wgg');
//edge cases
equal(Url.getFileExtension('http://...'), '');
equal(Url.getFileExtension('foo/.bar/testvideo'), '');
equal(Url.getFileExtension(''), '');
equal(Url.getFileExtension(null), '');
equal(Url.getFileExtension(undefined), '');
// edge cases
QUnit.equal(Url.getFileExtension('http://...'), '');
QUnit.equal(Url.getFileExtension('foo/.bar/testvideo'), '');
QUnit.equal(Url.getFileExtension(''), '');
QUnit.equal(Url.getFileExtension(null), '');
QUnit.equal(Url.getFileExtension(undefined), '');
//with capital letters
equal(Url.getFileExtension('test.video.MP4'), 'mp4');
equal(Url.getFileExtension('test.video.FLV'), 'flv');
// with capital letters
QUnit.equal(Url.getFileExtension('test.video.MP4'), 'mp4');
QUnit.equal(Url.getFileExtension('test.video.FLV'), 'flv');
});
// isCrossOrigin tests
test('isCrossOrigin can identify cross origin urls', function() {
let win = {
QUnit.test('isCrossOrigin can identify cross origin urls', function() {
const win = {
location: {}
};
let Url = proxyquire('../../../src/js/utils/url.js', {
const Url_ = proxyquire('../../../src/js/utils/url.js', {
'global/window': win
});
win.location.protocol = window.location.protocol;
win.location.host = window.location.host;
ok(!Url.isCrossOrigin(`http://${win.location.host}/example.vtt`), 'http://google.com from http://google.com is not cross origin');
ok(Url.isCrossOrigin(`https://${win.location.host}/example.vtt`), 'https://google.com from http://google.com is cross origin');
ok(!Url.isCrossOrigin(`//${win.location.host}/example.vtt`), '//google.com from http://google.com is not cross origin');
ok(Url.isCrossOrigin('http://example.com/example.vtt'), 'http://example.com from http://google.com is cross origin');
ok(Url.isCrossOrigin('https://example.com/example.vtt'), 'https://example.com from http://google.com is cross origin');
ok(Url.isCrossOrigin('//example.com/example.vtt'), '//example.com from http://google.com is cross origin');
QUnit.ok(!Url_.isCrossOrigin(`http://${win.location.host}/example.vtt`), 'http://google.com from http://google.com is not cross origin');
QUnit.ok(Url_.isCrossOrigin(`https://${win.location.host}/example.vtt`), 'https://google.com from http://google.com is cross origin');
QUnit.ok(!Url_.isCrossOrigin(`//${win.location.host}/example.vtt`), '//google.com from http://google.com is not cross origin');
QUnit.ok(Url_.isCrossOrigin('http://example.com/example.vtt'), 'http://example.com from http://google.com is cross origin');
QUnit.ok(Url_.isCrossOrigin('https://example.com/example.vtt'), 'https://example.com from http://google.com is cross origin');
QUnit.ok(Url_.isCrossOrigin('//example.com/example.vtt'), '//example.com from http://google.com is cross origin');
// we cannot test that relative urls work on https, though
ok(!Url.isCrossOrigin('example.vtt'), 'relative url is not cross origin');
QUnit.ok(!Url_.isCrossOrigin('example.vtt'), 'relative url is not cross origin');
win.location.protocol = 'https:';
win.location.host = 'google.com';
ok(Url.isCrossOrigin('http://google.com/example.vtt'), 'http://google.com from https://google.com is cross origin');
ok(Url.isCrossOrigin('http://example.com/example.vtt'), 'http://example.com from https://google.com is cross origin');
ok(Url.isCrossOrigin('https://example.com/example.vtt'), 'https://example.com from https://google.com is cross origin');
ok(Url.isCrossOrigin('//example.com/example.vtt'), '//example.com from https://google.com is cross origin');
QUnit.ok(Url_.isCrossOrigin('http://google.com/example.vtt'), 'http://google.com from https://google.com is cross origin');
QUnit.ok(Url_.isCrossOrigin('http://example.com/example.vtt'), 'http://example.com from https://google.com is cross origin');
QUnit.ok(Url_.isCrossOrigin('https://example.com/example.vtt'), 'https://example.com from https://google.com is cross origin');
QUnit.ok(Url_.isCrossOrigin('//example.com/example.vtt'), '//example.com from https://google.com is cross origin');
});

View File

@ -1,133 +1,145 @@
/* eslint-env qunit */
import videojs from '../../src/js/video.js';
import TestHelpers from './test-helpers.js';
import Player from '../../src/js/player.js';
import * as Dom from '../../src/js/utils/dom.js';
import log from '../../src/js/utils/log.js';
import document from 'global/document';
q.module('video.js');
QUnit.module('video.js');
test('should create a video tag and have access children in old IE', function(){
var fixture = document.getElementById('qunit-fixture');
QUnit.test('should create a video tag and have access children in old IE', function() {
const fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<video id="test_vid_id"><source type="video/mp4"></video>';
var vid = document.getElementById('test_vid_id');
const vid = document.getElementById('test_vid_id');
ok(vid.childNodes.length === 1);
ok(vid.childNodes[0].getAttribute('type') === 'video/mp4');
QUnit.ok(vid.childNodes.length === 1);
QUnit.ok(vid.childNodes[0].getAttribute('type') === 'video/mp4');
});
test('should return a video player instance', function(){
var fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<video id="test_vid_id"></video><video id="test_vid_id2"></video>';
QUnit.test('should return a video player instance', function() {
const fixture = document.getElementById('qunit-fixture');
var player = videojs('test_vid_id', { techOrder: ['techFaker'] });
ok(player, 'created player from tag');
ok(player.id() === 'test_vid_id');
ok(videojs.getPlayers()['test_vid_id'] === player, 'added player to global reference');
fixture.innerHTML += '<video id="test_vid_id"></video>' +
'<video id="test_vid_id2"></video>';
var playerAgain = videojs('test_vid_id');
ok(player === playerAgain, 'did not create a second player from same tag');
const player = videojs('test_vid_id', { techOrder: ['techFaker'] });
equal(player, playerAgain, 'we did not make a new player');
QUnit.ok(player, 'created player from tag');
QUnit.ok(player.id() === 'test_vid_id');
QUnit.ok(videojs.getPlayers().test_vid_id === player,
'added player to global reference');
var tag2 = document.getElementById('test_vid_id2');
var player2 = videojs(tag2, { techOrder: ['techFaker'] });
ok(player2.id() === 'test_vid_id2', 'created player from element');
const playerAgain = videojs('test_vid_id');
QUnit.ok(player === playerAgain, 'did not create a second player from same tag');
QUnit.equal(player, playerAgain, 'we did not make a new player');
const tag2 = document.getElementById('test_vid_id2');
const player2 = videojs(tag2, { techOrder: ['techFaker'] });
QUnit.ok(player2.id() === 'test_vid_id2', 'created player from element');
});
test('should return a video player instance from el html5 tech', function() {
var fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<video id="test_vid_id"></video><video id="test_vid_id2"></video>';
QUnit.test('should return a video player instance from el html5 tech', function() {
const fixture = document.getElementById('qunit-fixture');
var vid = document.querySelector('#test_vid_id');
fixture.innerHTML += '<video id="test_vid_id"></video>' +
'<video id="test_vid_id2"></video>';
var player = videojs(vid);
ok(player, 'created player from tag');
ok(player.id() === 'test_vid_id');
ok(videojs.getPlayers()['test_vid_id'] === player, 'added player to global reference');
const vid = document.querySelector('#test_vid_id');
var playerAgain = videojs(vid);
ok(player === playerAgain, 'did not create a second player from same tag');
const player = videojs(vid);
equal(player, playerAgain, 'we did not make a new player');
QUnit.ok(player, 'created player from tag');
QUnit.ok(player.id() === 'test_vid_id');
QUnit.ok(videojs.getPlayers().test_vid_id === player,
'added player to global reference');
var tag2 = document.getElementById('test_vid_id2');
var player2 = videojs(tag2, { techOrder: ['techFaker'] });
ok(player2.id() === 'test_vid_id2', 'created player from element');
const playerAgain = videojs(vid);
QUnit.ok(player === playerAgain, 'did not create a second player from same tag');
QUnit.equal(player, playerAgain, 'we did not make a new player');
const tag2 = document.getElementById('test_vid_id2');
const player2 = videojs(tag2, { techOrder: ['techFaker'] });
QUnit.ok(player2.id() === 'test_vid_id2', 'created player from element');
});
test('should return a video player instance from el techfaker', function() {
var fixture = document.getElementById('qunit-fixture');
fixture.innerHTML += '<video id="test_vid_id"></video><video id="test_vid_id2"></video>';
QUnit.test('should return a video player instance from el techfaker', function() {
const fixture = document.getElementById('qunit-fixture');
var vid = document.querySelector('#test_vid_id');
fixture.innerHTML += '<video id="test_vid_id"></video>' +
'<video id="test_vid_id2"></video>';
var player = videojs(vid, {techOrder: ['techFaker']});
ok(player, 'created player from tag');
ok(player.id() === 'test_vid_id');
ok(videojs.getPlayers()['test_vid_id'] === player, 'added player to global reference');
const vid = document.querySelector('#test_vid_id');
const player = videojs(vid, {techOrder: ['techFaker']});
var playerAgain = videojs(vid);
ok(player === playerAgain, 'did not create a second player from same tag');
QUnit.ok(player, 'created player from tag');
QUnit.ok(player.id() === 'test_vid_id');
QUnit.ok(videojs.getPlayers().test_vid_id === player,
'added player to global reference');
equal(player, playerAgain, 'we did not make a new player');
const playerAgain = videojs(vid);
var tag2 = document.getElementById('test_vid_id2');
var player2 = videojs(tag2, { techOrder: ['techFaker'] });
ok(player2.id() === 'test_vid_id2', 'created player from element');
QUnit.ok(player === playerAgain, 'did not create a second player from same tag');
QUnit.equal(player, playerAgain, 'we did not make a new player');
const tag2 = document.getElementById('test_vid_id2');
const player2 = videojs(tag2, { techOrder: ['techFaker'] });
QUnit.ok(player2.id() === 'test_vid_id2', 'created player from element');
});
test('should add the value to the languages object', function() {
var code, data, result;
QUnit.test('should add the value to the languages object', function() {
const code = 'es';
const data = {Hello: 'Hola'};
const result = videojs.addLanguage(code, data);
code = 'es';
data = {'Hello': 'Hola'};
result = videojs.addLanguage(code, data);
ok(videojs.options.languages[code], 'should exist');
equal(videojs.options.languages['es']['Hello'], 'Hola', 'should match');
deepEqual(result['Hello'], videojs.options.languages['es']['Hello'], 'should also match');
QUnit.ok(videojs.options.languages[code], 'should exist');
QUnit.equal(videojs.options.languages.es.Hello, 'Hola', 'should match');
QUnit.deepEqual(result.Hello, videojs.options.languages.es.Hello, 'should also match');
});
test('should add the value to the languages object with lower case lang code', function() {
var code, data, result;
QUnit.test('should add the value to the languages object with lower case lang code', function() {
const code = 'DE';
const data = {Hello: 'Guten Tag'};
const result = videojs.addLanguage(code, data);
code = 'DE';
data = {'Hello': 'Guten Tag'};
result = videojs.addLanguage(code, data);
ok(videojs.options['languages'][code.toLowerCase()], 'should exist');
equal(videojs.options['languages'][code.toLowerCase()]['Hello'], 'Guten Tag', 'should match');
deepEqual(result, videojs.options['languages'][code.toLowerCase()], 'should also match');
QUnit.ok(videojs.options.languages[code.toLowerCase()], 'should exist');
QUnit.equal(videojs.options.languages[code.toLowerCase()].Hello,
'Guten Tag',
'should match');
QUnit.deepEqual(result,
videojs.options.languages[code.toLowerCase()],
'should also match');
});
test('should expose plugin registry function', function() {
var pluginName, pluginFunction, player;
QUnit.test('should expose plugin registry function', function() {
const pluginName = 'foo';
const pluginFunction = function(options) {};
pluginName = 'foo';
pluginFunction = function(options) {};
ok(videojs.plugin, 'should exist');
QUnit.ok(videojs.plugin, 'should exist');
videojs.plugin(pluginName, pluginFunction);
player = TestHelpers.makePlayer();
const player = TestHelpers.makePlayer();
ok(player.foo, 'should exist');
equal(player.foo, pluginFunction, 'should be equal');
QUnit.ok(player.foo, 'should exist');
QUnit.equal(player.foo, pluginFunction, 'should be equal');
});
test('should expose options and players properties for backward-compatibility', function() {
ok(typeof videojs.options, 'object', 'options should be an object');
ok(typeof videojs.players, 'object', 'players should be an object');
QUnit.test('should expose options and players properties for backward-compatibility', function() {
QUnit.ok(typeof videojs.options, 'object', 'options should be an object');
QUnit.ok(typeof videojs.players, 'object', 'players should be an object');
});
test('should expose DOM functions', function() {
QUnit.test('should expose DOM functions', function() {
// Keys are videojs methods, values are Dom methods.
let methods = {
const methods = {
isEl: 'isEl',
isTextNode: 'isTextNode',
createEl: 'createEl',
@ -142,11 +154,14 @@ test('should expose DOM functions', function() {
appendContent: 'appendContent'
};
let keys = Object.keys(methods);
const keys = Object.keys(methods);
expect(keys.length);
QUnit.expect(keys.length);
keys.forEach(function(vjsName) {
let domName = methods[vjsName];
strictEqual(videojs[vjsName], Dom[domName], `videojs.${vjsName} is a reference to Dom.${domName}`);
const domName = methods[vjsName];
QUnit.strictEqual(videojs[vjsName],
Dom[domName],
`videojs.${vjsName} is a reference to Dom.${domName}`);
});
});