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
252
gaia/apps/keyboard/test/unit/views/alternatives_char_menu_test.js
Executable file
252
gaia/apps/keyboard/test/unit/views/alternatives_char_menu_test.js
Executable file
|
|
@ -0,0 +1,252 @@
|
|||
'use strict';
|
||||
|
||||
/* global AlternativesCharMenuView */
|
||||
|
||||
require('/js/views/alternatives_char_menu_view.js');
|
||||
require('/js/views/key_view.js');
|
||||
|
||||
suite('Views > AlternativesCharMenuView', function() {
|
||||
var menu = null;
|
||||
var options = {
|
||||
};
|
||||
|
||||
var KEY_WIDTH = 30;
|
||||
var KEY_HEIGHT = 20;
|
||||
var altChars = ['a', 'b', 'c'];
|
||||
var fakeMenu;
|
||||
|
||||
var rootElement = document.createElement('div');
|
||||
document.body.appendChild(rootElement);
|
||||
|
||||
var dummyKeyElement = document.createElement('button');
|
||||
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
suite('basic show/hide testing', function() {
|
||||
setup(function() {
|
||||
menu = new AlternativesCharMenuView(rootElement, altChars, options,
|
||||
viewManager);
|
||||
});
|
||||
|
||||
test(' > show()', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
assert.equal(rootElement.firstElementChild,
|
||||
menu.getMenuContainer(),
|
||||
'Menu was not inserted into root Element');
|
||||
menu.hide();
|
||||
});
|
||||
|
||||
test(' > hide()', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
menu.hide();
|
||||
|
||||
assert.equal(rootElement.childElementCount, 0,
|
||||
'Menu was not removed from root Element!');
|
||||
});
|
||||
});
|
||||
|
||||
suite(' > getMenuTarget() - single row case', function() {
|
||||
setup(function() {
|
||||
fakeMenu = document.createElement('div');
|
||||
fakeMenu.style.position = 'absolute';
|
||||
fakeMenu.style.fontSize = 0;
|
||||
|
||||
// insert 3 keys for 1 row
|
||||
for (var i = 0; i < 3; i++) {
|
||||
var child = document.createElement('div');
|
||||
child.style.display = 'inline-block';
|
||||
child.style.width = KEY_WIDTH + 'px';
|
||||
child.style.height = KEY_HEIGHT + 'px';
|
||||
|
||||
fakeMenu.appendChild(child);
|
||||
}
|
||||
|
||||
rootElement.appendChild(fakeMenu);
|
||||
|
||||
menu = new AlternativesCharMenuView(rootElement, altChars, options,
|
||||
viewManager);
|
||||
|
||||
this.sinon.stub(menu, 'getMenuContainer');
|
||||
menu.getMenuContainer.returns(fakeMenu);
|
||||
|
||||
this.sinon.stub(menu, 'getBoundingClientRect',
|
||||
fakeMenu.getBoundingClientRect.bind(fakeMenu));
|
||||
|
||||
this.sinon.stub(menu, 'getLineHeight');
|
||||
menu.getLineHeight.returns(KEY_HEIGHT);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
menu.hide();
|
||||
});
|
||||
|
||||
test('the first element', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
var rect = fakeMenu.getBoundingClientRect();
|
||||
var target = menu.getMenuTarget(rect.left, rect.top);
|
||||
|
||||
assert.equal(target, menu.altKeyTargets[0],
|
||||
'Should map to the first element');
|
||||
});
|
||||
|
||||
test('the second element', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
var rect = fakeMenu.getBoundingClientRect();
|
||||
var target = menu.getMenuTarget(fakeMenu.offsetLeft + KEY_WIDTH +
|
||||
rect.left, rect.top);
|
||||
|
||||
assert.equal(target, menu.altKeyTargets[1],
|
||||
'Should map to the second element');
|
||||
});
|
||||
|
||||
test('the last element', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
var rect = fakeMenu.getBoundingClientRect();
|
||||
var target = menu.getMenuTarget(fakeMenu.offsetLeft +
|
||||
fakeMenu.offsetWidth +
|
||||
rect.left, rect.top);
|
||||
|
||||
assert.equal(target, menu.altKeyTargets[menu.altKeyTargets.length -1],
|
||||
'Should map to the last element');
|
||||
});
|
||||
});
|
||||
|
||||
suite(' > getMenuTarget() - 2 row case', function() {
|
||||
setup(function() {
|
||||
fakeMenu = document.createElement('div');
|
||||
fakeMenu.style.position = 'absolute';
|
||||
fakeMenu.style.width = KEY_WIDTH * 3 + 'px'; // 2 row
|
||||
|
||||
// insert 6 keys for 2 rows
|
||||
for (var i = 0; i < 6; i++) {
|
||||
var child = document.createElement('div');
|
||||
child.style.display = 'inline-block';
|
||||
child.style.width = KEY_WIDTH + 'px';
|
||||
child.style.height = KEY_HEIGHT + 'px';
|
||||
|
||||
fakeMenu.appendChild(child);
|
||||
}
|
||||
|
||||
rootElement.appendChild(fakeMenu);
|
||||
|
||||
var altChars = ['a', 'b', 'c', 'd', 'e', 'f'];
|
||||
menu = new AlternativesCharMenuView(rootElement, altChars, options,
|
||||
viewManager);
|
||||
|
||||
this.sinon.stub(menu, 'getMenuContainer');
|
||||
menu.getMenuContainer.returns(fakeMenu);
|
||||
|
||||
this.sinon.stub(menu, 'getBoundingClientRect',
|
||||
fakeMenu.getBoundingClientRect.bind(fakeMenu));
|
||||
|
||||
this.sinon.stub(menu, 'getLineHeight');
|
||||
menu.getLineHeight.returns(KEY_HEIGHT);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
menu.hide();
|
||||
});
|
||||
|
||||
test('2 row - the first element', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
var rect = fakeMenu.getBoundingClientRect();
|
||||
|
||||
var target = menu.getMenuTarget(rect.left, fakeMenu.offsetTop +
|
||||
fakeMenu.offsetHeight +
|
||||
rect.top);
|
||||
|
||||
assert.equal(target, menu.altKeyTargets[0],
|
||||
'Should map to the first element');
|
||||
});
|
||||
|
||||
test('2 row - the second element', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
var rect = fakeMenu.getBoundingClientRect();
|
||||
var target = menu.getMenuTarget(fakeMenu.offsetLeft + KEY_WIDTH +
|
||||
rect.left,
|
||||
fakeMenu.offsetTop +
|
||||
fakeMenu.offsetHeight +
|
||||
rect.top);
|
||||
|
||||
assert.equal(target, menu.altKeyTargets[1],
|
||||
'Should map to the second element');
|
||||
});
|
||||
|
||||
test('2 row - the 4th element in the upper row', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
var rect = fakeMenu.getBoundingClientRect();
|
||||
var target = menu.getMenuTarget(rect.left, rect.top);
|
||||
|
||||
assert.equal(target, menu.altKeyTargets[3],
|
||||
'Should map to the 4th element');
|
||||
});
|
||||
});
|
||||
|
||||
suite(' > getMenuTarget() - 2 row with one empty cell case', function() {
|
||||
setup(function() {
|
||||
fakeMenu = document.createElement('div');
|
||||
fakeMenu.style.position = 'absolute';
|
||||
fakeMenu.style.width = KEY_WIDTH * 3 + 'px'; // 2 row
|
||||
|
||||
// insert 5 keys for 2 rows
|
||||
// (would result in 3x2 cells with top top-right one being empty)
|
||||
for (var i = 0; i < 5; i++) {
|
||||
var child = document.createElement('div');
|
||||
child.style.display = 'inline-block';
|
||||
child.style.width = KEY_WIDTH + 'px';
|
||||
child.style.height = KEY_HEIGHT + 'px';
|
||||
|
||||
fakeMenu.appendChild(child);
|
||||
}
|
||||
|
||||
rootElement.appendChild(fakeMenu);
|
||||
|
||||
var altChars = ['a', 'b', 'c', 'd', 'e'];
|
||||
menu = new AlternativesCharMenuView(rootElement, altChars, options,
|
||||
viewManager);
|
||||
|
||||
this.sinon.stub(menu, 'getMenuContainer');
|
||||
menu.getMenuContainer.returns(fakeMenu);
|
||||
|
||||
this.sinon.stub(menu, 'getBoundingClientRect',
|
||||
fakeMenu.getBoundingClientRect.bind(fakeMenu));
|
||||
|
||||
this.sinon.stub(menu, 'getLineHeight');
|
||||
menu.getLineHeight.returns(KEY_HEIGHT);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
menu.hide();
|
||||
});
|
||||
|
||||
test('2 row - the empty element', function() {
|
||||
menu.show(dummyKeyElement);
|
||||
|
||||
var rect = fakeMenu.getBoundingClientRect();
|
||||
var target = menu.getMenuTarget(fakeMenu.offsetLeft + rect.left +
|
||||
KEY_WIDTH * 2, rect.top);
|
||||
|
||||
assert.equal(target, menu.altKeyTargets[4],
|
||||
'Should map to the last element');
|
||||
});
|
||||
});
|
||||
|
||||
suite(' isMenuTarget()', function() {
|
||||
test('isMenuTarget() returns true', function() {
|
||||
assert.isTrue(menu.isMenuTarget(menu.altKeyTargets[0]));
|
||||
});
|
||||
|
||||
test('isMenuTarget() returns false', function() {
|
||||
assert.isFalse(menu.isMenuTarget({dummy: 'dummy'}));
|
||||
});
|
||||
});
|
||||
});
|
||||
144
gaia/apps/keyboard/test/unit/views/candidate_panel_view_test.js
Executable file
144
gaia/apps/keyboard/test/unit/views/candidate_panel_view_test.js
Executable file
|
|
@ -0,0 +1,144 @@
|
|||
'use strict';
|
||||
|
||||
/* global CandidatePanelView */
|
||||
require('/js/views/base_view.js');
|
||||
require('/js/views/candidate_panel_view.js');
|
||||
|
||||
function createFakeCandidates(count) {
|
||||
var candidates = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
candidates.push('' + i);
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
suite('Views > CandidatePanelView', function() {
|
||||
var candidatePanelView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub(),
|
||||
getRemToPx: sinon.stub().returns(10)
|
||||
};
|
||||
|
||||
suite('some basic functions', function() {
|
||||
setup(function() {
|
||||
var target = {};
|
||||
var options = {className: 'basic-class'};
|
||||
candidatePanelView = new CandidatePanelView(target, options, viewManager);
|
||||
});
|
||||
|
||||
test('> render() ', function() {
|
||||
assert.equal(candidatePanelView.element, null);
|
||||
|
||||
candidatePanelView.render();
|
||||
assert.notEqual(candidatePanelView.element, null);
|
||||
|
||||
var classList = candidatePanelView.element.classList;
|
||||
assert.isTrue(classList.contains('basic-class'),
|
||||
'should contain the className specified in options');
|
||||
});
|
||||
|
||||
test('> getHeight()', function() {
|
||||
assert.equal(candidatePanelView.getHeight(), 32);
|
||||
});
|
||||
|
||||
suite('> showCandidates()', function() {
|
||||
test('> show 8 candidates', function() {
|
||||
candidatePanelView.render();
|
||||
|
||||
candidatePanelView.showCandidates(createFakeCandidates(8));
|
||||
|
||||
var suggestionsContainer =
|
||||
candidatePanelView.element.querySelector('.suggestions-container');
|
||||
assert.notEqual(suggestionsContainer, null);
|
||||
|
||||
var row = suggestionsContainer.querySelector('.candidate-row-first');
|
||||
assert.equal(row.childNodes.length, 8);
|
||||
|
||||
// Should not contain the toggle button
|
||||
var toggleButton =
|
||||
row.querySelector('.keyboard-candidate-panel-toggle-button');
|
||||
assert.equal(toggleButton, null);
|
||||
});
|
||||
|
||||
test('> show 9 candidates', function() {
|
||||
candidatePanelView.render();
|
||||
|
||||
candidatePanelView.showCandidates(createFakeCandidates(9));
|
||||
|
||||
var suggestionsContainer =
|
||||
candidatePanelView.element.querySelector('.suggestions-container');
|
||||
assert.notEqual(suggestionsContainer, null);
|
||||
|
||||
var row = suggestionsContainer.querySelector('.candidate-row-first');
|
||||
assert.equal(row.childNodes.length, 8);
|
||||
|
||||
// Should contain the toggle button
|
||||
var toggleButton = candidatePanelView.element.
|
||||
querySelector('.keyboard-candidate-panel-toggle-button');
|
||||
assert.notEqual(toggleButton, null);
|
||||
});
|
||||
|
||||
test('> candidates with different length', function() {
|
||||
candidatePanelView.render();
|
||||
|
||||
var candidates = ['1', '2', '3' , '4', '55', '6', '7', '8'];
|
||||
candidatePanelView.showCandidates(candidates);
|
||||
|
||||
var suggestionsContainer =
|
||||
candidatePanelView.element.querySelector('.suggestions-container');
|
||||
assert.notEqual(suggestionsContainer, null);
|
||||
|
||||
var row = suggestionsContainer.querySelector('.candidate-row-first');
|
||||
assert.equal(row.childNodes.length, 7);
|
||||
|
||||
// Should contain the toggle button
|
||||
var toggleButton = candidatePanelView.element.
|
||||
querySelector('.keyboard-candidate-panel-toggle-button');
|
||||
assert.notEqual(toggleButton, null);
|
||||
|
||||
|
||||
candidatePanelView.showMoreCandidates(1, ['9']);
|
||||
// Check it has the 2nd row
|
||||
var rows = suggestionsContainer.querySelectorAll('.candidate-row');
|
||||
assert.equal(rows.length, 2);
|
||||
|
||||
// Check 2nd row is shown as a grid
|
||||
var candidateElements = rows[1].querySelectorAll('span');
|
||||
assert.equal(candidateElements.length, 2);
|
||||
|
||||
assert.equal(candidateElements[0].textContent, '9');
|
||||
assert.equal(candidateElements[0].dataset.data, '9');
|
||||
assert.equal(candidateElements[0].style.flexGrow, 1);
|
||||
|
||||
// Will have a dummy element here make it look like a grid
|
||||
assert.equal(candidateElements[1].style.flexGrow, 7);
|
||||
});
|
||||
});
|
||||
|
||||
suite('candidatePanel with even width for each candidate', function() {
|
||||
setup(function() {
|
||||
var options = { widthUnit: 1 };
|
||||
candidatePanelView = new CandidatePanelView({}, options, viewManager);
|
||||
});
|
||||
|
||||
test('Each candidate has the same width', function() {
|
||||
candidatePanelView.render();
|
||||
candidatePanelView.showCandidates(createFakeCandidates(5));
|
||||
|
||||
var suggestionsContainer =
|
||||
candidatePanelView.element.querySelector('.suggestions-container');
|
||||
assert.notEqual(suggestionsContainer, null);
|
||||
|
||||
var candidateElements = suggestionsContainer.
|
||||
querySelectorAll('.candidate-row span');
|
||||
|
||||
assert.equal(candidateElements.length, 5);
|
||||
|
||||
for (var i = 0; i < candidateElements.length; i++) {
|
||||
assert.equal(candidateElements[i].style.flexGrow, 1);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
60
gaia/apps/keyboard/test/unit/views/emoji_key_view_test.js
Executable file
60
gaia/apps/keyboard/test/unit/views/emoji_key_view_test.js
Executable file
|
|
@ -0,0 +1,60 @@
|
|||
'use strict';
|
||||
|
||||
/* global EmojiKeyView */
|
||||
|
||||
require('/js/views/base_view.js');
|
||||
require('/js/views/emoji_key_view.js');
|
||||
|
||||
suite('Views > KeyView', function() {
|
||||
var emojiKeyView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
suite('some basic functions', function() {
|
||||
setup(function() {
|
||||
var target = {};
|
||||
var options = {};
|
||||
emojiKeyView = new EmojiKeyView(target, options, viewManager);
|
||||
});
|
||||
|
||||
test(' > render()', function() {
|
||||
assert.equal(emojiKeyView.element, null);
|
||||
|
||||
emojiKeyView.render();
|
||||
assert.notEqual(emojiKeyView.element, null);
|
||||
assert.isTrue(emojiKeyView.element.classList.contains('emoji'));
|
||||
});
|
||||
|
||||
test('additional class name', function() {
|
||||
var key = {
|
||||
value: 'k',
|
||||
};
|
||||
|
||||
var options = {
|
||||
classNames: ['another-className']
|
||||
};
|
||||
|
||||
var keyView = new EmojiKeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
options.classNames.forEach(function(className) {
|
||||
assert.isTrue(keyView.element.classList.contains(className));
|
||||
});
|
||||
});
|
||||
|
||||
test('invoke viewManager.registerView', function() {
|
||||
var mockViewManager = {
|
||||
registerView: this.sinon.stub()
|
||||
};
|
||||
|
||||
var target = {};
|
||||
var keyView = new EmojiKeyView(target, {}, mockViewManager);
|
||||
keyView.render();
|
||||
|
||||
assert.isTrue(mockViewManager.registerView.calledOnce);
|
||||
assert.isTrue(mockViewManager.registerView.calledWith(target,
|
||||
keyView));
|
||||
});
|
||||
});
|
||||
});
|
||||
97
gaia/apps/keyboard/test/unit/views/handwriting_pad_view_test.js
Executable file
97
gaia/apps/keyboard/test/unit/views/handwriting_pad_view_test.js
Executable file
|
|
@ -0,0 +1,97 @@
|
|||
'use strict';
|
||||
|
||||
/* global HandwritingPadView */
|
||||
|
||||
require('/js/views/handwriting_pad_view.js');
|
||||
|
||||
suite('Views > HandwritingPadView', function() {
|
||||
var handwritingPadView;
|
||||
var canvas;
|
||||
|
||||
var STROKE_WIDTH = 6;
|
||||
|
||||
var pressStart = {
|
||||
moved: false,
|
||||
clientX: 20,
|
||||
clientY: 20
|
||||
};
|
||||
|
||||
var pressMove = {
|
||||
moved: true,
|
||||
clientX: 25,
|
||||
clientY: 25
|
||||
};
|
||||
|
||||
var rootElement = document.createElement('div');
|
||||
document.body.appendChild(rootElement);
|
||||
document.body.style.pad = 0;
|
||||
document.body.style.margin = 0;
|
||||
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
suite('basic testing', function() {
|
||||
setup(function() {
|
||||
var target = {};
|
||||
handwritingPadView = new HandwritingPadView(target, {}, viewManager);
|
||||
handwritingPadView.render();
|
||||
canvas = handwritingPadView.element;
|
||||
});
|
||||
|
||||
test(' > get element', function() {
|
||||
assert.equal(canvas instanceof HTMLCanvasElement, true);
|
||||
});
|
||||
|
||||
test('invoke viewManager.registerView', function() {
|
||||
var mockViewManager = {
|
||||
registerView: this.sinon.stub()
|
||||
};
|
||||
|
||||
var target = {};
|
||||
var padView = new HandwritingPadView(target, {}, mockViewManager);
|
||||
padView.render();
|
||||
|
||||
assert.isTrue(mockViewManager.registerView.calledOnce);
|
||||
assert.isTrue(mockViewManager.registerView.calledWith(target,
|
||||
padView));
|
||||
});
|
||||
|
||||
test(' > drawHandwritingPad()', function() {
|
||||
rootElement.appendChild(canvas);
|
||||
|
||||
var point = handwritingPadView.drawHandwritingPad(pressStart, true,
|
||||
STROKE_WIDTH);
|
||||
|
||||
assert.equal(point.posX, pressStart.clientX * window.devicePixelRatio,
|
||||
'Error occured in drawCanvas when press start!');
|
||||
assert.equal(point.posY, pressStart.clientY * window.devicePixelRatio,
|
||||
'Error occured in drawCanvas when press start!');
|
||||
|
||||
point = handwritingPadView.drawHandwritingPad(pressMove, false,
|
||||
STROKE_WIDTH);
|
||||
|
||||
assert.equal(point.posX, pressMove.clientX * window.devicePixelRatio,
|
||||
'Error occured in drawCanvas when press move!');
|
||||
assert.equal(point.posY, pressMove.clientY * window.devicePixelRatio,
|
||||
'Error occured in drawCanvas when press move!');
|
||||
});
|
||||
|
||||
test(' > resize()', function() {
|
||||
Object.defineProperty(window, 'devicePixelRatio', {
|
||||
configurable: true,
|
||||
get: () => 2 }
|
||||
);
|
||||
|
||||
handwritingPadView.resize(200, 400);
|
||||
|
||||
var canvas = handwritingPadView.element;
|
||||
|
||||
assert.equal(canvas.width, '400');
|
||||
assert.equal(canvas.height, '800');
|
||||
|
||||
assert.equal(canvas.style.width, '200px');
|
||||
assert.equal(canvas.style.height, '400px');
|
||||
});
|
||||
});
|
||||
});
|
||||
244
gaia/apps/keyboard/test/unit/views/key_view_test.js
Executable file
244
gaia/apps/keyboard/test/unit/views/key_view_test.js
Executable file
|
|
@ -0,0 +1,244 @@
|
|||
'use strict';
|
||||
|
||||
/* global KeyView */
|
||||
|
||||
require('/js/views/key_view.js');
|
||||
|
||||
suite('Views > KeyView', function() {
|
||||
var keyView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
suite('some basic functions', function() {
|
||||
setup(function() {
|
||||
var target = {};
|
||||
var options = {};
|
||||
keyView = new KeyView(target, options, viewManager);
|
||||
});
|
||||
|
||||
test(' > render()', function() {
|
||||
assert.equal(keyView.element, null);
|
||||
|
||||
keyView.render();
|
||||
assert.notEqual(keyView.element, null);
|
||||
});
|
||||
|
||||
test(' > highlight() with upper case', function() {
|
||||
keyView.render();
|
||||
assert.isFalse(keyView.element.classList.contains('highlighted'));
|
||||
|
||||
keyView.highlight({upperCase: true});
|
||||
assert.isTrue(keyView.element.classList.contains('highlighted'));
|
||||
assert.isTrue(keyView.element.classList.contains('uppercase-popup'));
|
||||
});
|
||||
|
||||
test(' > highlight() with lower case', function() {
|
||||
keyView.render();
|
||||
assert.isFalse(keyView.element.classList.contains('highlighted'));
|
||||
|
||||
keyView.highlight({upperCase: false});
|
||||
assert.isTrue(keyView.element.classList.contains('highlighted'));
|
||||
assert.isTrue(keyView.element.classList.contains('lowercase-popup'));
|
||||
});
|
||||
|
||||
test(' > unHighlight()', function() {
|
||||
keyView.render();
|
||||
|
||||
keyView.highlight();
|
||||
assert.isTrue(keyView.element.classList.contains('highlighted'));
|
||||
|
||||
keyView.unHighlight();
|
||||
assert.isFalse(keyView.element.classList.contains('highlighted'));
|
||||
assert.isFalse(keyView.element.classList.contains('uppercase-popup'));
|
||||
assert.isFalse(keyView.element.classList.contains('lowercase-popup'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('DOM structures tests', function() {
|
||||
test('basic key', function() {
|
||||
var key = {
|
||||
value: 'k',
|
||||
lowercaseValue: 'l_k',
|
||||
keyCode: 999,
|
||||
keyCodeUpper: 9999,
|
||||
targetPage: 2
|
||||
};
|
||||
|
||||
var options = {
|
||||
keyWidth: 99
|
||||
};
|
||||
|
||||
var keyView = new KeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
assert.isTrue(keyView.element.classList.contains('keyboard-key'));
|
||||
assert.isFalse(keyView.element.classList.contains('special-key'));
|
||||
|
||||
assert.equal(keyView.element.getAttribute('role'), 'key');
|
||||
assert.equal(keyView.element.style.width, options.keyWidth + 'px');
|
||||
|
||||
// Keycode dataset
|
||||
assert.equal(keyView.element.dataset.keycode, key.keyCode);
|
||||
assert.equal(keyView.element.dataset.keycodeUpper, key.keyCodeUpper);
|
||||
|
||||
// target page dataset
|
||||
assert.equal(keyView.element.dataset.targetPage, key.targetPage);
|
||||
|
||||
//visual wrapper element
|
||||
var visualWrapper = keyView.element.firstElementChild;
|
||||
assert.equal(visualWrapper.className, 'visual-wrapper');
|
||||
|
||||
// Inner label
|
||||
var labelNode = visualWrapper.querySelector('.key-element');
|
||||
assert.equal(labelNode.innerHTML, key.value);
|
||||
assert.equal(labelNode.dataset.label, key.value);
|
||||
|
||||
// popups
|
||||
var uppercasePopup = visualWrapper.querySelector('.uppercase.popup');
|
||||
assert.equal(uppercasePopup.innerHTML, key.value);
|
||||
|
||||
var lowercasePopup = visualWrapper.querySelector('.lowercase.popup');
|
||||
assert.equal(lowercasePopup.innerHTML, key.lowercaseValue);
|
||||
});
|
||||
|
||||
test('special key', function() {
|
||||
var key = {
|
||||
isSpecialKey: true,
|
||||
value: 'k',
|
||||
lowercaseValue: 'l_k'
|
||||
};
|
||||
|
||||
var options = {
|
||||
keyWidth: 99
|
||||
};
|
||||
|
||||
var keyView = new KeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
assert.isTrue(keyView.element.classList.contains('keyboard-key'));
|
||||
assert.isTrue(keyView.element.classList.contains('special-key'));
|
||||
});
|
||||
|
||||
test('additional attribute list', function() {
|
||||
var key = {
|
||||
value: 'k',
|
||||
lowercaseValue: 'l_k'
|
||||
};
|
||||
|
||||
var options = {
|
||||
keyWidth: 99,
|
||||
attributeList: [
|
||||
{key: 'testKey', value: 'testValue'},
|
||||
{key: 'testKey2', value: 'testValue2'}
|
||||
]
|
||||
};
|
||||
|
||||
var keyView = new KeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
options.attributeList.forEach(function(attribute) {
|
||||
assert.equal(keyView.element.getAttribute(attribute.key),
|
||||
attribute.value);
|
||||
});
|
||||
});
|
||||
|
||||
test('additional class name', function() {
|
||||
var key = {
|
||||
value: 'k',
|
||||
lowercaseValue: 'l_k',
|
||||
className: 'test-className'
|
||||
};
|
||||
|
||||
var options = {
|
||||
keyWidth: 99,
|
||||
classNames: ['another-className']
|
||||
};
|
||||
|
||||
var keyView = new KeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
assert.isTrue(keyView.element.classList.contains('keyboard-key'));
|
||||
assert.isTrue(keyView.element.classList.contains(key.className));
|
||||
|
||||
options.classNames.forEach(function(className) {
|
||||
assert.isTrue(keyView.element.classList.contains(className));
|
||||
});
|
||||
});
|
||||
|
||||
test('disabled key', function() {
|
||||
var key = {
|
||||
value: 'k',
|
||||
lowercaseValue: 'l_k',
|
||||
disabled: true
|
||||
};
|
||||
|
||||
var options = {
|
||||
keyWidth: 99,
|
||||
};
|
||||
|
||||
var keyView = new KeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
assert.equal(keyView.element.getAttribute('disabled'), 'true');
|
||||
});
|
||||
|
||||
test('alt label node for option w/ altOutputChar case', function() {
|
||||
var key = {
|
||||
value: 'k',
|
||||
lowercaseValue: 'l_k',
|
||||
};
|
||||
|
||||
var options = {
|
||||
keyWidth: 99,
|
||||
altOutputChar: '*k'
|
||||
};
|
||||
|
||||
var keyView = new KeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
var visualWrapper = keyView.element.firstElementChild;
|
||||
|
||||
// Inner label
|
||||
var labelNode = visualWrapper.querySelector('.key-element.lowercase');
|
||||
assert.equal(labelNode.innerHTML, options.altOutputChar);
|
||||
});
|
||||
|
||||
test('altNote', function() {
|
||||
var key = {
|
||||
value: 'k',
|
||||
lowercaseValue: 'l_k',
|
||||
longPressValue: '#k'
|
||||
};
|
||||
|
||||
var options = {
|
||||
keyWidth: 99,
|
||||
altOutputChar: '*k'
|
||||
};
|
||||
|
||||
var keyView = new KeyView(key, options, viewManager);
|
||||
keyView.render();
|
||||
|
||||
var visualWrapper = keyView.element.firstElementChild;
|
||||
|
||||
var altNote = visualWrapper.querySelector('.alt-note');
|
||||
assert.equal(altNote.innerHTML, key.longPressValue);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Register View to viewManager', function() {
|
||||
test('invoke viewManager.registerView', function() {
|
||||
var mockViewManager = {
|
||||
registerView: this.sinon.stub()
|
||||
};
|
||||
|
||||
var target = {};
|
||||
var keyView = new KeyView(target, {}, mockViewManager);
|
||||
keyView.render();
|
||||
|
||||
assert.isTrue(mockViewManager.registerView.calledOnce);
|
||||
assert.isTrue(mockViewManager.registerView.calledWith(target,
|
||||
keyView));
|
||||
});
|
||||
});
|
||||
});
|
||||
144
gaia/apps/keyboard/test/unit/views/latin_candidate_panel_view_test.js
Executable file
144
gaia/apps/keyboard/test/unit/views/latin_candidate_panel_view_test.js
Executable file
|
|
@ -0,0 +1,144 @@
|
|||
'use strict';
|
||||
|
||||
/* global LatinCandidatePanelView, ViewUtils */
|
||||
require('/js/views/base_view.js');
|
||||
require('/js/views/view_utils.js');
|
||||
require('/js/views/candidate_panel_view.js');
|
||||
require('/js/views/latin_candidate_panel_view.js');
|
||||
|
||||
function createFakeCandidates(count) {
|
||||
var candidates = [];
|
||||
for (var i = 0; i < count; i++) {
|
||||
candidates.push('' + i);
|
||||
}
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
suite('Views > LatinCandidatePanelView', function() {
|
||||
var candidatePanelView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
suite('some basic functions', function() {
|
||||
setup(function() {
|
||||
var target = {};
|
||||
var options = {className: 'test-class'};
|
||||
candidatePanelView =
|
||||
new LatinCandidatePanelView(target, options, viewManager);
|
||||
});
|
||||
|
||||
test('> render() ', function() {
|
||||
assert.equal(candidatePanelView.element, null);
|
||||
|
||||
candidatePanelView.render();
|
||||
assert.notEqual(candidatePanelView.element, null);
|
||||
|
||||
var classList = candidatePanelView.element.classList;
|
||||
assert.isTrue(classList.contains('test-class'),
|
||||
'should contain the className specified in options');
|
||||
});
|
||||
|
||||
test('> show no candidates', function() {
|
||||
candidatePanelView.render();
|
||||
|
||||
candidatePanelView.showCandidates([]);
|
||||
|
||||
var suggestionsContainer =
|
||||
candidatePanelView.element.querySelector('.suggestions-container');
|
||||
assert.notEqual(suggestionsContainer, null);
|
||||
|
||||
// Should show dismiss button
|
||||
var dismissButton =
|
||||
candidatePanelView.element.querySelector('.dismiss-suggestions-button');
|
||||
assert.notEqual(dismissButton, null);
|
||||
|
||||
assert.isTrue(dismissButton.classList.contains('hide'));
|
||||
});
|
||||
|
||||
test('> show 3 candidates', function() {
|
||||
candidatePanelView.render();
|
||||
|
||||
candidatePanelView.showCandidates(createFakeCandidates(3));
|
||||
|
||||
var suggestionsContainer =
|
||||
candidatePanelView.element.querySelector('.suggestions-container');
|
||||
assert.notEqual(suggestionsContainer, null);
|
||||
|
||||
var candidateElements = suggestionsContainer.querySelectorAll('span');
|
||||
assert.equal(candidateElements.length, 3);
|
||||
|
||||
for (var i = 0; i < candidateElements.length; i++) {
|
||||
assert.equal(candidateElements[i].textContent, i);
|
||||
assert.equal(candidateElements[i].dataset.data, i);
|
||||
}
|
||||
|
||||
// Should show dismiss button
|
||||
var dismissButton =
|
||||
candidatePanelView.element.querySelector('.dismiss-suggestions-button');
|
||||
assert.notEqual(dismissButton, null);
|
||||
|
||||
assert.isFalse(dismissButton.classList.contains('hide'));
|
||||
});
|
||||
|
||||
test('> show 3 candidates, with the first as auto correction', function() {
|
||||
candidatePanelView.render();
|
||||
|
||||
candidatePanelView.showCandidates(['*1', '2', '3']);
|
||||
|
||||
var suggestionsContainer =
|
||||
candidatePanelView.element.querySelector('.suggestions-container');
|
||||
assert.notEqual(suggestionsContainer, null);
|
||||
|
||||
var candidateElements = suggestionsContainer.querySelectorAll('div');
|
||||
assert.equal(candidateElements.length, 3);
|
||||
|
||||
// The first candidate should be highlighted
|
||||
assert.isTrue(candidateElements[0].classList.contains('autocorrect'));
|
||||
});
|
||||
|
||||
test('Candidates scaling to 0.6', function() {
|
||||
candidatePanelView.render();
|
||||
|
||||
sinon.stub(ViewUtils, 'getScale', function() {
|
||||
return 0.6;
|
||||
});
|
||||
|
||||
var can = ['thisisverylongword', 'alsoverylongword', 'whatup'];
|
||||
candidatePanelView.showCandidates(can);
|
||||
|
||||
var spans = candidatePanelView.element.querySelectorAll('span');
|
||||
assert.equal(spans[0].textContent, can[0]);
|
||||
assert.equal(spans[1].textContent, can[1]);
|
||||
assert.equal(spans[2].textContent, can[2]);
|
||||
assert.equal(spans[0].style.width, '166.667%');
|
||||
assert.equal(spans[0].style.transformOrigin, 'left center 0px');
|
||||
assert.equal(spans[0].style.transform, 'scale(0.6)');
|
||||
|
||||
ViewUtils.getScale.restore();
|
||||
});
|
||||
|
||||
test('Candidats scaling to 0.5', function() {
|
||||
|
||||
candidatePanelView.render();
|
||||
|
||||
sinon.stub(ViewUtils, 'getScale', function() {
|
||||
return 0.5;
|
||||
});
|
||||
|
||||
var can = ['thisisverylongword', 'alsoverylongword', 'whatup'];
|
||||
candidatePanelView.showCandidates(can);
|
||||
|
||||
var spans = candidatePanelView.element.querySelectorAll('span');
|
||||
assert.equal(spans[0].textContent, 't…d');
|
||||
assert.equal(spans[1].textContent, 'a…d');
|
||||
assert.equal(spans[2].textContent, 'w…p');
|
||||
assert.equal(spans[0].style.width, '200%');
|
||||
assert.equal(spans[0].style.transformOrigin, 'left center 0px');
|
||||
assert.equal(spans[0].style.transform, 'scale(0.5)');
|
||||
|
||||
ViewUtils.getScale.restore();
|
||||
});
|
||||
});
|
||||
});
|
||||
523
gaia/apps/keyboard/test/unit/views/layout_page_view_test.js
Executable file
523
gaia/apps/keyboard/test/unit/views/layout_page_view_test.js
Executable file
|
|
@ -0,0 +1,523 @@
|
|||
'use strict';
|
||||
/* global LayoutPageView, KeyboardEvent */
|
||||
|
||||
require('/js/views/key_view.js');
|
||||
require('/js/views/handwriting_pad_view.js');
|
||||
require('/js/views/layout_page_view.js');
|
||||
|
||||
suite('Views > LayoutPageView', function() {
|
||||
var dummyLayout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a' }, { value: 'b' }]
|
||||
]
|
||||
};
|
||||
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
test(' > show() ', function() {
|
||||
var pageView = new LayoutPageView(dummyLayout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
pageView.show();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.dataset.active, 'true');
|
||||
});
|
||||
|
||||
test(' > hide() ', function() {
|
||||
var pageView = new LayoutPageView(dummyLayout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
pageView.hide();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.dataset.active, null);
|
||||
});
|
||||
|
||||
test(' > destroy() ', function() {
|
||||
var pageView = new LayoutPageView(dummyLayout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
pageView.destroy();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.parentNode, null);
|
||||
});
|
||||
|
||||
suite(' > render()', function() {
|
||||
test('Should add last-row class to last row', function() {
|
||||
var layout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a' }, { value: 'b' }],
|
||||
[{ value: 'c' }, { value: 'd' }],
|
||||
[{ value: 'e' }, { value: 'f' }]
|
||||
]
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
|
||||
var rows = container.querySelectorAll('.keyboard-row');
|
||||
assert.equal(rows.length, 3);
|
||||
assert.equal(rows[2].classList.contains('keyboard-last-row'), true);
|
||||
var keys = container.querySelectorAll('.keyboard-key');
|
||||
assert.equal(keys.length, 6);
|
||||
});
|
||||
|
||||
test('layout.keyClassName should be added to all keys', function() {
|
||||
var layout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a' }, { value: 'b' }]
|
||||
],
|
||||
keyClassName: 'c9'
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.querySelectorAll('.keyboard-key').length, 2);
|
||||
assert.equal(container.querySelectorAll('.keyboard-key.c9').length, 2);
|
||||
});
|
||||
|
||||
test('Keycode should be set', function() {
|
||||
var layout = {
|
||||
width: 9,
|
||||
keys: [
|
||||
[{ value: 'a', keyCode: 3 }, { value: 'b', keyCode: 98 }]
|
||||
]
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
|
||||
var keys = container.querySelectorAll('.keyboard-key');
|
||||
assert.equal(keys[0].dataset.keycode, 3);
|
||||
assert.equal(keys[1].dataset.keycode, 98);
|
||||
});
|
||||
|
||||
test('On uppercase flag, uppercase on keys, ' +
|
||||
'no lowercase class on container', function() {
|
||||
var layout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a', uppercaseValue: 'A' },
|
||||
{ value: 'b', uppercaseValue: 'B' }]
|
||||
]
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
pageView.setUpperCaseLock({
|
||||
isUpperCase: true,
|
||||
isUpperCaseLocked: false
|
||||
});
|
||||
|
||||
var container = pageView.element;
|
||||
|
||||
var keys = container.querySelectorAll('.keyboard-key .key-element');
|
||||
assert.equal(keys.length, 4);
|
||||
assert.equal(keys[0].textContent, 'A');
|
||||
assert.isTrue(keys[1].classList.contains('lowercase'));
|
||||
assert.equal(keys[1].textContent, 'a');
|
||||
assert.equal(keys[2].textContent, 'B');
|
||||
assert.isTrue(keys[3].classList.contains('lowercase'));
|
||||
assert.equal(keys[3].textContent, 'b');
|
||||
|
||||
assert.isFalse(container.classList.contains('lowercase'));
|
||||
});
|
||||
|
||||
test('No uppercase flag, uppercase on keys, ' +
|
||||
'lowercase class on container', function() {
|
||||
var layout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a', uppercaseValue: 'A' },
|
||||
{ value: 'b', uppercaseValue: 'B' }]
|
||||
]
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
pageView.setUpperCaseLock({
|
||||
isUpperCase: false,
|
||||
isUpperCaseLocked: false
|
||||
});
|
||||
|
||||
var container = pageView.element;
|
||||
|
||||
var keys = container.querySelectorAll('.keyboard-key .key-element');
|
||||
assert.equal(keys.length, 4);
|
||||
assert.equal(keys[0].textContent, 'A');
|
||||
assert.isTrue(keys[1].classList.contains('lowercase'));
|
||||
assert.equal(keys[1].textContent, 'a');
|
||||
assert.equal(keys[2].textContent, 'B');
|
||||
assert.isTrue(keys[3].classList.contains('lowercase'));
|
||||
assert.equal(keys[3].textContent, 'b');
|
||||
|
||||
assert.isTrue(container.classList.contains('lowercase'));
|
||||
});
|
||||
|
||||
test('create keyboard with handwriting pad', function() {
|
||||
var layout = {
|
||||
handwritingPadOptions: {
|
||||
ratio: 8.5,
|
||||
rowspan: 3
|
||||
},
|
||||
keys: [
|
||||
[
|
||||
{ value: 'a', ratio: 1.5 }
|
||||
], [
|
||||
{ value: 'b', ratio: 1.5 }
|
||||
], [
|
||||
{ value: 'c', ratio: 1.5 }
|
||||
], [
|
||||
{ value: 'd', ratio: 10 }
|
||||
]
|
||||
]
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
var pads = container.querySelectorAll('.handwriting-pad');
|
||||
assert.equal(pads.length, 1);
|
||||
});
|
||||
|
||||
suite('CSS classes on pageView', function() {
|
||||
test('with specificCssRule', function() {
|
||||
var layout = {
|
||||
width: 1,
|
||||
keys: [],
|
||||
layoutName: 'ar',
|
||||
specificCssRule: true
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.classList.contains('ar'), true);
|
||||
});
|
||||
|
||||
test('without specificCssRule', function() {
|
||||
var layout = {
|
||||
width: 1,
|
||||
keys: [],
|
||||
layoutName: 'ar',
|
||||
specificCssRule: false
|
||||
};
|
||||
|
||||
var pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.classList.contains('ar'), false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
suite(' > setUpperCaseLock()', function() {
|
||||
var pageView = null;
|
||||
setup(function() {
|
||||
|
||||
var layout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a' },
|
||||
{ value: 'Shift', keyCode: KeyboardEvent.DOM_VK_CAPS_LOCK }
|
||||
]
|
||||
]
|
||||
};
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
});
|
||||
|
||||
test('turn to uppercase', function() {
|
||||
pageView.setUpperCaseLock({
|
||||
isUpperCase: true,
|
||||
isUpperCaseLocked: false
|
||||
});
|
||||
|
||||
var container = pageView.element;
|
||||
assert.isFalse(container.classList.contains('lowercase'));
|
||||
|
||||
var capsLockKey = container.querySelector(
|
||||
'[data-keycode="' + KeyboardEvent.DOM_VK_CAPS_LOCK + '"]'
|
||||
);
|
||||
|
||||
assert.isTrue(capsLockKey.classList.contains('kbr-key-active'));
|
||||
assert.isFalse(capsLockKey.classList.contains('kbr-key-hold'));
|
||||
|
||||
assert.equal(capsLockKey.getAttribute('aria-pressed'), 'true');
|
||||
});
|
||||
|
||||
test('turn to lowercase', function() {
|
||||
pageView.setUpperCaseLock({
|
||||
isUpperCase: false,
|
||||
isUpperCaseLocked: false
|
||||
});
|
||||
|
||||
var container = pageView.element;
|
||||
assert.isTrue(container.classList.contains('lowercase'));
|
||||
|
||||
var capsLockKey = container.querySelector(
|
||||
'[data-keycode="' + KeyboardEvent.DOM_VK_CAPS_LOCK + '"]'
|
||||
);
|
||||
|
||||
assert.isFalse(capsLockKey.classList.contains('kbr-key-active'));
|
||||
assert.isFalse(capsLockKey.classList.contains('kbr-key-hold'));
|
||||
|
||||
assert.equal(capsLockKey.getAttribute('aria-pressed'), 'false');
|
||||
});
|
||||
|
||||
test('enable CapsLock', function() {
|
||||
pageView.setUpperCaseLock({
|
||||
isUpperCase: true,
|
||||
isUpperCaseLocked: true
|
||||
});
|
||||
|
||||
var container = pageView.element;
|
||||
assert.isFalse(container.classList.contains('lowercase'));
|
||||
|
||||
var capsLockKey = container.querySelector(
|
||||
'[data-keycode="' + KeyboardEvent.DOM_VK_CAPS_LOCK + '"]'
|
||||
);
|
||||
|
||||
assert.isFalse(capsLockKey.classList.contains('kbr-key-active'));
|
||||
assert.isTrue(capsLockKey.classList.contains('kbr-key-hold'));
|
||||
|
||||
assert.equal(capsLockKey.getAttribute('aria-pressed'), 'true');
|
||||
});
|
||||
});
|
||||
|
||||
suite(' > highlightKey() and unHighlightKey()', function() {
|
||||
var pageView = null;
|
||||
var keyView;
|
||||
|
||||
setup(function() {
|
||||
var layout = {
|
||||
width: 2,
|
||||
keys: []
|
||||
};
|
||||
|
||||
keyView = {
|
||||
highlight: sinon.stub(),
|
||||
unHighlight: sinon.stub()
|
||||
};
|
||||
|
||||
var viewManager = {
|
||||
getView: function() {
|
||||
return keyView;
|
||||
}
|
||||
};
|
||||
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
});
|
||||
|
||||
test('highlightKey() with upperCase', function() {
|
||||
pageView.isUpperCase = true;
|
||||
pageView.highlightKey({});
|
||||
|
||||
assert.isTrue(keyView.highlight.calledOnce);
|
||||
assert.isTrue(keyView.highlight.calledWith({upperCase: true}));
|
||||
});
|
||||
|
||||
test('highlightKey() with upperCase', function() {
|
||||
pageView.isUpperCase = false;
|
||||
pageView.highlightKey({});
|
||||
|
||||
assert.isTrue(keyView.highlight.calledOnce);
|
||||
assert.isTrue(keyView.highlight.calledWith({upperCase: false}));
|
||||
});
|
||||
|
||||
test('unHighlightKey()', function() {
|
||||
pageView.unHighlightKey({});
|
||||
assert.isTrue(keyView.unHighlight.calledOnce);
|
||||
});
|
||||
});
|
||||
|
||||
suite('> getHeight()', function() {
|
||||
var layout;
|
||||
var pageView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub(),
|
||||
getRemToPx: sinon.stub(),
|
||||
screenInPortraitMode: sinon.stub()
|
||||
};
|
||||
|
||||
var rootElement;
|
||||
|
||||
setup(function() {
|
||||
rootElement = document.createElement('div');
|
||||
document.body.appendChild(rootElement);
|
||||
|
||||
layout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a' }, { value: 'b' }],
|
||||
[{ value: 'c' }, { value: 'd' }],
|
||||
[{ value: 'e' }, { value: 'f' }],
|
||||
[{ value: 'g' }, { value: 'h' }]
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.removeChild(rootElement);
|
||||
});
|
||||
|
||||
test('w/ 4 rows, portrait', function() {
|
||||
viewManager.getRemToPx.returns(10);
|
||||
viewManager.screenInPortraitMode.returns(true);
|
||||
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
assert.equal(pageView.getHeight(), 4 * ((4.5 + 0.8) * 10));
|
||||
});
|
||||
|
||||
test('w/ 4 rows, landscape', function() {
|
||||
viewManager.getRemToPx.returns(10);
|
||||
viewManager.screenInPortraitMode.returns(false);
|
||||
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
assert.equal(pageView.getHeight(), 4 * ((3.8 + 0.8) * 10));
|
||||
});
|
||||
|
||||
test('w/ 5 rows, portrait', function() {
|
||||
layout.keys.push([{ value: 'i' }, { value: 'j' }]);
|
||||
viewManager.getRemToPx.returns(10);
|
||||
viewManager.screenInPortraitMode.returns(true);
|
||||
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
assert.equal(pageView.getHeight(), 5 * ((3.4 + 0.8) * 10));
|
||||
});
|
||||
|
||||
test('w/ 5 rows, landscape', function() {
|
||||
layout.keys.push([{ value: 'i' }, { value: 'j' }]);
|
||||
viewManager.getRemToPx.returns(10);
|
||||
viewManager.screenInPortraitMode.returns(false);
|
||||
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
assert.equal(pageView.getHeight(), 5 * ((2.85 + 0.8) * 10));
|
||||
});
|
||||
});
|
||||
|
||||
suite(' > getVisualData()', function() {
|
||||
var layout = {
|
||||
width: 2,
|
||||
keys: [
|
||||
[{ value: 'a' }, { value: 'b' }],
|
||||
[{ value: 'c' }, { value: 'd' }],
|
||||
[{ value: 'e' }, { value: 'f' }]
|
||||
]
|
||||
};
|
||||
var pageView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
var rootElement;
|
||||
|
||||
setup(function() {
|
||||
rootElement = document.createElement('div');
|
||||
document.body.appendChild(rootElement);
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
document.body.removeChild(rootElement);
|
||||
});
|
||||
|
||||
test('check getVisualData sanity', function() {
|
||||
var layout = {
|
||||
width: 10,
|
||||
keys: [
|
||||
[{}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
|
||||
]
|
||||
};
|
||||
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
rootElement.appendChild(pageView.element);
|
||||
|
||||
var vData = pageView.getVisualData();
|
||||
|
||||
var visuals = [].slice.call(
|
||||
document.querySelectorAll('.visual-wrapper'));
|
||||
|
||||
visuals.forEach(function(v, ix) {
|
||||
assert.equal(v.offsetLeft, vData[ix].x, 'x for ' + ix);
|
||||
assert.equal(v.offsetTop, vData[ix].y, 'y for ' + ix);
|
||||
assert.equal(v.clientWidth, vData[ix].width, 'width for ' + ix);
|
||||
assert.equal(v.clientHeight, vData[ix].height, 'height for ' + ix);
|
||||
});
|
||||
});
|
||||
|
||||
test('check getVisualData sanity for filled up space', function() {
|
||||
var layout = {
|
||||
width: 4,
|
||||
keys: [
|
||||
[{}, {}, {}]
|
||||
]
|
||||
};
|
||||
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
rootElement.appendChild(pageView.element);
|
||||
|
||||
var vData = pageView.getVisualData();
|
||||
|
||||
|
||||
var visuals = [].slice.call(
|
||||
document.querySelectorAll('.visual-wrapper'));
|
||||
|
||||
visuals.forEach(function(v, ix) {
|
||||
assert.equal(v.offsetLeft, vData[ix].x, 'x for ' + ix);
|
||||
assert.equal(v.offsetTop, vData[ix].y, 'y for ' + ix);
|
||||
assert.equal(v.clientWidth, vData[ix].width, 'width for ' + ix);
|
||||
assert.equal(v.clientHeight, vData[ix].height, 'height for ' + ix);
|
||||
});
|
||||
});
|
||||
|
||||
test('getVisualData will return cached data', function() {
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var vData = pageView.getVisualData();
|
||||
var vData2 = pageView.getVisualData();
|
||||
|
||||
assert.equal(vData, vData2);
|
||||
});
|
||||
|
||||
test('getVisualData() will return cached data for different ' +
|
||||
'size', function() {
|
||||
pageView = new LayoutPageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var vData = pageView.getVisualData();
|
||||
|
||||
pageView.resize(480);
|
||||
var vData2 = pageView.getVisualData();
|
||||
assert.notEqual(vData, vData2);
|
||||
|
||||
var vData3 = pageView.getVisualData();
|
||||
assert.equal(vData2, vData3);
|
||||
});
|
||||
});
|
||||
});
|
||||
84
gaia/apps/keyboard/test/unit/views/swipeable_page_view_test.js
Executable file
84
gaia/apps/keyboard/test/unit/views/swipeable_page_view_test.js
Executable file
|
|
@ -0,0 +1,84 @@
|
|||
'use strict';
|
||||
|
||||
/* global SwipeablePageView */
|
||||
require('/js/views/key_view.js');
|
||||
require('/js/views/layout_page_view.js');
|
||||
require('/js/views/swipeable_section_view.js');
|
||||
require('/js/views/swiping_detector.js');
|
||||
require('/js/views/swipeable_panel_view.js');
|
||||
require('/js/views/swipeable_page_view.js');
|
||||
|
||||
suite('Views > SwipeablePageView', function() {
|
||||
var pageView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
setup(function() {
|
||||
var dummyLayout = {
|
||||
width: 2,
|
||||
panelKeys: [
|
||||
[{ value: 'a' }, { value: 'b' }]
|
||||
|
||||
],
|
||||
keys: [
|
||||
[{ value: 'a' }, { value: 'b' }]
|
||||
]
|
||||
|
||||
};
|
||||
|
||||
pageView = new SwipeablePageView(dummyLayout, {},
|
||||
viewManager);
|
||||
});
|
||||
|
||||
suite('some basic functions', function() {
|
||||
test('> render() ', function() {
|
||||
assert.equal(pageView.element, null);
|
||||
|
||||
pageView.render();
|
||||
assert.notEqual(pageView.element, null);
|
||||
|
||||
pageView.show();
|
||||
assert.equal(pageView.element.dataset.active, 'true');
|
||||
assert.ok(pageView.element.classList.contains('uppercase-only'));
|
||||
|
||||
var rows = pageView.element.querySelectorAll('.keyboard-row');
|
||||
assert.equal(rows.length, 1);
|
||||
|
||||
assert.ok(rows[0].classList.contains('swipe-switching-buttons'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('CSS classes on pageView', function() {
|
||||
test('with specificCssRule', function() {
|
||||
var layout = {
|
||||
panelKeys: [],
|
||||
keys: [],
|
||||
layoutName: 'ar',
|
||||
specificCssRule: true
|
||||
};
|
||||
|
||||
var pageView = new SwipeablePageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.classList.contains('ar'), true);
|
||||
});
|
||||
|
||||
test('without specificCssRule', function() {
|
||||
var layout = {
|
||||
width: 1,
|
||||
panelKeys: [],
|
||||
keys: [],
|
||||
layoutName: 'ar',
|
||||
specificCssRule: false
|
||||
};
|
||||
|
||||
var pageView = new SwipeablePageView(layout, {}, viewManager);
|
||||
pageView.render();
|
||||
|
||||
var container = pageView.element;
|
||||
assert.equal(container.classList.contains('ar'), false);
|
||||
});
|
||||
});
|
||||
});
|
||||
395
gaia/apps/keyboard/test/unit/views/swipeable_panel_view_test.js
Executable file
395
gaia/apps/keyboard/test/unit/views/swipeable_panel_view_test.js
Executable file
|
|
@ -0,0 +1,395 @@
|
|||
'use strict';
|
||||
|
||||
/* global SwipeablePanelView */
|
||||
require('/js/views/base_view.js');
|
||||
require('/js/views/key_view.js');
|
||||
require('/js/views/emoji_key_view.js');
|
||||
require('/js/views/swiping_detector.js');
|
||||
require('/js/views/swipeable_panel_view.js');
|
||||
|
||||
suite('Views > SwipeablePanelView', function() {
|
||||
var panelView = null;
|
||||
var viewManager = {
|
||||
registerView: sinon.stub()
|
||||
};
|
||||
|
||||
var layout = {
|
||||
panelKeys: []
|
||||
};
|
||||
|
||||
var sectionCount = 4;
|
||||
|
||||
for (var i = 0; i < 18 * sectionCount; i++) {
|
||||
layout.panelKeys.push({ value: i, type: 'emoji' });
|
||||
}
|
||||
|
||||
setup(function() {
|
||||
var options = {
|
||||
};
|
||||
|
||||
panelView = new SwipeablePanelView(layout, options,
|
||||
viewManager);
|
||||
});
|
||||
|
||||
suite('some basic functions', function() {
|
||||
test('> render() ', function() {
|
||||
assert.equal(panelView.element, null);
|
||||
|
||||
panelView.render();
|
||||
assert.notEqual(panelView.element, null);
|
||||
});
|
||||
|
||||
test('> render() check indicator elements', function() {
|
||||
panelView.render();
|
||||
|
||||
var indicators = panelView.element.querySelectorAll('.section-indicator');
|
||||
assert.equal(indicators.length, sectionCount);
|
||||
|
||||
assert.ok(indicators[0].classList.contains('active'));
|
||||
});
|
||||
|
||||
test('> move to the next section', function() {
|
||||
panelView.render();
|
||||
|
||||
panelView.gotoSection(1);
|
||||
var indicators = panelView.element.querySelectorAll('.section-indicator');
|
||||
|
||||
assert.isFalse(indicators[0].classList.contains('active'));
|
||||
assert.ok(indicators[1].classList.contains('active'));
|
||||
});
|
||||
});
|
||||
|
||||
suite('utilize different KeyView type', function() {
|
||||
test('> render() with KeyView ', function() {
|
||||
var layout = {
|
||||
panelKeys: [{value: 'key1'}, {value: 'key2'}]
|
||||
};
|
||||
|
||||
var panelView = new SwipeablePanelView(layout, {}, viewManager);
|
||||
panelView.render();
|
||||
|
||||
var keyView = panelView.element.querySelector('button.keyboard-key');
|
||||
assert.notEqual(keyView, null);
|
||||
});
|
||||
|
||||
test('> render() with EmojiKeyView ', function() {
|
||||
var layout = {
|
||||
panelKeys: [{value: 'key1', type: 'emoji'},
|
||||
{value: 'key2', type: 'emoji'}]
|
||||
};
|
||||
|
||||
var panelView = new SwipeablePanelView(layout, {}, viewManager);
|
||||
panelView.render();
|
||||
|
||||
var keyView = panelView.element.querySelector('button.emoji');
|
||||
assert.notEqual(keyView, null);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Render different number of elements', function() {
|
||||
test('> render() with no elements', function() {
|
||||
var layout = {
|
||||
panelKeys: [{value: 'key1'}, {value: 'key2'}]
|
||||
};
|
||||
|
||||
panelView = new SwipeablePanelView(layout, {}, viewManager);
|
||||
panelView.render();
|
||||
|
||||
assert.equal(panelView.sections[1], null);
|
||||
});
|
||||
|
||||
test('> render() with 2 emoji elements', function() {
|
||||
var layout = {
|
||||
panelKeys: [{value: 'key1', type: 'emoji'},
|
||||
{value: 'key2', type: 'emoji'}]
|
||||
};
|
||||
|
||||
panelView = new SwipeablePanelView(layout, {}, viewManager);
|
||||
panelView.render();
|
||||
|
||||
var section = panelView.sections[0];
|
||||
var keys = section.querySelectorAll('button.emoji');
|
||||
assert.equal(keys.length, 2);
|
||||
|
||||
var dummyElement = section.querySelector('span');
|
||||
assert.equal(dummyElement.style.flexGrow, 4);
|
||||
});
|
||||
|
||||
test('> render() one section at a time', function() {
|
||||
var layout = {
|
||||
panelKeys: []
|
||||
};
|
||||
|
||||
for (var i = 0; i < 20; i++) {
|
||||
layout.panelKeys.push({value: 'key' + i, type: 'emoji'});
|
||||
}
|
||||
|
||||
panelView = new SwipeablePanelView(layout, {}, viewManager);
|
||||
panelView.render();
|
||||
|
||||
var keys = panelView.sections[0].querySelectorAll('button.emoji');
|
||||
assert.equal(keys.length, 18);
|
||||
|
||||
keys = panelView.sections[1].querySelectorAll('button.emoji');
|
||||
assert.equal(keys.length, 2);
|
||||
|
||||
assert.equal(keys[0].textContent, 'key18');
|
||||
});
|
||||
});
|
||||
|
||||
suite('panning', function() {
|
||||
var rootElement = document.createElement('div');
|
||||
|
||||
setup(function() {
|
||||
document.body.appendChild(rootElement);
|
||||
var options = {
|
||||
totalWidth: 320
|
||||
};
|
||||
|
||||
panelView = new SwipeablePanelView(layout, options,
|
||||
viewManager);
|
||||
|
||||
panelView.render();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
rootElement.innerHTML = '';
|
||||
});
|
||||
|
||||
test('> panning the first section - forward', function() {
|
||||
assert.equal(panelView.sections[0].style.transform, '');
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: -20,
|
||||
position: {clientX: 0, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-20px)');
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(300px)');
|
||||
});
|
||||
|
||||
test('> panning the first section - backward', function() {
|
||||
assert.equal(panelView.sections[0].style.transform, '');
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 0, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: 20,
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, '');
|
||||
});
|
||||
|
||||
test('> panning the second section - forward', function() {
|
||||
panelView.gotoSection(1);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: -20,
|
||||
position: {clientX: 0, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(-20px)');
|
||||
assert.equal(panelView.sections[2].style.transform, 'translateX(300px)');
|
||||
});
|
||||
|
||||
test('> panning the second section - backward', function() {
|
||||
panelView.gotoSection(1);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: 20,
|
||||
position: {clientX: 40, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-300px)');
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(20px)');
|
||||
});
|
||||
|
||||
test('> panning the last section - forward', function() {
|
||||
panelView.gotoSection(sectionCount - 1);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: -20,
|
||||
position: {clientX: 0, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[sectionCount - 1].style.transform,
|
||||
'translateX(0px)');
|
||||
});
|
||||
|
||||
test('> panning the last section - backward', function() {
|
||||
panelView.gotoSection(sectionCount - 1);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: 20,
|
||||
position: {clientX: 40, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[sectionCount - 1].style.transform,
|
||||
'translateX(20px)');
|
||||
assert.equal(panelView.sections[sectionCount - 2].style.transform,
|
||||
'translateX(-300px)');
|
||||
});
|
||||
|
||||
test('> swiping through the first section - short distance', function() {
|
||||
rootElement.appendChild(panelView.element);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: -20,
|
||||
position: {clientX: 0, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-20px)');
|
||||
|
||||
panelView._handleSwipe({
|
||||
direction: 'left',
|
||||
vx: 0.3
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(0px)');
|
||||
});
|
||||
|
||||
test('> swiping through the first section - far enough', function() {
|
||||
rootElement.appendChild(panelView.element);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 100, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: -100,
|
||||
position: {clientX: 0, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-100px)');
|
||||
|
||||
panelView._handleSwipe({
|
||||
direction: 'left',
|
||||
vx: -0.3
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-320px)');
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(0px)');
|
||||
});
|
||||
|
||||
test('> swiping through the first section - fast enough', function() {
|
||||
rootElement.appendChild(panelView.element);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: -20,
|
||||
position: {clientX: 0, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-20px)');
|
||||
|
||||
panelView._handleSwipe({
|
||||
direction: 'left',
|
||||
vx: -1
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-320px)');
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(0px)');
|
||||
});
|
||||
|
||||
test('> swiping back to the first section, > threshold', function() {
|
||||
rootElement.appendChild(panelView.element);
|
||||
|
||||
panelView.gotoSection(1);
|
||||
|
||||
panelView._handleTouchStart({
|
||||
position: {clientX: 20, clientY: 0}
|
||||
});
|
||||
|
||||
panelView._handlePan({
|
||||
dx: 100,
|
||||
position: {clientX: 120, clientY: 0}
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(100px)');
|
||||
|
||||
panelView._handleSwipe({
|
||||
direction: 'right',
|
||||
vx: 0.3
|
||||
});
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(0px)');
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(320px)');
|
||||
});
|
||||
});
|
||||
|
||||
suite('rotate', function() {
|
||||
var rootElement = document.createElement('div');
|
||||
|
||||
setup(function() {
|
||||
document.body.appendChild(rootElement);
|
||||
var options = { totalWidth: 320 };
|
||||
|
||||
panelView = new SwipeablePanelView(layout, options,
|
||||
viewManager);
|
||||
|
||||
panelView.render();
|
||||
});
|
||||
|
||||
teardown(function() {
|
||||
rootElement.innerHTML = '';
|
||||
});
|
||||
|
||||
test('> rotate to landscape - at first section', function() {
|
||||
panelView.resize(590);
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(0px)');
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(590px)');
|
||||
});
|
||||
|
||||
test('> rotate to landscape - at second section', function() {
|
||||
panelView.gotoSection(1);
|
||||
panelView.resize(590);
|
||||
|
||||
assert.equal(panelView.sections[0].style.transform, 'translateX(-590px)');
|
||||
assert.equal(panelView.sections[1].style.transform, 'translateX(0px)');
|
||||
assert.equal(panelView.sections[2].style.transform, 'translateX(590px)');
|
||||
});
|
||||
|
||||
test('> rotate to landscape - at last section', function() {
|
||||
panelView.gotoSection(sectionCount - 1);
|
||||
panelView.resize(590);
|
||||
|
||||
assert.equal(
|
||||
panelView.sections[sectionCount - 1].style.transform,
|
||||
'translateX(0px)');
|
||||
assert.equal(
|
||||
panelView.sections[sectionCount - 2].style.transform,
|
||||
'translateX(-590px)');
|
||||
});
|
||||
});
|
||||
});
|
||||
161
gaia/apps/keyboard/test/unit/views/swiping_detector_test.js
Executable file
161
gaia/apps/keyboard/test/unit/views/swiping_detector_test.js
Executable file
|
|
@ -0,0 +1,161 @@
|
|||
'use strict';
|
||||
|
||||
/* global SwipingDetector */
|
||||
require('/js/views/swiping_detector.js');
|
||||
|
||||
suite('View utils > SwipingDetector', function() {
|
||||
function fakeTouchDispatch(type, panel, xs, ys) {
|
||||
var touches = [];
|
||||
|
||||
for (var i = 0; i < xs.length; i++) {
|
||||
var x = xs[i];
|
||||
var y = ys[i];
|
||||
var touch = document.createTouch(window, panel, 42, x, y,
|
||||
x, y, x, y,
|
||||
0, 0, 0, 0);
|
||||
touches.push(touch);
|
||||
}
|
||||
var touchList = document.createTouchList(touches);
|
||||
|
||||
var eventTouches = (type == 'touchstart' || type == 'touchmove') ?
|
||||
touchList : null;
|
||||
var eventChanged = (type == 'touchmove') ?
|
||||
null : touchList;
|
||||
|
||||
var e = document.createEvent('TouchEvent');
|
||||
e.initTouchEvent(type, true, true,
|
||||
null, null, false, false, false, false,
|
||||
eventTouches, null, eventChanged);
|
||||
|
||||
panel.dispatchEvent(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
function touchStart(panel, xs, ys) {
|
||||
return fakeTouchDispatch('touchstart', panel, xs, ys);
|
||||
}
|
||||
|
||||
function touchMove(panel, xs, ys) {
|
||||
return fakeTouchDispatch('touchmove', panel, xs, ys);
|
||||
}
|
||||
|
||||
function touchEnd(panel, xs, ys) {
|
||||
return fakeTouchDispatch('touchend', panel, xs, ys);
|
||||
}
|
||||
|
||||
function swipe(clock, panel, fromX, toX, fromY, toY, duration, noEnd) {
|
||||
var events = [];
|
||||
|
||||
duration = duration || 350;
|
||||
events.push(touchStart(panel, [fromX], [fromY]));
|
||||
|
||||
var diffX = Math.abs(toX - fromX);
|
||||
var diffY = Math.abs(toY - fromY);
|
||||
var delta = Math.max(diffX, diffY);
|
||||
var step = step || 1;
|
||||
|
||||
var x = 0, y = 0;
|
||||
var tick = duration / delta;
|
||||
for (var i = 0; i < delta; i++) {
|
||||
var newX = fromX + x;
|
||||
var newY = fromY + y;
|
||||
|
||||
events.push(touchMove(panel, [newX], [newY]));
|
||||
clock.tick(tick);
|
||||
|
||||
if (newX < toX) {
|
||||
x++;
|
||||
}
|
||||
if (newX > toX) {
|
||||
x--;
|
||||
}
|
||||
if (newY < toY) {
|
||||
y++;
|
||||
}
|
||||
if (newY > toY) {
|
||||
y--;
|
||||
}
|
||||
}
|
||||
|
||||
if (!noEnd) {
|
||||
events.push(touchEnd(panel, [toX], [toY]));
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
function createFakeCoordinates(x, y, timeStamp, id) {
|
||||
return Object.freeze({
|
||||
screenX: x,
|
||||
screenY: y,
|
||||
clientX: x,
|
||||
clientY: y,
|
||||
timeStamp: timeStamp,
|
||||
identifier: id
|
||||
});
|
||||
}
|
||||
|
||||
var swipingDetector = null;
|
||||
var element = null;
|
||||
|
||||
setup(function() {
|
||||
element = document.createElement('div');
|
||||
swipingDetector = new SwipingDetector(element);
|
||||
|
||||
this.sinon.useFakeTimers();
|
||||
});
|
||||
|
||||
test('init', function() {
|
||||
swipingDetector.start();
|
||||
});
|
||||
|
||||
test('pan', function() {
|
||||
swipingDetector.start();
|
||||
|
||||
var panHandler = this.sinon.stub();
|
||||
swipingDetector.onpan = panHandler;
|
||||
|
||||
swipe(this.sinon.clock, element, 21, 0, 0, 0, 100, true);
|
||||
|
||||
assert.equal(panHandler.lastCall.args[0].dx, -20);
|
||||
});
|
||||
|
||||
test('swipe', function() {
|
||||
swipingDetector.start();
|
||||
|
||||
var swipeHandler = this.sinon.stub();
|
||||
swipingDetector.onswipe = swipeHandler;
|
||||
|
||||
swipe(this.sinon.clock, element, 0, 21, 0, 0, 100);
|
||||
assert.equal(swipeHandler.firstCall.args[0].direction, 'right');
|
||||
|
||||
swipe(this.sinon.clock, element, 20, 0, 0, 0, 300);
|
||||
assert.equal(swipeHandler.lastCall.args[0].direction, 'left');
|
||||
});
|
||||
|
||||
test('swipe will report velocity', function() {
|
||||
swipingDetector.start();
|
||||
|
||||
var swipeHandler = this.sinon.stub();
|
||||
swipingDetector.onswipe = swipeHandler;
|
||||
|
||||
swipingDetector.handleEvent({
|
||||
type: 'touchstart',
|
||||
touches: [createFakeCoordinates(0, 0, 0)],
|
||||
timeStamp: 0
|
||||
});
|
||||
|
||||
swipingDetector.handleEvent({
|
||||
type: 'touchmove',
|
||||
touches: [createFakeCoordinates(20, 0, 0)],
|
||||
timeStamp: 100
|
||||
});
|
||||
|
||||
swipingDetector.handleEvent({
|
||||
type: 'touchend',
|
||||
changedTouches: [createFakeCoordinates(20, 0, 0)],
|
||||
timeStamp: 100
|
||||
});
|
||||
|
||||
assert.equal(swipeHandler.firstCall.args[0].vx, 0.2);
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue