Files
shaka-player/spec/text_source_buffer_spec.js
T
Joey Parrish 2a34eff924 Add TextSourceBuffer
This is a SourceBuffer-work-alike for text, based on registered
parsers.  Actual parsers are needed now.

b/25323462

Change-Id: If2a3ce3d8a769e53d783304fe24519b8d98e093c
2015-11-25 12:14:05 -08:00

306 lines
9.7 KiB
JavaScript

/**
* @license
* Copyright 2015 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
goog.require('shaka.media.TextSourceBuffer');
goog.require('shaka.util.EventManager');
describe('TextSourceBuffer', function() {
var TextSourceBuffer;
var dummyData = new ArrayBuffer();
var dummyMimeType = 'text/fake';
beforeAll(function() {
// Can't set this alias at load-time because the sources may not be loaded
// yet.
TextSourceBuffer = shaka.media.TextSourceBuffer;
});
describe('isTypeSupported', function() {
it('reports support only when a parser is installed', function() {
expect(TextSourceBuffer.isTypeSupported(dummyMimeType)).toBe(false);
TextSourceBuffer.registerParser(dummyMimeType, function() {});
expect(TextSourceBuffer.isTypeSupported(dummyMimeType)).toBe(true);
TextSourceBuffer.unregisterParser(dummyMimeType);
expect(TextSourceBuffer.isTypeSupported(dummyMimeType)).toBe(false);
});
});
describe('appendBuffer', function() {
var mockParser;
var mockTrack;
var sourceBuffer;
var eventManager;
var onUpdateEnd;
beforeEach(function() {
mockParser = jasmine.createSpy('mockParser');
mockTrack = createMockTrack();
TextSourceBuffer.registerParser(dummyMimeType, mockParser);
sourceBuffer = new TextSourceBuffer(mockTrack, dummyMimeType);
onUpdateEnd = jasmine.createSpy('onUpdateEnd');
eventManager = new shaka.util.EventManager();
eventManager.listen(sourceBuffer, 'updateend', onUpdateEnd);
});
afterEach(function() {
sourceBuffer = null;
TextSourceBuffer.unregisterParser(dummyMimeType);
mockTrack = null;
mockParser = null;
eventManager.destroy();
eventManager = null;
});
it('works asynchronously', function() {
mockParser.and.returnValue([1, 2, 3]);
sourceBuffer.appendBuffer(dummyData);
expect(mockTrack.addCue).not.toHaveBeenCalled();
});
it('dispatches an "updateend" event', function(done) {
mockParser.and.returnValue([]);
expect(sourceBuffer.updating).toBe(false);
sourceBuffer.appendBuffer(dummyData);
expect(sourceBuffer.updating).toBe(true);
eventToPromise(onUpdateEnd).then(function() {
expect(sourceBuffer.updating).toBe(false);
done();
});
});
it('adds cues to the track', function() {
expect(mockParser).not.toHaveBeenCalled();
expect(mockTrack.addCue).not.toHaveBeenCalled();
expect(mockTrack.removeCue).not.toHaveBeenCalled();
mockParser.and.returnValue([1, 2, 3]);
sourceBuffer.appendBuffer(dummyData);
eventToPromise(onUpdateEnd).then(function() {
expect(mockParser).toHaveBeenCalledWith(dummyData);
expect(mockTrack.addCue).toHaveBeenCalledWith(1);
expect(mockTrack.addCue).toHaveBeenCalledWith(2);
expect(mockTrack.addCue).toHaveBeenCalledWith(3);
expect(mockTrack.removeCue).not.toHaveBeenCalled();
mockTrack.addCue.calls.reset();
mockParser.calls.reset();
mockParser.and.returnValue([4, 5]);
sourceBuffer.appendBuffer(dummyData);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(mockParser).toHaveBeenCalledWith(dummyData);
expect(mockTrack.addCue).toHaveBeenCalledWith(4);
expect(mockTrack.addCue).toHaveBeenCalledWith(5);
done();
});
});
});
describe('remove', function() {
var mockTrack;
var sourceBuffer;
var eventManager;
var onUpdateEnd;
beforeEach(function() {
mockTrack = createMockTrack();
TextSourceBuffer.registerParser(dummyMimeType, function() {});
sourceBuffer = new TextSourceBuffer(mockTrack, dummyMimeType);
onUpdateEnd = jasmine.createSpy('onUpdateEnd');
eventManager = new shaka.util.EventManager();
eventManager.listen(sourceBuffer, 'updateend', onUpdateEnd);
});
afterEach(function() {
sourceBuffer = null;
TextSourceBuffer.unregisterParser(dummyMimeType);
mockTrack = null;
mockParser = null;
eventManager.destroy();
eventManager = null;
});
it('works asynchronously', function() {
var cue1 = createFakeCue(0, 1);
var cue2 = createFakeCue(1, 2);
var cue3 = createFakeCue(2, 3);
mockTrack.cues = [cue1, cue2, cue3];
sourceBuffer.remove(0, 1);
expect(mockTrack.removeCue).not.toHaveBeenCalled();
});
it('dispatches an "updateend" event', function(done) {
expect(sourceBuffer.updating).toBe(false);
sourceBuffer.remove(0, 1);
expect(sourceBuffer.updating).toBe(true);
eventToPromise(onUpdateEnd).then(function() {
expect(sourceBuffer.updating).toBe(false);
done();
});
});
it('removes cues which overlap the range', function(done) {
var cue1 = createFakeCue(0, 1);
var cue2 = createFakeCue(1, 2);
var cue3 = createFakeCue(2, 3);
mockTrack.cues = [cue1, cue2, cue3];
sourceBuffer.remove(0, 1);
eventToPromise(onUpdateEnd).then(function() {
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue1], [cue2]]);
mockTrack.removeCue.calls.reset();
sourceBuffer.remove(0.5, 0.9);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue1]]);
mockTrack.removeCue.calls.reset();
sourceBuffer.remove(3.00001, 5);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(mockTrack.removeCue).not.toHaveBeenCalled();
mockTrack.removeCue.calls.reset();
sourceBuffer.remove(0.5, 1.5);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue1], [cue2]]);
mockTrack.removeCue.calls.reset();
sourceBuffer.remove(3, Number.POSITIVE_INFINITY);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(mockTrack.removeCue.calls.allArgs()).toEqual([[cue3]]);
done();
});
});
});
describe('buffered', function() {
var mockTrack;
var sourceBuffer;
var eventManager;
var onUpdateEnd;
beforeEach(function() {
var fakeParser = function() { return []; };
mockTrack = createMockTrack();
TextSourceBuffer.registerParser(dummyMimeType, fakeParser);
sourceBuffer = new TextSourceBuffer(mockTrack, dummyMimeType);
onUpdateEnd = jasmine.createSpy('onUpdateEnd');
eventManager = new shaka.util.EventManager();
eventManager.listen(sourceBuffer, 'updateend', onUpdateEnd);
});
afterEach(function() {
sourceBuffer = null;
TextSourceBuffer.unregisterParser(dummyMimeType);
mockTrack = null;
eventManager.destroy();
eventManager = null;
});
it('reflects newly-added cues', function(done) {
expect(sourceBuffer.buffered.length).toBe(0);
var cue1 = createFakeCue(0, 1);
var cue2 = createFakeCue(1, 2);
mockTrack.cues = [cue1, cue2];
// call appendBuffer to trigger the update of buffered.
sourceBuffer.appendBuffer(dummyData);
eventToPromise(onUpdateEnd).then(function() {
expect(sourceBuffer.buffered.length).toBe(1);
expect(sourceBuffer.buffered.start(0)).toBe(0);
expect(sourceBuffer.buffered.end(0)).toBe(2);
var cue3 = createFakeCue(2, 3);
mockTrack.cues = [cue1, cue2, cue3];
sourceBuffer.appendBuffer(dummyData);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(sourceBuffer.buffered.length).toBe(1);
expect(sourceBuffer.buffered.start(0)).toBe(0);
expect(sourceBuffer.buffered.end(0)).toBe(3);
done();
});
});
it('reflects newly-removed cues', function(done) {
var cue1 = createFakeCue(0, 1);
var cue2 = createFakeCue(1, 2);
var cue3 = createFakeCue(2, 3);
mockTrack.cues = [cue1, cue2, cue3];
// call appendBuffer to trigger the update of buffered.
sourceBuffer.appendBuffer(dummyData);
eventToPromise(onUpdateEnd).then(function() {
expect(sourceBuffer.buffered.length).toBe(1);
expect(sourceBuffer.buffered.start(0)).toBe(0);
expect(sourceBuffer.buffered.end(0)).toBe(3);
mockTrack.cues = [cue1, cue2];
// call remove to trigger the update of buffered.
sourceBuffer.remove(-1, -1);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(sourceBuffer.buffered.length).toBe(1);
expect(sourceBuffer.buffered.start(0)).toBe(0);
expect(sourceBuffer.buffered.end(0)).toBe(2);
mockTrack.cues = [];
// call remove to trigger the update of buffered.
sourceBuffer.remove(-1, -1);
return eventToPromise(onUpdateEnd);
}).then(function() {
expect(sourceBuffer.buffered.length).toBe(0);
done();
});
});
});
function eventToPromise(eventSpy) {
return new Promise(function(resolve) {
eventSpy.and.callFake(resolve);
});
}
function createMockTrack() {
return {
addCue: jasmine.createSpy('addCue'),
removeCue: jasmine.createSpy('removeCue'),
cues: []
};
}
function createFakeCue(startTime, endTime) {
return { startTime: startTime, endTime: endTime };
}
});