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

Merge branch 't/52b'. Closes #52, closes #53, closes #202.

Aleksander Nowodzinski 10 лет назад
Родитель
Сommit
b2717ad4cc

+ 73 - 13
packages/ckeditor5-utils/tests/_utils/utils.js

@@ -5,17 +5,15 @@
 
 'use strict';
 
+/* global console:false */
+
 import amdUtils from '/tests/_utils/amd.js';
+import EmitterMixin from '/ckeditor5/core/emittermixin.js';
 
 const utils = {
 	/**
 	 * Defines CKEditor plugin which is a mock of an editor creator.
 	 *
-	 * If `proto` is not set or it does not define `create()` and `destroy()` methods,
-	 * then they will be set to Sinon spies. Therefore the shortest usage is:
-	 *
-	 *		testUtils.defineEditorCreatorMock( 'test1' );
-	 *
 	 * The mocked creator is available under:
 	 *
 	 *		editor.plugins.get( 'creator-thename' );
@@ -34,14 +32,6 @@ const utils = {
 				}
 			}
 
-			if ( !TestCreator.prototype.create ) {
-				TestCreator.prototype.create = sinon.spy().named( creatorName + '-create' );
-			}
-
-			if ( !TestCreator.prototype.destroy ) {
-				TestCreator.prototype.destroy = sinon.spy().named( creatorName + '-destroy' );
-			}
-
 			return TestCreator;
 		} );
 	},
@@ -62,6 +52,76 @@ const utils = {
 		}
 
 		return count;
+	},
+
+	/**
+	 * Creates an instance inheriting from {@link core.EmitterMixin} with one additional method `observe()`.
+	 * It allows observing changes to attributes in objects being {@link core.Observable observable}.
+	 *
+	 * The `observe()` method accepts:
+	 *
+	 * * `{String} observableName` – Identifier for the observable object. E.g. `"Editable"` when
+	 * you observe one of editor's editables. This name will be displayed on the console.
+	 * * `{core.Observable observable} – The object to observe.
+	 *
+	 * Typical usage:
+	 *
+	 *		const observer = utils.createObserver();
+	 *		observer.observe( 'Editable', editor.editables.current );
+	 *
+	 *		// Stop listening (method from the EmitterMixin):
+	 *		observer.stopListening();
+	 *
+	 * @returns {Emitter} The observer.
+	 */
+	createObserver() {
+		const observer = Object.create( EmitterMixin, {
+			observe: {
+				value: function observe( observableName, observable ) {
+					observer.listenTo( observable, 'change', ( evt, propertyName, value, oldValue ) => {
+						console.log( `[Change in ${ observableName }] ${ propertyName } = '${ value }' (was '${ oldValue }')` );
+					} );
+
+					return observer;
+				}
+			}
+		} );
+
+		return observer;
+	},
+
+	/**
+	 * Checkes wether observable properties are properly bound to each other.
+	 *
+	 * Syntax given that observable `A` is bound to observables [`B`, `C`, ...]:
+	 *
+	 *		assertBinding( A,
+	 *			{ initial `A` attributes },
+	 *			[
+	 *				[ B, { new `B` attributes } ],
+	 *				[ C, { new `C` attributes } ],
+	 *				...
+	 *			],
+	 *			{ `A` attributes after [`B`, 'C', ...] changed }
+	 *		);
+	 */
+	assertBinding( observable, stateBefore, data, stateAfter ) {
+		let key, pair;
+
+		for ( key in stateBefore ) {
+			expect( observable[ key ] ).to.be.equal( stateBefore[ key ] );
+		}
+
+		// Change attributes of bound observables.
+		for ( pair of data ) {
+			for ( key in pair[ 1 ] ) {
+				pair[ 0 ][ key ] = pair[ 1 ][ key ];
+			}
+		}
+
+		for ( key in stateAfter ) {
+			expect( observable[ key ] ).to.be.equal( stateAfter[ key ] );
+		}
 	}
 };
 

+ 24 - 0
packages/ckeditor5-utils/tests/editorui.js

@@ -0,0 +1,24 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+import Editor from '/ckeditor5/core/editor.js';
+import EditorUI from '/ckeditor5/core/editorui.js';
+
+describe( 'EditorUI', () => {
+	let editor, editorUI;
+
+	beforeEach( () => {
+		editor = new Editor();
+		editorUI = new EditorUI( editor );
+	} );
+
+	describe( 'constructor', () => {
+		it( 'sets all the properties', () => {
+			expect( editorUI ).to.have.property( 'editor', editor );
+		} );
+	} );
+} );

+ 3 - 31
packages/ckeditor5-utils/tests/observablemixin.js

@@ -6,12 +6,15 @@
 'use strict';
 
 import testUtils from '/tests/_utils/utils.js';
+import coreTestUtils from '/tests/core/_utils/utils.js';
 import ObservableMixin from '/ckeditor5/core/observablemixin.js';
 import EmitterMixin from '/ckeditor5/core/emittermixin.js';
 import EventInfo from '/ckeditor5/core/eventinfo.js';
 import CKEditorError from '/ckeditor5/core/ckeditorerror.js';
 import utils from '/ckeditor5/core/utils.js';
 
+const assertBinding = coreTestUtils.assertBinding;
+
 testUtils.createSinonSandbox();
 
 describe( 'ObservableMixin', () => {
@@ -781,35 +784,4 @@ describe( 'Observable', () => {
 			);
 		} );
 	} );
-
-	// Syntax given that observable `A` is bound to observables [`B`, `C`, ...]:
-	//
-	//		assertBinding( A,
-	//			{ initial `A` attributes },
-	//			[
-	//				[ B, { new `B` attributes } ],
-	//				[ C, { new `C` attributes } ],
-	//				...
-	//			],
-	//			{ `A` attributes after [`B`, 'C', ...] changed }
-	//		);
-	//
-	function assertBinding( observable, stateBefore, data, stateAfter ) {
-		let key, pair;
-
-		for ( key in stateBefore ) {
-			expect( observable[ key ] ).to.be.equal( stateBefore[ key ] );
-		}
-
-		// Change attributes of bound observables.
-		for ( pair of data ) {
-			for ( key in pair[ 1 ] ) {
-				pair[ 0 ][ key ] = pair[ 1 ][ key ];
-			}
-		}
-
-		for ( key in stateAfter ) {
-			expect( observable[ key ] ).to.be.equal( stateAfter[ key ] );
-		}
-	}
 } );

+ 57 - 9
packages/ckeditor5-utils/tests/utils-tests/utils.js

@@ -5,13 +5,18 @@
 
 'use strict';
 
+import testUtils from '/tests/_utils/utils.js';
 import amdTestUtils from '/tests/_utils/amd.js';
 import coreTestUtils from '/tests/core/_utils/utils.js';
+import Model from '/ckeditor5/core/ui/model.js';
 import Creator from '/ckeditor5/core/creator.js';
+import EmitterMixin from '/ckeditor5/core/emittermixin.js';
 
 let createFn3 = () => {};
 let destroyFn3 = () => {};
 
+testUtils.createSinonSandbox();
+
 coreTestUtils.defineEditorCreatorMock( 'test1' );
 coreTestUtils.defineEditorCreatorMock( 'test2', {
 	foo: 1,
@@ -48,23 +53,66 @@ describe( 'coreTestUtils.defineEditorCreatorMock()', () => {
 	it( 'should copy properties from the second argument', () => {
 		expect( TestCreator2.prototype ).to.have.property( 'foo', 1 );
 		expect( TestCreator2.prototype ).to.have.property( 'bar', 2 );
-	} );
-
-	it( 'should create spies for create() and destroy() if not defined', () => {
-		expect( TestCreator1.prototype.create ).to.have.property( 'called', false, 'test1.create' );
-		expect( TestCreator1.prototype.destroy ).to.have.property( 'called', false, 'test1.destroy' );
-		expect( TestCreator2.prototype.create ).to.have.property( 'called', false, 'test2.create' );
-		expect( TestCreator2.prototype.destroy ).to.have.property( 'called', false, 'test2.destroy' );
 
-		// Not spies:
 		expect( TestCreator3.prototype ).to.have.property( 'create', createFn3 );
 		expect( TestCreator3.prototype ).to.have.property( 'destroy', destroyFn3 );
 	} );
 } );
 
 describe( 'coreTestUtils.getIteratorCount()', () => {
-	it( 'should returns number of editable items ', () => {
+	it( 'should returns number of editable items', () => {
 		const count = coreTestUtils.getIteratorCount( [ 1, 2, 3, 4, 5 ] );
 		expect( count ).to.equal( 5 );
 	} );
 } );
+
+describe( 'coreTestUtils.createObserver()', () => {
+	let observable, observable2, observer;
+
+	beforeEach( () => {
+		observer = coreTestUtils.createObserver();
+		observable = new Model( { foo: 0, bar: 0 } );
+		observable2 = new Model( { foo: 0, bar: 0 } );
+	} );
+
+	it( 'should create an observer', () => {
+		function Emitter() {}
+		Emitter.prototype = EmitterMixin;
+
+		expect( observer  ).to.be.instanceof( Emitter );
+		expect( observer.observe ).is.a( 'function' );
+		expect( observer.stopListening ).is.a( 'function' );
+	} );
+
+	describe( 'Observer', () => {
+		/* global console:false  */
+
+		it( 'logs changes in the observable', () => {
+			const spy = testUtils.sinon.stub( console, 'log' );
+
+			observer.observe( 'Some observable', observable );
+			observer.observe( 'Some observable 2', observable2 );
+
+			observable.foo = 1;
+			expect( spy.callCount ).to.equal( 1 );
+
+			observable.foo = 2;
+			observable2.bar = 3;
+			expect( spy.callCount ).to.equal( 3 );
+		} );
+
+		it( 'stops listening when asked to do so', () => {
+			const spy = testUtils.sinon.stub( console, 'log' );
+
+			observer.observe( 'Some observable', observable );
+
+			observable.foo = 1;
+			expect( spy.callCount ).to.equal( 1 );
+
+			observer.stopListening();
+
+			observable.foo = 2;
+			expect( spy.callCount ).to.equal( 1 );
+		} );
+	} );
+} );