X-Git-Url: https://git.mdrn.pl/fnpeditor.git/blobdiff_plain/f4b30e13f370f50a926971df2d23ca423a0c88d8..edaa08a1858371fbdd9665a0220cb1b9732dd2dc:/src/smartxml/smartxml.test.js
diff --git a/src/smartxml/smartxml.test.js b/src/smartxml/smartxml.test.js
index e4e2724..5430278 100644
--- a/src/smartxml/smartxml.test.js
+++ b/src/smartxml/smartxml.test.js
@@ -163,6 +163,12 @@ describe('smartxml', function() {
node.setData({key1: 'value1', key2: 'value2'});
expect(node.getData()).to.eql({key1: 'value1', key2: 'value2'});
});
+
+ it('can remove specific data', function() {
+ node.setData('key', 'value');
+ node.setData('key', undefined);
+ expect(node.getData('key')).to.be.undefined;
+ });
});
describe('Changing node tag', function() {
@@ -219,6 +225,21 @@ describe('smartxml', function() {
expect(event.meta.oldVal).to.equal('value1');
});
});
+
+ describe('Searching for the last child text node', function() {
+ [
+ '
',
+ '',
+ ''
+ ].forEach(function(xml, i) {
+ var example = 'example ' + i;
+ it('returns last child text node ' + example + ')', function() {
+ var doc = getDocumentFromXML(xml),
+ lastTextNode = doc.root.getLastTextNode();
+ expect(lastTextNode.getText()).to.equal('last', example);
+ });
+ });
+ });
});
describe('Basic TextNode properties', function() {
@@ -401,6 +422,18 @@ describe('smartxml', function() {
expect(rootContents[0].getText()).to.equal('Alice a cat');
});
+ it('merges adjacent text nodes resulting from moving an element node in between', function() {
+ var doc = getDocumentFromXML(''),
+ span = doc.root.contents()[2],
+ a = doc.root.contents()[0];
+
+ a.append(span);
+
+ var rootContents = doc.root.contents();
+ expect(rootContents).to.have.length(2, 'one child left');
+ expect(rootContents[1].getText()).to.equal('Alice a cat');
+ });
+
it('inserts node at index', function() {
var doc = getDocumentFromXML(''),
b = doc.root.contents()[1];
@@ -924,7 +957,7 @@ describe('smartxml', function() {
expect(event.meta.node.sameNode(appended)).to.be.true;
});
- it('emits nodeMoved when appending aready existing node', function() {
+ it('emits nodeDetached/nodeAdded events with `move` flag when appending aready existing node', function() {
var node = elementNodeFromXML(''),
a = node.contents()[0],
b = node.contents()[1],
@@ -932,12 +965,17 @@ describe('smartxml', function() {
node.document.on('change', spy);
var appended = a.append(b),
- event = spy.args[0][0];
+ detachedEvent = spy.args[0][0],
+ addedEvent = spy.args[1][0];
+
+ expect(spy.callCount).to.equal(2);
+ expect(detachedEvent.type).to.equal('nodeDetached');
+ expect(detachedEvent.meta.node.sameNode(appended)).to.be.true;
+ expect(detachedEvent.meta.move).to.equal(true, 'move flag set to true for nodeDetachedEvent');
+ expect(addedEvent.type).to.equal('nodeAdded');
+ expect(addedEvent.meta.node.sameNode(appended)).to.be.true;
+ expect(addedEvent.meta.move).to.equal(true, 'move flag set to true for nodeAddedEvent');
- expect(spy.callCount).to.equal(1);
- expect(event.type).to.equal('nodeMoved');
- expect(event.meta.node.sameNode(appended)).to.be.true;
- expect(node.document.root.sameNode(event.meta.parent)).to.equal(true, 'previous parent attached to event meta');
});
it('emits nodeAdded event when prepending new node', function() {
@@ -951,18 +989,24 @@ describe('smartxml', function() {
expect(event.meta.node.sameNode(prepended)).to.be.true;
});
- it('emits nodeMoved when prepending aready existing node', function() {
+ it('emits nodeDetached/nodeAdded events with `move` flag when prepending aready existing node', function() {
var node = elementNodeFromXML(''),
a = node.contents()[0],
b = node.contents()[1],
spy = sinon.spy();
node.document.on('change', spy);
-
+
var prepended = a.prepend(b),
- event = spy.args[0][0];
- expect(spy.callCount).to.equal(1);
- expect(event.type).to.equal('nodeMoved');
- expect(event.meta.node.sameNode(prepended)).to.be.true;
+ detachedEvent = spy.args[0][0],
+ addedEvent = spy.args[1][0];
+
+ expect(spy.callCount).to.equal(2);
+ expect(detachedEvent.type).to.equal('nodeDetached');
+ expect(detachedEvent.meta.node.sameNode(prepended)).to.be.true;
+ expect(detachedEvent.meta.move).to.equal(true, 'move flag set to true for nodeDetachedEvent');
+ expect(addedEvent.type).to.equal('nodeAdded');
+ expect(addedEvent.meta.node.sameNode(prepended)).to.be.true;
+ expect(addedEvent.meta.move).to.equal(true, 'move flag set to true for nodeAddedEvent');
});
it('emits nodeAdded event when inserting node after another', function() {
@@ -976,18 +1020,23 @@ describe('smartxml', function() {
expect(event.meta.node.sameNode(inserted)).to.be.true;
});
- it('emits nodeMoved when inserting aready existing node after another', function() {
+ it('emits nodeDetached/nodeAdded events with `move` flag when inserting aready existing node after another', function() {
var node = elementNodeFromXML(''),
a = node.contents()[0],
b = node.contents()[1],
spy = sinon.spy();
node.document.on('change', spy);
var inserted = b.after(a),
- event = spy.args[0][0];
+ detachedEvent = spy.args[0][0],
+ addedEvent = spy.args[1][0];
- expect(spy.callCount).to.equal(1);
- expect(event.type).to.equal('nodeMoved');
- expect(event.meta.node.sameNode(inserted)).to.be.true;
+ expect(spy.callCount).to.equal(2);
+ expect(detachedEvent.type).to.equal('nodeDetached');
+ expect(detachedEvent.meta.node.sameNode(inserted)).to.be.true;
+ expect(detachedEvent.meta.move).to.equal(true, 'move flag set to true for nodeDetachedEvent');
+ expect(addedEvent.type).to.equal('nodeAdded');
+ expect(addedEvent.meta.node.sameNode(inserted)).to.be.true;
+ expect(addedEvent.meta.move).to.equal(true, 'move flag set to true for nodeAddedEvent');
});
it('emits nodeAdded event when inserting node before another', function() {
@@ -1001,18 +1050,23 @@ describe('smartxml', function() {
expect(event.meta.node.sameNode(inserted)).to.be.true;
});
- it('emits nodeAdded when inserting aready existing node before another', function() {
+ it('emits nodeDetached/nodeAdded events with `move` flag when inserting aready existing node before another', function() {
var node = elementNodeFromXML(''),
a = node.contents()[0],
b = node.contents()[1],
spy = sinon.spy();
node.document.on('change', spy);
var inserted = a.before(b),
- event = spy.args[0][0];
+ detachedEvent = spy.args[0][0],
+ addedEvent = spy.args[1][0];
- expect(spy.callCount).to.equal(1);
- expect(event.type).to.equal('nodeMoved');
- expect(event.meta.node.sameNode(inserted)).to.be.true;
+ expect(spy.callCount).to.equal(2);
+ expect(detachedEvent.type).to.equal('nodeDetached');
+ expect(detachedEvent.meta.node.sameNode(inserted)).to.be.true;
+ expect(detachedEvent.meta.move).to.equal(true, 'move flag set to true for nodeDetachedEvent');
+ expect(addedEvent.type).to.equal('nodeAdded');
+ expect(addedEvent.meta.node.sameNode(inserted)).to.be.true;
+ expect(addedEvent.meta.move).to.equal(true, 'move flag set to true for nodeAddedEvent');
});
it('emits nodeDetached and nodeAdded when replacing root node with another', function() {
@@ -1679,6 +1733,29 @@ describe('smartxml', function() {
doc.redo();
expect(doc.root.getAttr('t')).to.equal('1');
});
+ it('can perform undo of an operation performed after automatic transaction rollback', function() {
+ var doc = getDocumentFromXML(''),
+ extension = {document: {transformations: {
+ throwingTransformation: function() { throw new Error(); }
+ }}};
+
+ doc.registerExtension(extension);
+
+ doc.throwingTransformation();
+
+ doc.transaction(function() {
+ doc.root.setAttr('x', '2');
+ });
+
+ expect(doc.undoStack.length).to.equal(1);
+ expect(doc.root.getAttr('x')).to.equal('2');
+
+ doc.undo();
+
+ expect(doc.undoStack.length).to.equal(0);
+ expect(doc.root.getAttr('x')).to.be.undefined;
+
+ });
});
});