/**
* @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
*/
import CodeBlockEditing from '../src/codeblockediting';
import OutdentCodeBlockCommand from '../src/outdentcodeblockcommand';
import AlignmentEditing from '@ckeditor/ckeditor5-alignment/src/alignmentediting';
import BoldEditing from '@ckeditor/ckeditor5-basic-styles/src/bold/boldediting';
import Paragraph from '@ckeditor/ckeditor5-paragraph/src/paragraph';
import BlockQuoteEditing from '@ckeditor/ckeditor5-block-quote/src/blockquoteediting';
import ModelTestEditor from '@ckeditor/ckeditor5-core/tests/_utils/modeltesteditor';
import { getData as getModelData, setData as setModelData } from '@ckeditor/ckeditor5-engine/src/dev-utils/model';
describe( 'OutdentCodeBlockCommand', () => {
let editor, model, outdentCommand;
beforeEach( () => {
return ModelTestEditor
.create( {
plugins: [ CodeBlockEditing, Paragraph, BlockQuoteEditing, AlignmentEditing, BoldEditing ]
} )
.then( newEditor => {
editor = newEditor;
model = editor.model;
outdentCommand = new OutdentCodeBlockCommand( editor, 'backward' );
} );
} );
afterEach( () => {
return editor.destroy();
} );
describe( '#isEnabled', () => {
it( 'should be true when the selection is in a line containing the indent sequence', () => {
setModelData( model, 'f[]oo' );
// f[]oo
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
expect( outdentCommand.isEnabled ).to.be.true;
} );
it( 'should be true when any line in the selection contains more than the indent sequence', () => {
setModelData( model, 'f[ooba]r' );
// f[ooba]r
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
expect( outdentCommand.isEnabled ).to.be.true;
} );
it( 'should be true when any line in the selection contains the indent sequence', () => {
setModelData( model, 'f[ooba]r' );
// f[oo ba]r
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 1 ) );
} );
expect( outdentCommand.isEnabled ).to.be.true;
} );
it( 'should be false when the indent sequence is in other element', () => {
setModelData( model, 'foo[]' );
// foo[]
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
expect( outdentCommand.isEnabled ).to.be.false;
} );
it( 'should be false when there is no indent sequence in the line (caret inside text)', () => {
setModelData( model, 'f[]oo' );
expect( outdentCommand.isEnabled ).to.be.false;
} );
it( 'should be false when there is no indent sequence in the line (empty line)', () => {
setModelData( model, '[]' );
expect( outdentCommand.isEnabled ).to.be.false;
} );
it( 'should be false when there is no indent sequence in the line (caret at the end of a block)', () => {
setModelData( model, 'foo[]' );
expect( outdentCommand.isEnabled ).to.be.false;
} );
it( 'should be false when there is no corrent sequence in the line', () => {
setModelData( model, 'foo[]' );
// foo[]
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
expect( outdentCommand.isEnabled ).to.be.false;
} );
it( 'should be false when the sequence is not in leading characters of the line', () => {
setModelData( model, 'barfoo[]' );
// bar foo[]
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ), 3 );
} );
expect( outdentCommand.isEnabled ).to.be.false;
} );
it( 'should be false when the sequence is not in leading characters of the line (after other white-space characters)', () => {
setModelData( model, 'foo[]' );
// foo[]
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ), 0 );
} );
expect( outdentCommand.isEnabled ).to.be.false;
} );
describe( 'config.codeBlock.indentSequence', () => {
it( 'should be respected (#1)', () => {
return ModelTestEditor
.create( {
plugins: [ CodeBlockEditing, Paragraph, BlockQuoteEditing, AlignmentEditing, BoldEditing ],
codeBlock: {
indentSequence: ' '
}
} )
.then( newEditor => {
const editor = newEditor;
const model = editor.model;
const outdentCommand = new OutdentCodeBlockCommand( editor );
setModelData( model, 'foo[]' );
// foo[]
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
expect( outdentCommand.isEnabled ).to.be.true;
return editor.destroy();
} );
} );
it( 'should be respected (#2)', () => {
return ModelTestEditor
.create( {
plugins: [ CodeBlockEditing, Paragraph, BlockQuoteEditing, AlignmentEditing, BoldEditing ],
codeBlock: {
indentSequence: ' '
}
} )
.then( newEditor => {
const editor = newEditor;
const model = editor.model;
const outdentCommand = new OutdentCodeBlockCommand( editor );
setModelData( model, ' foo[]' );
// foo[]
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
expect( outdentCommand.isEnabled ).to.be.false;
return editor.destroy();
} );
} );
it( 'should disable the command when the config is not set', () => {
return ModelTestEditor
.create( {
plugins: [ CodeBlockEditing, Paragraph, BlockQuoteEditing, AlignmentEditing, BoldEditing ],
codeBlock: {
indentSequence: false
}
} )
.then( newEditor => {
const editor = newEditor;
const model = editor.model;
const outdentCommand = new OutdentCodeBlockCommand( editor );
setModelData( model, 'foo[]' );
// foo[]
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
expect( outdentCommand.isEnabled ).to.be.false;
return editor.destroy();
} );
} );
} );
} );
describe( 'execute()', () => {
it( 'should outdent a single line', () => {
setModelData( model, 'f[]oo' );
// f[]oo
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
outdentCommand.execute();
expect( getModelData( model ) ).to.equal( 'f[]oo' );
} );
it( 'should outdent only one level in a single line', () => {
setModelData( model, 'f[]oo' );
// f[]oo
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
outdentCommand.execute();
expect( getModelData( model ) ).to.equal( ' f[]oo' );
} );
it( 'should outdent multiple lines', () => {
setModelData( model, 'f[ooba]r' );
// f[oo ba]r
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ), 4 );
writer.insertText( ' ', model.document.getRoot().getChild( 0 ), 0 );
} );
outdentCommand.execute();
expect( getModelData( model ) ).to.equal( 'f[ooba]r' );
} );
it( 'should outdent only one level across multiple lines', () => {
setModelData( model, 'f[ooba]r' );
// f[oo ba]r
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ), 4 );
writer.insertText( ' ', model.document.getRoot().getChild( 0 ), 0 );
} );
outdentCommand.execute();
expect( getModelData( model ) ).to.equal( 'f[oo ba]r' );
} );
it( 'should outdent some lines', () => {
setModelData( model, 'f[ooba]r' );
// f[oo ba]r
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ), 4 );
} );
outdentCommand.execute();
expect( getModelData( model ) ).to.equal( 'f[ooba]r' );
} );
describe( 'config.codeBlock.indentSequence', () => {
it( 'should be respected', () => {
return ModelTestEditor
.create( {
plugins: [ CodeBlockEditing, Paragraph, BlockQuoteEditing, AlignmentEditing, BoldEditing ],
codeBlock: {
indentSequence: ' '
}
} )
.then( newEditor => {
const editor = newEditor;
const model = editor.model;
const outdentCommand = new OutdentCodeBlockCommand( editor );
setModelData( model, 'f[]oo' );
// f[]oo
model.change( writer => {
writer.insertText( ' ', model.document.getRoot().getChild( 0 ) );
} );
outdentCommand.execute();
expect( getModelData( model ) ).to.equal( 'f[]oo' );
return editor.destroy();
} );
} );
} );
} );
} );