import { Client, syncClients, expectClients, clearBuffer } from './utils.js'; describe( 'transform', () => { let john, kate; beforeEach( () => { return Promise.all( [ Client.get( 'john' ).then( client => ( john = client ) ), Client.get( 'kate' ).then( client => ( kate = client ) ) ] ); } ); afterEach( () => { clearBuffer(); return Promise.all( [ john.destroy(), kate.destroy() ] ); } ); describe( 'split', () => { describe( 'by wrap', () => { it( 'split inside wrapped element', () => { john.setData( 'F[]oo' ); kate.setData( '[Foo]' ); john.split(); kate.wrap( 'blockQuote' ); syncClients(); expectClients( '
' + 'F' + 'oo' + '
' ); } ); it( 'split inside wrapped element, then undo', () => { john.setData( 'F[]oo' ); kate.setData( '[Foo]' ); john.split(); kate.wrap( 'blockQuote' ); syncClients(); kate.undo(); syncClients(); expectClients( 'F' + 'oo' ); } ); it( 'element in same path, then undo', () => { // This is pretty weird case. Right now it cannot be reproduced with the features that we have. john.editor.model.schema.extend( 'paragraph', { allowIn: 'listItem' } ); john.editor.model.schema.extend( 'blockQuote', { allowIn: 'listItem' } ); kate.editor.model.schema.extend( 'paragraph', { allowIn: 'listItem' } ); kate.editor.model.schema.extend( 'blockQuote', { allowIn: 'listItem' } ); john.setData( 'A[]BC' ); kate.setData( 'AB[C]' ); john.split(); kate.wrap( 'blockQuote' ); syncClients(); expectClients( '' + 'A' + '' + '' + 'B' + '
' + 'C' + '
' + '
' ); john.undo(); kate.undo(); syncClients(); expectClients( '' + 'A' + 'B' + 'C' + '' ); } ); it( 'multiple elements', () => { john.setData( 'F[]ooBar' ); kate.setData( '[FooBar]' ); john.split(); kate.wrap( 'blockQuote' ); syncClients(); expectClients( '
' + 'F' + 'oo' + 'Bar' + '
' ); } ); it( 'multiple elements, then undo', () => { john.setData( 'F[]ooBar' ); kate.setData( '[FooBar]' ); john.split(); kate.wrap( 'blockQuote' ); syncClients(); john.undo(); kate.undo(); syncClients(); expectClients( 'Foo' + 'Bar' ); } ); it( 'intersecting wrap', () => { john.setData( 'Fo[]o' ); kate.setData( 'F[oo]' ); john.split(); kate.wrap( 'blockQuote' ); syncClients(); // Below would be the expected effect with correct wrap transformation. // expectClients( // 'Fo' + // 'o' // ); expectClients( 'Foo' ); } ); } ); describe( 'by unwrap', () => { it( 'element in same path', () => { john.setData( '
F[]oo
' ); kate.setData( '
[Foo]
' ); john.split(); kate.unwrap(); syncClients(); expectClients( 'F' + 'oo' ); } ); it( 'text in same path', () => { john.setData( '
F[]oo
' ); kate.setData( '
[]Foo
' ); john.split(); kate.unwrap(); syncClients(); expectClients( '
Foo
' ); } ); it( 'element in same position', () => { john.setData( '
[]Foo
' ); kate.setData( '
[]Foo
' ); john.split(); kate.unwrap(); syncClients(); expectClients( '
Foo
' ); } ); it( 'element in same path, then undo', () => { john.setData( '
F[]oo
' ); kate.setData( '
[Foo]
' ); john.split(); kate.unwrap(); syncClients(); john.undo(); syncClients(); expectClients( 'Foo' ); } ); it( 'element in same path, then undo both', () => { john.setData( '
F[]oo
' ); kate.setData( '
[Foo]
' ); john.split(); kate.unwrap(); syncClients(); john.undo(); kate.undo(); syncClients(); expectClients( '
Foo
' ); } ); it( 'text in same path, then undo', () => { john.setData( '
F[]oo
' ); kate.setData( '
[]Foo
' ); john.split(); kate.unwrap(); syncClients(); john.undo(); syncClients(); expectClients( '
Foo
' ); } ); it( 'multiple elements', () => { john.setData( '
F[]ooBar
' ); kate.setData( '
[FooBar]
' ); john.split(); kate.unwrap(); syncClients(); expectClients( 'F' + 'oo' + 'Bar' ); } ); } ); describe( 'by split', () => { it( 'text in same path #1', () => { john.setData( 'F[]oo' ); kate.setData( 'Fo[]o' ); john.split(); kate.split(); syncClients(); expectClients( 'F' + 'o' + 'o' ); } ); it( 'text in same path #2', () => { john.setData( '[]Foo' ); kate.setData( 'Foo[]' ); john.split(); kate.split(); syncClients(); expectClients( '' + 'Foo' + '' ); } ); it( 'text in same position', () => { john.setData( 'F[]oo' ); kate.setData( 'F[]oo' ); john.split(); kate.split(); syncClients(); expectClients( 'F' + 'oo' ); } ); it( 'text in same position, then undo', () => { john.setData( 'F[]oo' ); kate.setData( 'F[]oo' ); john.split(); kate.split(); syncClients(); john.undo(); syncClients(); expectClients( 'Foo' ); } ); it( 'text in same position, then undo and redo', () => { john.setData( 'F[]oo' ); kate.setData( 'F[]oo' ); john.split(); kate.split(); syncClients(); john.undo(); syncClients(); kate.undo(); kate.redo(); expectClients( 'Foo' ); } ); it( 'text in different path', () => { john.setData( 'F[]ooBar' ); kate.setData( 'FooB[]ar' ); john.split(); kate.split(); syncClients(); expectClients( 'F' + 'oo' + 'B' + 'ar' ); } ); } ); describe( 'by merge', () => { it( 'element into paragraph #1', () => { john.setData( 'Fo[]oBar' ); kate.setData( 'Foo[]Bar' ); john.split(); kate.merge(); syncClients(); expectClients( 'Fo' + 'oBar' ); } ); it( 'element into paragraph #2', () => { john.setData( 'Foo[]Bar' ); kate.setData( 'Foo[]Bar' ); john.split(); kate.merge(); syncClients(); expectClients( 'FooBar' ); john.undo(); syncClients(); expectClients( 'FooBar' ); } ); it( 'element into paragraph #3', () => { john.setData( 'Foo[]Bar' ); kate.setData( 'Foo[]Bar' ); john.split(); kate.merge(); syncClients(); expectClients( 'FooBar' ); john.undo(); kate.undo(); syncClients(); expectClients( 'FooBar' ); } ); it( 'element into paragraph #4', () => { john.setData( 'FooB[]ar' ); kate.setData( 'Foo[]Bar' ); john.split(); kate.merge(); syncClients(); expectClients( 'FooB' + 'ar' ); john.undo(); kate.undo(); syncClients(); expectClients( 'FooBar' ); } ); it( 'element into heading', () => { john.setData( 'FooB[]ar' ); kate.setData( 'Foo[]Bar' ); john.split(); kate.merge(); syncClients(); expectClients( 'FooB' + 'ar' ); } ); it( 'element into heading with undo #1', () => { john.setData( 'FooB[]ar' ); kate.setData( 'Foo[]Bar' ); john.split(); kate.merge(); syncClients(); expectClients( 'FooB' + 'ar' ); john.undo(); kate.undo(); syncClients(); expectClients( 'FooBar' ); } ); it( 'element into heading with undo #2', () => { john.setData( 'FooB[]ar' ); kate.setData( 'Foo[]Bar' ); john.split(); kate.merge(); kate.undo(); syncClients(); expectClients( 'Foo' + 'B' + 'ar' ); } ); } ); describe( 'by delete', () => { it( 'text from two elements #1', () => { john.setData( 'F[]ooBar' ); kate.setData( 'Fo[oB]ar' ); john.split(); kate.delete(); syncClients(); expectClients( 'Foar' ); } ); it( 'text from two elements #2', () => { john.setData( 'Fo[]oBar' ); kate.setData( 'F[ooB]ar' ); john.split(); kate.delete(); syncClients(); expectClients( 'Far' ); } ); it( 'text from one element', () => { john.setData( 'F[]oo Bar' ); kate.setData( 'Foo B[ar]' ); john.split(); kate.delete(); syncClients(); expectClients( 'F' + 'oo B' ); } ); } ); describe( 'by move', () => { it( 'move inside split element after split position', () => { john.setData( 'F[]ooBar' ); kate.setData( 'Foo[Ba]r' ); john.split(); kate.move( [ 0, 3 ] ); syncClients(); expectClients( 'F' + 'ooBa' + 'r' ); } ); } ); } ); } );