mediawiki-extensions-Visual.../modules/ve/test/actions/ve.IndentationAction.test.js
Ed Sanders 1261a5f471 Fix unindent action when acting on multiple list items
This is caused by a limitation of surface fragments in that they
always expand to include insertions touching them. In this case
we build surface fragments contain adjacent listItems, so when
the first listItem is de-listed a transaction is first created to
split the list. This insertion of ('/list', 'list') is adjacent
to the second surface fragment and so becomes part of that fragment.

This then causes the wrong node to be passed to unindentListItem.

The workaround is to use the inner range of the listItem, not
the outer range.

Bug: 48390

Change-Id: I7418910412d292ef4953e294a97f66e48d6f776f
2013-05-12 22:15:09 +01:00

81 lines
2.8 KiB
JavaScript

/*!
* VisualEditor Actions IndentationAction tests.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
QUnit.module( 've.IndentationAction' );
/* Tests */
function runIndentationChangeTest( assert, range, method, expectedSelection, expectedData, expectedOriginalData, msg ) {
var selection,
dom = ve.createDocumentFromHTML( ve.dm.example.isolationHTML ),
surface = new ve.Surface( new ve.init.Target( $( '<div>' ) ), dom ),
indentationAction = new ve.IndentationAction( surface ),
data = ve.copyArray( surface.getModel().getDocument().getFullData() ),
originalData = ve.copyArray( data );
expectedData( data );
if ( expectedOriginalData ) {
expectedOriginalData( originalData );
}
surface.getModel().change( null, range );
indentationAction[method]();
assert.deepEqual( surface.getModel().getDocument().getFullData(), data, msg + ': data models match' );
assert.deepEqual( surface.getModel().getSelection(), expectedSelection, msg + ': selections match' );
selection = surface.getModel().undo();
assert.deepEqual( surface.getModel().getDocument().getFullData(), originalData, msg + ' (undo): data models match' );
assert.deepEqual( selection, range, msg + ' (undo): selections match' );
surface.destroy();
}
QUnit.test( 'decrease', 2, function ( assert ) {
var i,
cases = [
{
'range': new ve.Range( 14, 16 ),
'method': 'decrease',
'expectedSelection': new ve.Range( 14, 16 ),
'expectedData': function ( data ) {
data.splice( 11, 2, { 'type': '/list' }, { 'type': 'paragraph' } );
data.splice( 19, 2, { 'type': '/paragraph' }, { 'type': 'list', 'attributes': { 'style': 'bullet' } } );
},
'expectedOriginalData': function ( data ) {
// generated: 'wrapper' is removed by the action and not restored by undo
delete data[12].internal;
},
'msg': 'decrease indentation on partial selection of list item "Item 2"'
},
{
'range': new ve.Range( 3, 19 ),
'method': 'decrease',
'expectedSelection': new ve.Range( 1, 15 ),
'expectedData': function ( data ) {
data.splice( 0, 2 );
data.splice( 8, 2 );
data.splice( 16, 1, { 'type': 'list', 'attributes': { 'style': 'bullet' } } );
delete data[0].internal;
delete data[8].internal;
},
'expectedOriginalData': function ( data ) {
// generated: 'wrapper' is removed by the action and not restored by undo
delete data[2].internal;
delete data[12].internal;
},
'msg': 'decrease indentation on Items 1 & 2'
}
];
QUnit.expect( cases.length * 4 );
for ( i = 0; i < cases.length; i++ ) {
runIndentationChangeTest( assert, cases[i].range, cases[i].method, cases[i].expectedSelection, cases[i].expectedData, cases[i].expectedOriginalData, cases[i].msg );
}
} );