Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
parent
93e3a48004
commit
b38dea0597
25901 changed files with 9982925 additions and 369 deletions
281
gaia/apps/camera/test/unit/views/controls_test.js
Executable file
281
gaia/apps/camera/test/unit/views/controls_test.js
Executable file
|
|
@ -0,0 +1,281 @@
|
|||
suite('views/controls', function() {
|
||||
/*jshint maxlen:false*/
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs([
|
||||
'views/controls',
|
||||
'drag'
|
||||
], function(ControlsView, Drag) {
|
||||
self.ControlsView = ControlsView;
|
||||
self.Drag = Drag;
|
||||
self.style = loadCss('/style/controls.css', function() { done(); });
|
||||
});
|
||||
});
|
||||
|
||||
suiteTeardown(function() {
|
||||
this.style.remove();
|
||||
});
|
||||
|
||||
function loadCss(url, done) {
|
||||
var link = document.createElement('link');
|
||||
link.type = 'text/css';
|
||||
link.rel = 'stylesheet';
|
||||
link.href = url;
|
||||
link.onload = done;
|
||||
document.head.appendChild(link);
|
||||
return link;
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
var self = this;
|
||||
|
||||
this.sandbox = sinon.sandbox.create();
|
||||
|
||||
this.image = {
|
||||
classList: {
|
||||
add: function() {}
|
||||
}
|
||||
};
|
||||
|
||||
window.URL = window.URL || {};
|
||||
window.URL.createObjectURL = window.URL.createObjectURL || function() {};
|
||||
window.URL.revokeObjectURL = window.URL.revokeObjectURL || function() {};
|
||||
this.sandbox.stub(window.URL, 'createObjectURL').returns('<object-url>');
|
||||
this.sandbox.stub(window.URL, 'revokeObjectURL');
|
||||
|
||||
this.sandbox.stub(window, 'Image', function() { return self.image; });
|
||||
this.sandbox.spy(this.ControlsView.prototype, 'onSwitchTapped');
|
||||
|
||||
this.drag = sinon.createStubInstance(this.Drag);
|
||||
this.view = new this.ControlsView({ drag: this.drag });
|
||||
this.view.els.image = undefined;
|
||||
this.classes = this.view.el.classList;
|
||||
|
||||
this.sandbox.stub(this.view.els.thumbnail);
|
||||
this.sandbox.spy(this.view, 'set');
|
||||
this.sandbox.spy(this.view, 'unset');
|
||||
this.sandbox.spy(this.view, 'emit');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.sandbox.restore();
|
||||
});
|
||||
|
||||
suite('ControlsView#setThumbnail()', function() {
|
||||
test('Should set the thumbnail image src to the object url', function() {
|
||||
this.view.els.image = this.image;
|
||||
this.view.setThumbnail('<blob>');
|
||||
assert.equal(this.view.els.image.src, '<object-url>');
|
||||
});
|
||||
|
||||
test('Should revokeObjectURL if image is already set', function() {
|
||||
this.view.setThumbnail('<blob-1>');
|
||||
sinon.assert.notCalled(window.URL.revokeObjectURL);
|
||||
|
||||
this.view.setThumbnail('<blob-2>');
|
||||
sinon.assert.calledWith(window.URL.revokeObjectURL, '<object-url>');
|
||||
});
|
||||
|
||||
test('Should set thumbnail to `true`', function() {
|
||||
this.view.setThumbnail('<blob>');
|
||||
sinon.assert.calledWith(this.view.set, 'thumbnail', true);
|
||||
});
|
||||
|
||||
test('Should create an Image and add it to the thmbnail container', function() {
|
||||
this.view.setThumbnail('<blob>');
|
||||
sinon.assert.called(window.Image);
|
||||
sinon.assert.called(this.view.els.thumbnail.appendChild, this.image);
|
||||
});
|
||||
});
|
||||
|
||||
suite('ControlsView#set()', function() {
|
||||
test('Should add the class if only one argument is given', function() {
|
||||
this.view.set('key');
|
||||
assert.isTrue(this.classes.contains('key'));
|
||||
});
|
||||
|
||||
test('Should add a key/value class if a truthy value is given', function() {
|
||||
this.view.set('key', 'val');
|
||||
assert.isTrue(this.classes.contains('key-val'));
|
||||
});
|
||||
|
||||
test('Should remove the previous class when the value is changed', function() {
|
||||
this.view.set('key', 'val');
|
||||
assert.isTrue(this.classes.contains('key-val'));
|
||||
|
||||
this.view.set('key', 'val2');
|
||||
assert.isFalse(this.classes.contains('key-val1'));
|
||||
assert.isTrue(this.classes.contains('key-val2'));
|
||||
});
|
||||
|
||||
test('Should only accept string keys', function() {
|
||||
this.view.set(false);
|
||||
assert.isFalse(this.classes.contains('false'));
|
||||
this.view.set(0);
|
||||
assert.isFalse(this.classes.contains('0'));
|
||||
});
|
||||
|
||||
test('Should remove the class for any falsy values', function() {
|
||||
this.view.set('key');
|
||||
assert.isTrue(this.classes.contains('key'));
|
||||
this.view.set('key', undefined);
|
||||
assert.isFalse(this.classes.contains('key'));
|
||||
|
||||
this.view.set('key');
|
||||
assert.isTrue(this.classes.contains('key'));
|
||||
this.view.set('key', 0);
|
||||
assert.isFalse(this.classes.contains('key'));
|
||||
|
||||
this.view.set('key');
|
||||
assert.isTrue(this.classes.contains('key'));
|
||||
this.view.set('key', null);
|
||||
assert.isFalse(this.classes.contains('key'));
|
||||
|
||||
this.view.set('key');
|
||||
assert.isTrue(this.classes.contains('key'));
|
||||
this.view.set('key', '');
|
||||
assert.isFalse(this.classes.contains('key'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('ControlsView#setScreenReaderVisible()', function() {
|
||||
test('hide the view from screen reader', function() {
|
||||
this.view.setScreenReaderVisible(false);
|
||||
assert.equal(this.view.el.getAttribute('aria-hidden'), 'true');
|
||||
});
|
||||
|
||||
test('show the view to the screen reader', function() {
|
||||
this.view.el.setAttribute('aria-hidden', true);
|
||||
this.view.setScreenReaderVisible(true);
|
||||
assert.equal(this.view.el.getAttribute('aria-hidden'), 'false');
|
||||
});
|
||||
});
|
||||
|
||||
suite('ControlsView#enable()', function() {
|
||||
test('Should add an enabled class if no value is given', function() {
|
||||
this.view.enable();
|
||||
assert.isTrue(this.classes.contains('enabled'));
|
||||
});
|
||||
|
||||
test('Should add a key-enabled class if key is given', function() {
|
||||
this.view.enable('key');
|
||||
assert.isTrue(this.classes.contains('key-enabled'));
|
||||
});
|
||||
|
||||
test('Should remove \'disabled\' class', function() {
|
||||
this.classes.add('disabled');
|
||||
this.view.enable();
|
||||
assert.isFalse(this.classes.contains('disabled'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('ControlsView#disabled()', function() {
|
||||
test('Should add an \'disables\' class if no value is given', function() {
|
||||
this.view.disable();
|
||||
assert.isTrue(this.classes.contains('disabled'));
|
||||
});
|
||||
|
||||
test('Should add a key-enabled class if key is given', function() {
|
||||
this.view.disable('key');
|
||||
assert.isTrue(this.classes.contains('key-disabled'));
|
||||
});
|
||||
|
||||
test('Should remove \'enabled\' class', function() {
|
||||
this.classes.add('enabled');
|
||||
this.view.disable();
|
||||
assert.isFalse(this.classes.contains('enabled'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('ControlsView#onSwitchTapped()', function() {
|
||||
setup(function() {
|
||||
this.event = {
|
||||
preventDefault: sinon.spy(),
|
||||
stopPropagation: sinon.spy()
|
||||
};
|
||||
this.spy = this.ControlsView.prototype.onSwitchTapped;
|
||||
this.view.enable();
|
||||
});
|
||||
|
||||
test('It emits a `modechanged` event', function() {
|
||||
this.view.onSwitchTapped(this.event);
|
||||
sinon.assert.calledWith(this.view.emit, 'modechanged');
|
||||
});
|
||||
|
||||
test('It prevents default to stop the event becoming a click', function() {
|
||||
this.view.onSwitchTapped(this.event);
|
||||
sinon.assert.called(this.event.preventDefault);
|
||||
});
|
||||
|
||||
test('It is debounced to defend against button bashing', function() {
|
||||
this.view.setupSwitch();
|
||||
var callback = this.drag.on.withArgs('tapped').args[0][1];
|
||||
|
||||
callback(this.event);
|
||||
callback(this.event);
|
||||
callback(this.event);
|
||||
callback(this.event);
|
||||
|
||||
sinon.assert.calledOnce(this.spy);
|
||||
});
|
||||
});
|
||||
|
||||
suite('ControlsView#onSwitchSnapped()', function() {
|
||||
setup(function() {
|
||||
this.view.set('mode', 'picture');
|
||||
});
|
||||
|
||||
test('It fires \'modechanged\' when the switch changes position', function() {
|
||||
|
||||
// Didn't change
|
||||
this.view.onSwitchSnapped({ x: 'left' });
|
||||
assert.isFalse(this.view.emit.calledWith('modechanged'));
|
||||
|
||||
// Changed
|
||||
this.view.onSwitchSnapped({ x: 'right' });
|
||||
assert.isTrue(this.view.emit.calledWith('modechanged'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('ControlsView#suspendModeSwitch()', function() {
|
||||
test('It ignores user input on switch when suspended', function() {
|
||||
this.view.suspendModeSwitch(true);
|
||||
assert.ok(this.view.set.calledWith('switch-toggle-disabled'));
|
||||
});
|
||||
|
||||
test('It accepts user input on switch when unsuspended', function() {
|
||||
this.view.suspendModeSwitch(false);
|
||||
assert.ok(this.view.unset.calledWith('switch-toggle-disabled'));
|
||||
});
|
||||
});
|
||||
|
||||
test('The switch should appear in the video position when set before the view is in the DOM', function() {
|
||||
var view = new this.ControlsView();
|
||||
view.setMode('video');
|
||||
view.appendTo(document.body);
|
||||
assert.equal(view.drag.handle.el.style.transform, 'translate(64px, 0px)');
|
||||
assert.equal(view.els.switch.getAttribute('data-l10n-id'),
|
||||
'video-mode-button');
|
||||
});
|
||||
|
||||
test('ControlsView#localize', function() {
|
||||
var view = new this.ControlsView();
|
||||
view.localize();
|
||||
for (var el in view.elsL10n) {
|
||||
assert.equal(view.els[el].getAttribute('data-l10n-id'), view.elsL10n[el]);
|
||||
}
|
||||
assert.equal(view.els.switch.getAttribute('data-l10n-id'),
|
||||
'picture-mode-button');
|
||||
});
|
||||
|
||||
test('ControlsView#setCaptureLabel', function() {
|
||||
var view = new this.ControlsView();
|
||||
[true, false].forEach(function(recording) {
|
||||
view.setCaptureLabel(recording);
|
||||
assert.equal(view.els.capture.getAttribute('data-l10n-id'),
|
||||
recording ? 'stop-capture-button' : 'capture-button');
|
||||
});
|
||||
});
|
||||
});
|
||||
36
gaia/apps/camera/test/unit/views/face_test.js
Executable file
36
gaia/apps/camera/test/unit/views/face_test.js
Executable file
|
|
@ -0,0 +1,36 @@
|
|||
suite('views/face', function() {
|
||||
/*jshint maxlen:false*/
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs(['views/face'], function(FaceView) {
|
||||
self.FaceView = FaceView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
var self = this;
|
||||
// Shortcuts
|
||||
this.view = new this.FaceView();
|
||||
|
||||
});
|
||||
|
||||
suite('FaceView#setPosition()', function() {
|
||||
test('Should set top left css values', function() {
|
||||
this.view.setPosition(42, 101);
|
||||
assert.equal(this.view.el.style.left, '42px');
|
||||
assert.equal(this.view.el.style.top, '101px');
|
||||
});
|
||||
});
|
||||
|
||||
suite('FaceView#setDiameter()', function() {
|
||||
test('Should set width height css values', function() {
|
||||
this.view.setDiameter(50);
|
||||
assert.equal(this.view.el.style.width, '50px');
|
||||
assert.equal(this.view.el.style.height, '50px');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
75
gaia/apps/camera/test/unit/views/faces_test.js
Executable file
75
gaia/apps/camera/test/unit/views/faces_test.js
Executable file
|
|
@ -0,0 +1,75 @@
|
|||
suite('views/faces', function() {
|
||||
/*jshint maxlen:false*/
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs(['views/faces'], function(FacesView) {
|
||||
self.FacesView = FacesView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
var self = this;
|
||||
this.FaceView = sinon.spy();
|
||||
this.FaceView.prototype = {
|
||||
FaceView: sinon.spy(),
|
||||
hide: sinon.spy(),
|
||||
appendTo: sinon.spy(),
|
||||
setPosition: sinon.spy(),
|
||||
setDiameter: sinon.spy(),
|
||||
show: sinon.spy()
|
||||
};
|
||||
// Shortcuts
|
||||
this.view = new this.FacesView({
|
||||
FaceView: this.FaceView
|
||||
});
|
||||
});
|
||||
|
||||
suite('FacesView#createFaces()', function() {
|
||||
test('Should create Face Views for the given number of faces', function() {
|
||||
this.view.createFaces(10);
|
||||
assert.ok(this.view.faces.length === 10);
|
||||
this.view.createFaces(5);
|
||||
assert.ok(this.view.faces.length === 15);
|
||||
});
|
||||
});
|
||||
|
||||
suite('FacesView#renderFace()', function() {
|
||||
test('Should show and configure the face view based on the face object', function() {
|
||||
var face = {
|
||||
x: 320,
|
||||
y: 400,
|
||||
diameter: 300
|
||||
};
|
||||
var faceView = new this.FaceView();
|
||||
this.view.renderFace(face, faceView);
|
||||
assert.ok(faceView.setPosition.called);
|
||||
assert.ok(faceView.setDiameter.called);
|
||||
assert.ok(faceView.show.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('FacesView#hideFaces()', function() {
|
||||
test('Should call hide once for each face view', function() {
|
||||
var faceView = {
|
||||
hide: sinon.spy()
|
||||
};
|
||||
this.view.faces = [faceView, faceView, faceView];
|
||||
this.view.hideFaces();
|
||||
assert.ok(faceView.hide.calledThrice);
|
||||
});
|
||||
});
|
||||
|
||||
suite('FacesView#clear()', function() {
|
||||
test('Should remove faces DOM elements and reset faces', function() {
|
||||
this.view.el.removeChild = sinon.spy();
|
||||
this.view.faces = ['face', 'face', 'face'];
|
||||
this.view.clear();
|
||||
assert.ok(this.view.el.removeChild.calledThrice);
|
||||
assert.ok(this.view.faces.length === 0);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
45
gaia/apps/camera/test/unit/views/hud_test.js
Executable file
45
gaia/apps/camera/test/unit/views/hud_test.js
Executable file
|
|
@ -0,0 +1,45 @@
|
|||
suite('views/hud', function() {
|
||||
'use strict';
|
||||
|
||||
var view;
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs(['views/hud'], function(HudView) {
|
||||
self.HudView = HudView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
view = new this.HudView();
|
||||
});
|
||||
|
||||
test('HudView#setFlashMode()', function() {
|
||||
[{ title: 'flash-on', icon: 'flash-on' },
|
||||
{ title: 'flash-off', icon: 'flash-off' },
|
||||
{ title: 'flash-auto', icon: 'flash-auto' }].forEach(function(mode) {
|
||||
view.setFlashMode(mode);
|
||||
assert.equal(view.els.flash.dataset.icon, mode.icon);
|
||||
assert.equal(view.els.flash.getAttribute('data-l10n-id'),
|
||||
mode.title + '-button');
|
||||
});
|
||||
});
|
||||
|
||||
test('HudView#setCamera()', function() {
|
||||
[{ title: 'toggle-camera-rear', icon: 'toggle-camera-rear' },
|
||||
{ title: 'toggle-camera-front', icon: 'toggle-camera-front' }].forEach(
|
||||
function(mode) {
|
||||
view.setCamera(mode);
|
||||
assert.equal(view.els.camera.dataset.icon, mode.icon);
|
||||
assert.equal(view.els.camera.getAttribute('data-l10n-id'),
|
||||
mode.title + '-button');
|
||||
});
|
||||
});
|
||||
|
||||
test('HudView#setMenuLabel()', function() {
|
||||
view.els.settings.removeAttribute('data-l10n-id');
|
||||
view.setMenuLabel();
|
||||
assert.equal(view.els.settings.getAttribute('data-l10n-id'), 'menu-button');
|
||||
});
|
||||
});
|
||||
178
gaia/apps/camera/test/unit/views/notification_test.js
Executable file
178
gaia/apps/camera/test/unit/views/notification_test.js
Executable file
|
|
@ -0,0 +1,178 @@
|
|||
suite('views/notification', function() {
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs(['views/notification'], function(NotificationView) {
|
||||
self.NotificationView = NotificationView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.view = new this.NotificationView();
|
||||
this.clock = sinon.useFakeTimers();
|
||||
});
|
||||
|
||||
suite('NotificationView#display()', function() {
|
||||
suite('Temporary', function() {
|
||||
test('Should add the item to the view', function() {
|
||||
assert.equal(this.view.el.getAttribute('role'), 'presentation');
|
||||
this.view.display({ text: 'l10nId' });
|
||||
var child = this.view.el.children[0];
|
||||
assert.ok(child);
|
||||
assert.equal(child.getAttribute('role'), 'status');
|
||||
assert.equal(child.getAttribute('aria-live'), 'assertive');
|
||||
});
|
||||
|
||||
test('Should add `text` as textContent', function() {
|
||||
this.view.display({ text: 'l10nId' });
|
||||
var child = this.view.el.children[0];
|
||||
assert.equal(child.firstChild.getAttribute('data-l10n-id'), 'l10nId');
|
||||
assert.equal(child.getAttribute('role'), 'status');
|
||||
assert.equal(child.getAttribute('aria-live'), 'assertive');
|
||||
});
|
||||
|
||||
test('Should assign className to the item element', function() {
|
||||
this.view.display({ text: 'l10nId', className: 'bar' });
|
||||
var child = this.view.el.children[0];
|
||||
assert.isTrue(child.classList.contains('bar'));
|
||||
assert.equal(child.getAttribute('role'), 'status');
|
||||
assert.equal(child.getAttribute('aria-live'), 'assertive');
|
||||
});
|
||||
|
||||
test('Should remove the last non-persistent item that is in the way', function() {
|
||||
this.view.display({ text: 'l10nId' });
|
||||
var first = this.view.el.children[0];
|
||||
|
||||
assert.ok(first);
|
||||
assert.equal(first.firstChild.getAttribute('data-l10n-id'), 'l10nId');
|
||||
|
||||
this.view.display({ text: 'l10nId2' });
|
||||
var second = this.view.el.children[0];
|
||||
|
||||
assert.ok(second);
|
||||
assert.equal(first.parentNode, null, 'not in dom');
|
||||
assert.equal(second.firstChild.getAttribute('data-l10n-id'),
|
||||
'l10nId2');
|
||||
});
|
||||
|
||||
test('Should auto clear notification after 3s', function() {
|
||||
this.view.display({ text: 'l10nId' });
|
||||
var first = this.view.el.children[0];
|
||||
|
||||
assert.ok(first);
|
||||
assert.equal(first.firstChild.getAttribute('data-l10n-id'), 'l10nId');
|
||||
|
||||
this.clock.tick(1000);
|
||||
assert.ok(first.parentNode, 'is in dom');
|
||||
|
||||
this.clock.tick(1000);
|
||||
assert.ok(first.parentNode, 'is in dom');
|
||||
|
||||
this.clock.tick(1000);
|
||||
assert.equal(first.parentNode, null, 'not in dom');
|
||||
});
|
||||
|
||||
test('Should not mutate the passed object', function() {
|
||||
var options = { text: 'l10nId' };
|
||||
|
||||
this.view.display(options);
|
||||
|
||||
assert.equal(Object.keys(options).length, 1);
|
||||
assert.equal(options.text, 'l10nId');
|
||||
});
|
||||
});
|
||||
|
||||
suite('Persistent', function() {
|
||||
test('Should remain in the DOM until cleared', function() {
|
||||
var id = this.view.display({ text: 'l10nId', persistent: true });
|
||||
var el = this.view.el.children[0];
|
||||
|
||||
assert.ok(el.parentNode, 'is in dom');
|
||||
|
||||
this.clock.tick(1000);
|
||||
assert.ok(el.parentNode, 'is in dom');
|
||||
|
||||
this.clock.tick(3000);
|
||||
assert.ok(el.parentNode, 'is in dom');
|
||||
|
||||
this.view.clear(id);
|
||||
assert.ok(!el.parentNode, 'not in dom');
|
||||
});
|
||||
|
||||
test('Should hide to show temporary notifications, then return', function() {
|
||||
var els = {};
|
||||
|
||||
this.view.display({ text: 'l10nId', persistent: true, className: 'persistent' });
|
||||
els.persistent = this.view.el.querySelector('.persistent');
|
||||
|
||||
assert.ok(els.persistent.parentNode, 'should be in DOM');
|
||||
assert.isFalse(els.persistent.classList.contains('hidden'));
|
||||
|
||||
this.view.display({ text: 'l10nId', className: 'temporary' });
|
||||
els.temporary = this.view.el.querySelector('.temporary');
|
||||
|
||||
assert.ok(els.temporary.parentNode, 'should be in DOM');
|
||||
assert.isTrue(els.persistent.classList.contains('hidden'));
|
||||
|
||||
this.clock.tick(1000);
|
||||
assert.isTrue(els.persistent.classList.contains('hidden'));
|
||||
|
||||
this.clock.tick(3000);
|
||||
assert.ok(!els.temporary.parentNode);
|
||||
assert.isFalse(els.persistent.classList.contains('hidden'));
|
||||
});
|
||||
|
||||
test('Should replace first persistent item with second', function() {
|
||||
var els = {};
|
||||
|
||||
this.view.display({ text: 'l10nId', persistent: true, className: 'persistent1' });
|
||||
els.persistent1 = this.view.el.querySelector('.persistent1');
|
||||
|
||||
assert.ok(els.persistent1.parentNode, 'should be in DOM');
|
||||
|
||||
this.view.display({ text: 'l10nId', persistent: true, className: 'persistent2' });
|
||||
els.persistent2 = this.view.el.querySelector('.persistent2');
|
||||
|
||||
assert.ok(els.persistent2.parentNode, 'should be in DOM');
|
||||
assert.ok(!els.persistent1.parentNode, 'should not be in DOM');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite('NotificationView#clear()', function() {
|
||||
test('Should be able to clear notifications early', function() {
|
||||
var id = this.view.display({ text: 'l10nId' });
|
||||
var el = this.view.el.children[0];
|
||||
|
||||
assert.ok(el.parentNode);
|
||||
this.view.clear(id);
|
||||
assert.equal(el.parentNode, null);
|
||||
});
|
||||
|
||||
test('Should not throw when attempting to clear a notification twice', function() {
|
||||
var id = this.view.display({ text: 'l10nId' });
|
||||
var el = this.view.el.children[0];
|
||||
|
||||
assert.ok(el.parentNode);
|
||||
this.view.clear(id);
|
||||
assert.equal(el.parentNode, null);
|
||||
this.view.clear(id);
|
||||
});
|
||||
|
||||
test('Should show hidden persistent notification', function() {
|
||||
var persistent = this.view.display({ text: 'l10nId', persistent: true });
|
||||
var els = {};
|
||||
|
||||
els.persistent = this.view.el.children[0];
|
||||
assert.ok(els.persistent.parentNode, 'is in the dom');
|
||||
|
||||
var temporary = this.view.display({ text: 'l10nId' });
|
||||
assert.isTrue(els.persistent.classList.contains('hidden'), 'is hidden');
|
||||
|
||||
this.view.clear(temporary);
|
||||
assert.isFalse(els.persistent.classList.contains('hidden'), 'is not hidden');
|
||||
});
|
||||
});
|
||||
});
|
||||
52
gaia/apps/camera/test/unit/views/overlay_test.js
Executable file
52
gaia/apps/camera/test/unit/views/overlay_test.js
Executable file
|
|
@ -0,0 +1,52 @@
|
|||
/*jshint maxlen:false*/
|
||||
'use strict';
|
||||
|
||||
suite('views/overlay', function() {
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs([
|
||||
'views/overlay'
|
||||
], function(OverlayView) {
|
||||
self.OverlayView = OverlayView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.view = new this.OverlayView({
|
||||
type: 'unavailable',
|
||||
closable: false
|
||||
});
|
||||
});
|
||||
|
||||
suite('OverlayView#getOverlayData()', function() {
|
||||
test('Should return correct data for \'unavailable\'', function() {
|
||||
var output = this.view.getData('unavailable');
|
||||
assert.equal(output.title, 'nocard2-title');
|
||||
assert.equal(output.body, 'nocard3-text');
|
||||
});
|
||||
|
||||
test('Should return correct data for \'nospace\'', function() {
|
||||
var output = this.view.getData('nospace');
|
||||
assert.equal(output.title, 'nospace2-title');
|
||||
assert.equal(output.body, 'nospace2-text');
|
||||
});
|
||||
|
||||
test('Should return correct data for \'shared\'', function() {
|
||||
var output = this.view.getData('shared');
|
||||
assert.equal(output.title, 'pluggedin2-title');
|
||||
assert.equal(output.body, 'pluggedin2-text');
|
||||
});
|
||||
|
||||
test('Should return correct data for \'request-fail\'', function() {
|
||||
var output = this.view.getData('request-fail');
|
||||
assert.equal(output.title, 'camera-unavailable-title');
|
||||
assert.equal(output.body, 'camera-unavailable-text');
|
||||
});
|
||||
|
||||
test('Should return false for unknown key', function() {
|
||||
var output = this.view.getData('something-not-known');
|
||||
assert.equal(output, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
95
gaia/apps/camera/test/unit/views/preview-gallery_test.js
Executable file
95
gaia/apps/camera/test/unit/views/preview-gallery_test.js
Executable file
|
|
@ -0,0 +1,95 @@
|
|||
suite('views/preview-gallery', function() {
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs(['views/preview-gallery'], function(previewGalleryView) {
|
||||
self.previewGalleryView = previewGalleryView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.view = new this.previewGalleryView();
|
||||
this.clock = sinon.useFakeTimers();
|
||||
});
|
||||
|
||||
suite('previewGalleryView#showOptionsMenu()', function() {
|
||||
test('Should show the option menu', function() {
|
||||
this.view.showOptionsMenu();
|
||||
assert.equal(this.view.optionsMenuContainer.children[0].getAttribute(
|
||||
'data-type'), 'action');
|
||||
});
|
||||
});
|
||||
|
||||
suite('previewGalleryView#onFrameWheel', function() {
|
||||
var mockWheelRight = {
|
||||
type: 'wheel', deltaMode: 2, DOM_DELTA_PAGE: 2, deltaX: 1
|
||||
}, mockWheelLeft = {
|
||||
type: 'wheel', deltaMode: 2, DOM_DELTA_PAGE: 2, deltaX: -1
|
||||
}, mockWheelDown = {
|
||||
type: 'wheel', deltaMode: 2, DOM_DELTA_PAGE: 2, deltaY: 1
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
sinon.spy(this.view, 'emit');
|
||||
sinon.stub(this.view, 'onVideoPaused');
|
||||
});
|
||||
|
||||
test('wheel right', function() {
|
||||
this.view.onFrameWheel(mockWheelRight);
|
||||
assert.isTrue(this.view.emit.calledWith('swipe', 'left'));
|
||||
sinon.assert.notCalled(this.view.onVideoPaused);
|
||||
});
|
||||
|
||||
test('wheel left', function() {
|
||||
this.view.onFrameWheel(mockWheelLeft);
|
||||
assert.isTrue(this.view.emit.calledWith('swipe', 'right'));
|
||||
sinon.assert.notCalled(this.view.onVideoPaused);
|
||||
});
|
||||
|
||||
test('wheel right when video is playing', function() {
|
||||
this.view.videoPlaying = true;
|
||||
this.view.onFrameWheel(mockWheelRight);
|
||||
assert.isTrue(this.view.emit.calledWith('swipe', 'left'));
|
||||
sinon.assert.calledOnce(this.view.onVideoPaused);
|
||||
});
|
||||
|
||||
test('wheel down', function() {
|
||||
this.view.onFrameWheel(mockWheelDown);
|
||||
sinon.assert.notCalled(this.view.emit);
|
||||
});
|
||||
});
|
||||
|
||||
suite('previewGalleryView#updateCountText', function() {
|
||||
setup(function() {
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
test('Accessible labelling', function() {
|
||||
var total = 1, current = 3;
|
||||
this.view.updateCountText(current, total);
|
||||
assert.equal(this.view.els.mediaFrame.getAttribute('data-l10n-id'),
|
||||
'media-frame');
|
||||
assert.deepEqual(JSON.parse(this.view.els.mediaFrame.getAttribute(
|
||||
'data-l10n-args')), { total: total, current: current });
|
||||
});
|
||||
});
|
||||
|
||||
suite('Options menu', function() {
|
||||
test('showOptionsMenu', function() {
|
||||
assert.isFalse(this.view.el.classList.contains('action-menu'));
|
||||
this.view.showOptionsMenu();
|
||||
assert.ok(this.view.el.classList.contains('action-menu'));
|
||||
});
|
||||
|
||||
test('hideOptionsMenu', function() {
|
||||
this.view.optionsMenuContainer = document.createElement('div');
|
||||
this.view.el.appendChild(this.view.optionsMenuContainer);
|
||||
this.view.el.classList.add('action-menu');
|
||||
|
||||
this.view.hideOptionsMenu();
|
||||
assert.isFalse(this.view.el.classList.contains('action-menu'));
|
||||
});
|
||||
});
|
||||
});
|
||||
58
gaia/apps/camera/test/unit/views/setting-options_test.js
Executable file
58
gaia/apps/camera/test/unit/views/setting-options_test.js
Executable file
|
|
@ -0,0 +1,58 @@
|
|||
suite('views/setting-options', function() {
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs([
|
||||
'views/setting-options'
|
||||
], function(SettingOptionsView) {
|
||||
self.SettingOptionsView = SettingOptionsView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.sandbox = sinon.sandbox.create();
|
||||
this.view = new this.SettingOptionsView({
|
||||
model: { on: sinon.spy(), get: sinon.spy() },
|
||||
l10n: {
|
||||
formatValue: function(id) {
|
||||
return Promise.resolve(id);
|
||||
},
|
||||
}
|
||||
});
|
||||
this.view.els.ul = document.createElement('ul');
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.sandbox.restore();
|
||||
});
|
||||
|
||||
suite('SettingOptionsView#renderOption()', function() {
|
||||
var option = {
|
||||
key: 'key',
|
||||
title: 'title'
|
||||
};
|
||||
|
||||
test('localizable not selected', function() {
|
||||
this.view.renderOption(true, option);
|
||||
var rendered = this.view.els.key;
|
||||
|
||||
assert.equal(rendered.getAttribute('role'), 'option');
|
||||
assert.equal(rendered.getAttribute('data-l10n-id'), 'title');
|
||||
assert.isNull(rendered.getAttribute('aria-selected'));
|
||||
});
|
||||
|
||||
test('not localizable selected', function() {
|
||||
// Make current option selected.
|
||||
this.view.selectedKey = option.key;
|
||||
|
||||
this.view.renderOption(false, option);
|
||||
var rendered = this.view.els.key;
|
||||
|
||||
assert.equal(rendered.getAttribute('role'), 'option');
|
||||
assert.equal(rendered.textContent, 'title');
|
||||
assert.equal(rendered.getAttribute('aria-selected'), 'true');
|
||||
});
|
||||
});
|
||||
});
|
||||
49
gaia/apps/camera/test/unit/views/setting_test.js
Executable file
49
gaia/apps/camera/test/unit/views/setting_test.js
Executable file
|
|
@ -0,0 +1,49 @@
|
|||
suite('views/setting', function() {
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs([
|
||||
'views/setting'
|
||||
], function(SettingView) {
|
||||
self.SettingView = SettingView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.sandbox = sinon.sandbox.create();
|
||||
this.model = {
|
||||
on: sinon.spy(),
|
||||
selected: sinon.stub().returns({ title: 'title' }),
|
||||
get: sinon.stub().returns({ title: 'title', value: 'value' })
|
||||
};
|
||||
this.model.get.withArgs('title').returns('title');
|
||||
this.view = new this.SettingView({ model: this.model });
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.sandbox.restore();
|
||||
});
|
||||
|
||||
suite('SettingView#render()', function() {
|
||||
setup(function() {
|
||||
this.view.l10n = {
|
||||
formatValue: function(id) {
|
||||
return Promise.resolve(id);
|
||||
},
|
||||
setAttributes: sinon.spy()
|
||||
};
|
||||
this.view.render();
|
||||
});
|
||||
|
||||
test('render setting accessibility', function(done) {
|
||||
assert.equal(this.view.el.getAttribute('role'), 'option');
|
||||
Promise.resolve().then(() => {
|
||||
assert.isTrue(this.view.l10n.setAttributes.calledWith(this.view.el,
|
||||
'setting-option-title', { value: 'title' }));
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
78
gaia/apps/camera/test/unit/views/settings_test.js
Executable file
78
gaia/apps/camera/test/unit/views/settings_test.js
Executable file
|
|
@ -0,0 +1,78 @@
|
|||
suite('views/settings', function() {
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs([
|
||||
'views/settings',
|
||||
'views/setting-options'
|
||||
], function(SettingsView, OptionsView) {
|
||||
self.SettingsView = SettingsView;
|
||||
self.OptionsView = OptionsView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
var self = this;
|
||||
this.sandbox = sinon.sandbox.create();
|
||||
|
||||
var OptionsView = sinon.spy(function() {
|
||||
var view = sinon.createStubInstance(self.OptionsView);
|
||||
view.render.returns(view);
|
||||
view.appendTo.returns(view);
|
||||
view.on.returns(view);
|
||||
return view;
|
||||
});
|
||||
|
||||
this.view = new this.SettingsView({ OptionsView: OptionsView });
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
this.sandbox.restore();
|
||||
});
|
||||
|
||||
suite('SettingsView#onClick()', function() {
|
||||
test('Should not let clicks propagate', function() {
|
||||
var spy = sinon.spy();
|
||||
this.view.onClick({ stopPropagation: spy });
|
||||
assert.isTrue(spy.called);
|
||||
});
|
||||
});
|
||||
|
||||
suite('SettingsView#showSetting()', function() {
|
||||
setup(function() {
|
||||
this.model = {};
|
||||
this.sandbox.spy(this.view, 'showPane');
|
||||
this.view.showSetting(this.model);
|
||||
});
|
||||
|
||||
test('Should create and append a new OptionsView', function() {
|
||||
assert.isTrue(this.view.OptionsView.called);
|
||||
assert.isTrue(this.view.optionsView.appendTo.called);
|
||||
});
|
||||
|
||||
test('Should pass the model into the OptionsView', function() {
|
||||
var options = this.view.OptionsView.args[0][0];
|
||||
assert.equal(options.model, this.model);
|
||||
});
|
||||
|
||||
test('Should show pane 2', function() {
|
||||
assert.isTrue(this.view.showPane.calledWith(2));
|
||||
});
|
||||
});
|
||||
|
||||
suite('SettingsView#goBack()', function() {
|
||||
test('Should destroy the options view (sync)', function() {
|
||||
var options = this.view.optionsView = { destroy: sinon.spy() };
|
||||
this.view.goBack();
|
||||
assert.isTrue(options.destroy.called);
|
||||
});
|
||||
|
||||
test('Should switch back to pane 1', function() {
|
||||
sinon.spy(this.view, 'showPane');
|
||||
this.view.goBack();
|
||||
assert.isTrue(this.view.showPane.calledWith(1));
|
||||
});
|
||||
});
|
||||
});
|
||||
39
gaia/apps/camera/test/unit/views/timer_test.js
Executable file
39
gaia/apps/camera/test/unit/views/timer_test.js
Executable file
|
|
@ -0,0 +1,39 @@
|
|||
suite('views/countdown', function() {
|
||||
'use strict';
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs(['views/countdown'], function(CountdownView) {
|
||||
self.CountdownView = CountdownView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.countdown = new this.CountdownView();
|
||||
this.countdown.emit = sinon.spy();
|
||||
});
|
||||
|
||||
suite('CountdownView#set()', function() {
|
||||
test('Should update the text content of the counter', function() {
|
||||
this.countdown.set(1000);
|
||||
assert.ok(this.countdown.el.innerHTML.indexOf(1000) > -1);
|
||||
});
|
||||
});
|
||||
|
||||
suite('CountdownView#reset()', function() {
|
||||
test('Should clear the countdown text', function() {
|
||||
this.countdown.set(1000);
|
||||
assert.isTrue(this.countdown.el.innerHTML.indexOf('1000') > -1);
|
||||
this.countdown.reset();
|
||||
assert.isFalse(this.countdown.el.innerHTML.indexOf('1000') > -1);
|
||||
});
|
||||
|
||||
test('Should remove `immanent` class', function() {
|
||||
this.countdown.setImmanent(true);
|
||||
assert.isTrue(this.countdown.el.classList.contains('immanent'));
|
||||
this.countdown.reset();
|
||||
assert.isFalse(this.countdown.el.classList.contains('immanent'));
|
||||
});
|
||||
});
|
||||
});
|
||||
184
gaia/apps/camera/test/unit/views/viewfinder_test.js
Executable file
184
gaia/apps/camera/test/unit/views/viewfinder_test.js
Executable file
|
|
@ -0,0 +1,184 @@
|
|||
suite('views/viewfinder', function() {
|
||||
'use strict';
|
||||
|
||||
var SENSOR_ANGLE = 90;
|
||||
|
||||
suiteSetup(function(done) {
|
||||
var self = this;
|
||||
requirejs(['views/viewfinder'], function(ViewfinderView) {
|
||||
self.ViewfinderView = ViewfinderView;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
setup(function() {
|
||||
this.viewfinder = new this.ViewfinderView();
|
||||
this.viewfinder.width = 300;
|
||||
this.viewfinder.height = 500;
|
||||
});
|
||||
|
||||
suite('ViewfinderView#updatePreview()', function() {
|
||||
setup(function() {
|
||||
sinon.stub(this.viewfinder, 'updatePreviewMetrics');
|
||||
});
|
||||
|
||||
test('Should prefer this.scaleType if defined', function() {
|
||||
var preview = { width: 1600, height: 900 };
|
||||
var scaleType;
|
||||
|
||||
this.viewfinder.scaleType = 'fit';
|
||||
this.viewfinder.updatePreview(preview, SENSOR_ANGLE);
|
||||
scaleType = this.viewfinder.updatePreviewMetrics.args[0][3];
|
||||
assert.equal(scaleType, 'fit');
|
||||
|
||||
this.viewfinder.scaleType = 'foobar';
|
||||
this.viewfinder.updatePreview(preview, SENSOR_ANGLE);
|
||||
scaleType = this.viewfinder.updatePreviewMetrics.args[1][3];
|
||||
assert.equal(scaleType, 'foobar');
|
||||
});
|
||||
|
||||
test('Should choose \'fill\' scaleType if preview aspect > container aspect', function() {
|
||||
var scaleType;
|
||||
|
||||
this.viewfinder.scaleType = undefined;
|
||||
|
||||
this.viewfinder.updatePreview({ width: 1600, height: 900 }, SENSOR_ANGLE);
|
||||
scaleType = this.viewfinder.updatePreviewMetrics.args[0][3];
|
||||
assert.equal(scaleType, 'fill');
|
||||
|
||||
this.viewfinder.updatePreview({ width: 400, height: 300 }, SENSOR_ANGLE);
|
||||
scaleType = this.viewfinder.updatePreviewMetrics.args[1][3];
|
||||
assert.equal(scaleType, 'fit');
|
||||
});
|
||||
|
||||
test('Should add negative scale style if `mirror` argument is true', function() {
|
||||
var preview = { width: 1600, height: 900 };
|
||||
|
||||
this.viewfinder.updatePreview(preview, SENSOR_ANGLE, true);
|
||||
assert.isTrue(this.viewfinder.els.videoContainer.style.transform.indexOf('scale(-1') === -1);
|
||||
|
||||
this.viewfinder.updatePreview(preview, SENSOR_ANGLE, false);
|
||||
assert.isFalse(this.viewfinder.els.videoContainer.style.transform.indexOf('scale(-1') !== -1);
|
||||
});
|
||||
});
|
||||
|
||||
suite('ViewfinderView#updatePreviewMetrics()', function() {
|
||||
setup(function() {
|
||||
this.viewfinder.container = {
|
||||
width: this.viewfinder.height,
|
||||
height: this.viewfinder.width
|
||||
};
|
||||
|
||||
this.container = this.viewfinder.container;
|
||||
});
|
||||
|
||||
test('Should set a \'scale-type\' attribute', function() {
|
||||
var previewSize = { width: 400, height: 300 };
|
||||
|
||||
this.viewfinder.updatePreviewMetrics(previewSize, SENSOR_ANGLE, false, 'fill');
|
||||
assert.equal(this.viewfinder.el.getAttribute('scale-type'), 'fill');
|
||||
this.viewfinder.updatePreviewMetrics(previewSize, SENSOR_ANGLE, false, 'fit');
|
||||
assert.equal(this.viewfinder.el.getAttribute('scale-type'), 'fit');
|
||||
});
|
||||
|
||||
suite('\'fill\'', function() {
|
||||
test('Should match frame width to container width when preview aspect > container aspect', function() {
|
||||
var previewSize = { width: 1600, height: 900 };
|
||||
|
||||
// Run test-case
|
||||
this.viewfinder.updatePreviewMetrics(previewSize, SENSOR_ANGLE, false, 'fill');
|
||||
|
||||
// Frame
|
||||
var frame = {
|
||||
width: parseInt(this.viewfinder.els.frame.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.frame.style.height, 10)
|
||||
};
|
||||
|
||||
// Video container
|
||||
var video = {
|
||||
width: parseInt(this.viewfinder.els.videoContainer.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.videoContainer.style.height, 10)
|
||||
};
|
||||
|
||||
assert.equal(frame.width, this.container.height);
|
||||
assert.ok(frame.height > this.container.width);
|
||||
|
||||
assert.equal(video.height, this.container.height);
|
||||
assert.ok(video.width > this.container.width);
|
||||
});
|
||||
|
||||
test('Should match frame height to container height when preview aspect < container aspect', function() {
|
||||
var previewSize = { width: 400, height: 300 };
|
||||
|
||||
// Run test-case
|
||||
this.viewfinder.updatePreviewMetrics(previewSize, SENSOR_ANGLE, false, 'fill');
|
||||
|
||||
var frame = {
|
||||
width: parseInt(this.viewfinder.els.frame.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.frame.style.height, 10)
|
||||
};
|
||||
|
||||
var video = {
|
||||
width: parseInt(this.viewfinder.els.videoContainer.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.videoContainer.style.height, 10)
|
||||
};
|
||||
|
||||
assert.ok(frame.width > this.container.height);
|
||||
assert.equal(frame.height, this.container.width);
|
||||
|
||||
assert.ok(video.height > this.container.height);
|
||||
assert.equal(video.width, this.container.width);
|
||||
});
|
||||
});
|
||||
|
||||
suite('\'fit\'', function() {
|
||||
test('Should match frame height to container height when preview aspect > container aspect', function() {
|
||||
var previewSize = { width: 1600, height: 900 };
|
||||
|
||||
// Run test-case
|
||||
this.viewfinder.updatePreviewMetrics(previewSize, SENSOR_ANGLE, false, 'fit');
|
||||
|
||||
var frame = {
|
||||
width: parseInt(this.viewfinder.els.frame.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.frame.style.height, 10)
|
||||
};
|
||||
|
||||
var video = {
|
||||
width: parseInt(this.viewfinder.els.videoContainer.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.videoContainer.style.height, 10)
|
||||
};
|
||||
|
||||
assert.equal(frame.height, this.container.width);
|
||||
assert.ok(frame.width < this.container.height);
|
||||
|
||||
assert.equal(video.width, this.container.width);
|
||||
assert.ok(video.height < this.container.height);
|
||||
});
|
||||
|
||||
test('Should match frame width to container width when preview aspect < container aspect', function() {
|
||||
var previewSize = { width: 400, height: 300 };
|
||||
|
||||
// Run test-case
|
||||
this.viewfinder.updatePreviewMetrics(previewSize, SENSOR_ANGLE, false, 'fit');
|
||||
|
||||
var frame = {
|
||||
width: parseInt(this.viewfinder.els.frame.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.frame.style.height, 10)
|
||||
};
|
||||
|
||||
var video = {
|
||||
width: parseInt(this.viewfinder.els.videoContainer.style.width, 10),
|
||||
height: parseInt(this.viewfinder.els.videoContainer.style.height, 10)
|
||||
};
|
||||
|
||||
// Check width is equal and height is shorter
|
||||
assert.equal(frame.width, this.container.height);
|
||||
assert.ok(frame.height < this.container.width);
|
||||
|
||||
// Check container width is shorter and container height is equal
|
||||
assert.ok(video.width < this.container.width);
|
||||
assert.equal(video.height, this.container.height);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue