smartxml: caching text nodes via expando
[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     sinon = require('libs/sinon'),
8     wlxml = require('wlxml/wlxml'),
9     corePlugin = require('./core.js'),
10     expect = chai.expect;
11
12 var getDocumentFromXML = function(xml, options) {
13     var doc = wlxml.WLXMLDocumentFromXML(xml, options || {});
14     doc.registerExtension(corePlugin.documentExtension);
15     return doc;
16 };
17
18 var getTextNodes = function(text, doc) {
19     /* globals Node */
20     var toret = [];
21     var search = function(node) {
22         node.contents().forEach(function(node) {
23             if(node.nodeType === Node.TEXT_NODE) {
24                 if(node.getText() === text) {
25                     toret.push(node);
26                 }
27             } else {
28                 search(node);
29             }
30         });
31     };
32     search(doc.root);
33     return toret;
34 };
35
36 var getTextNode = function(text, doc) {
37     var nodes = getTextNodes(text, doc),
38         error;
39     if(nodes.length === 0) {
40         error = 'Text not found';
41     } else if(nodes.length > 1) {
42         error = 'Text not unique';
43     } else if(nodes[0].getText() !== text) {
44         error = 'I was trying to cheat your test :(';
45     }
46     if(error) {
47         throw new Error(error);
48     }
49     return nodes[0];
50 };
51
52
53 describe('Document extensions', function() {
54     describe('break content', function() {
55         it('break text into two nodes', function() {
56             var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
57                 textNode = doc.root.contents()[0].contents()[0];
58             
59             var result = textNode.breakContent({offset:3});
60
61             var section = doc.root;
62             expect(section.contents().length).to.equal(2);
63             expect(section.contents()[0].contents()[0].getText()).to.equal('Ali');
64             expect(section.contents()[1].contents()[0].getText()).to.equal('ce');
65
66             expect(result.first.sameNode(section.contents()[0])).to.equal(true);
67             expect(result.second.sameNode(section.contents()[1])).to.equal(true);
68             expect(result.emptyText).to.equal(undefined, 'no new text node created');
69         });
70         it('puts empty text node when breaking at the very beginning', function() {
71             var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
72                 textNode = doc.root.contents()[0].contents()[0];
73             
74             var result = textNode.breakContent({offset:0}),
75                 firstNode = doc.root.contents()[0];
76
77             expect(result.emptyText.sameNode(firstNode.contents()[0]));
78             expect(result.emptyText.getText()).to.equal('');
79         });
80         it('puts empty text node when breaking at the very end', function() {
81             var doc = getDocumentFromXML('<section><div>Alice</div></section>'),
82             textNode = doc.root.contents()[0].contents()[0];
83             
84             var result = textNode.breakContent({offset:5}),
85                 secondNode = doc.root.contents()[1];
86             
87             expect(result.emptyText.sameNode(secondNode.contents()[0]));
88             expect(result.emptyText.getText()).to.equal('');
89         });
90     });
91
92     describe('mergin text with preceding content', function() {
93         it('does nothing if text node parent has no preceding element', function() {
94             var doc = getDocumentFromXML('<section><div><div>some text</div></div></section>'),
95                 text = getTextNode('some text', doc),
96                 spy = sinon.spy();
97
98             doc.on('change', spy);
99             text.mergeContentUp();
100             expect(spy.callCount).to.equal(0);
101         });
102         it('does nothing if text node parent is precedeed by text node', function() {
103             var doc = getDocumentFromXML('<section><div></div>another text<div>some text</div></section>'),
104                 text = getTextNode('some text', doc),
105                 spy = sinon.spy();
106
107             doc.on('change', spy);
108             text.mergeContentUp();
109             expect(spy.callCount).to.equal(0);
110         });
111         it('does nothing if text node is not first child of its parent', function() {
112             var doc = getDocumentFromXML('<section><div></div><div><a></a>some text</div></section>'),
113                 text = getTextNode('some text', doc),
114                 spy = sinon.spy();
115
116             doc.on('change', spy);
117             text.mergeContentUp();
118             expect(spy.callCount).to.equal(0);
119         });
120         it('moves text node and its siblings to the block element preceding text node parent', function() {
121             var doc = getDocumentFromXML('<section><div></div><div>some text<span>is</span> here!</div></section>'),
122                 text = getTextNode('some text', doc);
123             
124             text.mergeContentUp();
125             
126             var contents = doc.root.contents();
127             expect(contents.length).to.equal(1);
128             expect(contents[0].contents().length).to.equal(3);
129             expect(contents[0].contents()[0].getText()).to.equal('some text');
130             expect(contents[0].contents()[1].getTagName()).to.equal('span');
131             expect(contents[0].contents()[2].getText()).to.equal(' here!');
132         });
133     });
134 });
135
136
137 });