Update grunt's jshint task
[fnpeditor.git] / src / wlxml / extensions / list / list.test.js
1 define(function(require) {
2     
3 'use strict';
4
5 /* jshint multistr:true */
6 /* globals describe, it */
7
8 var chai = require('libs/chai'),
9     wlxml = require('wlxml/wlxml'),
10     expect = chai.expect,
11     $ = require('libs/jquery'),
12     listsExtension = require('wlxml/extensions/list/list');
13
14
15 var getDocumentFromXML = function(xml, options) {
16     var doc = wlxml.WLXMLDocumentFromXML(xml, options || {});
17     doc.registerExtension(listsExtension);
18     return doc;
19 };
20
21 var removeEmptyTextNodes = function(xml) {
22     /* globals Node */
23     xml = $($.trim(xml));
24     xml.find(':not(iframe)')
25         .addBack()
26         .contents()
27         .filter(function() {return this.nodeType === Node.TEXT_NODE;})
28         .each(function() {
29             if(!this.data.length) {
30                 $(this).remove();
31             }
32         });
33     return $('<w>').append(xml).html();
34 };
35
36
37 describe('Lists extension', function() {
38
39     describe('creating lists', function() {
40         it('allows creation of a list from existing sibling DocumentElements', function() {
41             var doc = getDocumentFromXML('<section>Alice<div>has</div>a<div>cat</div></section>'),
42                 section = doc.root,
43                 div1 = section.contents()[1],
44                 textA = section.contents()[2];
45             
46             doc.createList({node1: div1, node2: textA});
47
48             expect(section.contents().length).to.equal(3, 'section has three child nodes');
49
50             var child1 = section.contents()[0],
51                 list = section.contents()[1],
52                 child3 = section.contents()[2];
53
54             expect(child1.getText()).to.equal('Alice');
55             expect(list.is('list')).to.equal(true, 'second child is a list');
56             expect(list.contents().length).to.equal(2, 'list contains two elements');
57             list.contents().forEach(function(child) {
58                  expect(child.getClass()).to.equal('item', 'list childs have wlxml class of item');
59             });
60             expect(child3.contents()[0].getText()).to.equal('cat');
61         });
62
63         it('allows creating nested list from existing sibling list items', function() {
64             var doc = getDocumentFromXML('\
65                 <section>\
66                     <div class="list">\
67                         <div class="item">A</div>\
68                         <div class="item">B</div>\
69                         <div class="item">C</div>\
70                         <div class="item">D</div>\
71                     </div>\
72                 </section>');
73                 
74                 var outerList = doc.root.contents('.list')[0],
75                 itemB = outerList.contents('.item')[1],
76                 itemC = outerList.contents('.item')[2];
77
78             
79             doc.createList({node1: itemB, node2: itemC});
80
81             var outerListItems = outerList.contents('.item'),
82                 innerList = outerListItems[1].contents()[0];
83             
84             var innerListItems = innerList.contents('.item');
85
86             expect(outerListItems.length).to.equal(3, 'outer list has three items');
87             expect(outerListItems[0].contents()[0].getText()).to.equal('A', 'first outer item ok');
88             expect(outerListItems[1].getClass()).to.equal('item', 'inner list is wrapped by item element');
89
90             expect(innerList.is('list')).to.equal(true, 'inner list created');
91             expect(innerListItems.length).to.equal(2, 'inner list has two items');
92             expect(innerListItems[0].contents()[0].getText()).to.equal('B', 'first inner item ok');
93             expect(innerListItems[1].contents()[0].getText()).to.equal('C', 'second inner item ok');
94
95             expect(outerListItems[2].contents()[0].getText()).to.equal('D', 'last outer item ok');
96
97         });
98     });
99
100     describe('extracting list items', function() {
101         it('creates two lists with extracted items in the middle if extracting from the middle of the list', function() {
102             var doc = getDocumentFromXML(removeEmptyTextNodes('\
103                 <section>\
104                     <div class="list">\
105                         <div class="item">0</div>\
106                         <div class="item">1</div>\
107                         <div class="item">2</div>\
108                         <div class="item">3</div>\
109                     </div>\
110                 </section>')),
111                 list = doc.root.contents()[0],
112                 item1 = list.contents()[1],
113                 item2 = list.contents()[2];
114
115             doc.extractItems({item1: item1, item2: item2});
116
117             var section = doc.root,
118                 list1 = section.contents()[0],
119                 oldItem1 = section.contents()[1],
120                 oldItem2 = section.contents()[2],
121                 list2 = section.contents()[3];
122
123             expect(section.contents().length).to.equal(4, 'section contains two old items and two lists');
124             
125             expect(list1.is('list')).to.equal(true, 'first section child is a list');
126             expect(list1.contents().length).to.equal(1, 'first list has one child');
127             expect(list1.contents()[0].contents()[0].getText()).to.equal('0', 'first item of the first list is a first item of the original list');
128
129             expect(oldItem1.contents()[0].getText()).to.equal('1', 'first item got extracted');
130             expect(oldItem1.getClass() === '').to.equal(true, 'first extracted element has no wlxml class');
131
132             expect(oldItem2.contents()[0].getText()).to.equal('2', 'second item got extracted');
133             expect(oldItem2.getClass() === '').to.equal(true, 'second extracted element has no wlxml class');
134
135             expect(list2.is('list')).to.equal(true, 'last section child is a list');
136             expect(list2.contents().length).to.equal(1, 'second list has one child');
137             expect(list2.contents()[0].contents()[0].getText()).to.equal('3', 'first item of the second list is a last item of the original list');
138         });
139
140         it('puts extracted items above the list if starting item is the first one', function() {
141             var doc = getDocumentFromXML(removeEmptyTextNodes('\
142                 <section>\
143                     <div class="list">\
144                         <div class="item">0</div>\
145                         <div class="item">1</div>\
146                         <div class="item">2</div>\
147                     </div>\
148                 </section>')),
149                 list = doc.root.contents()[0],
150                 item1 = list.contents()[0],
151                 item2 = list.contents()[1],
152                 item3 = list.contents()[2];
153
154             doc.extractItems({item1: item1, item2: item2});
155
156             var section = doc.root,
157                 oldItem1 = section.contents()[0],
158                 oldItem2 = section.contents()[1],
159                 newList = section.contents()[2];
160
161             expect(section.contents().length).to.equal(3, 'section has three children');
162             expect(oldItem1.contents()[0].getText()).to.equal('0', 'first item extracted');
163             expect(oldItem2.contents()[0].getText()).to.equal('1', 'second item extracted');
164             expect(newList.is('list')).to.equal(true, 'list lies below extracted item');
165             expect(newList.contents().length).to.equal(1, 'list has now one child');
166         });
167
168         it('puts extracted items below the list if ending item is the last one', function() {
169             var doc = getDocumentFromXML(removeEmptyTextNodes('\
170                 <section>\
171                     <div class="list">\
172                         <div class="item">0</div>\
173                         <div class="item">1</div>\
174                         <div class="item">2</div>\
175                     </div>\
176                 </section>')),
177                 list = doc.root.contents()[0],
178                 item1 = list.contents()[0],
179                 item2 = list.contents()[1],
180                 item3 = list.contents()[2];
181
182             doc.extractItems({item1: item2, item2: item3});
183
184             var section = doc.root,
185                 oldItem1 = section.contents()[1],
186                 oldItem2 = section.contents()[2],
187                 newList = section.contents()[0];
188
189             expect(section.contents().length).to.equal(3, 'section has three children');
190             expect(oldItem1.contents()[0].getText()).to.equal('1', 'first item extracted');
191             expect(oldItem2.contents()[0].getText()).to.equal('2', 'second item extracted');
192             expect(newList.is('list')).to.equal(true, 'list lies above extracted item');
193             expect(newList.contents().length).to.equal(1, 'list has now one child');
194         });
195
196         it('removes list if all its items are extracted', function() {
197             var doc = getDocumentFromXML(removeEmptyTextNodes('\
198                 <section>\
199                     <div class="list">\
200                         <div class="item">some item</div>\
201                         <div class="item">some item 2</div>\
202                     </div>\
203                 </section>')),
204                 list = doc.root.contents()[0],
205                 item1 = list.contents()[0],
206                 item2 = list.contents()[1];
207
208             doc.extractItems({item1: item1, item2: item2});
209
210             var section = doc.root,
211                 oldItem1 = section.contents()[0],
212                 oldItem2 = section.contents()[1];
213
214             expect(section.contents().length).to.equal(2, 'section contains two children');
215             expect(oldItem1.contents()[0].getText()).to.equal('some item');
216             expect(oldItem2.contents()[0].getText()).to.equal('some item 2');
217         });
218
219         it('creates two lists with extracted items in the middle if extracting from the middle of the list - nested case' , function() {
220             var doc = getDocumentFromXML(removeEmptyTextNodes('\
221                 <section>\
222                     <div class="list">\
223                         <div class="item">0</div>\
224                         <div class="item">\
225                             <div class="list.items">\
226                                 <div class="item">1.1</div>\
227                                 <div class="item">1.2</div>\
228                                 <div class="item">1.3</div>\
229                             </div>\
230                         </div>\
231                         <div class="item">2</div>\
232                     </div>\
233                 </section>')),
234                 list = doc.root.contents()[0],
235                 nestedList = list.contents()[1].contents()[0],
236                 nestedListItem = nestedList.contents()[1];
237
238             doc.extractItems({item1: nestedListItem, item2: nestedListItem}); //@@ name!
239
240             list = doc.root.contents()[0];
241             var item1 = list.contents()[0],
242                 item2 = list.contents()[1], //
243                 item3 = list.contents()[2],
244                 item4 = list.contents()[3], //
245                 item5 = list.contents()[4],
246                 nestedList1 = item2.contents()[0],
247                 nestedList2 = item4.contents()[0];
248
249             expect(list.contents().length).to.equal(5, 'top list has five items');
250             
251             expect(item1.contents()[0].getText()).to.equal('0', 'first item ok');
252
253             expect(item2.getClass()).to.equal('item', 'first nested list is still wrapped in item element');
254             expect(nestedList1.contents().length).to.equal(1, 'first nested list is left with one child');
255             expect(nestedList1.contents()[0].contents()[0].getText()).to.equal('1.1', 'first nested list item left alone');
256             
257             expect(item3.contents()[0].getText()).to.equal('1.2', 'third item ok');
258
259             expect(item4.getClass()).to.equal('item', 'second nested list is still wrapped in item element');
260             expect(nestedList2.contents().length).to.equal(1, 'second nested list is left with one child');
261             expect(nestedList2.contents()[0].contents()[0].getText()).to.equal('1.3', 'second nested list item left alone');
262
263             expect(item5.contents()[0].getText()).to.equal('2', 'last item ok');
264         });
265
266         it('puts extracted items below the list if ending item is the last one - nested case' , function() {
267             var doc = getDocumentFromXML(removeEmptyTextNodes('\
268                 <section>\
269                     <div class="list.items">\
270                         <div class="item">0</div>\
271                         <div class="item">\
272                             <div class="list.items">\
273                                 <div class="item">1.1</div>\
274                                 <div class="item">1.2</div>\
275                                 <div class="item">1.3</div>\
276                             </div>\
277                         </div>\
278                         <div class="item">2</div>\
279                     </div>\
280                 </section>')),
281                 list = doc.root.contents()[0],
282                 nestedList = list.contents()[1].contents()[0],
283                 nestedListItem1 = nestedList.contents()[1],
284                 nestedListItem2 = nestedList.contents()[2];
285
286             doc.extractItems({item1: nestedListItem1, item2: nestedListItem2});
287             list = doc.root.contents()[0];
288             var item1 = list.contents()[0],
289                 item2 = list.contents()[1],
290                 item3 = list.contents()[2],
291                 item4 = list.contents()[3],
292                 item5 = list.contents()[4];
293             nestedList = item2.contents()[0];
294
295             expect(list.contents().length).to.equal(5, 'top list has five items');
296             expect(item1.contents()[0].getText()).to.equal('0', 'first item ok');
297             expect(item2.getClass()).to.equal('item', 'nested list is still wrapped in item element');
298             expect(nestedList.contents().length).to.equal(1, 'nested list is left with one child');
299             expect(nestedList.contents()[0].contents()[0].getText()).to.equal('1.1', 'nested list item left alone');
300             expect(item3.contents()[0].getText()).to.equal('1.2', 'third item ok');
301             expect(item4.contents()[0].getText()).to.equal('1.3', 'fourth item ok');
302             expect(item5.contents()[0].getText()).to.equal('2', 'fifth item ok');
303         });
304
305         it('puts extracted items above the list if starting item is the first one - nested case' , function() {
306             var doc = getDocumentFromXML(removeEmptyTextNodes('\
307                 <section>\
308                     <div class="list.items">\
309                         <div class="item">0</div>\
310                         <div class="item">\
311                             <div class="list.items">\
312                                 <div class="item">1.1</div>\
313                                 <div class="item">1.2</div>\
314                                 <div class="item">1.3</div>\
315                             </div>\
316                         </div>\
317                         <div class="item">2</div>\
318                     </div>\
319                 </section>')),
320                 list = doc.root.contents()[0],
321                 nestedList = list.contents()[1].contents()[0],
322                 nestedListItem1 = nestedList.contents()[0],
323                 nestedListItem2 = nestedList.contents()[1];
324
325             doc.extractItems({item1: nestedListItem1, item2: nestedListItem2});
326
327             list = doc.root.contents()[0];
328             var item1 = list.contents()[0],
329                 item2 = list.contents()[1],
330                 item3 = list.contents()[2],
331                 item4 = list.contents()[3],
332                 item5 = list.contents()[4];
333             nestedList = item4.contents()[0];
334
335             expect(list.contents().length).to.equal(5, 'top list has five items');
336             expect(item1.contents()[0].getText()).to.equal('0', 'first item ok');
337             expect(item2.contents()[0].getText()).to.equal('1.1', 'second item ok');
338             expect(item3.contents()[0].getText()).to.equal('1.2', 'third item ok');
339             
340             expect(item4.getClass()).to.equal('item', 'nested list is still wrapped in item element');
341             expect(nestedList.contents().length).to.equal(1, 'nested list is left with one child');
342             expect(nestedList.contents()[0].contents()[0].getText()).to.equal('1.3', 'nested list item left alone');
343             expect(item5.contents()[0].getText()).to.equal('2', 'fifth item ok');
344         });
345
346         it('removes list if all its items are extracted - nested case', function() {
347             var doc = getDocumentFromXML(removeEmptyTextNodes('\
348                 <section>\
349                     <div class="list.items">\
350                         <div class="item">0</div>\
351                         <div class="item">\
352                             <div class="list.items">\
353                                 <div class="item">1.1</div>\
354                                 <div class="item">1.2</div>\
355                             </div>\
356                         </div>\
357                         <div class="item">2</div>\
358                     </div>\
359                 </section>')),
360                 list = doc.root.contents()[0],
361                 nestedList = list.contents()[1].contents()[0],
362                 nestedListItem1 = nestedList.contents()[0],
363                 nestedListItem2 = nestedList.contents()[1];
364
365             doc.extractItems({item1: nestedListItem1, item2: nestedListItem2});
366
367             list = doc.root.contents()[0];
368             var item1 = list.contents()[0],
369                 item2 = list.contents()[1],
370                 item3 = list.contents()[2],
371                 item4 = list.contents()[3];
372
373             expect(list.contents().length).to.equal(4, 'top list has four items');
374             expect(item1.contents()[0].getText()).to.equal('0', 'first item ok');
375             expect(item2.contents()[0].getText()).to.equal('1.1', 'second item ok');
376             expect(item3.contents()[0].getText()).to.equal('1.2', 'third item ok');
377             expect(item4.contents()[0].getText()).to.equal('2', 'fourth item ok');
378         });
379
380         it('extracts items out of outer most list when merge flag is set to false', function() {
381             var doc = getDocumentFromXML(removeEmptyTextNodes('\
382                 <section>\
383                     <div class="list.items">\
384                         <div class="item">0</div>\
385                         <div class="item">\
386                             <div class="list.items">\
387                                 <div class="item">1.1</div>\
388                                 <div class="item">1.2</div>\
389                             </div>\
390                         </div>\
391                         <div class="item">2</div>\
392                     </div>\
393                 </section>')),
394                 section = doc.root,
395                 list = section.contents()[0],
396                 nestedList = list.contents()[1].contents()[0],
397                 nestedListItem = nestedList.contents()[0];
398
399             var test = doc.extractItems({item1: nestedListItem, item2: nestedListItem, merge: false});
400
401             expect(test).to.equal(true, 'extraction status ok');
402
403             var sectionContents = section.contents(),
404                 extractedItem = sectionContents[1];
405
406             expect(sectionContents.length).to.equal(3, 'section has three children');
407             expect(sectionContents[0].is('list')).to.equal(true, 'first child is a list');
408
409             expect(extractedItem.getTagName()).to.equal('div', 'extracted item is a wlxml div');
410             expect(extractedItem.getClass()).to.equal('', 'extracted item has no wlxml class');
411             expect(extractedItem.contents()[0].getText()).to.equal('1.1', 'extracted item ok');
412             expect(sectionContents[2].is('list')).to.equal(true, 'second child is a list');
413         });
414     });
415
416 });
417
418 });