8
0
Просмотр исходного кода

Merge pull request #295 from ckeditor/t/ckeditor5/383

Other: Removed the CKEditor 5 logger and its usage. Part of ckeditor/ckeditor5#383.

BREAKING CHANGE: Removed the CKEditor 5 logger utility.
Piotr Jasiun 6 лет назад
Родитель
Сommit
26824d7b84

+ 10 - 21
packages/ckeditor5-utils/src/dom/rect.js

@@ -10,7 +10,6 @@
 import isRange from './isrange';
 import isWindow from './iswindow';
 import getBorderWidths from './getborderwidths';
-import log from '../log';
 import isText from './istext';
 import { isElement } from 'lodash-es';
 
@@ -67,26 +66,16 @@ export default class Rect {
 		} );
 
 		if ( isElement( source ) || isSourceRange ) {
-			const sourceNode = isSourceRange ? source.startContainer : source;
-
-			if ( !sourceNode.ownerDocument || !sourceNode.ownerDocument.body.contains( sourceNode ) ) {
-				/**
-				 * The `Rect` class depends on `getBoundingClientRect` and `getClientRects` DOM methods.
-				 * If the {@link #constructor source} of a rect in an HTML element or a DOM range but it does
-				 * not belong to any rendered DOM tree, these methods will fail to obtain the geometry and
-				 * the rect instance makes little sense to the features using it.
-				 *
-				 * To get rid of this warning make sure the source passed to the constructor
-				 * is a descendant of `window.document.body`.
-				 *
-				 * @error rect-source-not-in-dom
-				 * @param {String} source The source of the Rect instance.
-				 */
-				log.warn(
-					'rect-source-not-in-dom: The source of this rect does not belong to any rendered DOM tree.',
-					{ source }
-				);
-			}
+			// The `Rect` class depends on `getBoundingClientRect` and `getClientRects` DOM methods. If the source
+			// of a rect in an HTML element or a DOM range but it does not belong to any rendered DOM tree, these methods
+			// will fail to obtain the geometry and the rect instance makes little sense to the features using it.
+			// To get rid of this warning make sure the source passed to the constructor is a descendant of `window.document.body`.
+			// @if CK_DEBUG // const sourceNode = isSourceRange ? source.startContainer : source;
+			// @if CK_DEBUG // if ( !sourceNode.ownerDocument || !sourceNode.ownerDocument.body.contains( sourceNode ) ) {
+			// @if CK_DEBUG // 	console.warn(
+			// @if CK_DEBUG // 		'rect-source-not-in-dom: The source of this rect does not belong to any rendered DOM tree.',
+			// @if CK_DEBUG // 		{ source } );
+			// @if CK_DEBUG // }
 
 			if ( isSourceRange ) {
 				copyRectProperties( this, Rect.getDomRangeRects( source )[ 0 ] );

+ 0 - 76
packages/ckeditor5-utils/src/log.js

@@ -1,76 +0,0 @@
-/**
- * @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 console */
-
-/**
- * @module utils/log
- */
-
-import { attachLinkToDocumentation } from './ckeditorerror';
-
-/**
- * The logging module.
- *
- * This object features two functions that should be used across CKEditor code base to log errors and warnings.
- * Despite being an overridable interface for native `console.*` this module serves also the goal to limit the
- * code size of a minified CKEditor package. During minification process the messages will be shortened and
- * links to their documentation will be logged to the console.
- *
- * All errors and warning should be documented in the following way:
- *
- *		/**
- *		 * Error thrown when a plugin cannot be loaded due to JavaScript errors, lack of plugins with a given name, etc.
- *		 *
- *		 * @error plugin-load
- *		 * @param pluginName The name of the plugin that could not be loaded.
- *		 * @param moduleName The name of the module which tried to load this plugin.
- *		 * /
- *		log.error( 'plugin-load: It was not possible to load the "{$pluginName}" plugin in module "{$moduleName}', {
- *			pluginName: 'foo',
- *			moduleName: 'bar'
- *		} );
- *
- * ### Warning vs Error vs Throw
- *
- * * Whenever a potentially incorrect situation occurs, which does not directly lead to an incorrect behavior,
- * log a warning.
- * * Whenever an incorrect situation occurs, but the app may continue working (although perhaps incorrectly),
- * log an error.
- * * Whenever it's really bad and it does not make sense to continue working, throw a {@link module:utils/ckeditorerror~CKEditorError}.
- *
- * @namespace
- */
-const log = {
-	/**
-	 * Logs an error to the console.
-	 *
-	 * Read more about error logging in the {@link module:utils/log} module.
-	 *
-	 * @param {String} message The error message in an `error-name: Error message.` format.
-	 * During the minification process the "Error message" part will be removed to limit the code size
-	 * and a link to this error documentation will be logged to the console.
-	 * @param {Object} [data] Additional data describing the error.
-	 */
-	error( message, data ) {
-		console.error( attachLinkToDocumentation( message ), data );
-	},
-
-	/**
-	 * Logs a warning to the console.
-	 *
-	 * Read more about error logging in the {@link module:utils/log} module.
-	 *
-	 * @param {String} message The warning message in a `warning-name: Warning message.` format.
-	 * During the minification process the "Warning message" part will be removed to limit the code size
-	 * and a link to this error documentation will be logged to the console.
-	 * @param {Object} [data] Additional data describing the warning.
-	 */
-	warn( message, data ) {
-		console.warn( attachLinkToDocumentation( message ), data );
-	}
-};
-
-export default log;

+ 5 - 2
packages/ckeditor5-utils/src/version.js

@@ -9,8 +9,8 @@
 
 /* globals window, global */
 
-import log from './log';
 import { version } from 'ckeditor5/package.json';
+import CKEditorError from './ckeditorerror';
 
 const windowOrGlobal = typeof window === 'object' ? window : global;
 
@@ -138,7 +138,10 @@ if ( windowOrGlobal.CKEDITOR_VERSION ) {
 	 *
 	 * @error ckeditor-duplicated-modules
 	 */
-	log.error( 'ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated.' );
+	throw new CKEditorError(
+		'ckeditor-duplicated-modules: Some CKEditor 5 modules are duplicated.',
+		null
+	);
 } else {
 	windowOrGlobal.CKEDITOR_VERSION = version;
 }

+ 1 - 1
packages/ckeditor5-utils/tests/_utils-tests/utils.js

@@ -29,7 +29,7 @@ describe( 'utils - testUtils', () => {
 		} );
 
 		it( 'should create an observer', () => {
-			function Emitter() { }
+			function Emitter() {}
 			Emitter.prototype = EmitterMixin;
 
 			expect( observer ).to.be.instanceof( Emitter );

+ 4 - 4
packages/ckeditor5-utils/tests/collection.js

@@ -522,7 +522,7 @@ describe( 'Collection', () => {
 			sinon.assert.calledWithExactly( spy, callback, ctx );
 			expect( ret ).to.deep.equal( [ 'foo' ], 'ret value was forwarded' );
 
-			function callback() { }
+			function callback() {}
 		} );
 	} );
 
@@ -538,7 +538,7 @@ describe( 'Collection', () => {
 			sinon.assert.calledWithExactly( spy, callback, ctx );
 			expect( ret ).to.equal( needl, 'ret value was forwarded' );
 
-			function callback() { }
+			function callback() {}
 		} );
 	} );
 
@@ -555,7 +555,7 @@ describe( 'Collection', () => {
 			sinon.assert.calledWithExactly( spy, callback, ctx );
 			expect( ret ).to.deep.equal( [ needl ], 'ret value was forwarded' );
 
-			function callback() { }
+			function callback() {}
 		} );
 	} );
 
@@ -700,7 +700,7 @@ describe( 'Collection', () => {
 			} );
 
 			it( 'does not chain', () => {
-				const returned = collection.bindTo( new Collection() ).using( () => { } );
+				const returned = collection.bindTo( new Collection() ).using( () => {} );
 
 				expect( returned ).to.be.undefined;
 			} );

+ 55 - 78
packages/ckeditor5-utils/tests/dom/rect.js

@@ -3,17 +3,13 @@
  * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
  */
 
-/* global window, document */
+/* global window, document, console */
 
 import Rect from '../../src/dom/rect';
-import log from '../../src/log';
-import testUtils from '@ckeditor/ckeditor5-core/tests/_utils/utils';
 
 describe( 'Rect', () => {
 	let geometry;
 
-	testUtils.createSinonSandbox();
-
 	beforeEach( () => {
 		geometry = {
 			top: 10,
@@ -24,7 +20,11 @@ describe( 'Rect', () => {
 			height: 20
 		};
 
-		testUtils.sinon.stub( log, 'warn' );
+		sinon.stub( console, 'warn' );
+	} );
+
+	afterEach( () => {
+		sinon.restore();
 	} );
 
 	describe( 'constructor()', () => {
@@ -38,7 +38,7 @@ describe( 'Rect', () => {
 		it( 'should accept HTMLElement', () => {
 			const element = document.createElement( 'div' );
 
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
+			sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
 
 			assertRect( new Rect( element ), geometry );
 		} );
@@ -47,7 +47,7 @@ describe( 'Rect', () => {
 			const range = document.createRange();
 
 			range.selectNode( document.body );
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
+			sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
 
 			assertRect( new Rect( range ), geometry );
 		} );
@@ -57,7 +57,7 @@ describe( 'Rect', () => {
 			const range = document.createRange();
 
 			range.collapse();
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
+			sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
 
 			assertRect( new Rect( range ), geometry );
 		} );
@@ -69,8 +69,8 @@ describe( 'Rect', () => {
 
 			range.setStart( element, 0 );
 			range.collapse();
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [] );
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
+			sinon.stub( range, 'getClientRects' ).returns( [] );
+			sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
 
 			const expectedGeometry = Object.assign( {}, geometry );
 			expectedGeometry.right = expectedGeometry.left;
@@ -80,10 +80,10 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should accept the window (viewport)', () => {
-			testUtils.sinon.stub( window, 'innerWidth' ).value( 1000 );
-			testUtils.sinon.stub( window, 'innerHeight' ).value( 500 );
-			testUtils.sinon.stub( window, 'scrollX' ).value( 100 );
-			testUtils.sinon.stub( window, 'scrollY' ).value( 200 );
+			sinon.stub( window, 'innerWidth' ).value( 1000 );
+			sinon.stub( window, 'innerHeight' ).value( 500 );
+			sinon.stub( window, 'scrollX' ).value( 100 );
+			sinon.stub( window, 'scrollY' ).value( 200 );
 
 			assertRect( new Rect( window ), {
 				top: 0,
@@ -124,10 +124,10 @@ describe( 'Rect', () => {
 				const range = document.createRange();
 				range.selectNode( iframeWindow.document.body );
 
-				testUtils.sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
+				sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
 				assertRect( new Rect( range ), geometry );
 
-				testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
+				sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
 				assertRect( new Rect( element ), geometry );
 
 				iframe.remove();
@@ -161,29 +161,6 @@ describe( 'Rect', () => {
 
 			assertRect( geometry, sourceGeometry );
 		} );
-
-		it( 'should warn if the source does not belong to rendered DOM tree (HTML element)', () => {
-			const element = document.createElement( 'div' );
-
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
-
-			const rect = new Rect( element );
-			sinon.assert.calledOnce( log.warn );
-			sinon.assert.calledWithExactly( log.warn, sinon.match( /^rect-source-not-in-dom/ ), { source: element } );
-			assertRect( rect, geometry );
-		} );
-
-		it( 'should warn if the source does not belong to rendered DOM tree (DOM Range)', () => {
-			const range = document.createRange();
-
-			range.collapse();
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
-
-			const rect = new Rect( range );
-			sinon.assert.calledOnce( log.warn );
-			sinon.assert.calledWithExactly( log.warn, sinon.match( /^rect-source-not-in-dom/ ), { source: range } );
-			assertRect( rect, geometry );
-		} );
 	} );
 
 	describe( 'clone()', () => {
@@ -452,7 +429,7 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should not fail when the rect is for document#body', () => {
-			testUtils.sinon.stub( document.body, 'getBoundingClientRect' ).returns( {
+			sinon.stub( document.body, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,
 				bottom: 100,
@@ -482,7 +459,7 @@ describe( 'Rect', () => {
 				ancestor.appendChild( element );
 				iframeWindow.document.body.appendChild( ancestor );
 
-				testUtils.sinon.stub( ancestor, 'getBoundingClientRect' ).returns( {
+				sinon.stub( ancestor, 'getBoundingClientRect' ).returns( {
 					top: 0,
 					right: 50,
 					bottom: 50,
@@ -491,7 +468,7 @@ describe( 'Rect', () => {
 					height: 50
 				} );
 
-				testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
+				sinon.stub( element, 'getBoundingClientRect' ).returns( {
 					top: 0,
 					right: 100,
 					bottom: 100,
@@ -517,7 +494,7 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should return the visible rect (HTMLElement), partially cropped', () => {
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
+			sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,
 				bottom: 100,
@@ -526,7 +503,7 @@ describe( 'Rect', () => {
 				height: 100
 			} );
 
-			testUtils.sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
+			sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
 				top: 50,
 				right: 150,
 				bottom: 150,
@@ -546,7 +523,7 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should return the visible rect (HTMLElement), fully visible', () => {
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
+			sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,
 				bottom: 100,
@@ -555,7 +532,7 @@ describe( 'Rect', () => {
 				height: 100
 			} );
 
-			testUtils.sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
+			sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 150,
 				bottom: 150,
@@ -578,7 +555,7 @@ describe( 'Rect', () => {
 			ancestorB.appendChild( ancestorA );
 			document.body.appendChild( ancestorB );
 
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
+			sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,
 				bottom: 100,
@@ -587,7 +564,7 @@ describe( 'Rect', () => {
 				height: 100
 			} );
 
-			testUtils.sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
+			sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
 				top: 50,
 				right: 100,
 				bottom: 100,
@@ -596,7 +573,7 @@ describe( 'Rect', () => {
 				height: 50
 			} );
 
-			testUtils.sinon.stub( ancestorB, 'getBoundingClientRect' ).returns( {
+			sinon.stub( ancestorB, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 150,
 				bottom: 100,
@@ -619,7 +596,7 @@ describe( 'Rect', () => {
 			range.setStart( ancestorA, 0 );
 			range.setEnd( ancestorA, 1 );
 
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [ {
+			sinon.stub( range, 'getClientRects' ).returns( [ {
 				top: 0,
 				right: 100,
 				bottom: 100,
@@ -628,7 +605,7 @@ describe( 'Rect', () => {
 				height: 100
 			} ] );
 
-			testUtils.sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
+			sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
 				top: 50,
 				right: 150,
 				bottom: 150,
@@ -648,7 +625,7 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should return null if there\'s no visible rect', () => {
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( {
+			sinon.stub( element, 'getBoundingClientRect' ).returns( {
 				top: 0,
 				right: 100,
 				bottom: 100,
@@ -657,7 +634,7 @@ describe( 'Rect', () => {
 				height: 100
 			} );
 
-			testUtils.sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
+			sinon.stub( ancestorA, 'getBoundingClientRect' ).returns( {
 				top: 150,
 				right: 200,
 				bottom: 200,
@@ -818,8 +795,8 @@ describe( 'Rect', () => {
 		it( 'should exclude scrollbars and borders of a HTMLElement', () => {
 			const element = document.createElement( 'div' );
 
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
-			testUtils.sinon.stub( window, 'getComputedStyle' ).returns( {
+			sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
+			sinon.stub( window, 'getComputedStyle' ).returns( {
 				borderTopWidth: '5px',
 				borderRightWidth: '10px',
 				borderLeftWidth: '5px',
@@ -853,12 +830,12 @@ describe( 'Rect', () => {
 		} );
 
 		it( 'should exclude scrollbars from viewport\'s rect', () => {
-			testUtils.sinon.stub( window, 'innerWidth' ).value( 1000 );
-			testUtils.sinon.stub( window, 'innerHeight' ).value( 500 );
-			testUtils.sinon.stub( window, 'scrollX' ).value( 100 );
-			testUtils.sinon.stub( window, 'scrollY' ).value( 200 );
+			sinon.stub( window, 'innerWidth' ).value( 1000 );
+			sinon.stub( window, 'innerHeight' ).value( 500 );
+			sinon.stub( window, 'scrollX' ).value( 100 );
+			sinon.stub( window, 'scrollY' ).value( 200 );
 
-			testUtils.sinon.stub( document, 'documentElement' ).value( {
+			sinon.stub( document, 'documentElement' ).value( {
 				clientWidth: 990,
 				clientHeight: 490
 			} );
@@ -878,11 +855,11 @@ describe( 'Rect', () => {
 
 			// Mock the properties of the top window. Then make sure the ones
 			// from the child are used.
-			testUtils.sinon.stub( window, 'innerWidth' ).value( 1000 );
-			testUtils.sinon.stub( window, 'innerHeight' ).value( 500 );
-			testUtils.sinon.stub( window, 'scrollX' ).value( 100 );
-			testUtils.sinon.stub( window, 'scrollY' ).value( 200 );
-			testUtils.sinon.stub( document, 'documentElement' ).value( {
+			sinon.stub( window, 'innerWidth' ).value( 1000 );
+			sinon.stub( window, 'innerHeight' ).value( 500 );
+			sinon.stub( window, 'scrollX' ).value( 100 );
+			sinon.stub( window, 'scrollY' ).value( 200 );
+			sinon.stub( document, 'documentElement' ).value( {
 				clientWidth: 990,
 				clientHeight: 490
 			} );
@@ -890,12 +867,12 @@ describe( 'Rect', () => {
 			iframe.addEventListener( 'load', () => {
 				const iframeWindow = iframe.contentWindow;
 
-				testUtils.sinon.stub( iframeWindow, 'innerWidth' ).value( 500 );
-				testUtils.sinon.stub( iframeWindow, 'innerHeight' ).value( 250 );
-				testUtils.sinon.stub( iframeWindow, 'scrollX' ).value( 50 );
-				testUtils.sinon.stub( iframeWindow, 'scrollY' ).value( 100 );
+				sinon.stub( iframeWindow, 'innerWidth' ).value( 500 );
+				sinon.stub( iframeWindow, 'innerHeight' ).value( 250 );
+				sinon.stub( iframeWindow, 'scrollX' ).value( 50 );
+				sinon.stub( iframeWindow, 'scrollY' ).value( 100 );
 
-				testUtils.sinon.stub( iframeWindow.document, 'documentElement' ).value( {
+				sinon.stub( iframeWindow.document, 'documentElement' ).value( {
 					clientWidth: 480,
 					clientHeight: 230
 				} );
@@ -911,7 +888,7 @@ describe( 'Rect', () => {
 
 				// Safari fails because of "afterEach()" hook tries to restore values from removed element.
 				// We need to restore these values manually.
-				testUtils.sinon.restore();
+				sinon.restore();
 				iframe.remove();
 				done();
 			} );
@@ -925,7 +902,7 @@ describe( 'Rect', () => {
 			const range = document.createRange();
 
 			range.selectNode( document.body );
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
+			sinon.stub( range, 'getClientRects' ).returns( [ geometry ] );
 
 			const rects = Rect.getDomRangeRects( range );
 			expect( rects ).to.have.length( 1 );
@@ -938,7 +915,7 @@ describe( 'Rect', () => {
 			const secondGeometry = { top: 20, right: 80, bottom: 60, left: 40, width: 40, height: 40 };
 
 			range.collapse();
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [ geometry, secondGeometry ] );
+			sinon.stub( range, 'getClientRects' ).returns( [ geometry, secondGeometry ] );
 
 			const rects = Rect.getDomRangeRects( range );
 			expect( rects ).to.have.length( 2 );
@@ -954,8 +931,8 @@ describe( 'Rect', () => {
 
 			range.setStart( element, 0 );
 			range.collapse();
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [] );
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
+			sinon.stub( range, 'getClientRects' ).returns( [] );
+			sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
 
 			const expectedGeometry = Object.assign( {}, geometry );
 			expectedGeometry.right = expectedGeometry.left;
@@ -975,8 +952,8 @@ describe( 'Rect', () => {
 
 			range.setStart( textNode, 3 );
 			range.collapse();
-			testUtils.sinon.stub( range, 'getClientRects' ).returns( [] );
-			testUtils.sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
+			sinon.stub( range, 'getClientRects' ).returns( [] );
+			sinon.stub( element, 'getBoundingClientRect' ).returns( geometry );
 
 			const expectedGeometry = Object.assign( {}, geometry );
 			expectedGeometry.right = expectedGeometry.left;

+ 0 - 75
packages/ckeditor5-utils/tests/log.js

@@ -1,75 +0,0 @@
-/**
- * @license Copyright (c) 2003-2019, CKSource - Frederico Knabben. All rights reserved.
- * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license
- */
-
-/* globals console */
-
-import log from '../src/log';
-import { DOCUMENTATION_URL } from '../src/ckeditorerror';
-
-describe( 'log', () => {
-	let spy;
-
-	beforeEach( () => {
-		if ( spy ) {
-			spy.restore();
-		}
-	} );
-
-	describe( 'warn()', () => {
-		it( 'logs the message to the console using console.warn()', () => {
-			spy = sinon.stub( console, 'warn' );
-			const data = { bar: 1 };
-
-			log.warn( 'foo', data );
-
-			sinon.assert.calledOnce( spy );
-			sinon.assert.calledWith( spy, 'foo', data );
-
-			log.warn( 'bar' );
-			sinon.assert.calledTwice( spy );
-			sinon.assert.calledWith( spy, 'bar' );
-		} );
-
-		it( 'contains a link which leads to the documentation', () => {
-			spy = sinon.stub( console, 'warn' );
-
-			log.warn( 'model-schema-no-item: Specified item cannot be found.' );
-
-			const logMessage = 'model-schema-no-item: Specified item cannot be found. ' +
-				`Read more: ${ DOCUMENTATION_URL }#error-model-schema-no-item\n`;
-
-			sinon.assert.calledOnce( spy );
-			sinon.assert.calledWith( spy, logMessage );
-		} );
-	} );
-
-	describe( 'error()', () => {
-		it( 'logs the message to the console using console.error()', () => {
-			spy = sinon.stub( console, 'error' );
-			const data = { bar: 1 };
-
-			log.error( 'foo', data );
-
-			sinon.assert.calledOnce( spy );
-			sinon.assert.calledWith( spy, 'foo', data );
-
-			log.error( 'bar' );
-			sinon.assert.calledTwice( spy );
-			sinon.assert.calledWith( spy, 'bar' );
-		} );
-
-		it( 'contains a link which leads to the documentation', () => {
-			spy = sinon.stub( console, 'error' );
-
-			log.error( 'model-schema-no-item: Specified item cannot be found.' );
-
-			const logMessage = 'model-schema-no-item: Specified item cannot be found. ' +
-				`Read more: ${ DOCUMENTATION_URL }#error-model-schema-no-item\n`;
-
-			sinon.assert.calledOnce( spy );
-			sinon.assert.calledWith( spy, logMessage );
-		} );
-	} );
-} );