mediawiki-extensions-Cite/modules/ve-cite/tests/ve.dm.Transaction.test.js
Ed Sanders 099b8f8153 Use canonical ve.dm.TransactionBuilder.static.newFrom* methods
Change-Id: I9ce6860e19e833b576f7b9fb239b96de394b667c
2016-11-30 19:06:13 +00:00

192 lines
6.2 KiB
JavaScript

/*!
* VisualEditor DataModel Cite-specific Transaction tests.
*
* @copyright 2011-2016 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
QUnit.module( 've.dm.Transaction (Cite)', ve.test.utils.mwEnvironment );
// FIXME: Duplicates test runner; should be using a data provider
QUnit.test( 'newFromDocumentInsertion with references', function ( assert ) {
var i, j, doc2, tx, actualStoreItems, expectedStoreItems, removalOps, doc,
complexDoc = ve.dm.citeExample.createExampleDocument( 'complexInternalData' ),
comment = { type: 'alienMeta', originalDomElements: $( '<!-- hello -->' ).toArray() },
withReference = [
{ type: 'paragraph' },
'B', 'a', 'r',
{ type: 'mwReference', attributes: {
mw: {},
about: '#mwt4',
listIndex: 0,
listGroup: 'mwReference/',
listKey: 'auto/0',
refGroup: '',
contentsUsed: true
} },
{ type: '/mwReference' },
{ type: '/paragraph' },
{ type: 'internalList' },
{ type: 'internalItem' },
{ type: 'paragraph', internal: { generated: 'wrapper' } },
'B',
'a',
'z',
{ type: '/paragraph' },
{ type: '/internalItem' },
{ type: '/internalList' }
],
cases = [
{
msg: 'metadata insertion',
doc: 'complexInternalData',
offset: 0,
range: new ve.Range( 0, 7 ),
modify: function ( newDoc ) {
newDoc.commit( ve.dm.TransactionBuilder.static.newFromMetadataInsertion(
newDoc, 4, 0, [ comment ]
) );
},
removalOps: [
{
type: 'replace',
remove: complexDoc.getData( new ve.Range( 0, 7 ) ),
insert: [
{ type: 'paragraph' },
{ type: '/paragraph' }
],
removeMetadata: complexDoc.getMetadata( new ve.Range( 0, 7 ) ),
insertMetadata: [ undefined, undefined ],
insertedDataLength: 2,
insertedDataOffset: 0
},
{ type: 'retain', length: 26 }
],
expectedOps: [
{
type: 'replace',
remove: [],
insert: complexDoc.getData( new ve.Range( 0, 4 ) )
// Reference gets (unnecessarily) renumbered from auto/0 to auto/1
.concat( [
ve.extendObject( true, {}, complexDoc.data.data[ 4 ],
{ attributes: { listKey: 'auto/1' } }
)
] )
.concat( complexDoc.getData( new ve.Range( 5, 7 ) ) ),
removeMetadata: [],
insertMetadata: complexDoc.getMetadata( new ve.Range( 0, 4 ) )
.concat( [ [ comment ] ] )
.concat( complexDoc.getMetadata( new ve.Range( 5, 7 ) ) )
},
{ type: 'retain', length: 3 },
{
type: 'replace',
remove: complexDoc.getData( new ve.Range( 8, 32 ) ),
insert: complexDoc.getData( new ve.Range( 8, 32 ) ),
removeMetadata: complexDoc.getMetadata( new ve.Range( 8, 32 ) ),
insertMetadata: complexDoc.getMetadata( new ve.Range( 8, 32 ) )
},
{ type: 'retain', length: 1 }
]
},
{
msg: 'metadata removal',
doc: 'complexInternalData',
offset: 24,
range: new ve.Range( 24, 31 ),
modify: function ( newDoc ) {
newDoc.commit( ve.dm.TransactionBuilder.static.newFromMetadataRemoval(
newDoc, 6, new ve.Range( 0, 1 )
) );
},
removalOps: [
{ type: 'retain', length: 24 },
{
type: 'replace',
remove: complexDoc.getData( new ve.Range( 24, 31 ) ),
insert: [],
removeMetadata: complexDoc.getMetadata( new ve.Range( 24, 31 ) ),
insertMetadata: []
},
{ type: 'retain', length: 2 }
],
expectedOps: [
{ type: 'retain', length: 8 },
{
type: 'replace',
remove: complexDoc.getData( new ve.Range( 8, 24 ) )
.concat( complexDoc.getData( new ve.Range( 31, 32 ) ) ),
insert: complexDoc.getData( new ve.Range( 8, 32 ) ),
removeMetadata: complexDoc.getMetadata( new ve.Range( 8, 24 ) )
.concat( complexDoc.getMetadata( new ve.Range( 31, 32 ) ) ),
insertMetadata: complexDoc.getMetadata( new ve.Range( 8, 30 ) )
.concat( [ [] ] )
.concat( complexDoc.getMetadata( new ve.Range( 31, 32 ) ) )
},
{ type: 'retain', length: 1 }
]
},
{
msg: 'inserting a brand new document; internal lists are merged and items renumbered',
doc: 'complexInternalData',
offset: 7,
newDocData: withReference,
removalOps: [],
expectedOps: [
{ type: 'retain', length: 7 },
{
type: 'replace',
remove: [],
insert: withReference.slice( 0, 4 )
// Renumber listIndex from 0 to 2
// Renumber listKey from auto/0 to auto/1
.concat( [
ve.extendObject( true, {}, withReference[ 4 ],
{ attributes: { listIndex: 2, listKey: 'auto/1' } }
)
] )
.concat( withReference.slice( 5, 7 ) )
},
{ type: 'retain', length: 1 },
{
type: 'replace',
remove: complexDoc.getData( new ve.Range( 8, 32 ) ),
insert: complexDoc.getData( new ve.Range( 8, 32 ) )
.concat( withReference.slice( 8, 15 ) ),
removeMetadata: complexDoc.getMetadata( new ve.Range( 8, 32 ) ),
insertMetadata: complexDoc.getMetadata( new ve.Range( 8, 32 ) )
.concat( new Array( 7 ) )
},
{ type: 'retain', length: 1 }
]
}
];
QUnit.expect( 3 * cases.length );
for ( i = 0; i < cases.length; i++ ) {
doc = ve.dm.citeExample.createExampleDocument( cases[ i ].doc );
if ( cases[ i ].newDocData ) {
doc2 = new ve.dm.Document( cases[ i ].newDocData );
removalOps = [];
} else if ( cases[ i ].range ) {
doc2 = doc.cloneFromRange( cases[ i ].range );
cases[ i ].modify( doc2 );
tx = ve.dm.TransactionBuilder.static.newFromRemoval( doc, cases[ i ].range, true );
doc.commit( tx );
removalOps = tx.getOperations();
}
assert.deepEqualWithDomElements( removalOps, cases[ i ].removalOps, cases[ i ].msg + ': removal' );
tx = ve.dm.TransactionBuilder.static.newFromDocumentInsertion( doc, cases[ i ].offset, doc2 );
assert.deepEqualWithDomElements( tx.getOperations(), cases[ i ].expectedOps, cases[ i ].msg + ': transaction' );
actualStoreItems = [];
expectedStoreItems = cases[ i ].expectedStoreItems || [];
for ( j = 0; j < expectedStoreItems.length; j++ ) {
actualStoreItems[ j ] = doc.store.value( OO.getHash( expectedStoreItems[ j ] ) );
}
assert.deepEqual( actualStoreItems, expectedStoreItems, cases[ i ].msg + ': store items' );
}
} );