Esanders has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/287990

Change subject: Unify action test runners
......................................................................

Unify action test runners

Bug: T90370
Change-Id: I1a0ca8d33d89b24feb80ff604d24fa3028c7e137
---
M tests/ui/actions/ve.ui.AnnotationAction.test.js
M tests/ui/actions/ve.ui.ContentAction.test.js
M tests/ui/actions/ve.ui.FormatAction.test.js
M tests/ui/actions/ve.ui.IndentationAction.test.js
M tests/ui/actions/ve.ui.LinkAction.test.js
M tests/ui/actions/ve.ui.ListAction.test.js
M tests/ui/actions/ve.ui.TableAction.test.js
M tests/ve.test.utils.js
8 files changed, 175 insertions(+), 254 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor 
refs/changes/90/287990/1

diff --git a/tests/ui/actions/ve.ui.AnnotationAction.test.js 
b/tests/ui/actions/ve.ui.AnnotationAction.test.js
index c4d9cb7..cdb809c 100644
--- a/tests/ui/actions/ve.ui.AnnotationAction.test.js
+++ b/tests/ui/actions/ve.ui.AnnotationAction.test.js
@@ -8,45 +8,28 @@
 
 /* Tests */
 
-function runAnnotationActionTest( assert, html, method, args, selection, 
expectedData, msg ) {
-       var surface = ve.test.utils.createModelOnlySurfaceFromHtml( html || 
ve.dm.example.html ),
-               AnnotationAction = new ve.ui.AnnotationAction( surface ),
-               data = ve.copy( surface.getModel().getDocument().getFullData() 
);
-
-       expectedData( data );
-       surface.getModel().setSelection( ve.dm.Selection.static.newFromJSON( 
surface.getModel().getDocument(), selection ) );
-       AnnotationAction[ method ].apply( AnnotationAction, args );
-
-       assert.equalLinearData( surface.getModel().getDocument().getFullData(), 
data, msg + ': data models match' );
-}
-
 QUnit.test( 'toggle', function ( assert ) {
        var i,
+               newBold = { type: 'textStyle/bold' },
                html = '<p>Foo<b>bar</b><strong>baz</strong><i>quux</i> 
white\u3000space</p>',
                cases = [
                        {
                                html: html,
-                               selection: {
-                                       type: 'linear',
-                                       range: new ve.Range( 1, 4 )
-                               },
+                               rangeOrSelection: new ve.Range( 1, 4 ),
                                method: 'toggle',
                                args: [ 'textStyle/bold' ],
                                expectedData: function ( data ) {
                                        data.splice( 1, 3,
-                                               [ 'F', [ 3 ] ],
-                                               [ 'o', [ 3 ] ],
-                                               [ 'o', [ 3 ] ]
+                                               [ 'F', [ newBold ] ],
+                                               [ 'o', [ newBold ] ],
+                                               [ 'o', [ newBold ] ]
                                        );
                                },
                                msg: 'toggle bold on plain text'
                        },
                        {
                                html: html,
-                               selection: {
-                                       type: 'linear',
-                                       range: new ve.Range( 7, 10 )
-                               },
+                               rangeOrSelection: new ve.Range( 7, 10 ),
                                method: 'toggle',
                                args: [ 'textStyle/bold' ],
                                expectedData: function ( data ) {
@@ -56,10 +39,7 @@
                        },
                        {
                                html: html,
-                               selection: {
-                                       type: 'linear',
-                                       range: new ve.Range( 4, 10 )
-                               },
+                               rangeOrSelection: new ve.Range( 4, 10 ),
                                method: 'toggle',
                                args: [ 'textStyle/bold' ],
                                expectedData: function ( data ) {
@@ -69,49 +49,43 @@
                        },
                        {
                                html: html,
-                               selection: {
-                                       type: 'linear',
-                                       range: new ve.Range( 1, 14 )
-                               },
+                               rangeOrSelection: new ve.Range( 1, 14 ),
                                method: 'toggle',
                                args: [ 'textStyle/bold' ],
                                expectedData: function ( data ) {
                                        data.splice( 1, 3,
-                                               [ 'F', [ 3 ] ],
-                                               [ 'o', [ 3 ] ],
-                                               [ 'o', [ 3 ] ]
+                                               [ 'F', [ newBold ] ],
+                                               [ 'o', [ newBold ] ],
+                                               [ 'o', [ newBold ] ]
                                        );
                                        data.splice( 10, 4,
-                                               [ 'q', [ 2, 3 ] ],
-                                               [ 'u', [ 2, 3 ] ],
-                                               [ 'u', [ 2, 3 ] ],
-                                               [ 'x', [ 2, 3 ] ]
+                                               [ 'q', [ ve.dm.example.italic, 
newBold ] ],
+                                               [ 'u', [ ve.dm.example.italic, 
newBold ] ],
+                                               [ 'u', [ ve.dm.example.italic, 
newBold ] ],
+                                               [ 'x', [ ve.dm.example.italic, 
newBold ] ]
                                        );
                                },
                                msg: 'toggle bold on plain, bold, strong then 
underlined text'
                        },
                        {
                                html: html,
-                               selection: {
-                                       type: 'linear',
-                                       range: new ve.Range( 14, 21 )
-                               },
+                               rangeOrSelection: new ve.Range( 14, 21 ),
                                method: 'toggle',
                                args: [ 'textStyle/bold' ],
                                expectedData: function ( data ) {
                                        data.splice( 15, 5,
-                                               [ 'w', [ 3 ] ],
-                                               [ 'h', [ 3 ] ],
-                                               [ 'i', [ 3 ] ],
-                                               [ 't', [ 3 ] ],
-                                               [ 'e', [ 3 ] ]
+                                               [ 'w', [ newBold ] ],
+                                               [ 'h', [ newBold ] ],
+                                               [ 'i', [ newBold ] ],
+                                               [ 't', [ newBold ] ],
+                                               [ 'e', [ newBold ] ]
                                        );
                                },
                                msg: 'trailing whitespace is not annotated'
                        },
                        {
                                html: ve.dm.example.annotatedTableHtml,
-                               selection: {
+                               rangeOrSelection: {
                                        type: 'table',
                                        tableRange: new ve.Range( 0, 52 ),
                                        fromCol: 0,
@@ -129,8 +103,11 @@
                        }
                ];
 
-       QUnit.expect( cases.length * 1 );
+       QUnit.expect( ve.test.utils.countActionTests( cases ) );
        for ( i = 0; i < cases.length; i++ ) {
-               runAnnotationActionTest( assert, cases[ i ].html, cases[ i 
].method, cases[ i ].args, cases[ i ].selection, cases[ i ].expectedData, 
cases[ i ].msg );
+               ve.test.utils.runActionTest(
+                       'annotation', assert, cases[ i ].html, false, cases[ i 
].method, cases[ i ].args, cases[ i ].rangeOrSelection,
+                       cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].expectedRangeOrSelection, cases[ i ].undo, 
cases[ i ].msg
+               );
        }
 } );
diff --git a/tests/ui/actions/ve.ui.ContentAction.test.js 
b/tests/ui/actions/ve.ui.ContentAction.test.js
index c83c30c..d78a394 100644
--- a/tests/ui/actions/ve.ui.ContentAction.test.js
+++ b/tests/ui/actions/ve.ui.ContentAction.test.js
@@ -8,31 +8,8 @@
 
 /* Tests */
 
-function runContentActionTest( assert, html, createView, method, args, 
rangeOrSelection, expectedData, expectedRangeOrSelection, msg ) {
-       var surface = createView ?
-                       ve.test.utils.createViewOnlySurfaceFromHtml( html || 
ve.dm.example.html ) :
-                       ve.test.utils.createModelOnlySurfaceFromHtml( html || 
ve.dm.example.html ),
-               contentAction = new ve.ui.ContentAction( surface ),
-               data = ve.copy( surface.getModel().getDocument().getFullData() 
),
-               documentModel = surface.getModel().getDocument(),
-               selection = ve.test.utils.selectionFromRangeOrSelection( 
documentModel, rangeOrSelection ),
-               expectedSelection = expectedRangeOrSelection && 
ve.test.utils.selectionFromRangeOrSelection( documentModel, 
expectedRangeOrSelection );
-
-       if ( expectedData ) {
-               expectedData( data );
-       }
-       surface.getModel().setSelection( selection );
-       contentAction[ method ].apply( contentAction, args || [] );
-
-       assert.equalLinearData( surface.getModel().getDocument().getFullData(), 
data, msg + ': data models match' );
-       if ( expectedSelection ) {
-               assert.equalHash( surface.getModel().getSelection(), 
expectedSelection, msg + ': selections match' );
-       }
-}
-
-QUnit.test( 'insert', function ( assert ) {
+QUnit.test( 'insert/remove/select/selectAll', function ( assert ) {
        var i,
-               expected = 0,
                cases = [
                        {
                                rangeOrSelection: new ve.Range( 3, 4 ),
@@ -44,6 +21,7 @@
                                        );
                                },
                                expectedRangeOrSelection: new ve.Range( 3, 6 ),
+                               undo: true,
                                msg: 'insert text (annotate=false)'
                        },
                        {
@@ -52,12 +30,13 @@
                                args: [ 'Foo', true ],
                                expectedData: function ( data ) {
                                        data.splice( 3, 1,
-                                               [ 'F', [ 1 ] ],
-                                               [ 'o', [ 1 ] ],
-                                               [ 'o', [ 1 ] ]
+                                               [ 'F', [ ve.dm.example.italic ] 
],
+                                               [ 'o', [ ve.dm.example.italic ] 
],
+                                               [ 'o', [ ve.dm.example.italic ] 
]
                                        );
                                },
                                expectedRangeOrSelection: new ve.Range( 3, 6 ),
+                               undo: true,
                                msg: 'insert text (annotate=true)'
                        },
                        {
@@ -70,6 +49,7 @@
                                        );
                                },
                                expectedRangeOrSelection: new ve.Range( 6 ),
+                               undo: true,
                                msg: 'insert text (collapseToEnd=true)'
                        },
                        {
@@ -79,6 +59,7 @@
                                        data.splice( 1, 3 );
                                },
                                expectedRangeOrSelection: new ve.Range( 1 ),
+                               undo: true,
                                msg: 'remove text'
                        },
                        {
@@ -119,16 +100,11 @@
                        }
                ];
 
+       QUnit.expect( ve.test.utils.countActionTests( cases ) );
        for ( i = 0; i < cases.length; i++ ) {
-               expected++;
-               if ( cases[ i ].expectedRangeOrSelection ) {
-                       expected++;
-               }
-       }
-       QUnit.expect( expected );       for ( i = 0; i < cases.length; i++ ) {
-               runContentActionTest(
-                       assert, cases[ i ].html, cases[ i ].createView, cases[ 
i ].method, cases[ i ].args, cases[ i ].rangeOrSelection,
-                       cases[ i ].expectedData, cases[ i 
].expectedRangeOrSelection, cases[ i ].msg
+               ve.test.utils.runActionTest(
+                       'content', assert, cases[ i ].html, cases[ i 
].createView, cases[ i ].method, cases[ i ].args, cases[ i ].rangeOrSelection,
+                       cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].expectedRangeOrSelection, cases[ i ].undo, 
cases[ i ].msg
                );
        }
 } );
diff --git a/tests/ui/actions/ve.ui.FormatAction.test.js 
b/tests/ui/actions/ve.ui.FormatAction.test.js
index 85628d7..ebd14af 100644
--- a/tests/ui/actions/ve.ui.FormatAction.test.js
+++ b/tests/ui/actions/ve.ui.FormatAction.test.js
@@ -12,21 +12,22 @@
        var i,
                cases = [
                        {
-                               range: new ve.Range( 14, 16 ),
+                               rangeOrSelection: new ve.Range( 14, 16 ),
                                type: 'heading',
                                attributes: { level: 2 },
-                               expectedRange: new ve.Range( 14, 16 ),
+                               expectedRangeOrSelection: new ve.Range( 14, 16 
),
                                expectedData: function ( data ) {
                                        data.splice( 12, 1, { type: 'heading', 
attributes: { level: 2 } } );
                                        data.splice( 19, 1, { type: '/heading' 
} );
                                },
+                               undo: true,
                                msg: 'converting partial selection of list item 
"Item 2" to level 2 heading'
                        },
                        {
-                               range: new ve.Range( 15, 50 ),
+                               rangeOrSelection: new ve.Range( 15, 50 ),
                                type: 'heading',
                                attributes: { level: 3 },
-                               expectedRange: new ve.Range( 15, 50 ),
+                               expectedRangeOrSelection: new ve.Range( 15, 50 
),
                                expectedData: function ( data ) {
                                        data.splice( 12, 1, { type: 'heading', 
attributes: { level: 3 } } );
                                        data.splice( 19, 1, { type: '/heading' 
} );
@@ -37,13 +38,14 @@
                                        data.splice( 45, 1, { type: 'heading', 
attributes: { level: 3 } } );
                                        data.splice( 52, 1, { type: '/heading' 
} );
                                },
+                               undo: true,
                                msg: 'converting partial selection across two 
lists surrounding a paragraph'
                        },
                        {
-                               range: new ve.Range( 4, 28 ),
+                               rangeOrSelection: new ve.Range( 4, 28 ),
                                type: 'heading',
                                attributes: { level: 1 },
-                               expectedRange: new ve.Range( 4, 28 ),
+                               expectedRangeOrSelection: new ve.Range( 4, 28 ),
                                expectedData: function ( data ) {
                                        data.splice( 2, 1, { type: 'heading', 
attributes: { level: 1 } } );
                                        data.splice( 9, 1, { type: '/heading' } 
);
@@ -52,13 +54,14 @@
                                        data.splice( 22, 1, { type: 'heading', 
attributes: { level: 1 } } );
                                        data.splice( 29, 1, { type: '/heading' 
} );
                                },
+                               undo: true,
                                msg: 'converting partial selection of all list 
items to level 1 headings'
                        },
                        {
-                               range: new ve.Range( 5, 26 ),
+                               rangeOrSelection: new ve.Range( 5, 26 ),
                                type: 'preformatted',
                                attributes: undefined,
-                               expectedRange: new ve.Range( 5, 26 ),
+                               expectedRangeOrSelection: new ve.Range( 5, 26 ),
                                expectedData: function ( data ) {
                                        data.splice( 2, 1, { type: 
'preformatted' } );
                                        data.splice( 9, 1, { type: 
'/preformatted' } );
@@ -67,34 +70,40 @@
                                        data.splice( 22, 1, { type: 
'preformatted' } );
                                        data.splice( 29, 1, { type: 
'/preformatted' } );
                                },
+                               undo: true,
                                msg: 'converting partial selection of some list 
items to preformatted text'
                        },
                        {
-                               range: new ve.Range( 146, 159 ),
+                               rangeOrSelection: new ve.Range( 146, 159 ),
                                type: 'paragraph',
                                attributes: undefined,
-                               expectedRange: new ve.Range( 146, 159 ),
+                               expectedRangeOrSelection: new ve.Range( 146, 
159 ),
                                expectedData: function ( data ) {
                                        data.splice( 145, 1, { type: 
'paragraph' } );
                                        data.splice( 159, 1, { type: 
'/paragraph' } );
                                },
+                               undo: true,
                                msg: 'converting heading in list item to 
paragraph'
                        },
                        {
-                               range: new ve.Range( 165, 180 ),
+                               rangeOrSelection: new ve.Range( 165, 180 ),
                                type: 'paragraph',
                                attributes: undefined,
-                               expectedRange: new ve.Range( 165, 180 ),
+                               expectedRangeOrSelection: new ve.Range( 165, 
180 ),
                                expectedData: function ( data ) {
                                        data.splice( 162, 1, { type: 
'paragraph' } );
                                        data.splice( 183, 1, { type: 
'/paragraph' } );
                                },
+                               undo: true,
                                msg: 'converting preformatted in list item to 
paragraph'
                        }
                ];
 
-       QUnit.expect( cases.length * 4 );
+       QUnit.expect( ve.test.utils.countActionTests( cases ) );
        for ( i = 0; i < cases.length; i++ ) {
-               ve.test.utils.runFormatConverterTest( assert, cases[ i ].range, 
cases[ i ].type, cases[ i ].attributes, cases[ i ].expectedRange, cases[ i 
].expectedData, cases[ i ].msg );
+               ve.test.utils.runActionTest(
+                       'format', assert, cases[ i ].html || 
ve.dm.example.isolationHtml, false, 'convert', [ cases[ i ].type, cases[ i 
].attributes ], cases[ i ].rangeOrSelection,
+                       cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].expectedRangeOrSelection, cases[ i ].undo, 
cases[ i ].msg
+               );
        }
 } );
diff --git a/tests/ui/actions/ve.ui.IndentationAction.test.js 
b/tests/ui/actions/ve.ui.IndentationAction.test.js
index 3537064..e76393f 100644
--- a/tests/ui/actions/ve.ui.IndentationAction.test.js
+++ b/tests/ui/actions/ve.ui.IndentationAction.test.js
@@ -8,36 +8,13 @@
 
 /* Tests */
 
-function runIndentationChangeTest( assert, range, method, expectedRange, 
expectedData, expectedOriginalData, msg ) {
-       var surface = ve.test.utils.createModelOnlySurfaceFromHtml( 
ve.dm.example.isolationHtml ),
-               indentationAction = new ve.ui.IndentationAction( surface ),
-               data = ve.copy( surface.getModel().getDocument().getFullData() 
),
-               originalData = ve.copy( data );
-
-       expectedData( data );
-       if ( expectedOriginalData ) {
-               expectedOriginalData( originalData );
-       }
-
-       surface.getModel().setLinearSelection( range );
-       indentationAction[ method ]();
-
-       assert.equalLinearData( surface.getModel().getDocument().getFullData(), 
data, msg + ': data models match' );
-       assert.equalRange( surface.getModel().getSelection().getRange(), 
expectedRange, msg + ': ranges match' );
-
-       surface.getModel().undo();
-
-       assert.equalLinearData( surface.getModel().getDocument().getFullData(), 
originalData, msg + ' (undo): data models match' );
-       assert.equalRange( surface.getModel().getSelection().getRange(), range, 
msg + ' (undo): ranges match' );
-}
-
 QUnit.test( 'increase/decrease', 2, function ( assert ) {
        var i,
                cases = [
                        {
-                               range: new ve.Range( 14, 16 ),
+                               rangeOrSelection: new ve.Range( 14, 16 ),
                                method: 'decrease',
-                               expectedRange: new ve.Range( 14, 16 ),
+                               expectedRangeOrSelection: 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' } } );
@@ -46,12 +23,13 @@
                                        // generated: 'wrapper' is removed by 
the action and not restored by undo
                                        delete data[ 12 ].internal;
                                },
+                               undo: true,
                                msg: 'decrease indentation on partial selection 
of list item "Item 2"'
                        },
                        {
-                               range: new ve.Range( 3, 19 ),
+                               rangeOrSelection: new ve.Range( 3, 19 ),
                                method: 'decrease',
-                               expectedRange: new ve.Range( 1, 15 ),
+                               expectedRangeOrSelection: new ve.Range( 1, 15 ),
                                expectedData: function ( data ) {
                                        data.splice( 0, 2 );
                                        data.splice( 8, 2 );
@@ -64,22 +42,27 @@
                                        delete data[ 2 ].internal;
                                        delete data[ 12 ].internal;
                                },
+                               undo: true,
                                msg: 'decrease indentation on Items 1 & 2'
                        },
                        {
-                               range: new ve.Range( 3, 19 ),
+                               rangeOrSelection: new ve.Range( 3, 19 ),
                                method: 'increase',
-                               expectedRange: new ve.Range( 5, 21 ),
+                               expectedRangeOrSelection: new ve.Range( 5, 21 ),
                                expectedData: function ( data ) {
                                        data.splice( 0, 0, { type: 'list', 
attributes: { style: 'bullet' } }, { type: 'listItem' } );
                                        data.splice( 23, 0, { type: '/list' }, 
{ type: '/listItem' } );
                                },
+                               undo: true,
                                msg: 'increase indentation on Items 1 & 2'
                        }
                ];
 
-       QUnit.expect( cases.length * 4 );
+       QUnit.expect( ve.test.utils.countActionTests( cases ) );
        for ( i = 0; i < cases.length; i++ ) {
-               runIndentationChangeTest( assert, cases[ i ].range, cases[ i 
].method, cases[ i ].expectedRange, cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].msg );
+               ve.test.utils.runActionTest(
+                       'indentation', assert, cases[ i ].html || 
ve.dm.example.isolationHtml, false, cases[ i ].method, [], cases[ i 
].rangeOrSelection,
+                       cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].expectedRangeOrSelection, cases[ i ].undo, 
cases[ i ].msg
+               );
        }
 } );
diff --git a/tests/ui/actions/ve.ui.LinkAction.test.js 
b/tests/ui/actions/ve.ui.LinkAction.test.js
index 8ca52ca..cfb2db6 100644
--- a/tests/ui/actions/ve.ui.LinkAction.test.js
+++ b/tests/ui/actions/ve.ui.LinkAction.test.js
@@ -8,125 +8,96 @@
 
 /* Tests */
 
-function runAutolinkTest( assert, html, method, range, expectedRange, 
expectedData, expectedOriginalData, msg ) {
-       var status, actualData,
-               expectFail = /^Don't/.test( msg ),
-               surface = ve.test.utils.createModelOnlySurfaceFromHtml( html || 
ve.dm.example.html ),
-               linkAction = new ve.ui.LinkAction( surface ),
-               data = ve.copy( surface.getModel().getDocument().getFullData() 
),
-               originalData = ve.copy( data ),
-               makeLinkAnnotation = function ( linktext ) {
-                       return linkAction.getLinkAnnotation( linktext ).element;
-               };
-
-       expectedData( data, makeLinkAnnotation );
-       if ( expectedOriginalData ) {
-               expectedOriginalData( originalData );
-       }
-       surface.getModel().setLinearSelection( range );
-       status = linkAction[ method ]();
-       assert.equal( status, !expectFail, msg + ': action return value' );
-
-       actualData = surface.getModel().getDocument().getFullData();
-       ve.dm.example.postprocessAnnotations( actualData, 
surface.getModel().getDocument().getStore() );
-       assert.equalLinearData( actualData, data, msg + ': data models match' );
-       assert.equalRange( surface.getModel().getSelection().getRange(), 
expectedRange, msg + ': ranges match' );
-
-       if ( status ) {
-               surface.getModel().undo();
-       }
-
-       assert.equalLinearData( surface.getModel().getDocument().getFullData(), 
originalData, msg + ' (undo): data models match' );
-       assert.equalRange( surface.getModel().getSelection().getRange(), 
expectedRange, msg + ' (undo): ranges match' );
-}
-
 QUnit.test( 'autolink', function ( assert ) {
        var i,
                cases = [
                        {
                                html: '<p>http://example.com xyz</p>',
-                               range: new ve.Range( 1, 20 ),
+                               rangeOrSelection: new ve.Range( 1, 20 ),
                                method: 'autolinkUrl',
-                               expectedRange: new ve.Range( 20, 20 ),
-                               expectedData: function ( data, makeAnnotation ) 
{
+                               expectedRangeOrSelection: new ve.Range( 20 ),
+                               expectedData: function ( data, action ) {
                                        var i,
-                                               a = makeAnnotation( 
'http://example.com' );
+                                               a = action.getLinkAnnotation( 
'http://example.com' );
                                        for ( i = 1; i < 19; i++ ) {
-                                               data[ i ] = [ data[ i ], [ a ] 
];
+                                               data[ i ] = [ data[ i ], [ 
a.element ] ];
                                        }
                                },
                                msg: 'Autolink after space'
                        },
                        {
                                html: '<p>http://example.com</p><p>xyz</p>',
-                               range: new ve.Range( 1, 21 ),
+                               rangeOrSelection: new ve.Range( 1, 21 ),
                                method: 'autolinkUrl',
-                               expectedRange: new ve.Range( 21, 21 ),
-                               expectedData: function ( data, makeAnnotation ) 
{
+                               expectedRangeOrSelection: new ve.Range( 21 ),
+                               expectedData: function ( data, action ) {
                                        var i,
-                                               a = makeAnnotation( 
'http://example.com' );
+                                               a = action.getLinkAnnotation( 
'http://example.com' );
                                        for ( i = 1; i < 19; i++ ) {
-                                               data[ i ] = [ data[ i ], [ a ] 
];
+                                               data[ i ] = [ data[ i ], [ 
a.element ] ];
                                        }
                                },
                                msg: 'Autolink after newline'
                        },
                        {
                                html: '<p>Http://Example.COm xyz</p>',
-                               range: new ve.Range( 1, 20 ),
+                               rangeOrSelection: new ve.Range( 1, 20 ),
                                method: 'autolinkUrl',
-                               expectedRange: new ve.Range( 20, 20 ),
-                               expectedData: function ( data, makeAnnotation ) 
{
+                               expectedRangeOrSelection: new ve.Range( 20 ),
+                               expectedData: function ( data, action ) {
                                        var i,
-                                               a = makeAnnotation( 
'Http://Example.COm' );
+                                               a = action.getLinkAnnotation( 
'Http://Example.COm' );
                                        for ( i = 1; i < 19; i++ ) {
-                                               data[ i ] = [ data[ i ], [ a ] 
];
+                                               data[ i ] = [ data[ i ], [ 
a.element ] ];
                                        }
                                },
                                msg: 'Autolink with mixed case'
                        },
                        {
                                html: '<p>http://example.com.) xyz</p>',
-                               range: new ve.Range( 1, 22 ),
+                               rangeOrSelection: new ve.Range( 1, 22 ),
                                method: 'autolinkUrl',
-                               expectedRange: new ve.Range( 22, 22 ),
-                               expectedData: function ( data, makeAnnotation ) 
{
+                               expectedRangeOrSelection: new ve.Range( 22 ),
+                               expectedData: function ( data, action ) {
                                        var i,
-                                               a = makeAnnotation( 
'http://example.com' );
+                                               a = action.getLinkAnnotation( 
'http://example.com' );
                                        for ( i = 1; i < 19; i++ ) {
-                                               data[ i ] = [ data[ i ], [ a ] 
];
+                                               data[ i ] = [ data[ i ], [ 
a.element ] ];
                                        }
                                },
                                msg: 'Strip trailing punctuation'
                        },
                        {
                                html: '<p>"http://example.com"; xyz</p>',
-                               range: new ve.Range( 2, 22 ),
+                               rangeOrSelection: new ve.Range( 2, 22 ),
                                method: 'autolinkUrl',
-                               expectedRange: new ve.Range( 22, 22 ),
-                               expectedData: function ( data, makeAnnotation ) 
{
+                               expectedRangeOrSelection: new ve.Range( 22 ),
+                               expectedData: function ( data, action ) {
                                        var i,
-                                               a = makeAnnotation( 
'http://example.com' );
+                                               a = action.getLinkAnnotation( 
'http://example.com' );
                                        for ( i = 2; i < 20; i++ ) {
-                                               data[ i ] = [ data[ i ], [ a ] 
];
+                                               data[ i ] = [ data[ i ], [ 
a.element ] ];
                                        }
                                },
                                msg: 'Strip trailing quotes'
                        },
                        {
                                html: '<p>http://.) xyz</p>',
-                               range: new ve.Range( 1, 11 ),
+                               rangeOrSelection: new ve.Range( 1, 11 ),
                                method: 'autolinkUrl',
-                               expectedRange: new ve.Range( 1, 11 ),
-                               expectedData: function ( /*data, 
makeAnnotation*/ ) {
+                               expectedRangeOrSelection: new ve.Range( 1, 11 ),
+                               expectedData: function () {
                                        /* no change, no link */
                                },
                                msg: 'Don\'t link if stripping leaves bare 
protocol'
                        }
                ];
 
-       QUnit.expect( cases.length * 5 );
+       QUnit.expect( ve.test.utils.countActionTests( cases ) );
        for ( i = 0; i < cases.length; i++ ) {
-               runAutolinkTest( assert, cases[ i ].html, cases[ i ].method, 
cases[ i ].range, cases[ i ].expectedRange, cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].msg );
+               ve.test.utils.runActionTest(
+                       'link', assert, cases[ i ].html, false, cases[ i 
].method, [], cases[ i ].rangeOrSelection,
+                       cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].expectedRangeOrSelection, cases[ i ].undo, 
cases[ i ].msg
+               );
        }
 } );
diff --git a/tests/ui/actions/ve.ui.ListAction.test.js 
b/tests/ui/actions/ve.ui.ListAction.test.js
index 9b760dc..1639418 100644
--- a/tests/ui/actions/ve.ui.ListAction.test.js
+++ b/tests/ui/actions/ve.ui.ListAction.test.js
@@ -8,50 +8,27 @@
 
 /* Tests */
 
-function runListConverterTest( assert, html, method, style, range, 
expectedRange, expectedData, expectedOriginalData, msg ) {
-       var surface = ve.test.utils.createModelOnlySurfaceFromHtml( html || 
ve.dm.example.html ),
-               surfaceModel = surface.getModel(),
-               listAction = new ve.ui.ListAction( surface ),
-               data = ve.copy( surfaceModel.getDocument().getFullData() ),
-               originalData = ve.copy( data );
-
-       expectedData( data );
-       if ( expectedOriginalData ) {
-               expectedOriginalData( originalData );
-       }
-       surfaceModel.setLinearSelection( range );
-       listAction[ method ]( style );
-
-       assert.equalLinearData( surfaceModel.getDocument().getFullData(), data, 
msg + ': data models match' );
-       assert.equalRange( surfaceModel.getSelection().getRange(), 
expectedRange, msg + ': ranges match' );
-
-       surfaceModel.undo();
-
-       assert.equalLinearData( surfaceModel.getDocument().getFullData(), 
originalData, msg + ' (undo): data models match' );
-       assert.equalRange( surfaceModel.getSelection().getRange(), range, msg + 
' (undo): ranges match' );
-}
-
 QUnit.test( '(un)wrap', function ( assert ) {
        var i,
                cases = [
                        {
-                               range: new ve.Range( 56, 60 ),
+                               rangeOrSelection: new ve.Range( 56, 60 ),
                                method: 'wrap',
                                style: 'bullet',
-                               expectedRange: new ve.Range( 58, 64 ),
+                               expectedRangeOrSelection: new ve.Range( 58, 64 
),
                                expectedData: function ( data ) {
                                        data.splice( 55, 0, { type: 'list', 
attributes: { style: 'bullet' } }, { type: 'listItem' } );
                                        data.splice( 60, 0, { type: '/listItem' 
}, { type: 'listItem' } );
                                        data.splice( 65, 0, { type: '/listItem' 
}, { type: '/list' } );
                                },
+                               undo: true,
                                msg: 'wrapping two paragraphs in a list'
                        },
                        {
                                html: ve.dm.example.isolationHtml,
-                               range: new ve.Range( 191, 211 ),
+                               rangeOrSelection: new ve.Range( 191, 211 ),
                                method: 'unwrap',
-                               style: 'bullet',
-                               expectedRange: new ve.Range( 187, 205 ),
+                               expectedRangeOrSelection: new ve.Range( 187, 
205 ),
                                expectedData: function ( data ) {
                                        delete data[ 190 ].internal;
                                        delete data[ 202 ].internal;
@@ -69,12 +46,16 @@
                                        delete data[ 190 ].internal;
                                        delete data[ 202 ].internal;
                                },
+                               undo: true,
                                msg: 'unwrapping two double listed paragraphs'
                        }
                ];
 
-       QUnit.expect( cases.length * 4 );
+       QUnit.expect( ve.test.utils.countActionTests( cases ) );
        for ( i = 0; i < cases.length; i++ ) {
-               runListConverterTest( assert, cases[ i ].html, cases[ i 
].method, cases[ i ].style, cases[ i ].range, cases[ i ].expectedRange, cases[ 
i ].expectedData, cases[ i ].expectedOriginalData, cases[ i ].msg );
+               ve.test.utils.runActionTest(
+                       'list', assert, cases[ i ].html, false, cases[ i 
].method, [ cases[ i ].style ], cases[ i ].rangeOrSelection,
+                       cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].expectedRangeOrSelection, cases[ i ].undo, 
cases[ i ].msg
+               );
        }
 } );
diff --git a/tests/ui/actions/ve.ui.TableAction.test.js 
b/tests/ui/actions/ve.ui.TableAction.test.js
index a110758..da828a0 100644
--- a/tests/ui/actions/ve.ui.TableAction.test.js
+++ b/tests/ui/actions/ve.ui.TableAction.test.js
@@ -8,29 +8,8 @@
 
 /* Tests */
 
-function runTableActionTest( assert, html, method, args, rangeOrSelection, 
expectedData, expectedRangeOrSelection, msg ) {
-       var surface = ve.test.utils.createModelOnlySurfaceFromHtml( html || 
ve.dm.example.html ),
-               tableAction = new ve.ui.TableAction( surface ),
-               data = ve.copy( surface.getModel().getDocument().getFullData() 
),
-               documentModel = surface.getModel().getDocument(),
-               selection = ve.test.utils.selectionFromRangeOrSelection( 
documentModel, rangeOrSelection ),
-               expectedSelection = expectedRangeOrSelection && 
ve.test.utils.selectionFromRangeOrSelection( documentModel, 
expectedRangeOrSelection );
-
-       if ( expectedData ) {
-               expectedData( data );
-       }
-       surface.getModel().setSelection( selection );
-       tableAction[ method ].apply( tableAction, args || [] );
-
-       assert.equalLinearData( surface.getModel().getDocument().getFullData(), 
data, msg + ': data models match' );
-       if ( expectedSelection ) {
-               assert.equalHash( surface.getModel().getSelection(), 
expectedSelection, msg + ': selections match' );
-       }
-}
-
 QUnit.test( 'create / insert / mergeCells / delete / changeCellStyle', 
function ( assert ) {
        var i,
-               expected = 0,
                tableCellTail = [
                        { type: 'paragraph', internal: { generated: 'wrapper' } 
},
                        { type: '/paragraph' },
@@ -444,17 +423,11 @@
                        }
                ];
 
+       QUnit.expect( ve.test.utils.countActionTests( cases ) );
        for ( i = 0; i < cases.length; i++ ) {
-               expected++;
-               if ( cases[ i ].expectedRangeOrSelection ) {
-                       expected++;
-               }
-       }
-       QUnit.expect( expected );
-       for ( i = 0; i < cases.length; i++ ) {
-               runTableActionTest(
-                       assert, cases[ i ].html, cases[ i ].method, cases[ i 
].args, cases[ i ].rangeOrSelection,
-                       cases[ i ].expectedData, cases[ i 
].expectedRangeOrSelection, cases[ i ].msg
+               ve.test.utils.runActionTest(
+                       'table', assert, cases[ i ].html, false, cases[ i 
].method, cases[ i ].args, cases[ i ].rangeOrSelection,
+                       cases[ i ].expectedData, cases[ i 
].expectedOriginalData, cases[ i ].expectedRangeOrSelection, cases[ i ].undo, 
cases[ i ].msg
                );
        }
 } );
diff --git a/tests/ve.test.utils.js b/tests/ve.test.utils.js
index be3c039..ebe6c87 100644
--- a/tests/ve.test.utils.js
+++ b/tests/ve.test.utils.js
@@ -86,6 +86,57 @@
                assert.equalRange( 
surface.getModel().getSelection().getRange(), range, msg + ' (undo): ranges 
match' );
        };
 
+       ve.test.utils.countActionTests = function ( cases ) {
+               var i, expected = 0;
+               for ( i = 0; i < cases.length; i++ ) {
+                       expected += cases[ i ].undo ? 2 : 1;
+                       if ( cases[ i ].expectedRangeOrSelection ) {
+                               expected += cases[ i ].undo ? 2 : 1;
+                       }
+               }
+               return expected;
+       };
+
+       ve.test.utils.runActionTest = function ( actionName, assert, html, 
createView, method, args, rangeOrSelection, expectedData, expectedOriginalData, 
expectedRangeOrSelection, undo, msg ) {
+               var actualData,
+                       surface = createView ?
+                               ve.test.utils.createViewOnlySurfaceFromHtml( 
html || ve.dm.example.html ) :
+                               ve.test.utils.createModelOnlySurfaceFromHtml( 
html || ve.dm.example.html ),
+                       action = ve.ui.actionFactory.create( actionName, 
surface ),
+                       data = ve.copy( 
surface.getModel().getDocument().getFullData() ),
+                       originalData = ve.copy( data ),
+                       documentModel = surface.getModel().getDocument(),
+                       selection = 
ve.test.utils.selectionFromRangeOrSelection( documentModel, rangeOrSelection ),
+                       expectedSelection = expectedRangeOrSelection && 
ve.test.utils.selectionFromRangeOrSelection( documentModel, 
expectedRangeOrSelection );
+
+               ve.dm.example.postprocessAnnotations( data, 
surface.getModel().getDocument().getStore() );
+
+               if ( expectedData ) {
+                       expectedData( data, action );
+               }
+               if ( expectedOriginalData ) {
+                       expectedOriginalData( originalData, action );
+               }
+               surface.getModel().setSelection( selection );
+               action[ method ].apply( action, args || [] );
+
+               actualData = surface.getModel().getDocument().getFullData();
+               ve.dm.example.postprocessAnnotations( actualData, 
surface.getModel().getDocument().getStore() );
+               assert.equalLinearData( actualData, data, msg + ': data models 
match' );
+               if ( expectedSelection ) {
+                       assert.equalHash( surface.getModel().getSelection(), 
expectedSelection, msg + ': selections match' );
+               }
+
+               if ( undo ) {
+                       surface.getModel().undo();
+
+                       assert.equalLinearData( 
surface.getModel().getDocument().getFullData(), originalData, msg + ' (undo): 
data models match' );
+                       if ( expectedSelection ) {
+                               assert.equalHash( 
surface.getModel().getSelection(), selection, msg + ' (undo): selections match' 
);
+                       }
+               }
+       };
+
        ve.test.utils.countGetModelFromDomTests = function ( cases ) {
                var msg, n = 0;
                for ( msg in cases ) {

-- 
To view, visit https://gerrit.wikimedia.org/r/287990
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1a0ca8d33d89b24feb80ff604d24fa3028c7e137
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to