Browse Source

Added unit tests for FakeSelectionObserver.

Szymon Kupś 9 years ago
parent
commit
a6e9c07e9f

+ 1 - 1
packages/ckeditor5-engine/src/view/document.js

@@ -13,7 +13,7 @@ import MutationObserver from './observer/mutationobserver.js';
 import SelectionObserver from './observer/selectionobserver.js';
 import FocusObserver from './observer/focusobserver.js';
 import KeyObserver from './observer/keyobserver.js';
-import FakeSelectionObserver from './observer/fakeselecitonobserver.js';
+import FakeSelectionObserver from './observer/fakeselectionobserver.js';
 import mix from '../../utils/mix.js';
 import ObservableMixin from '../../utils/observablemixin.js';
 

+ 9 - 7
packages/ckeditor5-engine/src/view/observer/fakeselecitonobserver.js

@@ -11,7 +11,7 @@ import { keyCodes } from '../../../utils/keyboard.js';
  * Fake selection observer class. If view selection is fake it is placed in dummy DOM container. This observer listens
  * on {@link engine.view.Document#keydown keydown} events and handles moving fake view selection to the correct place
  * if arrow keys are pressed.
- * Fires {@link engine.view.Document#selectionChage selectionChage event} simulating natural behaviour of
+ * Fires {@link engine.view.Document#selectionChage selectionChange event} simulating natural behaviour of
  * {@link engine.view.observer.SelectionObserver SelectionObserver}.
  *
  * @memberOf engine.view.observer
@@ -25,11 +25,18 @@ export default class FakeSelectionObserver extends Observer {
 	 */
 	constructor( document ) {
 		super( document );
+	}
+
+	/**
+	 * @inheritDoc
+	 */
+	observe() {
+		const document = this.document;
 
 		document.on( 'keydown', ( eventInfo, data ) => {
 			const selection = document.selection;
 
-			if ( selection.isFake && _isArrowKeyCode( data.keyCode ) ) {
+			if ( selection.isFake && _isArrowKeyCode( data.keyCode ) && this.isEnabled ) {
 				// Prevents default key down handling - no selection change will occur.
 				data.preventDefault();
 
@@ -39,11 +46,6 @@ export default class FakeSelectionObserver extends Observer {
 	}
 
 	/**
-	 * @inheritDoc
-	 */
-	observe() {}
-
-	/**
 	 * Handles collapsing view selection according to given key code. If left or up key is provided - new selection will be
 	 * collapsed to left. If right or down key is pressed - new selection will be collapsed to right.
 	 *

+ 136 - 0
packages/ckeditor5-engine/tests/view/observer/fakeselectionobserver.js

@@ -0,0 +1,136 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals document */
+
+import FakeSelectionObserver from '/ckeditor5/engine/view/observer/fakeselectionobserver.js';
+import ViewDocument from '/ckeditor5/engine/view/document.js';
+import DomEventData from '/ckeditor5/engine/view/observer/domeventdata.js';
+import { keyCodes } from '/ckeditor5/utils/keyboard.js';
+import { setData, stringify } from '/ckeditor5/engine/dev-utils/view.js';
+
+describe( 'FakeSelectionObserver', () => {
+	let observer;
+	let viewDocument;
+	let root;
+
+	beforeEach( () => {
+		viewDocument = new ViewDocument();
+		root = viewDocument.createRoot( document.getElementById( 'main' ) );
+		observer = viewDocument.getObserver( FakeSelectionObserver );
+		viewDocument.selection.setFake();
+	} );
+
+	it( 'should do nothing if selection is not fake', () => {
+		viewDocument.selection.setFake( false );
+
+		return checkEventPrevention( keyCodes.arrowleft, false );
+	} );
+
+	it( 'should do nothing if is disabled', () => {
+		observer.disable();
+
+		return checkEventPrevention( keyCodes.arrowleft, false );
+	} );
+
+	it( 'should prevent default for left arrow key', ( ) => {
+		return checkEventPrevention( keyCodes.arrowleft );
+	} );
+
+	it( 'should prevent default for right arrow key', ( ) => {
+		return checkEventPrevention( keyCodes.arrowright );
+	} );
+
+	it( 'should prevent default for up arrow key', ( ) => {
+		return checkEventPrevention( keyCodes.arrowup );
+	} );
+
+	it( 'should prevent default for down arrow key', ( ) => {
+		return checkEventPrevention( keyCodes.arrowdown );
+	} );
+
+	it( 'should fire selectionChange event with new selection when left arrow key is pressed', () => {
+		return checkSelectionChange(
+			'<container:p>foo[<strong>bar</strong>]baz</container:p>',
+			keyCodes.arrowleft,
+			'<container:p>foo[]<strong>bar</strong>baz</container:p>'
+		);
+	} );
+
+	it( 'should fire selectionChange event with new selection when right arrow key is pressed', () => {
+		return checkSelectionChange(
+			'<container:p>foo[<strong>bar</strong>]baz</container:p>',
+			keyCodes.arrowright,
+			'<container:p>foo<strong>bar</strong>[]baz</container:p>'
+		);
+	} );
+
+	it( 'should fire selectionChange event with new selection when up arrow key is pressed', () => {
+		return checkSelectionChange(
+			'<container:p>foo[<strong>bar</strong>]baz</container:p>',
+			keyCodes.arrowup,
+			'<container:p>foo[]<strong>bar</strong>baz</container:p>'
+		);
+	} );
+
+	it( 'should fire selectionChange event with new selection when down arrow key is pressed', () => {
+		return checkSelectionChange(
+			'<container:p>foo[<strong>bar</strong>]baz</container:p>',
+			keyCodes.arrowdown,
+			'<container:p>foo<strong>bar</strong>[]baz</container:p>'
+		);
+	} );
+
+	// Checks if preventDefault method was called by FakeSelectionObserver for specified key code.
+	//
+	// @param {Number} keyCode
+	// @param {Boolean} shouldPrevent If set to true method checks if event was prevented.
+	// @returns {Promise}
+	function checkEventPrevention( keyCode, shouldPrevent = true ) {
+		return new Promise( resolve => {
+			const data = {
+				keyCode,
+				preventDefault: sinon.spy(),
+			};
+
+			viewDocument.once( 'keydown', () => {
+				if ( shouldPrevent ) {
+					sinon.assert.calledOnce( data.preventDefault );
+				} else {
+					sinon.assert.notCalled( data.preventDefault );
+				}
+
+				resolve();
+			}, { priority: 'lowest' } );
+
+			viewDocument.fire( 'keydown', new DomEventData( viewDocument, { target: document.body }, data ) );
+		} );
+	}
+
+	// Checks if proper selectionChange event is fired by FakeSelectionObserver for specified key.
+	//
+	// @param {String} initialData
+	// @param {Number} keyCode
+	// @param {String} output
+	// @returns {Promise}
+	function checkSelectionChange( initialData, keyCode, output ) {
+		return new Promise( resolve => {
+			viewDocument.once( 'selectionChange', ( eventInfo, data ) => {
+				expect( stringify( root.getChild( 0 ), data.newSelection, { showType: true } ) ).to.equal( output );
+				resolve();
+			} );
+
+			setData( viewDocument, initialData );
+			viewDocument.selection.setFake();
+
+			const data = {
+				keyCode,
+				preventDefault: sinon.spy(),
+			};
+
+			viewDocument.fire( 'keydown', new DomEventData( viewDocument, { target: document.body }, data ) );
+		} );
+	}
+} );