Some white space in the wlxml source handling rules
[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             });
212
213             describe('wrapping', function() {
214                 it('wraps DocumentNodeElement', function() {
215                     var c = canvas.fromXML('<section><div></div></section>'),
216                         div = c.doc().children()[0];
217                     
218                     var returned = div.wrapWithNodeElement({tag: 'header', klass: 'some.class'}),
219                         parent = div.parent(),
220                         parent2 = c.doc().children()[0];
221
222                     expect(returned.sameNode(parent)).to.be.true;
223                     expect(returned.sameNode(parent2)).to.be.true;
224                 });
225                 it('wraps DocumentTextElement', function() {
226                     var c = canvas.fromXML('<section>Alice</section>'),
227                         text = c.doc().children()[0];
228                     
229                     var returned = text.wrapWithNodeElement({tag: 'header', klass: 'some.class'}),
230                         parent = text.parent(),
231                         parent2 = c.doc().children()[0];
232
233                     expect(returned.sameNode(parent)).to.be.true;
234                     expect(returned.sameNode(parent2)).to.be.true;
235                 });
236                 
237                 it('wraps part of DocumentTextElement', function() {
238                     var c = canvas.fromXML('<section>Alice has a cat</section>'),
239                         text = c.doc().children()[0];
240                     
241                     var returned = text.wrapWithNodeElement({tag: 'header', klass: 'some.class', start: 5, end: 12}),
242                         children = c.doc().children();
243
244                     expect(children.length).to.equal(3);
245                     
246                     expect(children[0]).to.be.instanceOf(documentElement.DocumentTextElement);
247                     expect(children[0].getText()).to.equal('Alice');
248
249                     expect(children[1].sameNode(returned)).to.be.true;
250                     expect(children[1].children().length).to.equal(1);
251                     expect(children[1].children()[0].getText()).to.equal(' has a ');
252
253                     expect(children[2]).to.be.instanceOf(documentElement.DocumentTextElement);
254                     expect(children[2].getText()).to.equal('cat');
255                 });
256
257                 it('wraps text spanning multiple sibling DocumentTextNodes', function() {
258                     var c = canvas.fromXML('<section>Alice has a <span>small</span> cat</section>'),
259                         section = c.doc(),
260                         wrapper = c.wrapText({
261                             inside: section, 
262                             _with: {tag: 'span', klass: 'some.class'},
263                             offsetStart: 6,
264                             offsetEnd: 4,
265                             textNodeIdx: [0,2]
266                         });
267
268                     expect(section.children().length).to.equal(2);
269                     expect(section.children()[0]).to.be.instanceOf(documentElement.DocumentTextElement);
270                     expect(section.children()[0].getText()).to.equal('Alice ');
271
272                     var wrapper2 = section.children()[1];
273                     expect(wrapper2.sameNode(wrapper)).to.be.true;
274
275                     var wrapperChildren = wrapper.children();
276                     expect(wrapperChildren.length).to.equal(3);
277                     expect(wrapperChildren[0].getText()).to.equal('has a ');
278
279                     expect(wrapperChildren[1]).to.be.instanceOf(documentElement.DocumentNodeElement);
280                     expect(wrapperChildren[1].children().length).to.equal(1);
281                     expect(wrapperChildren[1].children()[0].getText()).to.equal('small');
282
283                     expect(wrapperChildren[2].getText()).to.equal(' cat');
284                 });
285             });
286         });
287
288     });
289 });
290
291
292 });