/** * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md. */ import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor'; import ParagraphCommand from '../src/paragraphcommand'; import Selection from '@ckeditor/ckeditor5-engine/src/model/selection'; import Range from '@ckeditor/ckeditor5-engine/src/model/range'; import { setData, getData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; describe( 'ParagraphCommand', () => { let editor, document, command, root, schema; beforeEach( () => { return ModelTestEditor.create().then( newEditor => { editor = newEditor; document = editor.document; schema = document.schema; command = new ParagraphCommand( editor ); root = document.getRoot(); editor.commands.add( 'paragraph', command ); schema.registerItem( 'paragraph', '$block' ); schema.registerItem( 'heading1', '$block' ); schema.registerItem( 'notBlock' ); schema.allow( { name: 'notBlock', inside: '$root' } ); schema.allow( { name: '$text', inside: 'notBlock' } ); } ); } ); afterEach( () => { command.destroy(); } ); describe( 'value', () => { it( 'responds to changes in selection (collapsed selection)', () => { setData( document, 'foo[]bar' ); expect( command.value ).to.be.false; setData( document, 'foo[]bar' ); expect( command.value ).to.be.true; } ); it( 'responds to changes in selection (non–collapsed selection)', () => { setData( document, '[foo]bar' ); expect( command.value ).to.be.false; setData( document, '[foobar]' ); expect( command.value ).to.be.false; setData( document, 'foo[bar]' ); expect( command.value ).to.be.true; setData( document, 'foo[bar]' ); expect( command.value ).to.be.true; setData( document, '[barfoo]' ); expect( command.value ).to.be.true; } ); it( 'has proper value when inside non-block element', () => { setData( document, '[foo]' ); expect( command.value ).to.be.false; } ); it( 'has proper value when moved from block to element that is not a block', () => { setData( document, '[foo]foo' ); const element = document.getRoot().getChild( 1 ); document.enqueueChanges( () => { document.selection.setRanges( [ Range.createIn( element ) ] ); } ); expect( command.value ).to.be.false; } ); it( 'should be refreshed after calling refresh()', () => { setData( document, '[foo]foo' ); const element = document.getRoot().getChild( 1 ); // Purposely not putting it in `document.enqueueChanges` to update command manually. document.selection.setRanges( [ Range.createIn( element ) ] ); expect( command.value ).to.be.true; command.refresh(); expect( command.value ).to.be.false; } ); } ); describe( 'execute()', () => { it( 'should update value after execution', () => { setData( document, '[]' ); command.execute(); expect( getData( document ) ).to.equal( '[]' ); expect( command.value ).to.be.true; } ); // https://github.com/ckeditor/ckeditor5-paragraph/issues/24 it( 'should not rename blocks which cannot become paragraphs', () => { document.schema.registerItem( 'restricted' ); document.schema.allow( { name: 'restricted', inside: '$root' } ); document.schema.disallow( { name: 'paragraph', inside: 'restricted' } ); document.schema.registerItem( 'fooBlock', '$block' ); document.schema.allow( { name: 'fooBlock', inside: 'restricted' } ); setData( document, 'a[bc' + '' + 'de]f' ); command.execute(); expect( getData( document ) ).to.equal( 'a[bc' + '' + 'de]f' ); } ); it( 'should not rename blocks which already are pargraphs', () => { const batch = editor.document.batch(); setData( document, 'foo[bar]' ); expect( batch.deltas.length ).to.equal( 0 ); command.execute( { batch } ); expect( batch.deltas.length ).to.equal( 1 ); } ); describe( 'custom options', () => { it( 'should use provided batch', () => { const batch = editor.document.batch(); setData( document, 'foo[]bar' ); expect( batch.deltas.length ).to.equal( 0 ); command.execute( { batch } ); expect( batch.deltas.length ).to.be.above( 0 ); } ); it( 'should use provided selection', () => { setData( document, 'foo[]barbazqux' ); const secondTolastHeading = root.getChild( 1 ); const lastHeading = root.getChild( 2 ); const selection = new Selection(); selection.addRange( Range.createFromParentsAndOffsets( secondTolastHeading, 0, lastHeading, 0 ) ); command.execute( { selection } ); expect( getData( document ) ).to.equal( 'foo[]barbazqux' ); } ); } ); describe( 'collapsed selection', () => { it( 'does nothing when executed with already applied', () => { setData( document, 'foo[]bar' ); command.execute(); expect( getData( document ) ).to.equal( 'foo[]bar' ); } ); it( 'converts topmost blocks', () => { schema.registerItem( 'inlineImage', '$inline' ); schema.allow( { name: '$text', inside: 'inlineImage' } ); setData( document, 'foo[]bar' ); command.execute(); expect( getData( document ) ).to.equal( 'foo[]bar' ); } ); } ); describe( 'non-collapsed selection', () => { it( 'converts all elements where selection is applied', () => { schema.registerItem( 'heading2', '$block' ); setData( document, 'foo[bar]baz' ); command.execute(); expect( getData( document ) ).to.equal( 'foo[bar]baz' ); } ); it( 'converts all elements even if already anchored in paragraph', () => { schema.registerItem( 'heading2', '$block' ); setData( document, 'foo[bar]' ); command.execute(); expect( getData( document ) ).to.equal( 'foo[bar]' ); } ); } ); } ); describe( 'isEnabled', () => { it( 'should be enabled when inside another block', () => { setData( document, 'f{}oo' ); expect( command.isEnabled ).to.be.true; } ); it( 'should be disabled if inside non-block', () => { setData( document, 'f{}oo' ); expect( command.isEnabled ).to.be.false; } ); it( 'should be disabled if selection is placed on non-block element', () => { setData( document, '[foo]' ); expect( command.isEnabled ).to.be.false; } ); } ); } );