mediawiki-extensions-Visual.../modules/ve-mw/test/dm/ve.dm.InternalList.test.js
Roan Kattouw 92c38eab85 The great directory split of 2013
Move all MW-specific files into the ve-mw directory, in preparation
for moving them out into a separate repo.

All MW-specific files were moved into a parallel directory structure
in modules/ve-mw . Files with both generic and MW-specific things were
split up. Files in ve/init/mw/ were moved to ve-mw/init/ rather than
ve-mw/init/mw ; they're still named ve.init.mw.* but we should change
that. Some of the test files for core classes had MW-specific test cases,
so those were split up and the test runner was duplicated; we should
refactor our tests to use data providers so we can add cases more easily.

Split files:
* ve.ce.Node.css
* ve.ce.ContentBranchNode.test.js (MWEntityNode)
* ve.ce.Document.test.js (some core test cases genericized)
* ve.dm.InternalList.test.js (uses mwReference test document)
* ve.dm.SurfaceFragment.test.js, ve.ui.FormatAction.test.js
** Made core tests use heading instead of mwHeading
** Updated core tests because normal headings don't break out of lists
** Moved test runners into ve.test.utils.js
* ve.ui.Icons-*.css
* ve.ui.Dialog.css (MW parts into ve.ui.MWDialog.css)
* ve.ui.Tool.css
* ve.ui.Widget.css (move ve-ui-rtl and ve-ui-ltr to ve.ui.css)

ve.dm.Converter.test.js: Moved runner functions into ve.test.utils.js

ve.dm.example.js:
* Refactored createExampleDocument so mwExample can use it
* Removed wgExtensionAssetsPath detection, moved into mw-preload.js
* Genericized withMeta example document (original version copied to mwExample)
* Moved references example document to mwExample

ve.dm.mwExample.js:
* Move withMeta and references example documents from ve.dm.example.js
* Add createExampleDocument function

ve-mw/test/index.php: Runner for MW-specific tests only

ve-mw/test/mw-preload.js: Sets VE_TESTDIR for Special:JavaScriptTest only

ve.ui.Window.js:
* Remove magic path interpolation in addLocalStyleSheets()
* Pass full(er) paths to addLocalStyleSheets(), here and in subclasses

ve.ui.MWDialog.js: Subclass of Dialog that adds MW versions of stylesheets

ve.ui.MW*Dialog.js:
* Subclass MWDialog rather than Dialog
* Load both core and MW versions of stylesheets that have both

ve.ui.PagedDialog.js: Converted to a mixin rather than an abstract base class
* Don't inherit ve.ui.Dialog
* Rather than overriding initialize(), provide initializePages() which the
  host class is supposed to call from its initialize()
* Rename onOutlineSelect to onPageOutlineSelect

ve.ui.MWMetaDialog.js, ve.ui.MWTransclusionDialog.js:
* Use PagedDialog as a mixin rather than a base class, inherit MWDialog

bullet-icon.png: Unused, deleted

Stuff we should do later:
* Refactor tests to use data providers
* Write utility function for SVG compat check
* Separate omnibus CSS files such as ve.ui.Widget.css
* Separate omnibus RL modules
* Use icon classes in ViewPageTarget

Change-Id: I1b28f8ba7f2d2513e5c634927a854686fb9dd5a5
2013-07-02 20:51:38 -07:00

187 lines
5 KiB
JavaScript

/*!
* VisualEditor DataModel MediaWiki-specific InternalList tests.
*
* @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
QUnit.module( 've.dm.InternalList' );
/* Tests */
QUnit.test( 'addNode/removeNode', 6, function ( assert ) {
var doc = ve.dm.mwExample.createExampleDocument( 'references' ),
newInternalList = new ve.dm.InternalList( doc ),
referenceNodes = [
doc.documentNode.children[0].children[0],
doc.documentNode.children[1].children[1],
doc.documentNode.children[1].children[3],
doc.documentNode.children[1].children[5],
doc.documentNode.children[2].children[0],
doc.documentNode.children[2].children[1]
],
expectedNodes = {
'mwReference/': {
'keyedNodes': {
'bar': [ referenceNodes[1], referenceNodes[3] ],
'quux': [ referenceNodes[2] ]
},
'firstNodes': [
referenceNodes[0],
referenceNodes[1],
referenceNodes[2],
referenceNodes[4],
referenceNodes[5]
],
'indexOrder': [ 0, 1, 2, 3, 4 ]
}
};
newInternalList.addNode( 'mwReference/', null, 0, referenceNodes[0] );
newInternalList.addNode( 'mwReference/', 'bar', 1, referenceNodes[1] );
newInternalList.addNode( 'mwReference/', 'quux', 2, referenceNodes[2] );
newInternalList.addNode( 'mwReference/', 'bar', 1, referenceNodes[3] );
newInternalList.addNode( 'mwReference/', null, 3, referenceNodes[4] );
newInternalList.addNode( 'mwReference/', null, 4, referenceNodes[5] );
newInternalList.onTransact();
assert.deepEqualWithNodeTree(
newInternalList.nodes,
expectedNodes,
'Nodes added in order'
);
newInternalList = new ve.dm.InternalList( doc );
newInternalList.addNode( 'mwReference/', null, 4, referenceNodes[5] );
newInternalList.addNode( 'mwReference/', null, 3, referenceNodes[4] );
newInternalList.addNode( 'mwReference/', 'bar', 1, referenceNodes[3] );
newInternalList.addNode( 'mwReference/', 'quux', 2, referenceNodes[2] );
newInternalList.addNode( 'mwReference/', 'bar', 1, referenceNodes[1] );
newInternalList.addNode( 'mwReference/', null, 0, referenceNodes[0] );
newInternalList.onTransact();
assert.deepEqualWithNodeTree(
newInternalList.nodes,
expectedNodes,
'Nodes added in reverse order'
);
newInternalList.removeNode( 'mwReference/', 'bar', 1, referenceNodes[1] );
newInternalList.onTransact();
assert.deepEqualWithNodeTree(
newInternalList.nodes,
{
'mwReference/': {
'keyedNodes': {
'bar': [ referenceNodes[3] ],
'quux': [ referenceNodes[2] ]
},
'firstNodes': [
referenceNodes[0],
referenceNodes[3],
referenceNodes[2],
referenceNodes[4],
referenceNodes[5]
],
'indexOrder': [ 0, 2, 1, 3, 4 ]
}
},
'Keys re-ordered after one item of key removed'
);
newInternalList.removeNode( 'mwReference/', 'bar', 1, referenceNodes[3] );
newInternalList.onTransact();
assert.deepEqualWithNodeTree(
newInternalList.nodes,
{
'mwReference/': {
'keyedNodes': {
'quux': [ referenceNodes[2] ]
},
'firstNodes': [
referenceNodes[0],
undefined,
referenceNodes[2],
referenceNodes[4],
referenceNodes[5]
],
'indexOrder': [ 0, 2, 3, 4 ]
}
},
'Keys truncated after last item of key removed'
);
newInternalList.removeNode( 'mwReference/', null, 0, referenceNodes[0] );
newInternalList.onTransact();
assert.deepEqualWithNodeTree(
newInternalList.nodes,
{
'mwReference/': {
'keyedNodes': {
'quux': [ referenceNodes[2] ]
},
'firstNodes': [
undefined,
undefined,
referenceNodes[2],
referenceNodes[4],
referenceNodes[5]
],
'indexOrder': [ 2, 3, 4 ]
}
},
'Removing keyless item'
);
newInternalList.removeNode( 'mwReference/', null, 4, referenceNodes[5] );
newInternalList.removeNode( 'mwReference/', null, 3, referenceNodes[4] );
newInternalList.removeNode( 'mwReference/', 'quux', 2, referenceNodes[2] );
newInternalList.onTransact();
assert.deepEqualWithNodeTree(
newInternalList.nodes,
{
'mwReference/': {
'keyedNodes': {},
'firstNodes': new Array( 5 ),
'indexOrder': []
}
},
'All nodes removed'
);
} );
QUnit.test( 'getItemInsertion', 4, function ( assert ) {
var insertion, index,
doc = ve.dm.mwExample.createExampleDocument( 'references' ),
internalList = doc.getInternalList();
insertion = internalList.getItemInsertion( 'mwReference/', 'foo', [] );
index = internalList.getItemNodeCount();
assert.equal( insertion.index, index, 'Insertion creates a new reference' );
assert.deepEqual(
insertion.transaction.getOperations(),
[
{ 'type': 'retain', 'length': 91 },
{
'type': 'replace',
'remove': [],
'insert': [
{ 'type': 'internalItem' },
{ 'type': '/internalItem' }
]
},
{ 'type': 'retain', 'length': 1 }
],
'New reference operations match' );
insertion = internalList.getItemInsertion( 'mwReference/', 'foo', [] );
assert.equal( insertion.index, index, 'Insertion with duplicate key reuses old index' );
assert.equal( insertion.transaction, null, 'Insertion with duplicate key has null transaction' );
} );