8
0
Просмотр исходного кода

Merge branch 'master' into t/329

Conflicts:
	src/model/document.js
	tests/model/selection.js
Szymon Cofalik 9 лет назад
Родитель
Сommit
c3f84592ad

+ 1 - 3
packages/ckeditor5-engine/src/model/document.js

@@ -161,9 +161,7 @@ export default class Document {
 
 		this.version++;
 
-		if ( operation.delta ) {
-			this.history.addDelta( operation.delta );
-		}
+		this.history.addDelta( operation.delta );
 
 		const batch = operation.delta && operation.delta.batch;
 

+ 4 - 4
packages/ckeditor5-engine/src/view/textproxy.js

@@ -9,12 +9,12 @@
  * TextProxy is a wrapper for substring of {@link engine.view.Text}. Instance of this class is created by
  * {@link engine.view.TreeWalker} when only a part of {@link engine.view.Text} needs to be returned.
  *
- * **Note:** TextProxy instances are created on the fly basing on the current state of parent {@link engine.view.Text}.
- * Because of this it is highly unrecommended to store references to TextProxy instances because they might get
- * invalidated due to operations on Document. Also TextProxy is not a {@link engine.view.Node} so it can not be
+ * **Note:** `TextProxy` instances are created on the fly basing on the current state of parent {@link engine.view.Text}.
+ * Because of this it is highly unrecommended to store references to `TextProxy` instances because they might get
+ * invalidated due to operations on the document. Also, `TextProxy` is not a {@link engine.view.Node} so it cannot be
  * inserted as a child of {@link engine.view.Element}.
  *
- * You should never create an instance of this class by your own. Instead, use string literals or {@link engine.model.Text}.
+ * You should never create an instance of this class by your own.
  *
  * @memberOf engine.view
  */

+ 10 - 11
packages/ckeditor5-engine/src/view/treewalker.js

@@ -88,7 +88,7 @@ export default class TreeWalker {
 
 		/**
 		 * Flag indicating whether all characters from {@link engine.view.Text} should be returned as one
-		 * {@link engine.view.Text} or one by one as {@link.engine.TextProxy}.
+		 * {@link engine.view.Text} or one by one as {@link engine.view.TextProxy}.
 		 *
 		 * @readonly
 		 * @member {Boolean} engine.view.TreeWalker#singleCharacters
@@ -105,10 +105,9 @@ export default class TreeWalker {
 		this.shallow = !!options.shallow;
 
 		/**
-		 * Flag indicating whether iterator should ignore `ELEMENT_END` tags. If the option is true walker will not
-		 * return a parent node of the start position. If this option is `true` each {@link engine.view.Element} will
-		 * be returned once, while if the option is `false` they might be returned twice:
-		 * for `'ELEMENT_START'` and `'ELEMENT_END'`.
+		 * Flag indicating whether iterator should ignore `ELEMENT_END` tags. If set to `true`, walker will not
+		 * return a parent node of the start position. Each {@link engine.view.Element} will be returned once.
+		 * When set to `false` each element might be returned twice: for `'ELEMENT_START'` and `'ELEMENT_END'`.
 		 *
 		 * @readonly
 		 * @member {Boolean} engine.view.TreeWalker#ignoreElementEnd
@@ -116,18 +115,18 @@ export default class TreeWalker {
 		this.ignoreElementEnd = !!options.ignoreElementEnd;
 
 		/**
-		 * Start boundary cached for optimization purposes.
+		 * Start boundary parent.
 		 *
 		 * @private
-		 * @member {engine.view.Element} engine.view.TreeWalker#_boundaryStartParent
+		 * @member {engine.view.Node} engine.view.TreeWalker#_boundaryStartParent
 		 */
 		this._boundaryStartParent = this.boundaries ? this.boundaries.start.parent : null;
 
 		/**
-		 * End boundary cached for optimization purposes.
+		 * End boundary parent.
 		 *
 		 * @private
-		 * @member {engine.view.Element} engine.view.TreeWalker#_boundaryEndParent
+		 * @member {engine.view.Node} engine.view.TreeWalker#_boundaryEndParent
 		 */
 		this._boundaryEndParent = this.boundaries ? this.boundaries.end.parent : null;
 	}
@@ -158,7 +157,7 @@ export default class TreeWalker {
 	 *
 	 * @private
 	 * @returns {Object}
-	 * @returns {Boolean} return.done True if iterator is done.
+	 * @returns {Boolean} return.done `true` if iterator is done, `false` otherwise.
 	 * @returns {engine.view.TreeWalkerValue} return.value Information about taken step.
 	 */
 	_next() {
@@ -279,7 +278,7 @@ export default class TreeWalker {
 
 		// Text {@link engine.view.Text} element is a specific parent because contains string instead of child nodes.
 		if ( parent instanceof Text ) {
-			node = parent._data[ position.offset - 1 ];
+			node = parent.data[ position.offset - 1 ];
 		} else {
 			node = parent.getChild( position.offset - 1 );
 		}

+ 3 - 2
packages/ckeditor5-engine/tests/conversion/modelconversiondispatcher.js

@@ -14,6 +14,7 @@ import ModelElement from '/ckeditor5/engine/model/element.js';
 import ModelRange from '/ckeditor5/engine/model/range.js';
 import ModelPosition from '/ckeditor5/engine/model/position.js';
 import RemoveOperation from '/ckeditor5/engine/model/operation/removeoperation.js';
+import { wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'ModelConversionDispatcher', () => {
 	let dispatcher, doc, root;
@@ -75,7 +76,7 @@ describe( 'ModelConversionDispatcher', () => {
 			const removeOperation = new RemoveOperation( imagePos, 1, 0 );
 
 			// Let's apply remove operation so reinsert operation won't break.
-			doc.applyOperation( removeOperation );
+			doc.applyOperation( wrapInDelta( removeOperation ) );
 
 			const cbInsertText = sinon.spy();
 			const cbInsertImage = sinon.spy();
@@ -85,7 +86,7 @@ describe( 'ModelConversionDispatcher', () => {
 			dispatcher.on( 'insert:image', cbInsertImage );
 			dispatcher.on( 'addAttribute:key:image', cbAddAttribute );
 
-			doc.applyOperation( removeOperation.getReversed() );
+			doc.applyOperation( wrapInDelta( removeOperation.getReversed() ) );
 
 			expect( cbInsertImage.called ).to.be.true;
 			expect( cbAddAttribute.called ).to.be.true;

+ 16 - 0
packages/ckeditor5-engine/tests/model/_utils/utils.js

@@ -6,6 +6,7 @@
 'use strict';
 
 import TreeWalker from '/ckeditor5/engine/model/treewalker.js';
+import Delta from '/ckeditor5/engine/model/delta/delta.js';
 
 /**
  * Returns tree structure as a simplified string. Elements are uppercase and characters are lowercase.
@@ -43,3 +44,18 @@ export function getNodesAndText( range ) {
 export function jsonParseStringify( object ) {
 	return JSON.parse( JSON.stringify( object ) );
 }
+
+/**
+ * Adds given {@link engine.model.operation.Operation operation} to a newly created {@link engine.model.delta.Delta delta}
+ * and returns it back. Every operation, when applied, have to be added to a delta. This helper function is useful in those
+ * tests which focus on operations, not deltas.
+ *
+ * @param {engine.model.operation.Operation} operation Operation to wrap
+ * @returns {engine.model.operation.Operation}
+ */
+export function wrapInDelta( operation ) {
+	const delta = new Delta();
+	delta.addOperation( operation );
+
+	return operation;
+}

+ 14 - 13
packages/ckeditor5-engine/tests/model/document/change-event.js

@@ -15,6 +15,7 @@ import AttributeOperation from '/ckeditor5/engine/model/operation/attributeopera
 import InsertOperation from '/ckeditor5/engine/model/operation/insertoperation.js';
 import MoveOperation from '/ckeditor5/engine/model/operation/moveoperation.js';
 import RemoveOperation from '/ckeditor5/engine/model/operation/removeoperation.js';
+import { wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'Document change event', () => {
 	let doc, root, graveyard, types, changes;
@@ -34,7 +35,7 @@ describe( 'Document change event', () => {
 	} );
 
 	it( 'should be fired when text is inserted', () => {
-		doc.applyOperation( new InsertOperation( new Position( root, [ 0 ] ), 'foo', doc.version ) );
+		doc.applyOperation( wrapInDelta( new InsertOperation( new Position( root, [ 0 ] ), 'foo', doc.version ) ) );
 
 		expect( changes ).to.have.length( 1 );
 		expect( types[ 0 ] ).to.equal( 'insert' );
@@ -43,7 +44,7 @@ describe( 'Document change event', () => {
 
 	it( 'should be fired when element is inserted', () => {
 		const element = new Element( 'p' );
-		doc.applyOperation( new InsertOperation( new Position( root, [ 0 ] ), element, doc.version ) );
+		doc.applyOperation( wrapInDelta( new InsertOperation( new Position( root, [ 0 ] ), element, doc.version ) ) );
 
 		expect( changes ).to.have.length( 1 );
 		expect( types[ 0 ] ).to.equal( 'insert' );
@@ -52,7 +53,7 @@ describe( 'Document change event', () => {
 
 	it( 'should be fired when nodes are inserted', () => {
 		const element = new Element( 'p' );
-		doc.applyOperation( new InsertOperation( new Position( root, [ 0 ] ), [ element, 'foo' ], doc.version ) );
+		doc.applyOperation( wrapInDelta( new InsertOperation( new Position( root, [ 0 ] ), [ element, 'foo' ], doc.version ) ) );
 
 		expect( changes ).to.have.length( 1 );
 		expect( types[ 0 ] ).to.equal( 'insert' );
@@ -67,14 +68,14 @@ describe( 'Document change event', () => {
 
 		root.insertChildren( 0, [ p1, p2 ] );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new MoveOperation(
 				new Position( root, [ 0, 0 ] ),
 				3,
 				new Position( root, [ 1, 0 ] ),
 				doc.version
 			)
-		);
+		) );
 
 		expect( changes ).to.have.length( 1 );
 		expect( types[ 0 ] ).to.equal( 'move' );
@@ -86,10 +87,10 @@ describe( 'Document change event', () => {
 		root.insertChildren( 0, 'foo' );
 
 		const removeOperation = new RemoveOperation( new Position( root, [ 0 ] ), 3, doc.version );
-		doc.applyOperation( removeOperation );
+		doc.applyOperation( wrapInDelta( removeOperation ) );
 
 		const reinsertOperation = removeOperation.getReversed();
-		doc.applyOperation( reinsertOperation );
+		doc.applyOperation( wrapInDelta( reinsertOperation ) );
 
 		expect( changes ).to.have.length( 2 );
 
@@ -107,7 +108,7 @@ describe( 'Document change event', () => {
 	it( 'should be fired when attribute is inserted', () => {
 		root.insertChildren( 0, 'foo' );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				Range.createFromParentsAndOffsets( root, 0, root, 3 ),
 				'key',
@@ -115,7 +116,7 @@ describe( 'Document change event', () => {
 				'new',
 				doc.version
 			)
-		);
+		) );
 
 		expect( changes ).to.have.length( 1 );
 		expect( types[ 0 ] ).to.equal( 'addAttribute' );
@@ -129,7 +130,7 @@ describe( 'Document change event', () => {
 		const elem = new Element( 'p', { key: 'old' } );
 		root.insertChildren( 0, elem );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				Range.createFromParentsAndOffsets( root, 0, elem, 0 ),
 				'key',
@@ -137,7 +138,7 @@ describe( 'Document change event', () => {
 				null,
 				doc.version
 			)
-		);
+		) );
 
 		expect( changes ).to.have.length( 1 );
 		expect( types[ 0 ] ).to.equal( 'removeAttribute' );
@@ -151,7 +152,7 @@ describe( 'Document change event', () => {
 		const elem = new Element( 'p', { key: 'old' } );
 		root.insertChildren( 0, elem );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				Range.createFromParentsAndOffsets( root, 0, elem, 0 ),
 				'key',
@@ -159,7 +160,7 @@ describe( 'Document change event', () => {
 				'new',
 				doc.version
 			)
-		);
+		) );
 
 		expect( changes ).to.have.length( 1 );
 		expect( types[ 0 ] ).to.equal( 'changeAttribute' );

+ 27 - 27
packages/ckeditor5-engine/tests/model/operation/attributeoperation.js

@@ -14,7 +14,7 @@ import Position from '/ckeditor5/engine/model/position.js';
 import Range from '/ckeditor5/engine/model/range.js';
 import Text from '/ckeditor5/engine/model/text.js';
 import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
-import { jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'AttributeOperation', () => {
 	let doc, root;
@@ -65,7 +65,7 @@ describe( 'AttributeOperation', () => {
 	it( 'should insert attribute to the set of nodes', () => {
 		root.insertChildren( 0, 'bar' );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 0 ] ), new Position( root, [ 2 ] ) ),
 				'isNew',
@@ -73,7 +73,7 @@ describe( 'AttributeOperation', () => {
 				true,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 3 );
@@ -85,7 +85,7 @@ describe( 'AttributeOperation', () => {
 	it( 'should add attribute to the existing attributes', () => {
 		root.insertChildren( 0, new Text( 'x', { foo: true, bar: true } ) );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
 				'isNew',
@@ -93,7 +93,7 @@ describe( 'AttributeOperation', () => {
 				true,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 1 );
@@ -106,7 +106,7 @@ describe( 'AttributeOperation', () => {
 	it( 'should change attribute to the set of nodes', () => {
 		root.insertChildren( 0, new Text( 'bar', { isNew: false } ) );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 0 ] ), new Position( root, [ 2 ] ) ),
 				'isNew',
@@ -114,7 +114,7 @@ describe( 'AttributeOperation', () => {
 				true,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 3 );
@@ -129,7 +129,7 @@ describe( 'AttributeOperation', () => {
 	it( 'should change attribute in the middle of existing attributes', () => {
 		root.insertChildren( 0, new Text( 'x', { foo: true, x: 1, bar: true } ) );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
 				'x',
@@ -137,7 +137,7 @@ describe( 'AttributeOperation', () => {
 				2,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 1 );
@@ -150,7 +150,7 @@ describe( 'AttributeOperation', () => {
 	it( 'should remove attribute', () => {
 		root.insertChildren( 0, new Text( 'x', { foo: true, x: true, bar: true } ) );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
 				'x',
@@ -158,7 +158,7 @@ describe( 'AttributeOperation', () => {
 				null,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 1 );
@@ -193,8 +193,8 @@ describe( 'AttributeOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( operation ) );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 3 );
@@ -209,7 +209,7 @@ describe( 'AttributeOperation', () => {
 
 		root.insertChildren( 0, [ eleA, eleB ] );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 0, 2 ] ), new Position( root, [ 1, 2 ] ) ),
 				'foo',
@@ -217,7 +217,7 @@ describe( 'AttributeOperation', () => {
 				true,
 				doc.version
 			)
-		);
+		) );
 
 		expect( root.getChild( 0 ).hasAttribute( 'foo' ) ).to.be.false;
 	} );
@@ -230,7 +230,7 @@ describe( 'AttributeOperation', () => {
 
 		root.insertChildren( 0, [ eleA, eleB ] );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 0, 3 ] ), new Position( root, [ 1, 0 ] ) ),
 				'foo',
@@ -238,7 +238,7 @@ describe( 'AttributeOperation', () => {
 				null,
 				doc.version
 			)
-		);
+		) );
 
 		expect( root.getChild( 0 ).hasAttribute( 'foo' ) ).to.be.true;
 	} );
@@ -256,8 +256,8 @@ describe( 'AttributeOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( operation ) );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 3 );
@@ -282,8 +282,8 @@ describe( 'AttributeOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( operation ) );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 3 );
@@ -299,7 +299,7 @@ describe( 'AttributeOperation', () => {
 		root.insertChildren( 0, 'x' );
 
 		expect( () => {
-			doc.applyOperation(
+			doc.applyOperation( wrapInDelta(
 				new AttributeOperation(
 					new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
 					'foo',
@@ -307,7 +307,7 @@ describe( 'AttributeOperation', () => {
 					null,
 					doc.version
 				)
-			);
+			) );
 		} ).to.throw( CKEditorError, /operation-attribute-no-attr-to-remove/ );
 	} );
 
@@ -315,7 +315,7 @@ describe( 'AttributeOperation', () => {
 		root.insertChildren( 0, new Text( 'x', { x: 1 } ) );
 
 		expect( () => {
-			doc.applyOperation(
+			doc.applyOperation( wrapInDelta(
 				new AttributeOperation(
 					new Range( new Position( root, [ 0 ] ), new Position( root, [ 1 ] ) ),
 					'x',
@@ -323,7 +323,7 @@ describe( 'AttributeOperation', () => {
 					2,
 					doc.version
 				)
-			);
+			) );
 		} ).to.throw( CKEditorError, /operation-attribute-attr-exists/ );
 	} );
 
@@ -353,14 +353,14 @@ describe( 'AttributeOperation', () => {
 		root.insertChildren( 0, new Text( 'abc', attrA ) );
 		root.insertChildren( 3, new Text( 'xyz', attrB ) );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new AttributeOperation(
 				new Range( new Position( root, [ 1 ] ), new Position( root, [ 3 ] ) ),
 				'foo',
 				'a',
 				'b',
 				doc.version
-			)
+			) )
 		);
 
 		expect( root._children._nodes[ 0 ].text ).to.equal( 'a' );

+ 13 - 13
packages/ckeditor5-engine/tests/model/operation/insertoperation.js

@@ -14,7 +14,7 @@ import InsertOperation from '/ckeditor5/engine/model/operation/insertoperation.j
 import RemoveOperation from '/ckeditor5/engine/model/operation/removeoperation.js';
 import Position from '/ckeditor5/engine/model/position.js';
 import Text from '/ckeditor5/engine/model/text.js';
-import { jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'InsertOperation', () => {
 	let doc, root;
@@ -35,13 +35,13 @@ describe( 'InsertOperation', () => {
 	} );
 
 	it( 'should insert node', () => {
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new InsertOperation(
 				new Position( root, [ 0 ] ),
 				new Text( 'x' ),
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 1 );
@@ -49,13 +49,13 @@ describe( 'InsertOperation', () => {
 	} );
 
 	it( 'should insert set of nodes', () => {
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new InsertOperation(
 				new Position( root, [ 0 ] ),
 				'bar',
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 3 );
@@ -67,13 +67,13 @@ describe( 'InsertOperation', () => {
 	it( 'should insert between existing nodes', () => {
 		root.insertChildren( 0, 'xy' );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new InsertOperation(
 				new Position( root, [ 1 ] ),
 				'bar',
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 5 );
@@ -85,13 +85,13 @@ describe( 'InsertOperation', () => {
 	} );
 
 	it( 'should insert text', () => {
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new InsertOperation(
 				new Position( root, [ 0 ] ),
 				[ 'foo', new Text( 'x' ), 'bar' ],
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 7 );
@@ -129,11 +129,11 @@ describe( 'InsertOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
+		doc.applyOperation( wrapInDelta( operation ) );
 
 		expect( doc.version ).to.equal( 1 );
 
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 0 );
@@ -148,11 +148,11 @@ describe( 'InsertOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
+		doc.applyOperation( wrapInDelta( operation ) );
 
 		expect( doc.version ).to.equal( 1 );
 
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 0 );

+ 15 - 15
packages/ckeditor5-engine/tests/model/operation/moveoperation.js

@@ -12,7 +12,7 @@ import MoveOperation from '/ckeditor5/engine/model/operation/moveoperation.js';
 import Position from '/ckeditor5/engine/model/position.js';
 import Element from '/ckeditor5/engine/model/element.js';
 import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
-import { jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'MoveOperation', () => {
 	let doc, root;
@@ -50,14 +50,14 @@ describe( 'MoveOperation', () => {
 
 		root.insertChildren( 0, [ p1, p2 ] );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new MoveOperation(
 				new Position( root, [ 0, 0 ] ),
 				1,
 				new Position( root, [ 1, 0 ] ),
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 2 );
@@ -71,14 +71,14 @@ describe( 'MoveOperation', () => {
 	it( 'should move position of children in one node backward', () => {
 		root.insertChildren( 0, 'xbarx' );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new MoveOperation(
 				new Position( root, [ 2 ] ),
 				2,
 				new Position( root, [ 1 ] ),
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 5 );
@@ -92,14 +92,14 @@ describe( 'MoveOperation', () => {
 	it( 'should move position of children in one node forward', () => {
 		root.insertChildren( 0, 'xbarx' );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new MoveOperation(
 				new Position( root, [ 1 ] ),
 				2,
 				new Position( root, [ 4 ] ),
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 5 );
@@ -143,7 +143,7 @@ describe( 'MoveOperation', () => {
 			doc.version
 		);
 
-		doc.applyOperation( operation );
+		doc.applyOperation( wrapInDelta( operation ) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 2 );
@@ -151,7 +151,7 @@ describe( 'MoveOperation', () => {
 		expect( p2.getChildCount() ).to.equal( 1 );
 		expect( p2.getChild( 0 ).name ).to.equal( 'x' );
 
-		doc.applyOperation( operation.getReversed() );
+		doc.applyOperation( wrapInDelta( operation.getReversed() ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 2 );
@@ -170,7 +170,7 @@ describe( 'MoveOperation', () => {
 			doc.version
 		);
 
-		expect( () => doc.applyOperation( operation ) ).to.throw( CKEditorError, /operation-move-nodes-do-not-exist/ );
+		expect( () => doc.applyOperation( wrapInDelta( operation ) ) ).to.throw( CKEditorError, /operation-move-nodes-do-not-exist/ );
 	} );
 
 	it( 'should throw an error if target or source parent-element specified by position does not exist', () => {
@@ -187,7 +187,7 @@ describe( 'MoveOperation', () => {
 
 		root.removeChildren( 2, 1 );
 
-		expect( () => doc.applyOperation( operation ) ).to.throw( CKEditorError, /operation-move-position-invalid/ );
+		expect( () => doc.applyOperation( wrapInDelta( operation ) ) ).to.throw( CKEditorError, /operation-move-position-invalid/ );
 	} );
 
 	it( 'should throw an error if operation tries to move a range between the beginning and the end of that range', () => {
@@ -200,7 +200,7 @@ describe( 'MoveOperation', () => {
 			doc.version
 		);
 
-		expect( () => doc.applyOperation( operation ) ).to.throw( CKEditorError, /operation-move-range-into-itself/ );
+		expect( () => doc.applyOperation( wrapInDelta( operation ) ) ).to.throw( CKEditorError, /operation-move-range-into-itself/ );
 	} );
 
 	it( 'should throw an error if operation tries to move a range into a sub-tree of a node that is in that range', () => {
@@ -214,7 +214,7 @@ describe( 'MoveOperation', () => {
 			doc.version
 		);
 
-		expect( () => doc.applyOperation( operation ) ).to.throw( CKEditorError, /operation-move-node-into-itself/ );
+		expect( () => doc.applyOperation( wrapInDelta( operation ) ) ).to.throw( CKEditorError, /operation-move-node-into-itself/ );
 	} );
 
 	it( 'should not throw an error if operation move a range into a sibling', () => {
@@ -230,7 +230,7 @@ describe( 'MoveOperation', () => {
 
 		expect(
 			() => {
-				doc.applyOperation( operation );
+				doc.applyOperation( wrapInDelta( operation ) );
 			}
 		).not.to.throw();
 
@@ -253,7 +253,7 @@ describe( 'MoveOperation', () => {
 
 		expect(
 			() => {
-				doc.applyOperation( operation );
+				doc.applyOperation( wrapInDelta( operation ) );
 			}
 		).not.to.throw();
 	} );

+ 2 - 2
packages/ckeditor5-engine/tests/model/operation/nooperation.js

@@ -9,7 +9,7 @@
 
 import Document from '/ckeditor5/engine/model/document.js';
 import NoOperation from '/ckeditor5/engine/model/operation/nooperation.js';
-import { jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'NoOperation', () => {
 	let noop, doc, root;
@@ -21,7 +21,7 @@ describe( 'NoOperation', () => {
 	} );
 
 	it( 'should not throw an error when applied', () => {
-		expect( () => doc.applyOperation( noop ) ).to.not.throw( Error );
+		expect( () => doc.applyOperation( wrapInDelta( noop ) ) ).to.not.throw( Error );
 	} );
 
 	it( 'should create a NoOperation as a reverse', () => {

+ 3 - 3
packages/ckeditor5-engine/tests/model/operation/reinsertoperation.js

@@ -13,7 +13,7 @@ import RemoveOperation from '/ckeditor5/engine/model/operation/removeoperation.j
 import MoveOperation from '/ckeditor5/engine/model/operation/moveoperation.js';
 import Position from '/ckeditor5/engine/model/position.js';
 import Element from '/ckeditor5/engine/model/element.js';
-import { jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'ReinsertOperation', () => {
 	let doc, root, graveyard, operation, graveyardPosition, rootPosition;
@@ -81,13 +81,13 @@ describe( 'ReinsertOperation', () => {
 		element.insertChildren( 0, 'xx' );
 		graveyard.insertChildren( 0, element );
 
-		doc.applyOperation( operation );
+		doc.applyOperation( wrapInDelta( operation ) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 2 );
 		expect( element.getChildCount() ).to.equal( 0 );
 
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 0 );

+ 11 - 11
packages/ckeditor5-engine/tests/model/operation/removeoperation.js

@@ -12,7 +12,7 @@ import ReinsertOperation from '/ckeditor5/engine/model/operation/reinsertoperati
 import RemoveOperation from '/ckeditor5/engine/model/operation/removeoperation.js';
 import MoveOperation from '/ckeditor5/engine/model/operation/moveoperation.js';
 import Position from '/ckeditor5/engine/model/position.js';
-import { jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'RemoveOperation', () => {
 	let doc, root, graveyard;
@@ -56,13 +56,13 @@ describe( 'RemoveOperation', () => {
 	it( 'should remove set of nodes and append them to holder element in graveyard root', () => {
 		root.insertChildren( 0, 'fozbar' );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new RemoveOperation(
 				new Position( root, [ 2 ] ),
 				2,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 4 );
@@ -76,29 +76,29 @@ describe( 'RemoveOperation', () => {
 	it( 'should create new holder element for each remove operation', () => {
 		root.insertChildren( 0, 'fozbar' );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new RemoveOperation(
 				new Position( root, [ 0 ] ),
 				1,
 				doc.version
 			)
-		);
+		) );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new RemoveOperation(
 				new Position( root, [ 0 ] ),
 				1,
 				doc.version
 			)
-		);
+		) );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new RemoveOperation(
 				new Position( root, [ 0 ] ),
 				1,
 				doc.version
 			)
-		);
+		) );
 
 		expect( graveyard.getChildCount() ).to.equal( 3 );
 		expect( graveyard.getChild( 0 ).getChild( 0 ).character ).to.equal( 'f' );
@@ -137,12 +137,12 @@ describe( 'RemoveOperation', () => {
 
 		root.insertChildren( 0, 'bar' );
 
-		doc.applyOperation( operation );
+		doc.applyOperation( wrapInDelta( operation ) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getChildCount() ).to.equal( 0 );
 
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getChildCount() ).to.equal( 3 );

+ 17 - 17
packages/ckeditor5-engine/tests/model/operation/rootattributeoperation.js

@@ -10,7 +10,7 @@
 import Document from '/ckeditor5/engine/model/document.js';
 import RootAttributeOperation from '/ckeditor5/engine/model/operation/rootattributeoperation.js';
 import CKEditorError from '/ckeditor5/utils/ckeditorerror.js';
-import { jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 
 describe( 'RootAttributeOperation', () => {
 	let doc, root;
@@ -59,7 +59,7 @@ describe( 'RootAttributeOperation', () => {
 	} );
 
 	it( 'should add attribute on the root element', () => {
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new RootAttributeOperation(
 				root,
 				'isNew',
@@ -67,7 +67,7 @@ describe( 'RootAttributeOperation', () => {
 				true,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.hasAttribute( 'isNew' ) ).to.be.true;
@@ -76,7 +76,7 @@ describe( 'RootAttributeOperation', () => {
 	it( 'should change attribute on the root element', () => {
 		root.setAttribute( 'isNew', false );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new RootAttributeOperation(
 				root,
 				'isNew',
@@ -84,7 +84,7 @@ describe( 'RootAttributeOperation', () => {
 				true,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.getAttribute( 'isNew' ) ).to.be.true;
@@ -93,7 +93,7 @@ describe( 'RootAttributeOperation', () => {
 	it( 'should remove attribute from the root element', () => {
 		root.setAttribute( 'x', true );
 
-		doc.applyOperation(
+		doc.applyOperation( wrapInDelta(
 			new RootAttributeOperation(
 				root,
 				'x',
@@ -101,7 +101,7 @@ describe( 'RootAttributeOperation', () => {
 				null,
 				doc.version
 			)
-		);
+		) );
 
 		expect( doc.version ).to.equal( 1 );
 		expect( root.hasAttribute( 'x' ) ).to.be.false;
@@ -130,8 +130,8 @@ describe( 'RootAttributeOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( operation ) );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.hasAttribute( 'x' ) ).to.be.false;
@@ -150,8 +150,8 @@ describe( 'RootAttributeOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( operation ) );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getAttribute( 'isNew' ) ).to.be.false;
@@ -170,8 +170,8 @@ describe( 'RootAttributeOperation', () => {
 
 		let reverse = operation.getReversed();
 
-		doc.applyOperation( operation );
-		doc.applyOperation( reverse );
+		doc.applyOperation( wrapInDelta( operation ) );
+		doc.applyOperation( wrapInDelta( reverse ) );
 
 		expect( doc.version ).to.equal( 2 );
 		expect( root.getAttribute( 'foo' ) ).to.be.true;
@@ -179,7 +179,7 @@ describe( 'RootAttributeOperation', () => {
 
 	it( 'should throw an error when one try to remove and the attribute does not exists', () => {
 		expect( () => {
-			doc.applyOperation(
+			doc.applyOperation( wrapInDelta(
 				new RootAttributeOperation(
 					root,
 					'foo',
@@ -187,7 +187,7 @@ describe( 'RootAttributeOperation', () => {
 					null,
 					doc.version
 				)
-			);
+			) );
 		} ).to.throw( CKEditorError, /operation-rootattribute-no-attr-to-remove/ );
 	} );
 
@@ -195,7 +195,7 @@ describe( 'RootAttributeOperation', () => {
 		root.setAttribute( 'x', 1 );
 
 		expect( () => {
-			doc.applyOperation(
+			doc.applyOperation( wrapInDelta(
 				new RootAttributeOperation(
 					root,
 					'x',
@@ -203,7 +203,7 @@ describe( 'RootAttributeOperation', () => {
 					2,
 					doc.version
 				)
-			);
+			) );
 		} ).to.throw( CKEditorError, /operation-rootattribute-attr-exists/ );
 	} );
 

+ 13 - 1
packages/ckeditor5-engine/tests/model/utils-tests/utils.js

@@ -5,10 +5,12 @@
 
 'use strict';
 
-import { getNodesAndText, jsonParseStringify } from '/tests/engine/model/_utils/utils.js';
+import { getNodesAndText, jsonParseStringify, wrapInDelta } from '/tests/engine/model/_utils/utils.js';
 import Document from '/ckeditor5/engine/model/document.js';
 import Range from '/ckeditor5/engine/model/range.js';
 import Element from '/ckeditor5/engine/model/element.js';
+import Operation from '/ckeditor5/engine/model/operation/operation.js';
+import Delta from '/ckeditor5/engine/model/delta/delta.js';
 
 describe( 'getNodesAndText', () => {
 	let doc, root, div, p;
@@ -43,3 +45,13 @@ describe( 'jsonParseStringify', () => {
 		expect( fooJsoned ).to.deep.equal( { ra: { bar: 'bar' } } );
 	} );
 } );
+
+describe( 'wrapInDelta', () => {
+	it( 'should return given operation wrapped in a delta', () => {
+		const op = new Operation( 0 );
+		const wrapped = wrapInDelta( op );
+
+		expect( wrapped ).to.equal( op );
+		expect( wrapped.delta ).to.be.instanceof( Delta );
+	} );
+} );