56f8ee60c688a3c68971a6e516ddc385fec8546d
[fnpeditor.git] / modules / documentCanvas / canvas / canvas.test3.js
1 define([
2 'libs/chai',
3 'modules/documentCanvas/canvas/canvas',
4 'modules/documentCanvas/canvas/documentElement'
5 ], function(chai, canvas, documentElement) {
6     
7 'use strict';
8
9 var expect = chai.expect;
10
11
12 describe('Canvas', function() {
13     describe('basic properties', function() {
14         it('renders empty document when canvas created from empty XML', function() {
15             var c = canvas.fromXML('');
16             expect(c.doc()).to.equal(null);
17         });
18
19         it('gives access to its document root node', function() {
20             var c = canvas.fromXML('<section></section>');
21             expect(c.doc().wlxmlTag).to.equal('section');
22         });
23
24         describe('DocumentElement', function() {
25             it('knows index of its child', function() {
26                 var c = canvas.fromXML('<section><div></div><header></header><span></span></section>'),
27                     root = c.doc(),
28                     child = root.children()[1];
29                 expect(root.childIndex(child)).to.equal(1);
30             });
31
32             describe('DocumentTextElement can have its content set', function() {
33                 var c = canvas.fromXML('<section>Alice</section>'),
34                     root = c.doc(),
35                     text = root.children()[0];
36                 
37                 text.setText('a cat');
38                 expect(root.children()[0].getText()).to.equal('a cat');
39             });
40         });
41     });
42
43     describe('document representation api', function() {
44         describe('document root element', function() {
45             var c = canvas.fromXML('<section></section>');
46             it('exists', function() {
47                 expect(c.doc()).to.be.instanceOf(documentElement.DocumentElement);
48             });
49             it('is of type DocumentNodeElement', function() {
50                 expect(c.doc()).to.be.instanceOf(documentElement.DocumentNodeElement);
51             });
52         });
53
54         describe('DocumentElements comparison', function() {
55             it('reports dwo DocumentElements to be the same when they represent the same wlxml document element', function() {
56                 var c = canvas.fromXML('<section><div></div><div></div></section>'),
57                     first_div1 = c.doc().children()[0],
58                     first_div2 = c.doc().children()[0],
59                     second_div = c.doc().children()[1];
60                 expect(first_div1.sameNode(first_div1)).to.be.true;
61                 expect(first_div1.sameNode(first_div2)).to.be.true;
62                 expect(first_div1.sameNode(second_div)).to.be.false;
63             });
64         });
65
66         describe('traversing', function() {
67             it('reports element nodes', function() {
68                 var c = canvas.fromXML('<section><div></div></section>'),
69                     children = c.doc().children();
70                 expect(children.length).to.equal(1);
71                 expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
72
73                 c = canvas.fromXML('<section><div></div><div></div></section>'),
74                     children = c.doc().children();
75                 expect(children.length).to.equal(2);
76                 expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
77                 expect(children[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
78             });
79             
80             it('reports text nodes', function() {
81                 var c = canvas.fromXML('<section>Alice</section>'),
82                     children = c.doc().children();
83                 expect(children.length).to.equal(1);
84                 expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
85             });
86
87             describe('accessing parents', function() {
88                 it('returns DocumentNodeElement representing parent in wlxml document as DocumentNodeElement parent', function() {
89                     var c = canvas.fromXML('<section><div></div></section>'),
90                         div = c.doc().children()[0];
91                     expect(div.parent().sameNode(c.doc())).to.be.true;
92                 });
93                 it('returns DocumentNodeElement representing parent in wlxml document as DocumentTextElement parent', function() {
94                     var c = canvas.fromXML('<section>Alice</section>'),
95                         text = c.doc().children()[0];
96                     expect(text.parent().sameNode(c.doc())).to.be.true;
97                 });
98             });
99
100             describe('free text handling', function() {
101                     it('sees free text', function() {
102                         var c = canvas.fromXML('<section>Alice <span>has</span> a cat</section>'),
103                             children = c.doc().children();
104                         expect(children.length).to.equal(3);
105                         expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
106                         expect(children[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
107                         expect(children[2]).to.be.instanceOf(documentElement.DocumentTextElement);
108                     });
109             });
110             
111             describe('white characters handling', function() {
112                 it('says empty element node has no children', function() {
113                     var c = canvas.fromXML('<section></section>');
114                     expect(c.doc().children().length).to.equal(0);
115                 });
116                 it('says element node with one space has one DocumentTextElement', function() {
117                     var c = canvas.fromXML('<section> </section>');
118                     expect(c.doc().children().length).to.equal(1);
119                     expect(c.doc().children()[0]).to.be.instanceOf(documentElement.DocumentTextElement);
120                 });
121                 it('ignores white space surrounding block elements', function() {
122                     var c = canvas.fromXML('<section> <div></div> </section>');
123                     var children = c.doc().children();
124                     expect(children.length).to.equal(1);
125                     expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
126                 });
127                 it('ignores white space between block elements', function() {
128                     var c = canvas.fromXML('<section><div></div> <div></div></section>');
129                     var children = c.doc().children();
130                     expect(children.length === 2);
131                     [0,1].forEach(function(idx) {
132                         expect(children[idx]).to.be.instanceOf(documentElement.DocumentNodeElement);
133                     });
134                 });
135
136                 it('trims white space from the beginning and the end of the block elements', function() {
137                     var c = canvas.fromXML('<section> Alice <span>has</span> a cat </section>');
138                     expect(c.doc().children()[0].getText()).to.equal('Alice ');
139                     expect(c.doc().children()[2].getText()).to.equal(' a cat');
140                 });
141
142                 it('normalizes string of white characters to one space at the inline element boundries', function() {
143                     var c = canvas.fromXML('<span>   Alice has a cat   </span>');
144                     expect(c.doc().children()[0].getText()).to.equal(' Alice has a cat ');
145                 });
146
147                 it('normalizes string of white characters to one space before inline element', function() {
148                     var c = canvas.fromXML('<div>Alice has  <span>a cat</span></div>');
149                     expect(c.doc().children()[0].getText()).to.equal('Alice has ');
150                 });
151                 
152                 it('normalizes string of white characters to one space after inline element', function() {
153                     var c = canvas.fromXML('<div>Alice has <span>a</span>  cat</div>');
154                     expect(c.doc().children()[2].getText()).to.equal(' cat');
155                 });
156             });
157         });
158
159         describe('manipulation api', function() {
160
161             describe('Basic Element inserting', function() {
162                 it('can put new NodeElement at the end', function() {
163                     var c = canvas.fromXML('<section></section>'),
164                         appended = c.doc().append({tag: 'header', klass: 'some.class'}),
165                         children = c.doc().children();
166
167                     expect(children.length).to.equal(1);
168                     expect(children[0].sameNode(appended));
169                 });
170
171                 it('can put new TextElement at the end', function() {
172                     var c = canvas.fromXML('<section></section>'),
173                         appended = c.doc().append({text: 'Alice'}),
174                         children = c.doc().children();
175
176                     expect(children.length).to.equal(1);
177                     expect(children[0].sameNode(appended));
178                     expect(children[0].getText()).to.equal('Alice');
179                 });
180
181                 it('can put new NodeElement after another NodeElement', function() {
182                     var c = canvas.fromXML('<section><div></div></section>'),
183                         div = c.doc().children()[0],
184                         added = div.after({tag: 'header', klass: 'some.class'}),
185                         children = c.doc().children();
186                     expect(children.length).to.equal(2);
187                     expect(children[1].sameNode(added));
188                 });
189
190                 it('can put new Nodeelement before another element', function() {
191                     var c = canvas.fromXML('<section><div></div></section>'),
192                         div = c.doc().children()[0],
193                         added = div.before({tag: 'header', klass: 'some.class'}),
194                         children = c.doc().children();
195                     expect(children.length).to.equal(2);
196                     expect(children[0].sameNode(added));
197                 });
198
199                 it('can put new DocumentNodeElement after DocumentTextElement', function() {
200                     var c = canvas.fromXML('<section>Alice</section>'),
201                         text = c.doc().children()[0],
202                         added = text.after({tag: 'p'}),
203                         children = c.doc().children();
204
205                     expect(children.length).to.equal(2);
206                     expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
207                     expect(children[0].getText()).to.equal('Alice');
208                     expect(children[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
209                     expect(children[1].sameNode(added)).to.be.true;
210                 });
211                 it('can put new DocumentNodeElement before DocumentTextElement', function() {
212                     var c = canvas.fromXML('<section>Alice</section>'),
213                         text = c.doc().children()[0],
214                         added = text.before({tag: 'p'}),
215                         children = c.doc().children();
216
217                     expect(children.length).to.equal(2);
218                     expect(children[0]).to.be.instanceOf(documentElement.DocumentNodeElement);
219                     expect(children[0].sameNode(added)).to.be.true;
220                     expect(children[1]).to.be.instanceOf(documentElement.DocumentTextElement);
221                     expect(children[1].getText()).to.equal('Alice');
222                 });
223             });
224
225             describe('Splitting text', function() {
226                 
227                 it('splits DocumentTextElement\'s parent into two DocumentNodeElements of the same type', function() {
228                     var c = canvas.fromXML('<section><header>Some header</header></section>'),
229                         section = c.doc(),
230                         text = section.children()[0].children()[0];
231
232                     text.split({offset: 5});
233                     expect(section.children().length).to.equal(2, 'section has two children');
234                     
235                     var header1 = section.children()[0];
236                     var header2 = section.children()[1];
237
238                     expect(header1.wlxmlTag).to.equal('header', 'first section child represents wlxml header');
239                     expect(header1.children().length).to.equal(1, 'first header has one text child');
240                     expect(header1.children()[0].getText()).to.equal('Some ', 'first header has correct content');
241                     expect(header2.wlxmlTag).to.equal('header', 'second section child represents wlxml header');
242                     expect(header2.children().length).to.equal(1, 'second header has one text child');
243                     expect(header2.children()[0].getText()).to.equal('header', 'second header has correct content');
244                 });
245
246                 it('keeps DocumentTextElement\'s parent\'s children elements intact', function() {
247                     var c = canvas.fromXML('\
248                             <section>\
249                                 <header>\
250                                     A <span>fancy</span> and <span>nice</span> header\
251                                 </header>\
252                             </section>'),
253                         section = c.doc(),
254                         header = section.children()[0],
255                         textAnd = header.children()[2];
256
257                     textAnd.split({offset: 2});
258                     
259                     var sectionChildren = section.children();
260                     expect(sectionChildren.length).to.equal(2, 'Section has two children');
261                     expect(sectionChildren[0].wlxmlTag).to.equal('header', 'First section element is a wlxml header');
262                     expect(sectionChildren[1].wlxmlTag).to.equal('header', 'Second section element is a wlxml header');
263
264                     var firstHeaderChildren = sectionChildren[0].children();
265                     expect(firstHeaderChildren.length).to.equal(3, 'First header has three children');
266                     expect(firstHeaderChildren[0].getText()).to.equal('A ', 'First header starts with a text');
267                     expect(firstHeaderChildren[1].wlxmlTag).to.equal('span', 'First header has span in the middle');
268                     expect(firstHeaderChildren[2].getText()).to.equal(' a', 'First header ends with text');
269
270                     var secondHeaderChildren = sectionChildren[1].children();
271                     expect(secondHeaderChildren.length).to.equal(3, 'Second header has three children');
272                     expect(secondHeaderChildren[0].getText()).to.equal('nd ', 'Second header starts with text');
273                     expect(secondHeaderChildren[1].wlxmlTag).to.equal('span', 'Second header has span in the middle');
274                     expect(secondHeaderChildren[2].getText()).to.equal(' header', 'Second header ends with text');
275                 });
276             });
277
278             describe('wrapping', function() {
279                 it('wraps DocumentNodeElement', function() {
280                     var c = canvas.fromXML('<section><div></div></section>'),
281                         div = c.doc().children()[0];
282                     
283                     var returned = div.wrapWithNodeElement({tag: 'header', klass: 'some.class'}),
284                         parent = div.parent(),
285                         parent2 = c.doc().children()[0];
286
287                     expect(returned.sameNode(parent)).to.be.true;
288                     expect(returned.sameNode(parent2)).to.be.true;
289                 });
290                 it('wraps DocumentTextElement', function() {
291                     var c = canvas.fromXML('<section>Alice</section>'),
292                         text = c.doc().children()[0];
293                     
294                     var returned = text.wrapWithNodeElement({tag: 'header', klass: 'some.class'}),
295                         parent = text.parent(),
296                         parent2 = c.doc().children()[0];
297
298                     expect(returned.sameNode(parent)).to.be.true;
299                     expect(returned.sameNode(parent2)).to.be.true;
300                 });
301                 
302                 it('wraps part of DocumentTextElement', function() {
303                     var c = canvas.fromXML('<section>Alice has a cat</section>'),
304                         text = c.doc().children()[0];
305                     
306                     var returned = text.wrapWithNodeElement({tag: 'header', klass: 'some.class', start: 5, end: 12}),
307                         children = c.doc().children();
308
309                     expect(children.length).to.equal(3);
310                     
311                     expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
312                     expect(children[0].getText()).to.equal('Alice');
313
314                     expect(children[1].sameNode(returned)).to.be.true;
315                     expect(children[1].children().length).to.equal(1);
316                     expect(children[1].children()[0].getText()).to.equal(' has a ');
317
318                     expect(children[2]).to.be.instanceOf(documentElement.DocumentTextElement);
319                     expect(children[2].getText()).to.equal('cat');
320                 });
321
322                 it('wraps text spanning multiple sibling DocumentTextNodes', function() {
323                     var c = canvas.fromXML('<section>Alice has a <span>small</span> cat</section>'),
324                         section = c.doc(),
325                         wrapper = c.wrapText({
326                             inside: section, 
327                             _with: {tag: 'span', klass: 'some.class'},
328                             offsetStart: 6,
329                             offsetEnd: 4,
330                             textNodeIdx: [0,2]
331                         });
332
333                     expect(section.children().length).to.equal(2);
334                     expect(section.children()[0]).to.be.instanceOf(documentElement.DocumentTextElement);
335                     expect(section.children()[0].getText()).to.equal('Alice ');
336
337                     var wrapper2 = section.children()[1];
338                     expect(wrapper2.sameNode(wrapper)).to.be.true;
339
340                     var wrapperChildren = wrapper.children();
341                     expect(wrapperChildren.length).to.equal(3);
342                     expect(wrapperChildren[0].getText()).to.equal('has a ');
343
344                     expect(wrapperChildren[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
345                     expect(wrapperChildren[1].children().length).to.equal(1);
346                     expect(wrapperChildren[1].children()[0].getText()).to.equal('small');
347
348                     expect(wrapperChildren[2].getText()).to.equal(' cat');
349                 });
350             });
351         });
352
353         describe('Lists api', function() {
354             it('allows creation of a list from existing sibling DocumentElements', function() {
355                 var c = canvas.fromXML('\
356                     <section>\
357                         Alice\
358                         <div>has</div>\
359                         a\
360                         <div>cat</div>\
361                     </section>'),
362                     section = c.doc(),
363                     textAlice = section.children()[0],
364                     divCat = section.children()[3]
365                 
366                 c.list.create({element1: textAlice, element2: divCat});
367
368                 expect(section.children().length).to.equal(1, 'section has one child element');
369
370                 var list = section.children()[0];
371                 expect(list.is('list')).to.equal(true, 'section\'s only child is a list');
372                 expect(list.children().length).to.equal(4, 'list contains four elements');
373             });
374         });
375
376     });
377 });
378
379
380 });