mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/VisualEditor
synced 2024-11-24 06:24:08 +00:00
Greatly simplified selection and node tree comparison tests
By first summarizing a node tree or node selection and then using the normal deepEqual function we are able to take advantage of native QUnit functionality to make diagnosing a problem easier under failing conditions and reduce the verbosity of the output under passing conditions. Change-Id: I4af5d69596cf5459aa32f61ee6d5b8355233c3df
This commit is contained in:
parent
d6cf4fff7f
commit
6d0a24bec6
|
@ -6,6 +6,10 @@ test( 'selectNodes', function() {
|
||||||
var doc = new ve.ce.Document( new ve.dm.Document( ve.dm.example.data ) ),
|
var doc = new ve.ce.Document( new ve.dm.Document( ve.dm.example.data ) ),
|
||||||
cases = ve.example.getSelectNodesCases( doc );
|
cases = ve.example.getSelectNodesCases( doc );
|
||||||
for ( var i = 0; i < cases.length; i++ ) {
|
for ( var i = 0; i < cases.length; i++ ) {
|
||||||
ve.example.nodeSelectionEqual( cases[i].actual, cases[i].expected, cases[i].msg );
|
deepEqual(
|
||||||
|
ve.example.getNodeSelectionSummary( cases[i].actual ),
|
||||||
|
ve.example.getNodeSelectionSummary( cases[i].expected ),
|
||||||
|
cases[i].msg
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -256,7 +256,11 @@ test( 'rebuildNodes', function() {
|
||||||
documentNode = doc.getDocumentNode();
|
documentNode = doc.getDocumentNode();
|
||||||
// Rebuild without changes
|
// Rebuild without changes
|
||||||
doc.rebuildNodes( documentNode, 1, 1, 5, 30 );
|
doc.rebuildNodes( documentNode, 1, 1, 5, 30 );
|
||||||
ve.example.nodeTreeEqual( documentNode, ve.dm.example.tree, 'rebuild without changes' );
|
deepEqual(
|
||||||
|
ve.example.getNodeTreeSummary( documentNode ),
|
||||||
|
ve.example.getNodeTreeSummary( ve.dm.example.tree ),
|
||||||
|
'rebuild without changes'
|
||||||
|
);
|
||||||
|
|
||||||
// XXX: Create a new document node tree from the old one
|
// XXX: Create a new document node tree from the old one
|
||||||
var tree = new ve.dm.DocumentNode( ve.dm.example.tree.getChildren() );
|
var tree = new ve.dm.DocumentNode( ve.dm.example.tree.getChildren() );
|
||||||
|
@ -266,7 +270,11 @@ test( 'rebuildNodes', function() {
|
||||||
tree.splice( 1, 1, new ve.dm.ParagraphNode( [new ve.dm.TextNode( 3 )] ) );
|
tree.splice( 1, 1, new ve.dm.ParagraphNode( [new ve.dm.TextNode( 3 )] ) );
|
||||||
// Rebuild with changes
|
// Rebuild with changes
|
||||||
doc.rebuildNodes( documentNode, 1, 1, 5, 5 );
|
doc.rebuildNodes( documentNode, 1, 1, 5, 5 );
|
||||||
ve.example.nodeTreeEqual( documentNode, tree, 'replace table with paragraph' );
|
deepEqual(
|
||||||
|
ve.example.getNodeTreeSummary( documentNode ),
|
||||||
|
ve.example.getNodeTreeSummary( tree ),
|
||||||
|
'replace table with paragraph'
|
||||||
|
);
|
||||||
} );
|
} );
|
||||||
|
|
||||||
test( 'getRelativeContentOffset', 1, function() {
|
test( 'getRelativeContentOffset', 1, function() {
|
||||||
|
@ -347,6 +355,10 @@ test( 'selectNodes', function() {
|
||||||
var doc = new ve.dm.Document( ve.dm.example.data ),
|
var doc = new ve.dm.Document( ve.dm.example.data ),
|
||||||
cases = ve.example.getSelectNodesCases( doc );
|
cases = ve.example.getSelectNodesCases( doc );
|
||||||
for ( var i = 0; i < cases.length; i++ ) {
|
for ( var i = 0; i < cases.length; i++ ) {
|
||||||
ve.example.nodeSelectionEqual( cases[i].actual, cases[i].expected, cases[i].msg );
|
deepEqual(
|
||||||
|
ve.example.getNodeSelectionSummary( cases[i].actual ),
|
||||||
|
ve.example.getNodeSelectionSummary( cases[i].expected ),
|
||||||
|
cases[i].msg
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -2,13 +2,13 @@ module( 've.dm.DocumentFragment' );
|
||||||
|
|
||||||
/* Tests */
|
/* Tests */
|
||||||
|
|
||||||
test( 'constructor', 156, function() {
|
test( 'constructor', 2, function() {
|
||||||
var fragment = new ve.dm.DocumentFragment( ve.dm.example.data );
|
var fragment = new ve.dm.DocumentFragment( ve.dm.example.data );
|
||||||
// Test count: 5 tests x 31 nodes = 155
|
deepEqual(
|
||||||
ve.example.nodeTreeEqual( fragment.getDocumentNode(), ve.dm.example.tree,
|
ve.example.getNodeTreeSummary( fragment.getDocumentNode() ),
|
||||||
|
ve.example.getNodeTreeSummary( ve.dm.example.tree ),
|
||||||
'node tree matches example data'
|
'node tree matches example data'
|
||||||
);
|
);
|
||||||
|
|
||||||
raises(
|
raises(
|
||||||
function() {
|
function() {
|
||||||
fragment = new ve.dm.DocumentFragment( [
|
fragment = new ve.dm.DocumentFragment( [
|
||||||
|
|
|
@ -149,35 +149,42 @@ test( 'commit/rollback', function() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
// Generate original document
|
||||||
|
var originalData = ve.dm.example.data,
|
||||||
|
originalDoc = new ve.dm.Document( originalData );
|
||||||
// Run tests
|
// Run tests
|
||||||
var originalDoc = new ve.dm.Document( ve.dm.example.data );
|
|
||||||
for ( var msg in cases ) {
|
for ( var msg in cases ) {
|
||||||
var doc = new ve.dm.Document( ve.copyArray( ve.dm.example.data ) ),
|
var testDocument = new ve.dm.Document( ve.copyArray( originalData ) ),
|
||||||
tx = new ve.dm.Transaction();
|
tx = new ve.dm.Transaction();
|
||||||
for ( var i = 0; i < cases[msg].calls.length; i++ ) {
|
for ( var i = 0; i < cases[msg].calls.length; i++ ) {
|
||||||
tx[cases[msg].calls[i][0]].apply( tx, cases[msg].calls[i].slice( 1 ) );
|
tx[cases[msg].calls[i][0]].apply( tx, cases[msg].calls[i].slice( 1 ) );
|
||||||
}
|
}
|
||||||
if ( 'expected' in cases[msg] ) {
|
if ( 'expected' in cases[msg] ) {
|
||||||
ve.dm.TransactionProcessor.commit( doc, tx );
|
// Generate expected document
|
||||||
var expected = ve.copyArray( ve.dm.example.data );
|
var expectedData = ve.copyArray( originalData );
|
||||||
cases[msg].expected( expected );
|
cases[msg].expected( expectedData );
|
||||||
deepEqual( doc.getData(), expected, 'commit (data): ' + msg );
|
var expectedDocument = new ve.dm.Document( expectedData );
|
||||||
var expectedDoc = new ve.dm.Document( expected );
|
// Commit
|
||||||
ve.example.nodeTreeEqual( doc.getDocumentNode(),
|
ve.dm.TransactionProcessor.commit( testDocument, tx );
|
||||||
expectedDoc.getDocumentNode(),
|
deepEqual( testDocument.getData(), expectedData, 'commit (data): ' + msg );
|
||||||
|
deepEqual(
|
||||||
|
ve.example.getNodeTreeSummary( testDocument.getDocumentNode() ),
|
||||||
|
ve.example.getNodeTreeSummary( expectedDocument.getDocumentNode() ),
|
||||||
'commit (tree): ' + msg
|
'commit (tree): ' + msg
|
||||||
);
|
);
|
||||||
ve.dm.TransactionProcessor.rollback( doc, tx );
|
// Rollback
|
||||||
deepEqual( doc.getData(), ve.dm.example.data, 'rollback (data): ' + msg );
|
ve.dm.TransactionProcessor.rollback( testDocument, tx );
|
||||||
ve.example.nodeTreeEqual( doc.getDocumentNode(),
|
deepEqual( testDocument.getData(), ve.dm.example.data, 'rollback (data): ' + msg );
|
||||||
originalDoc.getDocumentNode(),
|
deepEqual(
|
||||||
|
ve.example.getNodeTreeSummary( testDocument.getDocumentNode() ),
|
||||||
|
ve.example.getNodeTreeSummary( originalDoc.getDocumentNode() ),
|
||||||
'rollback (tree): ' + msg
|
'rollback (tree): ' + msg
|
||||||
);
|
);
|
||||||
} else if ( 'exception' in cases[msg] ) {
|
} else if ( 'exception' in cases[msg] ) {
|
||||||
/*jshint loopfunc:true */
|
/*jshint loopfunc:true */
|
||||||
raises(
|
raises(
|
||||||
function() {
|
function() {
|
||||||
ve.dm.TransactionProcessor.commit( doc, tx );
|
ve.dm.TransactionProcessor.commit( testDocument, tx );
|
||||||
},
|
},
|
||||||
cases[msg].exception,
|
cases[msg].exception,
|
||||||
'commit: ' + msg
|
'commit: ' + msg
|
||||||
|
|
|
@ -19,7 +19,7 @@ ve.example.getSelectNodesCases = function( doc ) {
|
||||||
'nodeRange': new ve.Range( 1, 4 )
|
'nodeRange': new ve.Range( 1, 4 )
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
'msg': 'partial leaf results have ranges with global offsets',
|
'msg': 'partial leaf results have ranges with global offsets'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'actual': doc.selectNodes( new ve.Range( 0, 10 ), 'leaves' ),
|
'actual': doc.selectNodes( new ve.Range( 0, 10 ), 'leaves' ),
|
||||||
|
@ -192,62 +192,62 @@ ve.example.getSelectNodesCases = function( doc ) {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that two node trees are equivalent.
|
* Builds a summary of a node tree.
|
||||||
*
|
*
|
||||||
* This will perform 5 assertions on each node
|
* Generated summaries contain node types, lengths, outer lengths, attributes and summaries for
|
||||||
|
* each child recusively. It's simple and fast to use deepEqual on this.
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
|
* @param {ve.Node} node Node tree to summarize
|
||||||
|
* @param {Boolean} [shallow] Do not summarize each child recursively
|
||||||
|
* @returns {Object} Summary of node tree
|
||||||
*/
|
*/
|
||||||
ve.example.nodeTreeEqual = function( a, b, desc, typePath ) {
|
ve.example.getNodeTreeSummary = function( node, shallow ) {
|
||||||
typePath = typePath ? typePath + '/' + a.getType() : a.getType();
|
var summary = {
|
||||||
var descPrefix = desc + ': (' + typePath + ') ';
|
'getType': node.getType(),
|
||||||
equal( a.getType(), b.getType(), descPrefix + 'type match' );
|
'getLength': node.getLength(),
|
||||||
equal( a.getLength(), b.getLength(), descPrefix + 'length match' );
|
'getOuterLength': node.getOuterLength(),
|
||||||
equal( a.getOuterLength(), b.getOuterLength(), descPrefix + 'outer length match' );
|
'attributes': node.attributes
|
||||||
deepEqual( a.attributes, b.attributes, descPrefix + 'attributes match' );
|
};
|
||||||
if ( a.children && b.children ) {
|
if ( node.children !== undefined ) {
|
||||||
// Prevent crashes if a.children and b.children have different lengths
|
summary['children.length'] = node.children.length;
|
||||||
var minLength = a.children.length < b.children.length ? a.children.length : b.children.length;
|
if ( !shallow ) {
|
||||||
equal( a.children.length, b.children.length, descPrefix + 'children count match' );
|
summary.children = [];
|
||||||
for ( var i = 0; i < minLength; i++ ) {
|
for ( var i = 0; i < node.children.length; i++ ) {
|
||||||
ve.example.nodeTreeEqual( a.children[i], b.children[i], desc, typePath );
|
summary.children.push( ve.example.getNodeTreeSummary( node.children[i] ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if ( a.children ) {
|
|
||||||
ok( false, descPrefix + 'children array expected but not present' );
|
|
||||||
} else if ( b.children ) {
|
|
||||||
ok( false, descPrefix + 'children array present but not expected' );
|
|
||||||
} else {
|
|
||||||
ok( true, descPrefix + 'node is childless' );
|
|
||||||
}
|
}
|
||||||
|
return summary;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asserts that two node selections are equivalent.
|
* Builds a summary of a node selection.
|
||||||
*
|
*
|
||||||
* This will perform 1 assertion to check the number of results in the selection and then 2
|
* Generated summaries contain length of results as well as node summaries, ranges, indexes, indexes
|
||||||
* assertions on each result
|
* within parent and node ranges for each result. It's simple and fast to use deepEqual on this.
|
||||||
*
|
*
|
||||||
* @method
|
* @method
|
||||||
|
* @param {Object[]} selection Selection to summarize
|
||||||
|
* @returns {Object} Summary of selection
|
||||||
*/
|
*/
|
||||||
ve.example.nodeSelectionEqual = function( a, b, desc ) {
|
ve.example.getNodeSelectionSummary = function( selection ) {
|
||||||
var descPrefix = desc ? desc + ': ' : '';
|
var summary = {
|
||||||
// Prevent crashes if a and b have different lengths
|
'length': selection.length
|
||||||
var minLength = a.length < b.length ? a.length : b.length;
|
};
|
||||||
equal( a.length, b.length, descPrefix + 'length match' );
|
if ( selection.length ) {
|
||||||
for ( var i = 0; i < minLength; i++ ) {
|
summary.results = [];
|
||||||
ok( a[i].node === b[i].node, descPrefix + 'node match (element ' + i + ')' );
|
for ( var i = 0; i < selection.length; i++ ) {
|
||||||
if ( a[i].range && b[i].range ) {
|
summary.results.push( {
|
||||||
deepEqual( a[i].range, b[i].range, descPrefix + 'range match (element ' + i + ')' );
|
'node': ve.example.getNodeTreeSummary( selection[i].node, true ),
|
||||||
} else {
|
'range': selection[i].range,
|
||||||
strictEqual( 'range' in a[i], 'range' in b[i],
|
'index': selection[i].index,
|
||||||
descPrefix + 'range existence match (element ' + i + ')' );
|
'indexInNode': selection[i].indexInNode,
|
||||||
|
'nodeRange': selection[i].nodeRange
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
deepEqual( a[i].index, b[i].index, descPrefix + 'index match (element ' + i + ')' );
|
|
||||||
deepEqual( a[i].indexInNode, b[i].indexInNode,
|
|
||||||
descPrefix + 'indexInNode match (element ' + i + ')' );
|
|
||||||
deepEqual( a[i].nodeRange, b[i].nodeRange,
|
|
||||||
descPrefix + 'nodeRange match (element ' + i +')' );
|
|
||||||
}
|
}
|
||||||
|
return summary;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue