/** * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /* global document */ import CodeBlockEditing from '../src/codeblockediting'; import CodeBlockCommand from '../src/codeblockcommand'; import AlignmentEditing from '@ckeditor/ckeditor5-alignment/src/alignmentediting'; import BoldEditing from '@ckeditor/ckeditor5-basic-styles/src/bold/boldediting'; import Enter from '@ckeditor/ckeditor5-enter/src/enter'; import ShiftEnter from '@ckeditor/ckeditor5-enter/src/shiftenter'; import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph'; import ClassicTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/classictesteditor'; import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model'; import { getData as getViewData } from '@ckeditor/ckeditor5-engine/src/dev-utils/view'; describe( 'CodeBlockEditing', () => { let editor, element, model, view; beforeEach( () => { element = document.createElement( 'div' ); document.body.appendChild( element ); return ClassicTestEditor .create( element, { plugins: [ CodeBlockEditing, AlignmentEditing, BoldEditing, Enter, Paragraph ] } ) .then( newEditor => { editor = newEditor; model = editor.model; view = editor.editing.view; } ); } ); afterEach( () => { return editor.destroy().then( () => element.remove() ); } ); it( 'defines plugin name', () => { expect( CodeBlockEditing.pluginName ).to.equal( 'CodeBlockEditing' ); } ); it( 'defines plugin dependencies', () => { expect( CodeBlockEditing.requires ).to.have.members( [ ShiftEnter ] ); } ); it( 'adds a codeBlock command', () => { expect( editor.commands.get( 'codeBlock' ) ).to.be.instanceOf( CodeBlockCommand ); } ); it( 'allows for codeBlock in the $root', () => { expect( model.schema.checkChild( [ '$root' ], 'codeBlock' ) ).to.be.true; } ); it( 'allows only for $text in codeBlock', () => { expect( model.schema.checkChild( [ '$root', 'codeBlock' ], '$text' ) ).to.equal( true ); expect( model.schema.checkChild( [ '$root', 'codeBlock' ], '$block' ) ).to.equal( false ); expect( model.schema.checkChild( [ '$root', 'codeBlock' ], 'codeBlock' ) ).to.equal( false ); } ); it( 'disallows all attributes for codeBlock', () => { setModelData( model, 'f[o]o' ); editor.execute( 'alignment', { value: 'right' } ); editor.execute( 'bold' ); expect( getModelData( model ) ).to.equal( 'f[o]o' ); } ); it( 'should force shiftEnter command when pressing enter inside a codeBlock', () => { const enterCommand = editor.commands.get( 'enter' ); const shiftEnterCommand = editor.commands.get( 'shiftEnter' ); sinon.spy( enterCommand, 'execute' ); sinon.spy( shiftEnterCommand, 'execute' ); setModelData( model, 'foo[]bar' ); editor.editing.view.document.fire( 'enter', { preventDefault: () => {} } ); expect( getModelData( model ) ).to.equal( 'foo[]bar' ); sinon.assert.calledOnce( shiftEnterCommand.execute ); sinon.assert.notCalled( enterCommand.execute ); } ); it( 'should execute enter command when pressing enter out of codeBlock', () => { const enterCommand = editor.commands.get( 'enter' ); const shiftEnterCommand = editor.commands.get( 'shiftEnter' ); sinon.spy( enterCommand, 'execute' ); sinon.spy( shiftEnterCommand, 'execute' ); setModelData( model, 'foo[]bar' ); editor.editing.view.document.fire( 'enter', { preventDefault: () => {} } ); expect( getModelData( model ) ).to.equal( 'foo[]bar' ); sinon.assert.calledOnce( enterCommand.execute ); sinon.assert.notCalled( shiftEnterCommand.execute ); } ); describe( 'editing pipeline m -> v', () => { it( 'should convert empty codeBlock to empty pre tag', () => { setModelData( model, '' ); expect( getViewData( view ) ).to.equal( '
[]
' ); } ); it( 'should convert non-empty codeBlock to pre tag', () => { setModelData( model, 'Foo' ); expect( getViewData( view ) ).to.equal( '
{}Foo
' ); } ); it( 'should convert codeBlock with softBreaks to pre tag #1', () => { setModelData( model, '' + 'Foo' + 'Bar' + 'Biz' + '' ); expect( getViewData( view ) ).to.equal( '
{}Foo

Bar

Biz
' ); } ); it( 'should convert codeBlock with softBreaks to pre tag #2', () => { setModelData( model, '' + '' + '' + 'Foo' + '' + '' + '' ); expect( getViewData( view ) ).to.equal( '
[]



Foo



' ); } ); } ); describe( 'data pipeline m -> v conversion ', () => { it( 'should convert empty codeBlock to empty pre tag', () => { setModelData( model, '' ); expect( editor.getData( { trim: 'none' } ) ).to.equal( '
 
' ); } ); it( 'should convert non-empty codeBlock to pre tag', () => { setModelData( model, 'Foo' ); expect( editor.getData() ).to.equal( '
Foo
' ); } ); it( 'should convert codeBlock with softBreaks to pre tag #1', () => { setModelData( model, '' + 'Foo' + 'Bar' + 'Biz' + '' ); expect( editor.getData() ).to.equal( '
Foo\nBar\nBiz
' ); } ); it( 'should convert codeBlock with softBreaks to pre tag #2', () => { setModelData( model, '' + '' + '' + 'Foo' + '' + '' + '' ); expect( editor.getData() ).to.equal( '
\n\nFoo\n\n
' ); } ); } ); describe( 'data pipeline v -> m conversion ', () => { it( 'should not convert empty pre tag to code block', () => { editor.setData( '
' );

			expect( getModelData( model ) ).to.equal( '[]' );
		} );

		it( 'should not convert pre with no code child to code block', () => {
			editor.setData( '
' ); expect( getModelData( model ) ).to.equal( '[]' ); } ); it( 'should convert pre > code to code block', () => { editor.setData( '
' ); expect( getModelData( model ) ).to.equal( '[]' ); } ); it( 'should convert pre > code with multi-line text to code block #1', () => { editor.setData( '
foo\nbar
' ); expect( getModelData( model ) ).to.equal( '[]' + 'foo' + '' + 'bar' + '' ); } ); it( 'should convert pre > code with multi-line text to code block #2', () => { editor.setData( '
\n\nfoo\n\n
' ); expect( getModelData( model ) ).to.equal( '[]' + '' + '' + 'foo' + '' + '' + '' ); } ); it( 'should convert pre > code with HTML inside', () => { editor.setData( '

Foo

\n

Bar

' ); expect( getModelData( model ) ).to.equal( '[]' + '

Foo

' + '' + '

Bar

' + '
' ); } ); it( 'should convert pre tag with HTML and nested pre tag', () => { editor.setData( '

Foo

Bar

Biz

' ); expect( getModelData( model ) ).to.equal( '[]

Foo

Bar

Biz

' ); } ); } ); } );