Skip to content

Commit

Permalink
Add more tests for the re-conversion scenarios.
Browse files Browse the repository at this point in the history
  • Loading branch information
jodator committed Oct 8, 2020
1 parent 8081dce commit 7e359d8
Showing 1 changed file with 221 additions and 11 deletions.
232 changes: 221 additions & 11 deletions packages/ckeditor5-engine/tests/conversion/downcasthelpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ describe( 'DowncastHelpers', () => {
} );

describe( 'config.triggerBy', () => {
describe( 'with simple block view structure', () => {
describe( 'with simple block view structure (without children)', () => {
beforeEach( () => {
model.schema.register( 'simpleBlock', {
allowIn: '$root',
Expand Down Expand Up @@ -144,21 +144,32 @@ describe( 'DowncastHelpers', () => {
it( 'should convert on attribute set', () => {
setModelData( model, '<simpleBlock></simpleBlock>' );

const [ viewBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
} );

const [ viewAfter ] = getNodes();

expectResult( '<div style="display:block"></div>' );
expect( viewAfter ).to.not.equal( viewBefore );
} );

it( 'should convert on attribute change', () => {
setModelData( model, '<simpleBlock toStyle="display:block"></simpleBlock>' );

const [ viewBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'toStyle', 'display:inline', modelRoot.getChild( 0 ) );
} );

const [ viewAfter ] = getNodes();

expectResult( '<div style="display:inline"></div>' );

expect( viewAfter ).to.not.equal( viewBefore );
} );

it( 'should convert on attribute remove', () => {
Expand All @@ -185,11 +196,131 @@ describe( 'DowncastHelpers', () => {
it( 'should do nothing if non-triggerBy attribute has changed', () => {
setModelData( model, '<simpleBlock></simpleBlock>' );

const [ viewBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'notTriggered', true, modelRoot.getChild( 0 ) );
} );

const [ viewAfter ] = getNodes();

expectResult( '<div></div>' );

expect( viewAfter ).to.equal( viewBefore );
} );
} );

describe( 'with simple block view structure (with children)', () => {
beforeEach( () => {
model.schema.register( 'simpleBlock', {
allowIn: '$root',
allowAttributes: [ 'toStyle', 'toClass' ]
} );
downcastHelpers.elementToElement( {
model: 'simpleBlock',
view: ( modelElement, { writer } ) => {
return writer.createContainerElement( 'div', getViewAttributes( modelElement ) );
},
triggerBy: [
'attribute:toStyle:simpleBlock',
'attribute:toClass:simpleBlock'
]
} );

model.schema.register( 'paragraph', {
inheritAllFrom: '$block',
allowIn: 'simpleBlock'
} );
downcastHelpers.elementToElement( { model: 'paragraph', view: 'p' } );
} );

it( 'should convert on insert', () => {
model.change( writer => {
const simpleBlock = writer.createElement( 'simpleBlock' );
const paragraph = writer.createElement( 'paragraph' );

writer.insert( simpleBlock, modelRoot, 0 );
writer.insert( paragraph, simpleBlock, 0 );
writer.insertText( 'foo', paragraph, 0 );
} );

expectResult( '<div><p>foo</p></div>' );
} );

it( 'should convert on attribute set', () => {
setModelData( model, '<simpleBlock><paragraph>foo</paragraph></simpleBlock>' );

const [ viewBefore, paraBefore, textBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
} );

const [ viewAfter, paraAfter, textAfter ] = getNodes();

expectResult( '<div style="display:block"><p>foo</p></div>' );

expect( viewAfter, 'simpleBlock' ).to.not.equal( viewBefore );
expect( paraAfter, 'para' ).to.equal( paraBefore );
expect( textAfter, 'text' ).to.equal( textBefore );
} );

it( 'should convert on attribute change', () => {
setModelData( model, '<simpleBlock toStyle="display:block"><paragraph>foo</paragraph></simpleBlock>' );

const [ viewBefore, paraBefore, textBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'toStyle', 'display:inline', modelRoot.getChild( 0 ) );
} );

const [ viewAfter, paraAfter, textAfter ] = getNodes();

expectResult( '<div style="display:inline"><p>foo</p></div>' );

expect( viewAfter, 'simpleBlock' ).to.not.equal( viewBefore );
expect( paraAfter, 'para' ).to.equal( paraBefore );
expect( textAfter, 'text' ).to.equal( textBefore );
} );

it( 'should convert on attribute remove', () => {
setModelData( model, '<simpleBlock toStyle="display:block"><paragraph>foo</paragraph></simpleBlock>' );

model.change( writer => {
writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
} );

expectResult( '<div><p>foo</p></div>' );
} );

it( 'should convert on one attribute add and other remove', () => {
setModelData( model, '<simpleBlock toStyle="display:block"><paragraph>foo</paragraph></simpleBlock>' );

model.change( writer => {
writer.removeAttribute( 'toStyle', modelRoot.getChild( 0 ) );
writer.setAttribute( 'toClass', true, modelRoot.getChild( 0 ) );
} );

expectResult( '<div class="is-classy"><p>foo</p></div>' );
} );

it( 'should do nothing if non-triggerBy attribute has changed', () => {
setModelData( model, '<simpleBlock><paragraph>foo</paragraph></simpleBlock>' );

const [ viewBefore, paraBefore, textBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'notTriggered', true, modelRoot.getChild( 0 ) );
} );

const [ viewAfter, paraAfter, textAfter ] = getNodes();

expectResult( '<div><p>foo</p></div>' );

expect( viewAfter, 'simpleBlock' ).to.equal( viewBefore );
expect( paraAfter, 'para' ).to.equal( paraBefore );
// TODO - is text always re-converted?
expect( textAfter, 'text' ).to.equal( textBefore );
} );
} );

Expand Down Expand Up @@ -227,11 +358,17 @@ describe( 'DowncastHelpers', () => {
it( 'should convert on attribute set', () => {
setModelData( model, '<complex></complex>' );

const [ outerDivBefore, innerDivBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
} );

const [ outerDivAfter, innerDivAfter ] = getNodes();

expectResult( '<div class="complex-outer"><div style="display:block"></div></div>' );
expect( outerDivAfter, 'outer div' ).to.not.equal( outerDivBefore );
expect( innerDivAfter, 'inner div' ).to.not.equal( innerDivBefore );
} );

it( 'should convert on attribute change', () => {
Expand Down Expand Up @@ -268,11 +405,18 @@ describe( 'DowncastHelpers', () => {
it( 'should do nothing if non-triggerBy attribute has changed', () => {
setModelData( model, '<complex></complex>' );

const [ outerDivBefore, innerDivBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'notTriggered', true, modelRoot.getChild( 0 ) );
} );

const [ outerDivAfter, innerDivAfter ] = getNodes();

expectResult( '<div class="complex-outer"><div></div></div>' );

expect( outerDivAfter, 'outer div' ).to.equal( outerDivBefore );
expect( innerDivAfter, 'inner div' ).to.equal( innerDivBefore );
} );
} );

Expand Down Expand Up @@ -360,15 +504,16 @@ describe( 'DowncastHelpers', () => {
it( 'should create new element on re-converting element', () => {
setModelData( model, '<complex></complex>' );

const renderedView = viewRoot.getChild( 0 );
const [ outerBefore, innerBefore ] = getNodes();

model.change( writer => {
writer.setAttribute( 'toStyle', 'display:block', modelRoot.getChild( 0 ) );
} );

const viewAfterReRender = viewRoot.getChild( 0 );
const [ outerAfter, innerAfter ] = getNodes();

expect( viewAfterReRender ).to.not.equal( renderedView );
expect( outerAfter, 'outer' ).to.not.equal( outerBefore );
expect( innerAfter, 'inner' ).to.not.equal( innerBefore );
} );

// Skipped, as it would require two-level mapping. See https://github.com/ckeditor/ckeditor5/issues/1589.
Expand Down Expand Up @@ -505,8 +650,8 @@ describe( 'DowncastHelpers', () => {
it( 'should convert element on adding slot', () => {
setModelData( model,
'<complex>' +
'<slot><paragraph>foo</paragraph></slot>' +
'<slot><paragraph>bar</paragraph></slot>' +
'<slot><paragraph>foo</paragraph></slot>' +
'<slot><paragraph>bar</paragraph></slot>' +
'</complex>' );

model.change( writer => {
Expand All @@ -515,11 +660,11 @@ describe( 'DowncastHelpers', () => {

expectResult(
'<div class="complex-slots">' +
'<div class="slots">' +
'<div class="slot"><p>foo</p></div>' +
'<div class="slot"><p>bar</p></div>' +
'<div class="slot"><p>baz</p></div>' +
'</div>' +
'<div class="slots">' +
'<div class="slot"><p>foo</p></div>' +
'<div class="slot"><p>bar</p></div>' +
'<div class="slot"><p>baz</p></div>' +
'</div>' +
'</div>'
);
} );
Expand Down Expand Up @@ -982,6 +1127,15 @@ describe( 'DowncastHelpers', () => {
writer.insert( paragraph, slot, 0 );
writer.insert( slot, modelRoot.getChild( 0 ), 'end' );
}

function* getNodes() {
const main = viewRoot.getChild( 0 );
yield main;

for ( const value of controller.view.createRangeIn( main ) ) {
yield value.item;
}
}
} );
} );

Expand Down Expand Up @@ -2770,6 +2924,62 @@ describe( 'DowncastHelpers', () => {
} );
} );

describe( 'reconversion', () => {
it( 'should foo', () => {
model.schema.register( 'paragraph', {
inheritAllFrom: '$block'
} );
downcastHelpers.elementToElement( { model: 'paragraph', view: 'p' } );
setModelData( model, '<paragraph>foo</paragraph>' );

const para = modelRoot.getChild( 0 );
const [ pBefore, textBefore ] = getNodes();

model.change( () => {
model.document.differ.refreshItem( para );
} );

const [ pAfter, textAfter ] = getNodes();

expectResult( '<p>foo</p>' );

expect( pAfter, '<p>' ).to.not.equal( pBefore );
expect( textAfter, 'foo' ).to.equal( textBefore );
} );

it( 'should bar', () => {
model.schema.register( 'paragraph', {
inheritAllFrom: '$block'
} );
downcastHelpers.elementToElement( { model: 'paragraph', view: 'p' } );
setModelData( model, '<paragraph>foo</paragraph>' );

const para = modelRoot.getChild( 0 );
const [ pBefore, textBefore ] = getNodes();

model.change( writer => {
model.document.differ.refreshItem( para );
writer.insertText( 'bar', para, 'end' );
} );

const [ pAfter, textAfter ] = getNodes();

expectResult( '<p>foobar</p>' );

expect( pAfter, '<p>' ).to.not.equal( pBefore );
expect( textAfter, 'foobar' ).to.not.equal( textBefore );
} );

function* getNodes() {
const main = viewRoot.getChild( 0 );
yield main;

for ( const value of controller.view.createRangeIn( main ) ) {
yield value.item;
}
}
} );

function expectResult( string ) {
expect( stringifyView( viewRoot, null, { ignoreRoot: true } ) ).to.equal( string );
}
Expand Down

0 comments on commit 7e359d8

Please sign in to comment.