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

Tests: Added tests for the ListStylesUI class.

Aleksander Nowodzinski 5 лет назад
Родитель
Сommit
13c418b98d
2 измененных файлов с 436 добавлено и 15 удалено
  1. 15 12
      packages/ckeditor5-list/src/liststylesui.js
  2. 421 3
      packages/ckeditor5-list/tests/liststylesui.js

+ 15 - 12
packages/ckeditor5-list/src/liststylesui.js

@@ -8,9 +8,12 @@
  */
  */
 
 
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
 import Plugin from '@ckeditor/ckeditor5-core/src/plugin';
-import SplitButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview';
-import { createDropdown, addToolbarToDropdown } from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
 import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import SplitButtonView from '@ckeditor/ckeditor5-ui/src/dropdown/button/splitbuttonview';
+import {
+	createDropdown,
+	addToolbarToDropdown
+} from '@ckeditor/ckeditor5-ui/src/dropdown/utils';
 
 
 import bulletedListIcon from '../theme/icons/bulletedlist.svg';
 import bulletedListIcon from '../theme/icons/bulletedlist.svg';
 import numberedListIcon from '../theme/icons/numberedlist.svg';
 import numberedListIcon from '../theme/icons/numberedlist.svg';
@@ -53,7 +56,7 @@ export default class ListStylesUI extends Plugin {
 			parentCommandName: 'bulletedList',
 			parentCommandName: 'bulletedList',
 			buttonLabel: t( 'Bulleted List' ),
 			buttonLabel: t( 'Bulleted List' ),
 			buttonIcon: bulletedListIcon,
 			buttonIcon: bulletedListIcon,
-			toolbarAriaLabel: t( 'Bulleted List styles toolbar' ),
+			toolbarAriaLabel: t( 'Bulleted list styles toolbar' ),
 			styleDefinitions: [
 			styleDefinitions: [
 				{
 				{
 					label: t( 'Toggle the "disc" list style' ),
 					label: t( 'Toggle the "disc" list style' ),
@@ -78,7 +81,7 @@ export default class ListStylesUI extends Plugin {
 			parentCommandName: 'numberedList',
 			parentCommandName: 'numberedList',
 			buttonLabel: t( 'Numbered List' ),
 			buttonLabel: t( 'Numbered List' ),
 			buttonIcon: numberedListIcon,
 			buttonIcon: numberedListIcon,
-			toolbarAriaLabel: t( 'Numbered List styles toolbar' ),
+			toolbarAriaLabel: t( 'Numbered list styles toolbar' ),
 			styleDefinitions: [
 			styleDefinitions: [
 				{
 				{
 					label: t( 'Toggle the decimal list style' ),
 					label: t( 'Toggle the decimal list style' ),
@@ -91,24 +94,24 @@ export default class ListStylesUI extends Plugin {
 					icon: listStyleDecimalWithLeadingZeroIcon
 					icon: listStyleDecimalWithLeadingZeroIcon
 				},
 				},
 				{
 				{
-					label: t( 'Toggle the lower roman list style' ),
+					label: t( 'Toggle the lowerroman list style' ),
 					type: 'lower-roman',
 					type: 'lower-roman',
 					icon: listStyleLowerRomanIcon
 					icon: listStyleLowerRomanIcon
 				},
 				},
 				{
 				{
-					label: t( 'Toggle the upper roman list style' ),
+					label: t( 'Toggle the upperroman list style' ),
 					type: 'upper-roman',
 					type: 'upper-roman',
 					icon: listStyleUpperRomanIcon
 					icon: listStyleUpperRomanIcon
 				},
 				},
 				{
 				{
-					label: t( 'Toggle the upper latin list style' ),
-					type: 'upper-latin',
-					icon: listStyleUpperLatinIcon
-				},
-				{
-					label: t( 'Toggle the lower latin list style' ),
+					label: t( 'Toggle the lower–latin list style' ),
 					type: 'lower-latin',
 					type: 'lower-latin',
 					icon: listStyleLowerLatinIcon
 					icon: listStyleLowerLatinIcon
+				},
+				{
+					label: t( 'Toggle the upper–latin list style' ),
+					type: 'upper-latin',
+					icon: listStyleUpperLatinIcon
 				}
 				}
 			]
 			]
 		} ) );
 		} ) );

+ 421 - 3
packages/ckeditor5-list/tests/liststylesui.js

@@ -3,18 +3,436 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
  */
 
 
+/* globals document */
+
+import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor';
+import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
+import BlockQuote from '@ckeditor/ckeditor5-block-quote/src/blockquote';
+import ButtonView from '@ckeditor/ckeditor5-ui/src/button/buttonview';
+import { setData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
+import ListStyles from '../src/liststyles';
 import ListStylesUI from '../src/liststylesui';
 import ListStylesUI from '../src/liststylesui';
+import DropdownView from '@ckeditor/ckeditor5-ui/src/dropdown/dropdownview';
+
+import bulletedListIcon from '../theme/icons/bulletedlist.svg';
+import numberedListIcon from '../theme/icons/numberedlist.svg';
+
+import listStyleDiscIcon from '../theme/icons/liststyledisc.svg';
+import listStyleCircleIcon from '../theme/icons/liststylecircle.svg';
+import listStyleSquareIcon from '../theme/icons/liststylesquare.svg';
+import listStyleDecimalIcon from '../theme/icons/liststyledecimal.svg';
+import listStyleDecimalWithLeadingZeroIcon from '../theme/icons/liststyledecimalleadingzero.svg';
+import listStyleLowerRomanIcon from '../theme/icons/liststylelowerroman.svg';
+import listStyleUpperRomanIcon from '../theme/icons/liststyleupperroman.svg';
+import listStyleLowerLatinIcon from '../theme/icons/liststylelowerlatin.svg';
+import listStyleUpperLatinIcon from '../theme/icons/liststyleupperlatin.svg';
 
 
 describe( 'ListStylesUI', () => {
 describe( 'ListStylesUI', () => {
+	let editorElement, editor, model, listStylesCommand;
+
+	beforeEach( () => {
+		editorElement = document.createElement( 'div' );
+		document.body.appendChild( editorElement );
+
+		return ClassicTestEditor.create( editorElement, { plugins: [ Paragraph, BlockQuote, ListStyles ] } )
+			.then( newEditor => {
+				editor = newEditor;
+				model = editor.model;
+
+				listStylesCommand = editor.commands.get( 'listStyles' );
+				// numberedListCommand = editor.commands.get( 'numberedList' );
+				// numberedListDropdown = editor.ui.componentFactory.create( 'numberedList' );
+			} );
+	} );
+
+	afterEach( () => {
+		editorElement.remove();
+
+		return editor.destroy();
+	} );
+
 	it( 'should be named', () => {
 	it( 'should be named', () => {
 		expect( ListStylesUI.pluginName ).to.equal( 'ListStylesUI' );
 		expect( ListStylesUI.pluginName ).to.equal( 'ListStylesUI' );
 	} );
 	} );
 
 
+	it( 'should be loaded', () => {
+		expect( editor.plugins.get( ListStylesUI ) ).to.be.instanceOf( ListStylesUI );
+	} );
+
 	describe( 'init()', () => {
 	describe( 'init()', () => {
-		it( 'returns null', () => {
-			const plugin = new ListStylesUI( {} );
+		describe( 'bulleted list dropdown', () => {
+			let bulletedListCommand, bulletedListDropdown;
+
+			beforeEach( () => {
+				bulletedListCommand = editor.commands.get( 'bulletedList' );
+				bulletedListDropdown = editor.ui.componentFactory.create( 'bulletedList' );
+			} );
+
+			it( 'should registered as "bulletedList" in the component factory', () => {
+				expect( bulletedListDropdown ).to.be.instanceOf( DropdownView );
+			} );
+
+			it( 'should have #isEnabled bound to the "bulletedList" command state', () => {
+				expect( bulletedListDropdown.isEnabled ).to.be.true;
+
+				bulletedListCommand.isEnabled = true;
+				expect( bulletedListDropdown.isEnabled ).to.be.true;
+
+				bulletedListCommand.isEnabled = false;
+				expect( bulletedListDropdown.isEnabled ).to.be.false;
+			} );
+
+			it( 'should have a specific CSS class', () => {
+				expect( bulletedListDropdown.class ).to.equal( 'ck-list-styles-dropdown' );
+			} );
+
+			describe( 'main split button', () => {
+				let mainButtonView;
+
+				beforeEach( () => {
+					mainButtonView = bulletedListDropdown.buttonView;
+				} );
+
+				it( 'should have a #label', () => {
+					expect( mainButtonView.label ).to.equal( 'Bulleted List' );
+				} );
+
+				it( 'should have an #icon', () => {
+					expect( mainButtonView.icon ).to.equal( bulletedListIcon );
+				} );
+
+				it( 'should have a #tooltip based on a label', () => {
+					expect( mainButtonView.tooltip ).to.be.true;
+				} );
+
+				it( 'should be toggleable', () => {
+					expect( mainButtonView.isToggleable ).to.be.true;
+				} );
+
+				it( 'should have the #isOn state bound to the value of the "bulletedList" command', () => {
+					expect( mainButtonView.isOn ).to.be.false;
+
+					bulletedListCommand.value = 'foo';
+					expect( mainButtonView.isOn ).to.be.true;
+
+					bulletedListCommand.value = null;
+					expect( mainButtonView.isOn ).to.be.false;
+				} );
+
+				it( 'should execute the "bulletedList" command and focus the editing view when clicked', () => {
+					sinon.spy( editor, 'execute' );
+					sinon.spy( editor.editing.view, 'focus' );
+
+					mainButtonView.fire( 'execute' );
+					sinon.assert.calledWithExactly( editor.execute, 'bulletedList' );
+					sinon.assert.calledOnce( editor.editing.view.focus );
+					sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+				} );
+			} );
+
+			describe( 'toolbar with style buttons', () => {
+				let toolbarView;
+
+				beforeEach( () => {
+					toolbarView = bulletedListDropdown.toolbarView;
+				} );
+
+				it( 'should be in the dropdown panel', () => {
+					expect( bulletedListDropdown.panelView.children.get( 0 ) ).to.equal( toolbarView );
+				} );
+
+				it( 'should have a proper ARIA label', () => {
+					expect( toolbarView.ariaLabel ).to.equal( 'Bulleted list styles toolbar' );
+				} );
+
+				it( 'should bring the "disc" list style button', () => {
+					const buttonView = toolbarView.items.get( 0 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the "disc" list style' );
+					expect( buttonView.icon ).to.equal( listStyleDiscIcon );
+				} );
+
+				it( 'should bring the "circle" list style button', () => {
+					const buttonView = toolbarView.items.get( 1 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the "circle" list style' );
+					expect( buttonView.icon ).to.equal( listStyleCircleIcon );
+				} );
+
+				it( 'should bring the "square" list style button', () => {
+					const buttonView = toolbarView.items.get( 2 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the "square" list style' );
+					expect( buttonView.icon ).to.equal( listStyleSquareIcon );
+				} );
+
+				describe( 'style button', () => {
+					let styleButtonView;
+
+					beforeEach( () => {
+						// "circle"
+						styleButtonView = toolbarView.items.get( 1 );
+
+						sinon.spy( editor, 'execute' );
+						sinon.spy( editor.editing.view, 'focus' );
+					} );
+
+					it( 'should be instances of ButtonView', () => {
+						expect( styleButtonView ).to.be.instanceOf( ButtonView );
+					} );
+
+					it( 'should change its #isOn state when the value of the "listStylesCommand" command changes', () => {
+						expect( styleButtonView.isOn ).to.be.false;
+
+						listStylesCommand.value = 'foo';
+						expect( styleButtonView.isOn ).to.be.false;
+
+						listStylesCommand.value = 'circle';
+						expect( styleButtonView.isOn ).to.be.true;
+
+						listStylesCommand.value = null;
+						expect( styleButtonView.isOn ).to.be.false;
+					} );
+
+					it( 'should apply the new style if none was set', () => {
+						setData( model, '<listItem listType="bulleted" listIndent="0">[]foo</listItem>' );
+
+						styleButtonView.fire( 'execute' );
+
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'circle' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+
+					it( 'should apply the new style if a different one was set', () => {
+						setData( model, '<listItem listType="bulleted" listStyle="square" listIndent="0">[]foo</listItem>' );
+
+						styleButtonView.fire( 'execute' );
+
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'circle' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+
+					it( 'should remove (toggle) the style if the same style was set', () => {
+						setData( model, '<listItem listType="bulleted" listStyle="circle" listIndent="0">[]foo</listItem>' );
+
+						styleButtonView.fire( 'execute' );
+
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'default' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+
+					it( 'should execute the "bulletedList" command and apply the style if selection was not anchored in a list', () => {
+						setData( model, '<paragraph>foo[]</paragraph>' );
+
+						styleButtonView.fire( 'execute' );
+
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'circle' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+				} );
+			} );
+		} );
+
+		describe( 'numbered list dropdown', () => {
+			let numberedListCommand, numberedListDropdown;
+
+			beforeEach( () => {
+				numberedListCommand = editor.commands.get( 'numberedList' );
+				numberedListDropdown = editor.ui.componentFactory.create( 'numberedList' );
+			} );
+
+			it( 'should registered as "numberedList" in the component factory', () => {
+				expect( numberedListDropdown ).to.be.instanceOf( DropdownView );
+			} );
+
+			it( 'should have #isEnabled bound to the "numberedList" command state', () => {
+				expect( numberedListDropdown.isEnabled ).to.be.true;
+
+				numberedListCommand.isEnabled = true;
+				expect( numberedListDropdown.isEnabled ).to.be.true;
+
+				numberedListCommand.isEnabled = false;
+				expect( numberedListDropdown.isEnabled ).to.be.false;
+			} );
+
+			it( 'should have a specific CSS class', () => {
+				expect( numberedListDropdown.class ).to.equal( 'ck-list-styles-dropdown' );
+			} );
+
+			describe( 'main split button', () => {
+				let mainButtonView;
+
+				beforeEach( () => {
+					mainButtonView = numberedListDropdown.buttonView;
+				} );
+
+				it( 'should have a #label', () => {
+					expect( mainButtonView.label ).to.equal( 'Numbered List' );
+				} );
+
+				it( 'should have an #icon', () => {
+					expect( mainButtonView.icon ).to.equal( numberedListIcon );
+				} );
+
+				it( 'should have a #tooltip based on a label', () => {
+					expect( mainButtonView.tooltip ).to.be.true;
+				} );
+
+				it( 'should be toggleable', () => {
+					expect( mainButtonView.isToggleable ).to.be.true;
+				} );
+
+				it( 'should have the #isOn state bound to the value of the "numberedList" command', () => {
+					expect( mainButtonView.isOn ).to.be.false;
+
+					numberedListCommand.value = 'foo';
+					expect( mainButtonView.isOn ).to.be.true;
+
+					numberedListCommand.value = null;
+					expect( mainButtonView.isOn ).to.be.false;
+				} );
+
+				it( 'should execute the "numberedList" command and focus the editing view when clicked', () => {
+					sinon.spy( editor, 'execute' );
+					sinon.spy( editor.editing.view, 'focus' );
+
+					mainButtonView.fire( 'execute' );
+					sinon.assert.calledWithExactly( editor.execute, 'numberedList' );
+					sinon.assert.calledOnce( editor.editing.view.focus );
+					sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+				} );
+			} );
+
+			describe( 'toolbar with style buttons', () => {
+				let toolbarView;
+
+				beforeEach( () => {
+					toolbarView = numberedListDropdown.toolbarView;
+				} );
+
+				it( 'should be in the dropdown panel', () => {
+					expect( numberedListDropdown.panelView.children.get( 0 ) ).to.equal( toolbarView );
+				} );
+
+				it( 'should have a proper ARIA label', () => {
+					expect( toolbarView.ariaLabel ).to.equal( 'Numbered list styles toolbar' );
+				} );
+
+				it( 'should bring the "decimal" list style button', () => {
+					const buttonView = toolbarView.items.get( 0 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the decimal list style' );
+					expect( buttonView.icon ).to.equal( listStyleDecimalIcon );
+				} );
+
+				it( 'should bring the "decimal-leading-zero" list style button', () => {
+					const buttonView = toolbarView.items.get( 1 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the decimal with leading zero list style' );
+					expect( buttonView.icon ).to.equal( listStyleDecimalWithLeadingZeroIcon );
+				} );
+
+				it( 'should bring the "lower-roman" list style button', () => {
+					const buttonView = toolbarView.items.get( 2 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the lower–roman list style' );
+					expect( buttonView.icon ).to.equal( listStyleLowerRomanIcon );
+				} );
+
+				it( 'should bring the "upper-roman" list style button', () => {
+					const buttonView = toolbarView.items.get( 3 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the upper–roman list style' );
+					expect( buttonView.icon ).to.equal( listStyleUpperRomanIcon );
+				} );
+
+				it( 'should bring the "lower–latin" list style button', () => {
+					const buttonView = toolbarView.items.get( 4 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the lower–latin list style' );
+					expect( buttonView.icon ).to.equal( listStyleLowerLatinIcon );
+				} );
+
+				it( 'should bring the "upper–latin" list style button', () => {
+					const buttonView = toolbarView.items.get( 5 );
+
+					expect( buttonView.label ).to.equal( 'Toggle the upper–latin list style' );
+					expect( buttonView.icon ).to.equal( listStyleUpperLatinIcon );
+				} );
+
+				describe( 'style button', () => {
+					let styleButtonView;
+
+					beforeEach( () => {
+						// "decimal-leading-zero""
+						styleButtonView = toolbarView.items.get( 1 );
+
+						sinon.spy( editor, 'execute' );
+						sinon.spy( editor.editing.view, 'focus' );
+					} );
+
+					it( 'should be instances of ButtonView', () => {
+						expect( styleButtonView ).to.be.instanceOf( ButtonView );
+					} );
+
+					it( 'should change its #isOn state when the value of the "listStylesCommand" command changes', () => {
+						expect( styleButtonView.isOn ).to.be.false;
+
+						listStylesCommand.value = 'foo';
+						expect( styleButtonView.isOn ).to.be.false;
+
+						listStylesCommand.value = 'decimal-leading-zero';
+						expect( styleButtonView.isOn ).to.be.true;
+
+						listStylesCommand.value = null;
+						expect( styleButtonView.isOn ).to.be.false;
+					} );
+
+					it( 'should apply the new style if none was set', () => {
+						setData( model, '<listItem listType="numbered" listIndent="0">[]foo</listItem>' );
+
+						styleButtonView.fire( 'execute' );
+
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'decimal-leading-zero' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+
+					it( 'should apply the new style if a different one was set', () => {
+						setData( model, '<listItem listType="numbered" listStyle="square" listIndent="0">[]foo</listItem>' );
+
+						styleButtonView.fire( 'execute' );
+
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'decimal-leading-zero' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+
+					it( 'should remove (toggle) the style if the same style was set', () => {
+						setData( model, '<listItem listType="numbered" listStyle="decimal-leading-zero" listIndent="0">[]foo</listItem>' );
+
+						styleButtonView.fire( 'execute' );
+
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'default' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+
+					it( 'should execute the "numberedList" command and apply the style if selection was not anchored in a list', () => {
+						setData( model, '<paragraph>foo[]</paragraph>' );
+
+						styleButtonView.fire( 'execute' );
 
 
-			expect( plugin.init() ).to.equal( null );
+						sinon.assert.calledWithExactly( editor.execute, 'listStyles', { type: 'decimal-leading-zero' } );
+						sinon.assert.calledOnce( editor.editing.view.focus );
+						sinon.assert.callOrder( editor.execute, editor.editing.view.focus );
+					} );
+				} );
+			} );
 		} );
 		} );
 	} );
 	} );
 } );
 } );