editor: Handling backspace/delete on the text boundries
[fnpeditor.git] / src / editor / plugins / core / core.test.js
1 define(function(require) {
2     
3 'use strict';
4 /* globals describe, it */
5
6 var chai = require('libs/chai'),
7     wlxml = require('wlxml/wlxml'),
8     corePlugin = require('./core.js'),
9     expect = chai.expect;
10
11 var getDocumentFromXML = function(xml, options) {
12     var doc = wlxml.WLXMLDocumentFromXML(xml, options || {});
13     doc.registerExtension(corePlugin.documentExtension);
14     return doc;
15 };
16
17 var getTextNodes = function(text, doc) {
18     /* globals Node */
19     var toret = [];
20     var search = function(node) {
21         node.contents().forEach(function(node) {
22             if(node.nodeType === Node.TEXT_NODE) {
23                 if(node.getText() === text) {
24                     toret.push(node);
25                 }
26             } else {
27                 search(node);
28             }
29         });
30     };
31     search(doc.root);
32     return toret;
33 };
34
35 var getTextNode = function(text, doc) {
36     var nodes = getTextNodes(text, doc),
37         error;
38     if(nodes.length === 0) {
39         error = 'Text not found';
40     } else if(nodes.length > 1) {
41         error = 'Text not unique';
42     } else if(nodes[0].getText() !== text) {
43         error = 'I was trying to cheat your test :(';
44     }
45     if(error) {
46         throw new Error(error);
47     }
48     return nodes[0];
49 };
50
51
52 describe('Document extensions', function() {
53     describe('break content', function() {
54         it('break text into two nodes', function() {
55             var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
56                 textNode = doc.root.contents()[0].contents()[0];
57             
58             var result = textNode.breakContent({offset:3});
59
60             var section = doc.root;
61             expect(section.contents().length).to.equal(2);
62             expect(section.contents()[0].contents()[0].getText()).to.equal('Ali');
63             expect(section.contents()[1].contents()[0].getText()).to.equal('ce');
64
65             expect(result.first.sameNode(section.contents()[0])).to.equal(true);
66             expect(result.second.sameNode(section.contents()[1])).to.equal(true);
67             expect(result.emptyText).to.equal(undefined, 'no new text node created');
68         });
69         it('puts empty text node when breaking at the very beginning', function() {
70             var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
71                 textNode = doc.root.contents()[0].contents()[0];
72             
73             var result = textNode.breakContent({offset:0}),
74                 firstNode = doc.root.contents()[0];
75
76             expect(result.emptyText.sameNode(firstNode.contents()[0]));
77             expect(result.emptyText.getText()).to.equal('');
78         });
79         it('puts empty text node when breaking at the very end', function() {
80             var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
81             textNode = doc.root.contents()[0].contents()[0];
82             
83             var result = textNode.breakContent({offset:5}),
84                 secondNode = doc.root.contents()[1];
85             
86             expect(result.emptyText.sameNode(secondNode.contents()[0]));
87             expect(result.emptyText.getText()).to.equal('');
88         });
89     });
90
91     describe('merging with adjacent content', function() {
92
93             describe('when text preceded by element', function() {
94                 describe('when text followed by element', function() {
95                     it('appends text to the preceding element, following elements stays in place', function() {
96                         var doc = getDocumentFromXML('<section><a>A</a>text<b>B</b></section>'),
97                             text = getTextNode('text', doc);
98                         
99                         text.mergeContentUp();
100                         var contents = doc.root.contents();
101                         
102                         expect(contents.length).to.equal(2);
103                         expect(contents[0].getTagName()).to.equal('a');
104                         expect(contents[0].contents()[0].getText()).to.equal('Atext');
105                         expect(contents[1].getTagName()).to.equal('b');
106                     });
107                 });
108                 describe('when text is a last child', function() {
109                     it('appends text to the preceding element', function() {
110                         var doc = getDocumentFromXML('<section><a>A</a>text</section>'),
111                             text = getTextNode('text', doc);
112                         
113                         text.mergeContentUp();
114                         var contents = doc.root.contents();
115                         
116                         expect(contents.length).to.equal(1);
117                         expect(contents[0].getTagName()).to.equal('a');
118                         expect(contents[0].contents()[0].getText()).to.equal('Atext');
119                     });
120                 });
121             });
122
123             describe('when text is a first child', function() {
124                 describe('when text followed by element', function() {
125                     it('appends text and its siblings to the parent preceding element', function() {
126                         var doc = getDocumentFromXML('<section><b>B</b><div>text<a>A</a></div></section>'),
127                             text = getTextNode('text', doc);
128                         
129                         text.mergeContentUp();
130                         var contents = doc.root.contents();
131                         
132                         expect(contents.length).to.equal(3);
133                         expect(contents[0].getTagName()).to.equal('b');
134                         expect(contents[1].getText()).to.equal('text');
135                         expect(contents[2].getTagName()).to.equal('a');
136                     });
137                     it('appends text and its siblings after the parent preceding text', function() {
138                         var doc = getDocumentFromXML('<section>B<div>text<a>A</a></div></section>'),
139                             text = getTextNode('text', doc);
140                         
141                         text.mergeContentUp();
142                         var contents = doc.root.contents();
143                         
144                         expect(contents.length).to.equal(2);
145                         expect(contents[0].getText()).to.equal('Btext');
146                         expect(contents[1].getTagName()).to.equal('a');
147                     });
148                 });
149             });
150     });
151 });
152
153
154 });