Parcourir la source

Changed: Change how dropdowns with `ButtonView` and `SplitButtonView` are created.

Maciej Gołaszewski il y a 7 ans
Parent
commit
83505e5a06

+ 0 - 19
packages/ckeditor5-ui/src/dropdown/helpers/createbuttonfordropdown.js

@@ -1,19 +0,0 @@
-/**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import ButtonView from '../../button/buttonview';
-
-/**
- * @module ui/dropdown/helpers/createbuttonfordropdown
- */
-
-export default function createButtonForDropdown( model, locale ) {
-	const buttonView = new ButtonView( locale );
-
-	// Dropdown expects "select" event to show contents.
-	buttonView.delegate( 'execute' ).to( buttonView, 'select' );
-
-	return buttonView;
-}

+ 0 - 54
packages/ckeditor5-ui/src/dropdown/helpers/createdropdownview.js

@@ -1,54 +0,0 @@
-/**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/**
- * @module ui/dropdown/helpers/createdropdownview
- */
-
-import DropdownPanelView from './../dropdownpanelview';
-import DropdownView from './../dropdownview';
-
-/**
- * A helper which creates an instance of {@link module:ui/dropdown/dropdownview~DropdownView} class using
- * a provided {@link module:ui/dropdown/dropdownmodel~DropdownModel}.
- *
- *		const model = new Model( {
- *			label: 'A dropdown',
- *			isEnabled: true,
- *			isOn: false,
- *			withText: true
- *		} );
- *
- *		const dropdown = createDropdown( model );
- *
- *		dropdown.render();
- *
- *		// Will render a dropdown labeled "A dropdown" with an empty panel.
- *		document.body.appendChild( dropdown.element );
- *
- * The model instance remains in control of the dropdown after it has been created. E.g. changes to the
- * {@link module:ui/dropdown/dropdownmodel~DropdownModel#label `model.label`} will be reflected in the
- * dropdown button's {@link module:ui/button/buttonview~ButtonView#label} attribute and in DOM.
- *
- * Also see {@link module:ui/dropdown/list/createlistdropdown~createListDropdown}.
- *
- * @param {module:ui/dropdown/dropdownmodel~DropdownModel} model Model of this dropdown.
- * @param {module:utils/locale~Locale} locale The locale instance.
- * @returns {module:ui/dropdown/dropdownview~DropdownView} The dropdown view instance.
- */
-export default function createDropdownView( model, buttonView, locale ) {
-	const panelView = new DropdownPanelView( locale );
-	const dropdownView = new DropdownView( locale, buttonView, panelView );
-
-	dropdownView.bind( 'isEnabled' ).to( model );
-
-	// TODO: check 'isOn' binding.
-	buttonView.bind( 'label', 'isEnabled', 'withText', 'keystroke', 'tooltip', 'icon' ).to( model );
-	buttonView.bind( 'isOn' ).to( model, 'isOn', dropdownView, 'isOpen', ( isOn, isOpen ) => {
-		return isOn || isOpen;
-	} );
-
-	return dropdownView;
-}

+ 0 - 20
packages/ckeditor5-ui/src/dropdown/helpers/createsplitbuttonfordropdown.js

@@ -1,20 +0,0 @@
-/**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-/**
- * @module ui/dropdown/helpers/createsplitbuttonfordropdown
- */
-
-import SplitButtonView from '../../button/splitbuttonview';
-
-export default function createSplitButtonForDropdown( model, locale ) {
-	const splitButtonView = new SplitButtonView( locale );
-
-	// TODO: Check if those binding are in good place (maybe move them to SplitButton) or add tests.
-	splitButtonView.actionView.bind( 'isOn' ).to( splitButtonView );
-	splitButtonView.actionView.bind( 'tooltip' ).to( splitButtonView );
-
-	return splitButtonView;
-}

+ 123 - 0
packages/ckeditor5-ui/src/dropdown/utils.js

@@ -0,0 +1,123 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/**
+ * @module ui/dropdown/utils
+ */
+
+import DropdownPanelView from './dropdownpanelview';
+import DropdownView from './dropdownview';
+import SplitButtonView from '../button/splitbuttonview';
+import ButtonView from '../button/buttonview';
+
+/**
+ * A helper which creates an instance of {@link module:ui/dropdown/dropdownview~DropdownView} class using
+ * a provided {@link module:ui/dropdown/dropdownmodel~DropdownModel}.
+ *
+ *		const model = new Model( {
+ *			label: 'A dropdown',
+ *			isEnabled: true,
+ *			isOn: false,
+ *			withText: true
+ *		} );
+ *
+ *		const dropdown = createDropdown( model );
+ *
+ *		dropdown.render();
+ *
+ *		// Will render a dropdown labeled "A dropdown" with an empty panel.
+ *		document.body.appendChild( dropdown.element );
+ *
+ * The model instance remains in control of the dropdown after it has been created. E.g. changes to the
+ * {@link module:ui/dropdown/dropdownmodel~DropdownModel#label `model.label`} will be reflected in the
+ * dropdown button's {@link module:ui/button/buttonview~ButtonView#label} attribute and in DOM.
+ *
+ * Also see {@link module:ui/dropdown/list/createlistdropdown~createListDropdown}.
+ *
+ * @param {module:ui/dropdown/dropdownmodel~DropdownModel} model Model of this dropdown.
+ * @param {module:utils/locale~Locale} locale The locale instance.
+ * @returns {module:ui/dropdown/dropdownview~DropdownView} The dropdown view instance.
+ */
+export function createDropdown( model, locale ) {
+	const buttonView = createButtonForDropdown( model, locale );
+
+	const dropdownView = prepareDropdown( locale, buttonView, model );
+
+	return dropdownView;
+}
+
+/**
+ * A helper which creates an instance of {@link module:ui/dropdown/dropdownview~DropdownView} class using
+ * a provided {@link module:ui/dropdown/dropdownmodel~DropdownModel}.
+ *
+ *		const model = new Model( {
+ *			label: 'A dropdown',
+ *			isEnabled: true,
+ *			isOn: false,
+ *			withText: true
+ *		} );
+ *
+ *		const dropdown = createDropdown( model );
+ *
+ *		dropdown.render();
+ *
+ *		// Will render a dropdown labeled "A dropdown" with an empty panel.
+ *		document.body.appendChild( dropdown.element );
+ *
+ * The model instance remains in control of the dropdown after it has been created. E.g. changes to the
+ * {@link module:ui/dropdown/dropdownmodel~DropdownModel#label `model.label`} will be reflected in the
+ * dropdown button's {@link module:ui/button/buttonview~ButtonView#label} attribute and in DOM.
+ *
+ * Also see {@link module:ui/dropdown/list/createlistdropdown~createListDropdown}.
+ *
+ * @param {module:ui/dropdown/dropdownmodel~DropdownModel} model Model of this dropdown.
+ * @param {module:utils/locale~Locale} locale The locale instance.
+ * @returns {module:ui/dropdown/dropdownview~DropdownView} The dropdown view instance.
+ */
+export function createSplitButtonDropdown( model, locale ) {
+	const buttonView = createSplitButtonForDropdown( model, locale );
+
+	const dropdownView = prepareDropdown( locale, buttonView, model );
+
+	buttonView.delegate( 'execute' ).to( dropdownView );
+
+	return dropdownView;
+}
+
+// @private
+function prepareDropdown( locale, buttonView, model ) {
+	const panelView = new DropdownPanelView( locale );
+	const dropdownView = new DropdownView( locale, buttonView, panelView );
+
+	dropdownView.bind( 'isEnabled' ).to( model );
+
+	buttonView.bind( 'label', 'isEnabled', 'withText', 'keystroke', 'tooltip', 'icon' ).to( model );
+	buttonView.bind( 'isOn' ).to( model, 'isOn', dropdownView, 'isOpen', ( isOn, isOpen ) => {
+		return isOn || isOpen;
+	} );
+
+	return dropdownView;
+}
+
+// @private
+function createSplitButtonForDropdown( model, locale ) {
+	const splitButtonView = new SplitButtonView( locale );
+
+	// TODO: Check if those binding are in good place (maybe move them to SplitButton) or add tests.
+	splitButtonView.actionView.bind( 'isOn' ).to( splitButtonView );
+	splitButtonView.actionView.bind( 'tooltip' ).to( splitButtonView );
+
+	return splitButtonView;
+}
+
+// @private
+function createButtonForDropdown( model, locale ) {
+	const buttonView = new ButtonView( locale );
+
+	// Dropdown expects "select" event to show contents.
+	buttonView.delegate( 'execute' ).to( buttonView, 'select' );
+
+	return buttonView;
+}

+ 3 - 5
packages/ckeditor5-ui/tests/dropdown/helpers/addlistviewtodropdown.js

@@ -12,13 +12,12 @@ import Model from '../../../src/model';
 import ListItemView from '../../../src/list/listitemview';
 import ListView from '../../../src/list/listview';
 
-import createButtonForDropdown from '../../../src/dropdown/helpers/createbuttonfordropdown';
-import createDropdownView from '../../../src/dropdown/helpers/createdropdownview';
+import { createDropdown } from './../../../src/dropdown/utils';
 
 import addListViewToDropdown from '../../../src/dropdown/helpers/addlistviewtodropdown';
 
 describe( 'addListViewToDropdown()', () => {
-	let dropdownView, buttonView, model, locale, items;
+	let dropdownView, model, locale, items;
 
 	beforeEach( () => {
 		locale = { t() {} };
@@ -30,8 +29,7 @@ describe( 'addListViewToDropdown()', () => {
 			label: 'foo'
 		} );
 
-		buttonView = createButtonForDropdown( model, locale );
-		dropdownView = createDropdownView( model, buttonView, locale );
+		dropdownView = createDropdown( model, locale );
 
 		addListViewToDropdown( dropdownView, model, locale );
 

+ 4 - 5
packages/ckeditor5-ui/tests/dropdown/helpers/addtoolbartodropdown.js

@@ -9,13 +9,12 @@ import Model from '../../../src/model';
 
 import ButtonView from '../../../src/button/buttonview';
 import ToolbarView from '../../../src/toolbar/toolbarview';
-import createButtonForDropdown from '../../../src/dropdown/helpers/createbuttonfordropdown';
-import createDropdownView from '../../../src/dropdown/helpers/createdropdownview';
+import { createDropdown } from '../../../src/dropdown/utils';
 
 import addToolbarToDropdown from '../../../src/dropdown/helpers/addtoolbartodropdown';
 
 describe( 'addToolbarToDropdown()', () => {
-	let dropdownView, buttonView, model, locale, buttons;
+	let dropdownView, model, locale, buttons;
 
 	beforeEach( () => {
 		locale = { t() {} };
@@ -33,8 +32,7 @@ describe( 'addToolbarToDropdown()', () => {
 			buttons
 		} );
 
-		buttonView = createButtonForDropdown( model, locale );
-		dropdownView = createDropdownView( model, buttonView, locale );
+		dropdownView = createDropdown( model, locale );
 
 		addToolbarToDropdown( dropdownView, model );
 
@@ -42,6 +40,7 @@ describe( 'addToolbarToDropdown()', () => {
 
 		document.body.appendChild( dropdownView.element );
 	} );
+
 	afterEach( () => {
 		dropdownView.element.remove();
 	} );

+ 3 - 3
packages/ckeditor5-ui/tests/dropdown/helpers/closedropdownonblur.js

@@ -6,15 +6,15 @@
 /* globals document, Event */
 
 import Model from '../../../src/model';
-import ButtonView from '../../../src/button/buttonview';
-import createDropdownView from '../../../src/dropdown/helpers/createdropdownview';
+
+import { createDropdown } from '../../../src/dropdown/utils';
 import closeDropdownOnBlur from '../../../src/dropdown/helpers/closedropdownonblur';
 
 describe( 'closeDropdownOnBlur()', () => {
 	let dropdownView;
 
 	beforeEach( () => {
-		dropdownView = createDropdownView( new Model(), new ButtonView(), {} );
+		dropdownView = createDropdown( new Model(), {} );
 
 		closeDropdownOnBlur( dropdownView );
 

+ 2 - 3
packages/ckeditor5-ui/tests/dropdown/helpers/closedropdownonexecute.js

@@ -6,15 +6,14 @@
 /* globals document */
 
 import Model from '../../../src/model';
-import ButtonView from '../../../src/button/buttonview';
-import createDropdownView from '../../../src/dropdown/helpers/createdropdownview';
 import closeDropdownOnExecute from '../../../src/dropdown/helpers/closedropdownonexecute';
+import { createDropdown } from '../../../src/dropdown/utils';
 
 describe( 'closeDropdownOnExecute()', () => {
 	let dropdownView;
 
 	beforeEach( () => {
-		dropdownView = createDropdownView( new Model(), new ButtonView(), {} );
+		dropdownView = createDropdown( new Model(), {} );
 
 		closeDropdownOnExecute( dropdownView );
 

+ 0 - 37
packages/ckeditor5-ui/tests/dropdown/helpers/createbuttonfordropdown.js

@@ -1,37 +0,0 @@
-/**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Model from '../../../src/model';
-
-import ButtonView from '../../../src/button/buttonview';
-
-import createButtonForDropdown from '../../../src/dropdown/helpers/createbuttonfordropdown';
-
-describe( 'createButtonForDropdown()', () => {
-	let buttonView, locale;
-
-	beforeEach( () => {
-		locale = { t() {} };
-		buttonView = createButtonForDropdown( new Model(), locale );
-	} );
-
-	it( 'accepts locale', () => {
-		expect( buttonView.locale ).to.equal( locale );
-	} );
-
-	it( 'returns ButtonView instance', () => {
-		expect( buttonView ).to.be.instanceof( ButtonView );
-	} );
-
-	it( 'delegates "execute" to "select" event', () => {
-		const spy = sinon.spy();
-
-		buttonView.on( 'select', spy );
-
-		buttonView.fire( 'execute' );
-
-		sinon.assert.calledOnce( spy );
-	} );
-} );

+ 0 - 125
packages/ckeditor5-ui/tests/dropdown/helpers/createdropdownview.js

@@ -1,125 +0,0 @@
-/**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import utilsTestUtils from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
-
-import Model from '../../../src/model';
-
-import ButtonView from '../../../src/button/buttonview';
-import DropdownView from '../../../src/dropdown/dropdownview';
-import DropdownPanelView from '../../../src/dropdown/dropdownpanelview';
-import createButtonForDropdown from '../../../src/dropdown/helpers/createbuttonfordropdown';
-import createDropdownView from '../../../src/dropdown/helpers/createdropdownview';
-
-const assertBinding = utilsTestUtils.assertBinding;
-
-describe( 'createDropdownView()', () => {
-	let dropdownView, buttonView, model, locale;
-
-	beforeEach( () => {
-		locale = { t() {} };
-		model = new Model();
-		buttonView = createButtonForDropdown( model, locale );
-		dropdownView = createDropdownView( model, buttonView, locale );
-	} );
-
-	it( 'accepts locale', () => {
-		expect( dropdownView.locale ).to.equal( locale );
-		expect( dropdownView.panelView.locale ).to.equal( locale );
-	} );
-
-	it( 'returns view', () => {
-		model = new Model();
-		buttonView = new ButtonView();
-		dropdownView = createDropdownView( model, buttonView, locale );
-
-		expect( dropdownView ).to.be.instanceOf( DropdownView );
-	} );
-
-	it( 'creates dropdown#panelView out of DropdownPanelView', () => {
-		model = new Model();
-		buttonView = new ButtonView();
-		dropdownView = createDropdownView( model, buttonView, locale );
-
-		expect( dropdownView.panelView ).to.be.instanceOf( DropdownPanelView );
-	} );
-
-	it( 'creates dropdown#buttonView out of buttonView', () => {
-		model = new Model();
-		buttonView = new ButtonView();
-		dropdownView = createDropdownView( model, buttonView, locale );
-
-		expect( dropdownView.buttonView ).to.equal( buttonView );
-	} );
-
-	it( 'binds button attributes to the model', () => {
-		const modelDef = {
-			label: 'foo',
-			isOn: false,
-			isEnabled: true,
-			withText: false,
-			tooltip: false
-		};
-
-		model = new Model( modelDef );
-		buttonView = new ButtonView();
-		createDropdownView( model, buttonView, locale );
-
-		assertBinding( buttonView,
-			modelDef,
-			[
-				[ model, { label: 'bar', isEnabled: false, isOn: true, withText: true, tooltip: true } ]
-			],
-			{ label: 'bar', isEnabled: false, isOn: true, withText: true, tooltip: true }
-		);
-	} );
-
-	it( 'binds button#isOn do dropdown #isOpen and model #isOn', () => {
-		const modelDef = {
-			label: 'foo',
-			isOn: false,
-			isEnabled: true,
-			withText: false,
-			tooltip: false
-		};
-
-		model = new Model( modelDef );
-		buttonView = new ButtonView();
-		dropdownView = createDropdownView( model, buttonView, locale );
-
-		dropdownView.isOpen = false;
-		expect( buttonView.isOn ).to.be.false;
-
-		model.isOn = true;
-		expect( buttonView.isOn ).to.be.true;
-
-		dropdownView.isOpen = true;
-		expect( buttonView.isOn ).to.be.true;
-
-		model.isOn = false;
-		expect( buttonView.isOn ).to.be.true;
-	} );
-
-	it( 'binds dropdown#isEnabled to the model', () => {
-		const modelDef = {
-			label: 'foo',
-			isEnabled: true,
-			withText: false,
-			tooltip: false
-		};
-
-		model = new Model( modelDef );
-		buttonView = new ButtonView();
-		dropdownView = createDropdownView( model, buttonView, locale );
-
-		assertBinding( dropdownView,
-			{ isEnabled: true },
-			[
-				[ model, { isEnabled: false } ]
-			],
-			{ isEnabled: false }
-		);
-	} );
-} );

+ 0 - 26
packages/ckeditor5-ui/tests/dropdown/helpers/createsplitbuttonfordropdown.js

@@ -1,26 +0,0 @@
-/**
- * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md.
- */
-
-import Model from '../../../src/model';
-import SplitButtonView from '../../../src/button/splitbuttonview';
-
-import createSplitButtonForDropdown from '../../../src/dropdown/helpers/createsplitbuttonfordropdown';
-
-describe( 'createSplitButtonForDropdown()', () => {
-	let buttonView, locale;
-
-	beforeEach( () => {
-		locale = { t() {} };
-		buttonView = createSplitButtonForDropdown( new Model(), locale );
-	} );
-
-	it( 'accepts locale', () => {
-		expect( buttonView.locale ).to.equal( locale );
-	} );
-
-	it( 'returns SplitButtonView instance', () => {
-		expect( buttonView ).to.be.instanceof( SplitButtonView );
-	} );
-} );

+ 2 - 3
packages/ckeditor5-ui/tests/dropdown/helpers/focusdropdowncontentsonarrows.js

@@ -9,17 +9,16 @@ import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard';
 
 import View from '../../../src/view';
 import Model from '../../../src/model';
-import ButtonView from '../../../src/button/buttonview';
 
 import focusDropdownContentsOnArrows from '../../../src/dropdown/helpers/focusdropdowncontentsonarrows';
-import createDropdownView from '../../../src/dropdown/helpers/createdropdownview';
+import { createDropdown } from './../../../src/dropdown/utils';
 
 describe( 'focusDropdownContentsOnArrows()', () => {
 	let dropdownView;
 	let panelChildView;
 
 	beforeEach( () => {
-		dropdownView = createDropdownView( new Model(), new ButtonView(), {} );
+		dropdownView = createDropdown( new Model(), {} );
 
 		panelChildView = new View();
 		panelChildView.setTemplate( { tag: 'div' } );

+ 7 - 15
packages/ckeditor5-ui/tests/dropdown/manual/dropdown.js

@@ -17,11 +17,10 @@ import ButtonView from '../../../src/button/buttonview';
 
 import addListViewToDropdown from '../../../src/dropdown/helpers/addlistviewtodropdown';
 import addToolbarToDropdown from '../../../src/dropdown/helpers/addtoolbartodropdown';
-import createDropdownView from '../../../src/dropdown/helpers/createdropdownview';
-import createButtonForDropdown from '../../../src/dropdown/helpers/createbuttonfordropdown';
 import closeDropdownOnBlur from '../../../src/dropdown/helpers/closedropdownonblur';
 import closeDropdownOnExecute from '../../../src/dropdown/helpers/closedropdownonexecute';
 import focusDropdownContentsOnArrows from '../../../src/dropdown/helpers/focusdropdowncontentsonarrows';
+import { createDropdown } from '../../../src/dropdown/utils';
 
 const ui = testUtils.createTestUIView( {
 	dropdown: '#dropdown',
@@ -39,8 +38,7 @@ function testEmpty() {
 		withText: true
 	} );
 
-	const buttonView = createButtonForDropdown( model, {} );
-	const dropdownView = createDropdownView( model, buttonView, {} );
+	const dropdownView = createDropdown( model, {} );
 
 	ui.dropdown.add( dropdownView );
 
@@ -65,8 +63,7 @@ function testList() {
 		items: collection
 	} );
 
-	const buttonView = createButtonForDropdown( model, {} );
-	const dropdownView = createDropdownView( model, buttonView, {} );
+	const dropdownView = createDropdown( model, {} );
 
 	addListViewToDropdown( dropdownView, model, {} );
 	closeDropdownOnBlur( dropdownView );
@@ -93,11 +90,8 @@ function testSharedModel() {
 		withText: true
 	} );
 
-	const buttonView1 = createButtonForDropdown( model, {} );
-	const buttonView2 = createButtonForDropdown( model, {} );
-
-	const dropdownView1 = createDropdownView( model, buttonView1, {} );
-	const dropdownView2 = createDropdownView( model, buttonView2, {} );
+	const dropdownView1 = createDropdown( model, {} );
+	const dropdownView2 = createDropdown( model, {} );
 
 	ui.dropdownShared.add( dropdownView1 );
 	ui.dropdownShared.add( dropdownView2 );
@@ -113,8 +107,7 @@ function testLongLabel() {
 		withText: true
 	} );
 
-	const buttonView = createButtonForDropdown( model, {} );
-	const dropdownView = createDropdownView( model, buttonView, {} );
+	const dropdownView = createDropdown( model, {} );
 
 	ui.dropdownLabel.add( dropdownView );
 
@@ -145,8 +138,7 @@ function testButton() {
 		buttons: buttonViews
 	} );
 
-	const buttonView = createButtonForDropdown( toolbarDropdownModel, locale );
-	const toolbarDropdown = createDropdownView( toolbarDropdownModel, buttonView, locale );
+	const toolbarDropdown = createDropdown( toolbarDropdownModel, locale );
 
 	addToolbarToDropdown( toolbarDropdown, toolbarDropdownModel );
 	closeDropdownOnBlur( toolbarDropdown );

+ 238 - 0
packages/ckeditor5-ui/tests/dropdown/utils.js

@@ -0,0 +1,238 @@
+/**
+ * @license Copyright (c) 2003-2018, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+import utilsTestUtils from '@ckeditor/ckeditor5-utils/tests/_utils/utils';
+
+import Model from '../../src/model';
+
+import ButtonView from '../../src/button/buttonview';
+import DropdownView from '../../src/dropdown/dropdownview';
+import DropdownPanelView from '../../src/dropdown/dropdownpanelview';
+import SplitButtonView from '../../src/button/splitbuttonview';
+import { createDropdown, createSplitButtonDropdown } from '../../src/dropdown/utils';
+
+const assertBinding = utilsTestUtils.assertBinding;
+
+describe( 'utils', () => {
+	let locale;
+
+	beforeEach( () => {
+		locale = { t() {} };
+	} );
+
+	describe( 'createDropdown()', () => {
+		let dropdownView, model;
+
+		beforeEach( () => {
+			model = new Model();
+			dropdownView = createDropdown( model, locale );
+		} );
+
+		it( 'accepts locale', () => {
+			expect( dropdownView.locale ).to.equal( locale );
+			expect( dropdownView.panelView.locale ).to.equal( locale );
+		} );
+
+		it( 'returns view', () => {
+			expect( dropdownView ).to.be.instanceOf( DropdownView );
+		} );
+
+		it( 'creates dropdown#panelView out of DropdownPanelView', () => {
+			expect( dropdownView.panelView ).to.be.instanceOf( DropdownPanelView );
+		} );
+
+		it( 'creates dropdown#buttonView out of ButtonView', () => {
+			expect( dropdownView.buttonView ).to.be.instanceOf( ButtonView );
+		} );
+
+		it( 'binds button attributes to the model', () => {
+			const modelDef = {
+				label: 'foo',
+				isOn: false,
+				isEnabled: true,
+				withText: false,
+				tooltip: false
+			};
+
+			model = new Model( modelDef );
+			dropdownView = createDropdown( model, locale );
+
+			assertBinding( dropdownView.buttonView,
+				modelDef,
+				[
+					[ model, { label: 'bar', isEnabled: false, isOn: true, withText: true, tooltip: true } ]
+				],
+				{ label: 'bar', isEnabled: false, isOn: true, withText: true, tooltip: true }
+			);
+		} );
+
+		it( 'binds button#isOn do dropdown #isOpen and model #isOn', () => {
+			const modelDef = {
+				label: 'foo',
+				isOn: false,
+				isEnabled: true,
+				withText: false,
+				tooltip: false
+			};
+
+			model = new Model( modelDef );
+			dropdownView = createDropdown( model, locale );
+
+			dropdownView.isOpen = false;
+			expect( dropdownView.buttonView.isOn ).to.be.false;
+
+			model.isOn = true;
+			expect( dropdownView.buttonView.isOn ).to.be.true;
+
+			dropdownView.isOpen = true;
+			expect( dropdownView.buttonView.isOn ).to.be.true;
+
+			model.isOn = false;
+			expect( dropdownView.buttonView.isOn ).to.be.true;
+		} );
+
+		it( 'binds dropdown#isEnabled to the model', () => {
+			const modelDef = {
+				label: 'foo',
+				isEnabled: true,
+				withText: false,
+				tooltip: false
+			};
+
+			model = new Model( modelDef );
+			dropdownView = createDropdown( model, locale );
+
+			assertBinding( dropdownView,
+				{ isEnabled: true },
+				[
+					[ model, { isEnabled: false } ]
+				],
+				{ isEnabled: false }
+			);
+		} );
+
+		describe( '#buttonView', () => {
+			it( 'accepts locale', () => {
+				expect( dropdownView.buttonView.locale ).to.equal( locale );
+			} );
+
+			it( 'is a ButtonView instance', () => {
+				expect( dropdownView.buttonView ).to.be.instanceof( ButtonView );
+			} );
+
+			it( 'delegates "execute" to "select" event', () => {
+				const spy = sinon.spy();
+
+				dropdownView.buttonView.on( 'select', spy );
+
+				dropdownView.buttonView.fire( 'execute' );
+
+				sinon.assert.calledOnce( spy );
+			} );
+		} );
+	} );
+
+	describe( 'createSplitButtonDropdown()', () => {
+		let dropdownView, model;
+
+		beforeEach( () => {
+			model = new Model();
+			dropdownView = createSplitButtonDropdown( model, locale );
+		} );
+
+		it( 'accepts locale', () => {
+			expect( dropdownView.locale ).to.equal( locale );
+			expect( dropdownView.panelView.locale ).to.equal( locale );
+		} );
+
+		it( 'returns view', () => {
+			expect( dropdownView ).to.be.instanceOf( DropdownView );
+		} );
+
+		it( 'creates dropdown#panelView out of DropdownPanelView', () => {
+			expect( dropdownView.panelView ).to.be.instanceOf( DropdownPanelView );
+		} );
+
+		it( 'creates dropdown#buttonView out of SplitButtonView', () => {
+			expect( dropdownView.buttonView ).to.be.instanceOf( SplitButtonView );
+		} );
+
+		it( 'binds button attributes to the model', () => {
+			const modelDef = {
+				label: 'foo',
+				isOn: false,
+				isEnabled: true,
+				withText: false,
+				tooltip: false
+			};
+
+			model = new Model( modelDef );
+			dropdownView = createDropdown( model, locale );
+
+			assertBinding( dropdownView.buttonView,
+				modelDef,
+				[
+					[ model, { label: 'bar', isEnabled: false, isOn: true, withText: true, tooltip: true } ]
+				],
+				{ label: 'bar', isEnabled: false, isOn: true, withText: true, tooltip: true }
+			);
+		} );
+
+		it( 'binds button#isOn do dropdown #isOpen and model #isOn', () => {
+			const modelDef = {
+				label: 'foo',
+				isOn: false,
+				isEnabled: true,
+				withText: false,
+				tooltip: false
+			};
+
+			model = new Model( modelDef );
+			dropdownView = createDropdown( model, locale );
+
+			dropdownView.isOpen = false;
+			expect( dropdownView.buttonView.isOn ).to.be.false;
+
+			model.isOn = true;
+			expect( dropdownView.buttonView.isOn ).to.be.true;
+
+			dropdownView.isOpen = true;
+			expect( dropdownView.buttonView.isOn ).to.be.true;
+
+			model.isOn = false;
+			expect( dropdownView.buttonView.isOn ).to.be.true;
+		} );
+
+		it( 'binds dropdown#isEnabled to the model', () => {
+			const modelDef = {
+				label: 'foo',
+				isEnabled: true,
+				withText: false,
+				tooltip: false
+			};
+
+			model = new Model( modelDef );
+			dropdownView = createDropdown( model, locale );
+
+			assertBinding( dropdownView,
+				{ isEnabled: true },
+				[
+					[ model, { isEnabled: false } ]
+				],
+				{ isEnabled: false }
+			);
+		} );
+
+		describe( '#buttonView', () => {
+			it( 'accepts locale', () => {
+				expect( dropdownView.buttonView.locale ).to.equal( locale );
+			} );
+
+			it( 'returns SplitButtonView instance', () => {
+				expect( dropdownView.buttonView ).to.be.instanceof( SplitButtonView );
+			} );
+		} );
+	} );
+} );