r101697 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r101696‎ | r101697 | r101698 >
Date:21:20, 2 November 2011
Author:tparscal
Status:ok
Tags:
Comment:
Moving hype tests to VisualEditor extension
Modified paths:
  • /trunk/extensions/VisualEditor/tests/es.DocumentNode.test.js (added) (history)

Diff [purge]

Index: trunk/extensions/VisualEditor/tests/es.DocumentNode.test.js
@@ -0,0 +1,288 @@
 2+module( 'es/bases' );
 3+
 4+function DocumentNodeStub( items, name, size ) {
 5+ this.name = name;
 6+ this.size = size;
 7+ return es.extendObject( new es.DocumentNode( items ), this );
 8+}
 9+
 10+DocumentNodeStub.prototype.getContentLength = function() {
 11+ return this.size;
 12+};
 13+
 14+DocumentNodeStub.prototype.getElementLength = function() {
 15+ // Mimic document data which has an opening and closing around the content
 16+ return this.size + 2;
 17+};
 18+
 19+test( 'es.DocumentNode', function() {
 20+
 21+ // Stub test
 22+
 23+ strictEqual(
 24+ ( new DocumentNodeStub( [], 'a', 0 ) ).getElementLength(),
 25+ 2,
 26+ 'DocumentNodeStub.getElementLength() returns initialized length plus 2 for elements'
 27+ );
 28+
 29+ // Stubs
 30+
 31+ var a = new DocumentNodeStub( [], 'a', 0 ),
 32+ b = new DocumentNodeStub( [], 'b', 1 ),
 33+ c = new DocumentNodeStub( [], 'c', 2 ),
 34+ d = new DocumentNodeStub( [], 'd', 3 ),
 35+ e = new DocumentNodeStub( [], 'e', 4 ),
 36+ root1 = new DocumentNodeStub( [a, b, c, d, e], 'root1', 20 ),
 37+ i;
 38+
 39+ // getRangeFromNode tests
 40+
 41+ var getRangeFromNodeTests = [
 42+ { 'input': a, 'output': new es.Range( 0, 2 ) },
 43+ { 'input': b, 'output': new es.Range( 2, 5 ) },
 44+ { 'input': c, 'output': new es.Range( 5, 9 ) },
 45+ { 'input': d, 'output': new es.Range( 9, 14 ) },
 46+ { 'input': e, 'output': new es.Range( 14, 20 ) },
 47+ { 'input': null, 'output': null }
 48+ ];
 49+
 50+ for ( i = 0; i < getRangeFromNodeTests.length; i++ ) {
 51+ deepEqual(
 52+ root1.getRangeFromNode( getRangeFromNodeTests[i].input ),
 53+ getRangeFromNodeTests[i].output,
 54+ 'getRangeFromNode returns the correct range or null if item is not found'
 55+ );
 56+ }
 57+
 58+ // getNodeFromOffset tests
 59+
 60+ var getNodeFromOffsetTests = [
 61+ { 'input': -1, 'output': null },
 62+ { 'input': 0, 'output': a },
 63+ { 'input': 1, 'output': a },
 64+ { 'input': 2, 'output': b },
 65+ { 'input': 3, 'output': b },
 66+ { 'input': 4, 'output': b },
 67+ { 'input': 5, 'output': c },
 68+ { 'input': 6, 'output': c },
 69+ { 'input': 7, 'output': c },
 70+ { 'input': 8, 'output': c },
 71+ { 'input': 9, 'output': d },
 72+ { 'input': 10, 'output': d },
 73+ { 'input': 11, 'output': d },
 74+ { 'input': 12, 'output': d },
 75+ { 'input': 13, 'output': d },
 76+ { 'input': 14, 'output': e },
 77+ { 'input': 15, 'output': e },
 78+ { 'input': 16, 'output': e },
 79+ { 'input': 17, 'output': e },
 80+ { 'input': 18, 'output': e },
 81+ { 'input': 19, 'output': e },
 82+ { 'input': 20, 'output': null }
 83+ ];
 84+
 85+ for ( i = 0; i < getNodeFromOffsetTests.length; i++ ) {
 86+ strictEqual(
 87+ root1.getNodeFromOffset( getNodeFromOffsetTests[i].input ),
 88+ getNodeFromOffsetTests[i].output,
 89+ 'getNodeFromOffset finds the right item or returns null when out of range'
 90+ );
 91+ }
 92+
 93+ // getOffsetFromNode tests
 94+
 95+ var getOffsetFromNodeTests = [
 96+ { 'input': a, 'output': 0 },
 97+ { 'input': b, 'output': 2 },
 98+ { 'input': c, 'output': 5 },
 99+ { 'input': d, 'output': 9 },
 100+ { 'input': e, 'output': 14 },
 101+ { 'input': null, 'output': -1 }
 102+ ];
 103+
 104+ for ( i = 0; i < getOffsetFromNodeTests.length; i++ ) {
 105+ strictEqual(
 106+ root1.getOffsetFromNode( getOffsetFromNodeTests[i].input ),
 107+ getOffsetFromNodeTests[i].output,
 108+ 'getOffsetFromNode finds the right offset or returns -1 when node is not found'
 109+ );
 110+ }
 111+} );
 112+
 113+test( 'es.DocumentNode.selectNodes', function() {
 114+
 115+ // selectNodes tests
 116+
 117+ // <f> a b c d e f g h </f> <g> a b c d e f g h </g> <h> a b c d e f g h </h>
 118+ //^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
 119+ //0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0
 120+ // 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8 0 1 2 3 4 5 6 7 8
 121+ var f = new DocumentNodeStub( [], 'f', 8 ),
 122+ g = new DocumentNodeStub( [], 'g', 8 ),
 123+ h = new DocumentNodeStub( [], 'h', 8 ),
 124+ root2 = new DocumentNodeStub( [f, g, h], 'root2', 30 );
 125+ // FIXME: QUnit thinks f == g because both are empty arrays. Rawr.
 126+ // TODO make sure there is a test case for everything that is special-cased in the code
 127+ // TODO also nest with a more complicated nested structure, like the one from es.DocumentModel.test.js
 128+
 129+ // Possible positions are:
 130+ // * before beginning
 131+ // * at beginning
 132+ // * middle
 133+ // * at end
 134+ // * past end
 135+ var selectNodesTests = [
 136+ // Complete set of combinations within the same node:
 137+ {
 138+ 'node': root2,
 139+ 'input': new es.Range( 0, 0 ),
 140+ 'output': [],
 141+ 'desc': 'Zero-length range before the beginning of a node'
 142+ },
 143+ {
 144+ 'node': root2,
 145+ 'input': new es.Range( 0, 1 ),
 146+ 'output': [{ 'node': f, 'range': new es.Range( 0, 0 ) }],
 147+ 'desc': 'Range starting before the beginning of a node and ending at the beginning'
 148+ },
 149+ {
 150+ 'node': root2,
 151+ 'input': new es.Range( 10, 15 ),
 152+ 'output': [{ 'node': g, 'range': new es.Range( 0, 4 ) }],
 153+ 'desc': 'Range starting before the beginning of a node and ending in the middle'
 154+ },
 155+ {
 156+ 'node': root2,
 157+ 'input': new es.Range( 20, 29 ),
 158+ 'output': [{ 'node': h, 'range': new es.Range( 0, 8 ) }],
 159+ 'desc': 'Range starting before the beginning of a node and ending at the end'
 160+ },
 161+ {
 162+ 'node': root2,
 163+ 'input': new es.Range( 0, 10 ),
 164+ 'output': [{ 'node': f } ],
 165+ 'desc': 'Range starting before the beginning of a node and ending past the end'
 166+ },
 167+ {
 168+ 'node': root2,
 169+ 'input': new es.Range( 11, 11 ),
 170+ 'output': [{ 'node': g, 'range': new es.Range( 0, 0 ) }],
 171+ 'desc': 'Zero-length range at the beginning of a node'
 172+ },
 173+ {
 174+ 'node': root2,
 175+ 'input': new es.Range( 21, 26 ),
 176+ 'output': [{ 'node': h, 'range': new es.Range( 0, 5 ) }],
 177+ 'desc': 'Range starting at the beginning of a node and ending in the middle'
 178+ },
 179+ {
 180+ 'node': root2,
 181+ 'input': new es.Range( 1, 9 ),
 182+ 'output': [{ 'node': f, 'range': new es.Range( 0, 8 ) }],
 183+ 'desc': 'Range starting at the beginning of a node and ending at the end'
 184+ },
 185+ {
 186+ 'node': root2,
 187+ 'input': new es.Range( 11, 20 ),
 188+ 'output': [{ 'node': g, 'range': new es.Range( 0, 8 ) }],
 189+ 'desc': 'Range starting at the beginning of a node and ending past the end'
 190+ },
 191+ {
 192+ 'node': root2,
 193+ 'input': new es.Range( 22, 22 ),
 194+ 'output': [{ 'node': h, 'range': new es.Range( 1, 1 ) }],
 195+ 'desc': 'Zero-length range in the middle of a node'
 196+ },
 197+ {
 198+ 'node': root2,
 199+ 'input': new es.Range( 2, 7 ),
 200+ 'output': [{ 'node': f, 'range': new es.Range( 1, 6 ) }],
 201+ 'desc': 'Range starting and ending in the middle of the same node'
 202+ },
 203+ {
 204+ 'node': root2,
 205+ 'input': new es.Range( 13, 19 ),
 206+ 'output': [{ 'node': g, 'range': new es.Range( 2, 8 ) }],
 207+ 'desc': 'Range starting in the middle of a node and ending at the end'
 208+ },
 209+ {
 210+ 'node': root2,
 211+ 'input': new es.Range( 24, 30 ),
 212+ 'output': [{ 'node': h, 'range': new es.Range( 3, 8 ) }],
 213+ 'desc': 'Range starting in the middle of a node and ending past the end'
 214+ },
 215+ {
 216+ 'node': root2,
 217+ 'input': new es.Range( 9, 9 ),
 218+ 'output': [{ 'node': f, 'range': new es.Range( 8, 8 ) }],
 219+ 'desc': 'Zero-length range at the end of a node'
 220+ },
 221+ {
 222+ 'node': root2,
 223+ 'input': new es.Range( 19, 20 ),
 224+ 'output': [{ 'node': g, 'range': new es.Range( 8, 8 ) }],
 225+ 'desc': 'Range starting at the end of a node and ending past the end'
 226+ },
 227+ {
 228+ 'node': root2,
 229+ 'input': new es.Range( 30, 30 ),
 230+ 'output': [],
 231+ 'desc': 'Zero-length range past the end of a node'
 232+ },
 233+ // TODO add a complete set of combinations for cross-node ranges
 234+ {
 235+ 'node': root2,
 236+ 'input': new es.Range( 5, 25 ),
 237+ 'output': [
 238+ { 'node': f, 'range': new es.Range( 4, 8 ) },
 239+ { 'node': g },
 240+ { 'node': h, 'range': new es.Range( 0, 4 ) }
 241+ ],
 242+ 'desc': 'Range starting in the middle of the first node and ending in the middle of the third'
 243+ },
 244+ {
 245+ 'node': root2,
 246+ 'input': new es.Range( 5, 11 ),
 247+ 'output': [
 248+ { 'node': f, 'range': new es.Range( 4, 8 ) },
 249+ { 'node': g, 'range': new es.Range( 0, 0 ) }
 250+ ],
 251+ 'desc': 'Range starting in the middle of a node and ending at the beginning of the second'
 252+ },
 253+ {
 254+ 'node': root2,
 255+ 'input': new es.Range( 5, 12 ),
 256+ 'output': [
 257+ { 'node': f, 'range': new es.Range( 4, 8 ) },
 258+ { 'node': g, 'range': new es.Range( 0, 1 ) }
 259+ ],
 260+ 'desc': 'Range starting in the middle of a node and ending after the first character of the second'
 261+ },
 262+ {
 263+ 'node': root2,
 264+ 'input': new es.Range( 8, 16 ),
 265+ 'output': [
 266+ { 'node': f, 'range': new es.Range( 7, 8 ) },
 267+ { 'node': g, 'range': new es.Range( 0, 5 ) }
 268+ ],
 269+ 'desc': 'Range starting before the last character of a node and ending in the middle of the next node'
 270+ },
 271+ {
 272+ 'node': root2,
 273+ 'input': new es.Range( 9, 16 ),
 274+ 'output': [
 275+ { 'node': f, 'range': new es.Range( 8, 8 ) },
 276+ { 'node': g, 'range': new es.Range( 0, 5 ) }
 277+ ],
 278+ 'desc': 'Range starting at the end of a node and ending in the middle of the next node'
 279+ }
 280+ ];
 281+
 282+ for ( var i = 0; i < selectNodesTests.length; i++ ) {
 283+ deepEqual(
 284+ root2.selectNodes( selectNodesTests[i].input ),
 285+ selectNodesTests[i].output,
 286+ selectNodesTests[i].desc
 287+ );
 288+ }
 289+} );

Status & tagging log