| Current File : /home/jvzmxxx/wiki1/extensions/VisualEditor/lib/ve/tests/ui/actions/ve.ui.TableAction.test.js |
/*!
* VisualEditor UserInterface Actions TableAction tests.
*
* @copyright 2011-2016 VisualEditor Team and others; see http://ve.mit-license.org
*/
QUnit.module( 've.ui.TableAction' );
/* Tests */
QUnit.test( 'create / insert / mergeCells / delete / changeCellStyle / moveRelative', function ( assert ) {
var i,
tableCellTail = [
{ type: 'paragraph', internal: { generated: 'wrapper' } },
{ type: '/paragraph' },
{ type: '/tableCell' }
],
tableHeader = [
{
type: 'tableCell',
attributes: {
colspan: 1,
rowspan: 1,
style: 'header'
}
}
].concat( tableCellTail ),
tableData = [
{
type: 'tableCell',
attributes: {
colspan: 1,
rowspan: 1,
style: 'data'
}
}
].concat( tableCellTail ),
cases = [
{
rangeOrSelection: new ve.Range( 0 ),
method: 'create',
args: [ {
cols: 1,
rows: 1,
attributes: { sortable: true }
} ],
expectedData: function ( data ) {
data.splice.apply( data, [ 0, 0 ].concat(
[
{ type: 'table', attributes: { sortable: true } },
{ type: 'tableSection', attributes: { style: 'body' } },
{ type: 'tableRow' }
],
tableData,
[
{ type: '/tableRow' },
{ type: '/tableSection' },
{ type: '/table' }
]
) );
},
expectedRangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 10 ),
fromCol: 0,
fromRow: 0,
toCol: 0,
toRow: 0
},
msg: 'create single cell table with attributes'
},
{
rangeOrSelection: new ve.Range( 0 ),
method: 'create',
args: [ {
cols: 3,
rows: 2,
header: true
} ],
expectedData: function ( data ) {
data.splice.apply( data, [ 0, 0 ].concat(
[
{ type: 'table' },
{ type: 'tableSection', attributes: { style: 'body' } },
{ type: 'tableRow' }
],
tableHeader,
tableHeader,
tableHeader,
[
{ type: '/tableRow' },
{ type: 'tableRow' }
],
tableData,
tableData,
tableData,
[
{ type: '/tableRow' },
{ type: 'tableRow' }
],
tableData,
tableData,
tableData,
[
{ type: '/tableRow' },
{ type: '/tableSection' },
{ type: '/table' }
]
) );
},
msg: 'create small table with header'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 5,
fromRow: 1,
toCol: 5,
toRow: 1
},
method: 'insert',
args: [ 'col', 'after' ],
expectedData: function ( data ) {
data.splice.apply( data, [ 168, 0 ].concat( tableData ) );
data.splice.apply( data, [ 130, 0 ].concat( tableData ) );
data.splice.apply( data, [ 116, 0 ].concat( tableData ) );
data.splice.apply( data, [ 102, 0 ].concat( tableData ) );
data.splice.apply( data, [ 82, 0 ].concat( tableData ) );
data.splice.apply( data, [ 56, 0 ].concat( tableData ) );
data.splice.apply( data, [ 33, 0 ].concat( tableData ) );
},
expectedRangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 199 ),
fromCol: 5,
fromRow: 1,
toCol: 5,
toRow: 1
},
msg: 'insert column at end of table'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 3,
fromRow: 0,
toCol: 3,
toRow: 0
},
method: 'insert',
args: [ 'col', 'before' ],
expectedData: function ( data ) {
data.splice.apply( data, [ 150, 0 ].concat( tableData ) );
data[ 90 ].attributes.colspan = 4;
data.splice.apply( data, [ 76, 0 ].concat( tableData ) );
data.splice.apply( data, [ 45, 0 ].concat( tableData ) );
data.splice.apply( data, [ 18, 0 ].concat( tableData ) );
},
msg: 'insert column in middle of table'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 0,
fromRow: 6,
toCol: 0,
toRow: 6
},
method: 'insert',
args: [ 'row', 'after' ],
expectedData: function ( data ) {
data.splice.apply( data, [ 169, 0 ].concat(
[
{ type: 'tableRow' }
],
tableData,
tableData,
tableData,
tableData,
tableData,
tableData,
[
{ type: '/tableRow' }
] )
);
},
msg: 'insert row at end of table'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 0,
fromRow: 3,
toCol: 0,
toRow: 3
},
method: 'insert',
args: [ 'row', 'before' ],
expectedData: function ( data ) {
data[ 45 ].attributes.rowspan = 5;
data.splice.apply( data, [ 83, 0 ].concat(
[
{ type: 'tableRow' }
],
tableData,
tableData,
tableData,
tableData,
tableData,
[
{ type: '/tableRow' }
] )
);
},
msg: 'insert row in middle of table'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 0,
fromRow: 0,
toCol: 2,
toRow: 1
},
method: 'mergeCells',
args: [],
expectedData: function ( data ) {
data[ 3 ].attributes.colspan = 3;
data[ 3 ].attributes.rowspan = 2;
data.splice( 40, 5 );
data.splice( 35, 5 );
data.splice( 13, 5 );
data.splice( 8, 5 );
},
msg: 'merge cells'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 1,
fromRow: 3,
toCol: 3,
toRow: 5
},
method: 'mergeCells',
args: [],
expectedData: function ( data ) {
data[ 90 ].attributes.colspan = 1;
data[ 90 ].attributes.rowspan = 1;
data.splice.apply( data, [ 124, 0 ].concat( tableData, tableData, tableData ) );
data.splice.apply( data, [ 110, 0 ].concat( tableData, tableData, tableData ) );
data.splice.apply( data, [ 96, 0 ].concat( tableData, tableData ) );
},
msg: 'unmerge cells'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 0,
fromRow: 0,
toCol: 5,
toRow: 5
},
method: 'mergeCells',
args: [],
expectedData: function ( data ) {
data[ 3 ].attributes.colspan = 6;
data[ 3 ].attributes.rowspan = 1;
data.splice( 8, 122 );
},
msg: 'merge full rows'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 0,
fromRow: 0,
toCol: 3,
toRow: 6
},
method: 'mergeCells',
args: [],
expectedData: function ( data ) {
data[ 3 ].attributes.colspan = 1;
data[ 3 ].attributes.rowspan = 7;
data.splice( 132, 24 );
data.splice( 118, 6 );
data.splice( 104, 6 );
data.splice( 84, 12 );
data.splice( 58, 18 );
data.splice( 35, 10 );
data.splice( 8, 15 );
},
msg: 'merge full columns'
},
{
html: '<table><tr><td></td><td>A</td></tr><tr><td></td><td></td></tr></table>',
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 25 ),
fromCol: 0,
fromRow: 0,
toCol: 1,
toRow: 0
},
method: 'mergeCells',
args: [],
expectedData: function ( data ) {
data.splice( 3, 4 );
data[ 3 ].attributes.colspan = 2;
data[ 3 ].attributes.rowspan = 1;
},
msg: 'merge when first cell is empty'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 0,
fromRow: 0,
toCol: 0,
toRow: 0
},
method: 'delete',
args: [ 'table' ],
expectedData: function ( data ) {
data.splice( 0, 171,
{ type: 'paragraph' },
{ type: '/paragraph' }
);
},
msg: 'delete whole table'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 0,
fromRow: 3,
toCol: 0,
toRow: 3
},
method: 'delete',
args: [ 'row' ],
expectedData: function ( data ) {
data[ 90 ].attributes.rowspan = 2;
data[ 45 ].attributes.rowspan = 3;
data.splice( 110, 0,
{
type: 'tableCell',
attributes: {
colspan: 3,
rowspan: 2,
style: 'data'
}
},
{ type: 'paragraph', internal: { generated: 'wrapper' } },
'1', '6',
{ type: '/paragraph' },
{ type: '/tableCell' }
);
data.splice( 83, 20 );
},
expectedRangeOrSelection: { type: 'null' },
msg: 'delete row'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 3,
fromRow: 0,
toCol: 3,
toRow: 0
},
method: 'delete',
args: [ 'col' ],
expectedData: function ( data ) {
data[ 90 ].attributes.colspan = 2;
data.splice( 150, 6 );
data.splice( 18, 5 );
},
expectedRangeOrSelection: { type: 'null' },
msg: 'delete column'
},
{
html: ve.dm.example.mergedCellsHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 171 ),
fromCol: 1,
fromRow: 0,
toCol: 2,
toRow: 1
},
method: 'changeCellStyle',
args: [ 'header' ],
expectedData: function ( data ) {
data[ 8 ].attributes.style = 'header';
data[ 13 ].attributes.style = 'header';
data[ 40 ].attributes.style = 'header';
},
msg: 'change style to header'
},
{
html: ve.dm.example.annotatedTableHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 0,
fromRow: 1,
toCol: 0,
toRow: 1
},
method: 'moveRelative',
args: [ 'row', 'before' ],
expectedData: function ( data ) {
var row = data.splice( 25, 25 );
data.splice.apply( data, [ 2, 0 ].concat( row ) );
},
expectedRangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 0,
fromRow: 0,
toCol: 0,
toRow: 0
},
msg: 'move row before'
},
{
html: ve.dm.example.annotatedTableHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 0,
fromRow: 0,
toCol: 0,
toRow: 0
},
method: 'moveRelative',
args: [ 'row', 'after' ],
expectedData: function ( data ) {
var row = data.splice( 25, 25 );
data.splice.apply( data, [ 2, 0 ].concat( row ) );
},
expectedRangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 0,
fromRow: 1,
toCol: 0,
toRow: 1
},
msg: 'move row after'
},
{
html: ve.dm.example.annotatedTableHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 1,
fromRow: 0,
toCol: 1,
toRow: 0
},
method: 'moveRelative',
args: [ 'col', 'before' ],
expectedData: function ( data ) {
var cell2 = data.splice( 34, 8 ),
cell1 = data.splice( 10, 7 );
data.splice.apply( data, [ 26 - cell1.length, 0 ].concat( cell2 ) );
data.splice.apply( data, [ 3, 0 ].concat( cell1 ) );
},
expectedRangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 0,
fromRow: 0,
toCol: 0,
toRow: 0
},
msg: 'move column before'
},
{
html: ve.dm.example.annotatedTableHtml,
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 0,
fromRow: 0,
toCol: 0,
toRow: 0
},
method: 'moveRelative',
args: [ 'col', 'after' ],
expectedData: function ( data ) {
var cell2 = data.splice( 26, 8 ),
cell1 = data.splice( 3, 7 );
data.splice.apply( data, [ 42 - cell1.length - cell2.length, 0 ].concat( cell2 ) );
data.splice.apply( data, [ 17 - cell1.length, 0 ].concat( cell1 ) );
},
expectedRangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 52 ),
fromCol: 1,
fromRow: 0,
toCol: 1,
toRow: 0
},
msg: 'move column after'
},
{
html: '<table><tr></tr><tr><td>A</td></tr></table>',
rangeOrSelection: {
type: 'table',
tableRange: new ve.Range( 0, 13 ),
fromCol: 0,
fromRow: 1,
toCol: 0,
toRow: 1
},
method: 'moveRelative',
args: [ 'row', 'before' ],
expectedData: function ( data ) {
var row = data.splice( 4, 7 );
data.splice.apply( data, [ 2, 0 ].concat( row ) );
},
msg: 'move row adjacent to sparse row'
}
];
QUnit.expect( ve.test.utils.countActionTests( cases ) );
for ( i = 0; i < cases.length; i++ ) {
ve.test.utils.runActionTest(
'table', assert, cases[ i ].html, false, cases[ i ].method, cases[ i ].args, cases[ i ].rangeOrSelection, cases[ i ].msg,
{
expectedData: cases[ i ].expectedData,
expectedRangeOrSelection: cases[ i ].expectedRangeOrSelection
}
);
}
} );