fabric.js/test/unit/itext_key_behaviour.js
Jeremy Shipman 0c936ed6bc Fix testem runner, and further improvements (#4593)
* Switched qunit dependency to npm

* Fixed testem not working

* Switched test.js build to use node-qunit.
As stated in the QUnit docs: The qunit package prior to 2.4.1 is an alternative CLI that is now published as node-qunit.

* Introduced qunit 2.4.1, with an npm script for running node tests

* Switched testem page fixture to use qunit package instead of qunitjs

* Configured testem to run in headless mode, and use new npm node test script for "Node" launcher configuration.
This means that individual tests will show up in testem output via the the `tap` test protocol.

* Made canvas_static 'toDataURL cropping' test asynchronous.

* Configured QUnit testTimeout and enabled 'noglobals' config

* Updated .travis.yml config to do cross-browser/env testing via Testem

* Specify qunit binary directly to fix confict with binary from node-qunit

* Avoid test hanging by aborting the animated cursor

* Firefox test fix, and enabled in Testem config
2017-12-31 09:51:07 +01:00

344 lines
16 KiB
JavaScript

(function(){
var canvas = fabric.document.createElement('canvas'),
ctx = canvas.getContext('2d');
QUnit.test('event selection:changed firing', function(assert) {
var iText = new fabric.IText('test neei some word\nsecond line'),
selection = 0;
iText.ctx = ctx;
function countSelectionChange() {
selection++;
}
iText.on('selection:changed', countSelectionChange);
iText.enterEditing();
assert.equal(selection, 1, 'will fire on enter edit since the cursor is changing for the first time');
selection = 0;
iText.selectAll();
assert.equal(selection, 1, 'should fire once on selectAll');
assert.equal(iText.selectionStart, 0, 'should start from 0');
assert.equal(iText.selectionEnd, 31, 'should end at end of text');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.selectWord();
assert.equal(selection, 1, 'should fire once on selectWord');
assert.equal(iText.selectionStart, 0, 'should start at word start');
assert.equal(iText.selectionEnd, 4, 'should end at word end');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.selectLine();
assert.equal(selection, 1, 'should fire once on selectLine');
assert.equal(iText.selectionStart, 0, 'should start at line start');
assert.equal(iText.selectionEnd, 19, 'should end at line end');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.moveCursorLeft({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorLeft');
assert.equal(iText.selectionStart, 1, 'should be 1 less than 2');
assert.equal(iText.selectionEnd, 1, 'should be 1 less than 2');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.moveCursorRight({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorRight');
assert.equal(iText.selectionStart, 3, 'should be 1 more than 2');
assert.equal(iText.selectionEnd, 3, 'should be 1 more than 2');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.moveCursorDown({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorDown');
assert.equal(iText.selectionStart, 22, 'should be on second line');
assert.equal(iText.selectionEnd, 22, 'should be on second line');
iText.moveCursorDown({ shiftKey: false});
assert.equal(selection, 2, 'should fire once on moveCursorDown');
assert.equal(iText.selectionStart, 31, 'should be at end of text');
assert.equal(iText.selectionEnd, 31, 'should be at end of text');
selection = 0;
iText.selectionStart = 22;
iText.selectionEnd = 22;
iText.moveCursorUp({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorUp');
assert.equal(iText.selectionStart, 2, 'should be back to first line');
assert.equal(iText.selectionEnd, 2, 'should be back on first line');
iText.moveCursorUp({ shiftKey: false});
assert.equal(selection, 2, 'should fire once on moveCursorUp');
assert.equal(iText.selectionStart, 0, 'should be back to first line');
assert.equal(iText.selectionEnd, 0, 'should be back on first line');
selection = 0;
iText.selectionStart = 0;
iText.selectionEnd = 0;
iText.moveCursorLeft({ shiftKey: false});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 0, 'should not move');
assert.equal(iText.selectionEnd, 0, 'should not move');
iText.moveCursorUp({ shiftKey: false});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 0, 'should not move');
assert.equal(iText.selectionEnd, 0, 'should not move');
selection = 0;
iText.selectionStart = 31;
iText.selectionEnd = 31;
iText.moveCursorRight({ shiftKey: false});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 31, 'should not move');
assert.equal(iText.selectionEnd, 31, 'should not move');
iText.moveCursorDown({ shiftKey: false});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 31, 'should not move');
assert.equal(iText.selectionEnd, 31, 'should not move');
selection = 0;
iText.selectionStart = 28;
iText.selectionEnd = 31;
iText.moveCursorUp({ shiftKey: false });
assert.equal(selection, 1, 'should fire');
assert.equal(iText.selectionStart, 9, 'should move to upper line start');
assert.equal(iText.selectionEnd, 9, 'should move to upper line end');
selection = 0;
iText.selectionStart = 1;
iText.selectionEnd = 4;
iText.moveCursorDown({ shiftKey: false });
assert.equal(selection, 1, 'should fire');
assert.equal(iText.selectionStart, 24, 'should move to down line');
assert.equal(iText.selectionEnd, 24, 'should move to down line');
selection = 0;
iText.selectionStart = 28;
iText.selectionEnd = 31;
iText.moveCursorLeft({ shiftKey: false });
assert.equal(selection, 1, 'should fire');
assert.equal(iText.selectionStart, 28, 'should move to selection Start');
assert.equal(iText.selectionEnd, 28, 'should move to selection Start');
selection = 0;
// needed or test hangs
iText.abortCursorAnimation();
// TODO verify and dp
// iText.selectionStart = 0;
// iText.selectionEnd = 0;
// iText.insertChars('hello');
// assert.equal(selection, 1, 'should fire once on insert multiple chars');
// assert.equal(iText.selectionStart, 5, 'should be at end of text inserted');
// assert.equal(iText.selectionEnd, 5, 'should be at end of text inserted');
});
QUnit.test('moving cursor with shift', function(assert) {
var iText = new fabric.IText('test need some word\nsecond line'),
selection = 0;
iText.ctx = ctx;
function countSelectionChange() {
selection++;
}
iText.on('selection:changed', countSelectionChange);
iText.enterEditing();
assert.equal(selection, 1, 'should fire on enter edit');
selection = 0;
iText.selectAll();
assert.equal(selection, 1, 'should fire once on selectAll');
assert.equal(iText.selectionStart, 0, 'should start from 0');
assert.equal(iText.selectionEnd, 31, 'should end at end of text');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.selectWord();
assert.equal(selection, 1, 'should fire once on selectWord');
assert.equal(iText.selectionStart, 0, 'should start at word start');
assert.equal(iText.selectionEnd, 4, 'should end at word end');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.selectLine();
assert.equal(selection, 1, 'should fire once on selectLine');
assert.equal(iText.selectionStart, 0, 'should start at line start');
assert.equal(iText.selectionEnd, 19, 'should end at line end');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.moveCursorLeft({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorLeft');
assert.equal(iText.selectionStart, 1, 'should be 1 less than 2');
assert.equal(iText.selectionEnd, 1, 'should be 1 less than 2');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.moveCursorRight({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorRight');
assert.equal(iText.selectionStart, 3, 'should be 1 more than 2');
assert.equal(iText.selectionEnd, 3, 'should be 1 more than 2');
selection = 0;
iText.selectionStart = 2;
iText.selectionEnd = 2;
iText.moveCursorDown({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorDown');
assert.equal(iText.selectionStart, 22, 'should be on second line');
assert.equal(iText.selectionEnd, 22, 'should be on second line');
iText.moveCursorDown({ shiftKey: false});
assert.equal(selection, 2, 'should fire once on moveCursorDown');
assert.equal(iText.selectionStart, 31, 'should be at end of text');
assert.equal(iText.selectionEnd, 31, 'should be at end of text');
selection = 0;
iText.selectionStart = 22;
iText.selectionEnd = 22;
iText.moveCursorUp({ shiftKey: false});
assert.equal(selection, 1, 'should fire once on moveCursorUp');
assert.equal(iText.selectionStart, 2, 'should be back to first line');
assert.equal(iText.selectionEnd, 2, 'should be back on first line');
iText.moveCursorUp({ shiftKey: false});
assert.equal(selection, 2, 'should fire once on moveCursorUp');
assert.equal(iText.selectionStart, 0, 'should be back to first line');
assert.equal(iText.selectionEnd, 0, 'should be back on first line');
selection = 0;
iText.selectionStart = 0;
iText.selectionEnd = 1;
iText._selectionDirection = 'left';
iText.moveCursorLeft({ shiftKey: true});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 0, 'should not move');
assert.equal(iText.selectionEnd, 1, 'should not move');
iText.moveCursorUp({ shiftKey: true});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 0, 'should not move');
assert.equal(iText.selectionEnd, 1, 'should not move');
selection = 0;
iText.selectionStart = 30;
iText.selectionEnd = 31;
iText._selectionDirection = 'right';
iText.moveCursorRight({ shiftKey: true});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 30, 'should not move');
assert.equal(iText.selectionEnd, 31, 'should not move');
iText.moveCursorDown({ shiftKey: true});
assert.equal(selection, 0, 'should not fire with no change');
assert.equal(iText.selectionStart, 30, 'should not move');
assert.equal(iText.selectionEnd, 31, 'should not move');
selection = 0;
// needed or test hangs
iText.abortCursorAnimation();
});
// QUnit.test('copy and paste', function(assert) {
// var event = { stopPropagation: function(){}, preventDefault: function(){} };
// var iText = new fabric.IText('test', { styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
// iText.enterEditing();
// iText.selectionStart = 0;
// iText.selectionEnd = 2;
// iText.hiddenTextarea.selectionStart = 0
// iText.hiddenTextarea.selectionEnd = 2
// iText.copy(event);
// assert.equal(fabric.copiedText, 'te', 'it copied first 2 characters');
// assert.equal(fabric.copiedTextStyle[0], iText.styles[0][0], 'style is referenced');
// assert.equal(fabric.copiedTextStyle[1], iText.styles[0][1], 'style is referenced');
// iText.selectionStart = 2;
// iText.selectionEnd = 2;
// iText.hiddenTextarea.value = 'tetest';
// iText.paste(event);
// assert.equal(iText.text, 'tetest', 'text has been copied');
// assert.notEqual(iText.styles[0][0], iText.styles[0][2], 'style is not referenced');
// assert.notEqual(iText.styles[0][1], iText.styles[0][3], 'style is not referenced');
// assert.deepEqual(iText.styles[0][0], iText.styles[0][2], 'style is copied');
// assert.deepEqual(iText.styles[0][1], iText.styles[0][3], 'style is copied');
// });
QUnit.test('copy', function(assert) {
var event = { stopPropagation: function(){}, preventDefault: function(){} };
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.selectionStart = 0;
iText.selectionEnd = 2;
iText.copy(event);
assert.equal(fabric.copiedText, 'te', 'it copied first 2 characters');
assert.equal(fabric.copiedTextStyle[0].fill, iText.styles[0][0].fill, 'style is cloned');
assert.equal(fabric.copiedTextStyle[1].fill, iText.styles[0][1].fill, 'style is referenced');
assert.equal(iText.styles[0][1].fontSize, undefined, 'style had not fontSize');
assert.equal(fabric.copiedTextStyle[1].fontSize, 25, 'style took fontSize from text element');
});
QUnit.test('removeChars', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
assert.ok(typeof iText.removeChars === 'function');
iText.removeChars(1,3);
assert.equal(iText.text, 'tt', 'text has been remoed');
assert.deepEqual(iText._text, ['t','t'], 'text has been remoed');
assert.equal(iText.styles[0][1], undefined, 'style has been removed');
});
QUnit.test('insertChars', function(assert) {
var iText = new fabric.IText('test');
assert.ok(typeof iText.insertChars === 'function');
iText.insertChars('ab', null, 1);
assert.equal(iText.text, 'tabest', 'text has been added');
assert.deepEqual(iText._text.join(''), 'tabest', '_text has been updated');
});
QUnit.test('insertChars can remove chars', function(assert) {
var iText = new fabric.IText('test');
iText.insertChars('ab', null, 1, 2);
assert.equal(iText.text, 'tabst', 'text has added');
assert.deepEqual(iText._text.join(''), 'tabst', '_text has been updated');
var iText = new fabric.IText('test');
iText.insertChars('ab', null, 1, 4);
assert.equal(iText.text, 'tab', 'text has added');
assert.deepEqual(iText._text.join(''), 'tab', '_text has been updated');
});
QUnit.test('insertChars pick up the style of the character behind and replicates it', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab', null, 1);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'red', 'style 0 1 has been inserted red');
assert.equal(iText.styles[0][2].fill, 'red', 'style 0 2 has been inserted red');
assert.equal(iText.styles[0][3].fill, 'blue', 'style 0 3 was the old blue moved 2 char later');
});
QUnit.test('insertChars removes style from the removed text', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab', null, 1, 2);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'red', 'style 0 1 has been inserted red');
assert.equal(iText.styles[0][2].fill, 'red', 'style 0 2 has been inserted red');
assert.equal(iText.styles[0][3], undefined, 'style 0 3 has been removed');
});
QUnit.test('insertChars handles new lines correctly', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab\n\n', null, 1);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'red', 'style 0 1 has been inserted red');
assert.equal(iText.styles[0][2].fill, 'red', 'style 0 2 has been inserted red');
assert.equal(iText.styles[2][0].fill, 'blue', 'blue has been moved down');
});
QUnit.test('insertChars can accept some style for the new text', function(assert) {
var iText = new fabric.IText('test', { fontSize: 25, styles: { 0: { 0: { fill: 'red' }, 1: { fill: 'blue' }}}});
iText.insertChars('ab\n\na', [{ fill: 'col1'},{ fill: 'col2'},{ fill: 'col3'},{ fill: 'col4'},{ fill: 'col5'}], 1);
assert.equal(iText.styles[0][0].fill, 'red', 'style 0 0 did not change');
assert.equal(iText.styles[0][1].fill, 'col1', 'style 0 1 has been inserted col1');
assert.equal(iText.styles[0][2].fill, 'col2', 'style 0 2 has been inserted col2');
assert.equal(iText.styles[1][0].fill, 'col4', 'style 1 0 has been inserted col4');
assert.equal(iText.styles[2][0].fill, 'col5', 'style 2 0 has been inserted col5');
assert.equal(iText.styles[2][1].fill, 'blue', 'style 2 1 has been inserted blue');
});
})();