8
0
Prechádzať zdrojové kódy

Added tests for ViewConsumable.revert method.

Szymon Kupś 9 rokov pred
rodič
commit
fd3906735a

+ 7 - 9
packages/ckeditor5-engine/src/treecontroller/viewconsumable.js

@@ -69,15 +69,9 @@ class ViewElementConsumables {
 		if ( elementOnly ) {
 			if ( this._canConsumeElement === false ) {
 				this._canConsumeElement = true;
-
-				return false;
-			}
-
-			if ( this._canConsumeElement === true ) {
-				return false;
 			}
 
-			return null;
+			return;
 		}
 
 		for ( let type in consumables ) {
@@ -140,10 +134,14 @@ class ViewElementConsumables {
 		const consumables = this._consumables[ type ];
 
 		for ( let name of items ) {
+			if ( type === 'attribute' && ( name === 'class' || name === 'style' ) ) {
+				// TODO: comment error
+				throw new CKEditorError( 'viewconsumable-invalid-attribute: Classes and styles should be handled separately.' );
+			}
 			const value = consumables.get( name );
 
 			if ( value === false ) {
-				consumables.get( name ).set( true );
+				consumables.set( name, true );
 			}
 		}
 	}
@@ -277,4 +275,4 @@ function getElement( description ) {
 	 * @error viewconsumable-element-missing
 	 */
 	throw new CKEditorError( 'viewconsumable-element-missing: Tree view Element is not provided.' );
-}
+}

+ 112 - 3
packages/ckeditor5-engine/tests/treecontroller/viewconsumable.js

@@ -7,8 +7,8 @@
 
 'use strict';
 
-import ViewElement from '/ckeditor5/core/treeview/element.js';
-import ViewConsumable from '/ckeditor5/core/treecontroller/viewconsumable.js';
+import ViewElement from '/ckeditor5/engine/treeview/element.js';
+import ViewConsumable from '/ckeditor5/engine/treecontroller/viewconsumable.js';
 
 describe( 'ViewConsumable', () => {
 	let viewConsumable;
@@ -216,6 +216,13 @@ describe( 'ViewConsumable', () => {
 			expect( viewConsumable.consume( el ) ).to.be.false;
 		} );
 
+		it( 'should not consume element already consumed', () => {
+			viewConsumable.add( el );
+
+			expect( viewConsumable.consume( el ) ).to.be.true;
+			expect( viewConsumable.consume( el ) ).to.be.false;
+		} );
+
 		it( 'should consume attributes, classes and styles', () => {
 			viewConsumable.add( { element: el, class: 'foobar', attribute: 'href', style: 'color' } );
 
@@ -334,4 +341,106 @@ describe( 'ViewConsumable', () => {
 			} ).to.throw( 'viewconsumable-invalid-attribute' );
 		} );
 	} );
-} );
+
+	describe( 'revert', () => {
+		it( 'should revert single element', () => {
+			viewConsumable.add( el );
+			viewConsumable.consume( el );
+			expect( viewConsumable.test( el ) ).to.be.false;
+			viewConsumable.revert( el );
+			expect( viewConsumable.test( el ) ).to.be.true;
+		} );
+
+		it( 'should not revert element that was never added', () => {
+			viewConsumable.revert( el );
+			expect( viewConsumable.test( el ) ).to.be.null;
+		} );
+
+		it( 'should do nothing on not consumed element', () => {
+			viewConsumable.add( el );
+			viewConsumable.revert( el );
+			expect( viewConsumable.test( el ) ).to.be.true;
+		} );
+
+		it( 'should revert classes, attributes and styles', () => {
+			viewConsumable.add( { element: el, class: 'foobar', style: 'color', attribute: 'name' } );
+			viewConsumable.consume( { element: el, class: 'foobar', style: 'color', attribute: 'name' } );
+
+			viewConsumable.revert( { element: el, class: 'foobar' } );
+			viewConsumable.revert( { element: el, style: 'color' } );
+			viewConsumable.revert( { element: el, attribute: 'name' } );
+
+			expect( viewConsumable.test( { element: el, class: 'foobar', style: 'color', attribute: 'name' } ) ).to.be.true;
+		} );
+
+		it( 'should revert multiple classes, attributes and styles in one call #1', () => {
+			viewConsumable.add( {
+				element: el,
+				class: 'foobar',
+				style: 'color',
+				attribute: 'name'
+			} );
+			viewConsumable.consume( { element: el, class: 'foobar', style: 'color', attribute: 'name' } );
+			viewConsumable.revert( { element: el, class: 'foobar', style: 'color', attribute: 'name' } );
+
+			expect( viewConsumable.test( { element: el, class: 'foobar', style: 'color', attribute: 'name' } ) ).to.be.true;
+		} );
+
+		it( 'should revert multiple classes, attributes and styles in one call #2', () => {
+			const description = {
+				element: el,
+				class: [ 'foobar', 'baz' ],
+				style: [ 'color', 'position' ],
+				attribute: [ 'name', 'href' ]
+			};
+
+			viewConsumable.add( description );
+			viewConsumable.consume( description );
+			viewConsumable.revert( description );
+
+			expect( viewConsumable.test( description ) ).to.be.true;
+		} );
+
+		it( 'should not revert non consumable items', () => {
+			viewConsumable.add( { element: el, class: 'foobar' } );
+			viewConsumable.consume( { element: el, class: 'foobar' }  );
+			viewConsumable.revert( { element: el, class: 'foobar', attribute: 'name' } );
+
+			expect( viewConsumable.test( { element: el, class: 'foobar' } ) ).to.be.true;
+			expect( viewConsumable.test( { element: el, attribute: 'name' } ) ).to.be.null;
+		} );
+
+		it( 'should allow to use additional parameters in one call', () => {
+			const el2 = new ViewElement( 'p' );
+			viewConsumable.add( el, el2 );
+			expect( viewConsumable.consume( el, el2 ) ).to.be.true;
+			viewConsumable.revert( el, el2 );
+
+			expect( viewConsumable.test( el, el2 ) ).to.be.true;
+		} );
+
+		it( 'should throw an error when element is not provided', () => {
+			expect( () => {
+				viewConsumable.revert( { style: 'color' } );
+			} ).to.throw( 'viewconsumable-element-missing' );
+		} );
+
+		it( 'should throw if class attribute is provided', () => {
+			viewConsumable.add( { element: el, class: 'foobar' } );
+			viewConsumable.consume( { element: el, class: 'foobar' } );
+
+			expect( () => {
+				viewConsumable.revert( { element: el, attribute: 'class' } );
+			} ).to.throw( 'viewconsumable-invalid-attribute' );
+		} );
+
+		it( 'should throw if style attribute is provided', () => {
+			viewConsumable.add( { element: el, style: 'color' } );
+			viewConsumable.consume( { element: el, style: 'color' } );
+
+			expect( () => {
+				viewConsumable.revert( { element: el, attribute: 'style' } );
+			} ).to.throw( 'viewconsumable-invalid-attribute' );
+		} );
+	} );
+} );