浏览代码

Made CC 100%.

Maciej Bukowski 6 年之前
父节点
当前提交
b5f54082ef
共有 2 个文件被更改,包括 65 次插入27 次删除
  1. 4 0
      packages/ckeditor5-watchdog/src/watchdog.js
  2. 61 27
      packages/ckeditor5-watchdog/tests/watchdog.js

+ 4 - 0
packages/ckeditor5-watchdog/src/watchdog.js

@@ -129,6 +129,10 @@ export default class Watchdog {
 	 * @returns {Promise.<module:core/editor/editor~Editor>}
 	 */
 	restart() {
+		try {
+			this._throttledSave.flush();
+		} catch( err ) { }
+
 		return Promise.resolve()
 			.then( () => this.destroy() )
 			.then( () => {

+ 61 - 27
packages/ckeditor5-watchdog/tests/watchdog.js

@@ -426,43 +426,37 @@ describe( 'Watchdog', () => {
 			} );
 		} );
 
-		it( 'editor should be reinitialized with the last data', () => {
-			const watchdog = new Watchdog( { crashNumberLimit: 2 } );
+		it( 'Watchdog should warn if the CKEditorError missing its context', () => {
+			const watchdog = new Watchdog();
 
 			watchdog.setCreator( ( el, config ) => FakeEditor.create( el, config ) );
 			watchdog.setDestructor( editor => editor.destroy() );
 
-			const errorSpy = sinon.spy();
-			watchdog.on( 'error', errorSpy );
-
-			const restartSpy = sinon.spy();
-			watchdog.on( 'restart', restartSpy );
-
 			// sinon.stub( window, 'onerror' ).value( undefined ); and similar don't work.
 			const originalErrorHandler = window.onerror;
 			window.onerror = undefined;
 
+			sinon.stub( console, 'error' );
+
 			return watchdog.create( document.createElement( 'div' ) ).then( () => {
-				setTimeout( () => { throw new CKEditorError( 'foo1', undefined, watchdog.editor ); } );
-				setTimeout( () => { throw new CKEditorError( 'foo2', undefined, watchdog.editor ); } );
-				setTimeout( () => { throw new CKEditorError( 'foo3', undefined, watchdog.editor ); } );
-				setTimeout( () => { throw new CKEditorError( 'foo4', undefined, watchdog.editor ); } );
+				setTimeout( () => { throw new CKEditorError( 'foo' ); } );
 
 				return new Promise( res => {
 					setTimeout( () => {
-						expect( errorSpy.callCount ).to.equal( 4 );
-						expect( watchdog.crashes.length ).to.equal( 4 );
-						expect( restartSpy.callCount ).to.equal( 2 );
-
 						window.onerror = originalErrorHandler;
 
+						expect( watchdog.crashes ).to.deep.equal( [] );
+
+						sinon.assert.calledOnce( console.error );
+						sinon.assert.calledWithExactly( console.error, 'The error is missing its context and Watchdog cannot restart the proper editor.' );
+
 						watchdog.destroy().then( res );
 					}, 5 );
 				} );
 			} );
 		} );
 
-		it( 'Watchdog should warn if the CKEditorError missing its context', () => {
+		it( 'editor should be restarted with the data before the crash #1', () => {
 			const watchdog = new Watchdog();
 
 			watchdog.setCreator( ( el, config ) => FakeEditor.create( el, config ) );
@@ -472,27 +466,60 @@ describe( 'Watchdog', () => {
 			const originalErrorHandler = window.onerror;
 			window.onerror = undefined;
 
-			sinon.stub( console, 'error' );
-
-			return watchdog.create( document.createElement( 'div' ) ).then( () => {
-				setTimeout( () => { throw new CKEditorError( 'foo' ); } );
+			return watchdog.create( document.createElement( 'div' ), {
+				initialData: '<p>foo</p>',
+				plugins: [ Paragraph ]
+			} ).then( () => {
+				setTimeout( () => { throw new CKEditorError( 'foo', undefined, watchdog.editor ); } );
 
 				return new Promise( res => {
-					setTimeout( () => {
+					watchdog.on( 'restart', () => {
 						window.onerror = originalErrorHandler;
 
-						expect( watchdog.crashes ).to.deep.equal( [] );
+						expect( watchdog.editor.getData() ).to.equal( '<p>foo</p>' );
 
-						sinon.assert.calledOnce( console.error );
-						sinon.assert.calledWithExactly( console.error, 'The error is missing its context and Watchdog cannot restart the proper editor.' );
+						watchdog.destroy().then( res );
+					} );
+				} );
+			} );
+		} );
+
+		it( 'editor should be restarted with the data before the crash #2', () => {
+			const watchdog = new Watchdog();
+
+			watchdog.setCreator( ( el, config ) => FakeEditor.create( el, config ) );
+			watchdog.setDestructor( editor => editor.destroy() );
+
+			// sinon.stub( window, 'onerror' ).value( undefined ); and similar don't work.
+			const originalErrorHandler = window.onerror;
+			window.onerror = undefined;
+
+			return watchdog.create( document.createElement( 'div' ), {
+				initialData: '<p>foo</p>',
+				plugins: [ Paragraph ]
+			} ).then( () => {
+				const doc = watchdog.editor.model.document;
+
+				watchdog.editor.model.change( writer => {
+					writer.insertText( 'bar', writer.createPositionAt( doc.getRoot(), 1 ) );
+				} );
+
+				setTimeout( () => { throw new CKEditorError( 'foo', undefined, watchdog.editor ); } );
+
+				return new Promise( res => {
+					watchdog.on( 'restart', () => {
+						window.onerror = originalErrorHandler;
+
+						console.log( watchdog.editor.getData() );
+						expect( watchdog.editor.getData() ).to.equal( '<p>foo</p><p>bar</p>' );
 
 						watchdog.destroy().then( res );
-					}, 5 );
+					} );
 				} );
 			} );
 		} );
 
-		it( 'editor should be restarted with the correct data when an error occurs #1', () => {
+		it( 'editor should be restarted with the data of the latest document version before the crash', () => {
 			const watchdog = new Watchdog();
 
 			watchdog.setCreator( ( el, config ) => FakeEditor.create( el, config ) );
@@ -506,6 +533,13 @@ describe( 'Watchdog', () => {
 				initialData: '<p>foo</p>',
 				plugins: [ Paragraph ]
 			} ).then( () => {
+				const doc = watchdog.editor.model.document;
+
+				watchdog.editor.model.document.version = -1000;
+				watchdog.editor.model.change( writer => {
+					writer.insertText( 'bar', writer.createPositionAt( doc.getRoot(), 1 ) );
+				} );
+
 				setTimeout( () => { throw new CKEditorError( 'foo', undefined, watchdog.editor ); } );
 
 				return new Promise( res => {