Ver código fonte

Added unit tests for bundle task.

Oskar Wrobel 9 anos atrás
pai
commit
70a83709f5

+ 3 - 18
dev/tasks/build/utils.js

@@ -17,11 +17,11 @@ const PassThrough = require( 'stream' ).PassThrough;
 const through = require( 'through2' );
 const fs = require( 'fs' );
 const sass = require( 'node-sass' );
-const del = require( 'del' );
 const minimist = require( 'minimist' );
 const sprite = require( 'gulp-svg-sprite' );
 const pipe = require( 'multipipe' );
 const filter = require( 'gulp-filter' );
+const mainUtils = require( '../utils' );
 
 const utils = {
 	/**
@@ -490,22 +490,6 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 	},
 
 	/**
-	 * Removes files and directories specified by `glob` starting from `rootDir`
-	 * and gently informs about deletion.
-	 *
-	 * @param {String} rootDir The path to the root directory (i.e. "dist/").
-	 * @param {String} glob Glob specifying what to clean.
-	 * @returns {Promise}
-	 */
-	clean( rootDir, glob ) {
-		return del( path.join( rootDir, glob ) ).then( paths => {
-			paths.forEach( p => {
-				gutil.log( `Deleted file '${ gutil.colors.cyan( p ) }'.` );
-			} );
-		} );
-	},
-
-	/**
 	 * Parses command line arguments and returns them as a user-friendly hash.
 	 *
 	 * @returns {Object} options
@@ -628,4 +612,5 @@ require( [ 'tests' ], bender.defer(), function( err ) {
 	}
 };
 
-module.exports = utils;
+// Assign properties from top level utils.
+module.exports = Object.assign( utils, mainUtils );

+ 6 - 7
dev/tasks/bundle/tasks.js

@@ -58,10 +58,9 @@ module.exports = ( config ) => {
 			 * CSS is already bundled by a build task, so we need only to copy it.
 			 */
 			function bundleCSS() {
-				return new Promise( ( resolve ) => {
-					const cssSource = path.join( sourceBuildDir, 'theme', 'ckeditor.css' );
-					utils.copyFile( cssSource, bundleDir, resolve );
-				} );
+				const cssSource = path.join( sourceBuildDir, 'theme', 'ckeditor.css' );
+
+				return utils.copyFile( cssSource, bundleDir );
 			}
 
 			// Lets wait for both - JS and CSS.
@@ -72,13 +71,13 @@ module.exports = ( config ) => {
 			/**
 			 * JS minification by UglifyJS.
 			 *
-			 * At this we don't minify JS file because there is no minifier fully sports esnext syntax.
+			 * At this moment we don't minify JS file because there is no minifier fully sports esnext syntax.
 			 * For consistency `ckeditor.min.js` file is created, but is not minified yed.
 			 */
 			js() {
 				let stream = gulp.src( path.join( bundleDir, config.MAIN_FILE ) );
 
-				return utils.saveStreamAsMinifiedFile( stream, bundleDir );
+				return utils.saveFileFromStreamAsMinified( stream, bundleDir );
 			},
 
 			/**
@@ -88,7 +87,7 @@ module.exports = ( config ) => {
 				let stream = gulp.src( path.join( bundleDir, 'ckeditor.css' ) )
 					.pipe( gulpCssnano() );
 
-				return utils.saveStreamAsMinifiedFile( stream, bundleDir );
+				return utils.saveFileFromStreamAsMinified( stream, bundleDir );
 			}
 		}
 	};

+ 15 - 18
dev/tasks/bundle/utils.js

@@ -11,31 +11,17 @@ const gulp = require( 'gulp' );
 const gulpRename = require( 'gulp-rename' );
 const gutil = require( 'gulp-util' );
 const filesize = require( 'filesize' );
-const clean = require( '../build/utils' ).clean;
+const mainUtils = require( '../utils' );
 
 const utils = {
 	/**
-	 * Copy file.
-	 *
-	 * @param {String} from source file path
-	 * @param {String} to destination path
-	 * @param {Function} [callback=() => {}] function executed at the end of asynchronous task
-	 * @returns {Stream}
-	 */
-	copyFile( from, to, callback = () => {} ) {
-		return gulp.src( from )
-			.pipe( gulp.dest( to ) )
-			.on( 'end', callback );
-	},
-
-	/**
 	 * Save files from stream in specific destination and add `.min` suffix to the name.
 	 *
 	 * @param {Stream} stream
 	 * @param {String} destination path
 	 * @returns {Stream}
 	 */
-	saveStreamAsMinifiedFile( stream, destination ) {
+	saveFileFromStreamAsMinified( stream, destination ) {
 		return stream
 			.pipe( gulpRename( {
 				suffix: '.min'
@@ -73,8 +59,19 @@ const utils = {
 		} );
 
 		gutil.log( gutil.colors.green( `\n${ files.join( '\n' ) }` ) );
+	},
+
+	/**
+	 * Copy specified file to specified destination.
+	 *
+	 * @param {String} from file path
+	 * @param {String} to copied file destination
+	 * @return {Stream}
+	 */
+	copyFile( from, to ) {
+		return gulp.src( from ).pipe( gulp.dest( to ) );
 	}
 };
 
-// Extends utils by a clean method from build utils.
-module.exports = Object.assign( utils, { clean } );
+// Assign properties from top level utils.
+module.exports = Object.assign( utils, mainUtils );

+ 30 - 0
dev/tasks/utils.js

@@ -0,0 +1,30 @@
+/**
+ * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+'use strict';
+
+const path = require( 'path' );
+const del = require( 'del' );
+const gutil = require( 'gulp-util' );
+
+const utils = {
+	/**
+	 * Removes files and directories specified by `glob` starting from `rootDir`
+	 * and gently informs about deletion.
+	 *
+	 * @param {String} rootDir The path to the root directory (i.e. "dist/").
+	 * @param {String} glob Glob specifying what to clean.
+	 * @returns {Promise}
+	 */
+	clean( rootDir, glob ) {
+		return del( path.join( rootDir, glob ) ).then( paths => {
+			paths.forEach( p => {
+				gutil.log( `Deleted file '${ gutil.colors.cyan( p ) }'.` );
+			} );
+		} );
+	}
+};
+
+module.exports = utils;

+ 5 - 0
dev/tests/build/utils.js

@@ -16,6 +16,7 @@ const path = require( 'path' );
 const stream = require( 'stream' );
 const Vinyl = require( 'vinyl' );
 const through = require( 'through2' );
+const mainUtils = require( '../../tasks/utils' );
 
 describe( 'build-utils', () => {
 	const utils = require( '../../tasks/build/utils' );
@@ -29,6 +30,10 @@ describe( 'build-utils', () => {
 		sandbox.restore();
 	} );
 
+	it( 'should be extended by level utils', () => {
+		expect( utils.clean ).to.be.equal( mainUtils.clean );
+	} );
+
 	describe( 'noop', () => {
 		it( 'should return PassTrough stream', () => {
 			const PassThrough = stream.PassThrough;

+ 64 - 0
dev/tests/bundle/tasks.js

@@ -0,0 +1,64 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* global describe, it, beforeEach, afterEach */
+
+'use strict';
+
+const mockery = require( 'mockery' );
+const sinon = require( 'sinon' );
+
+describe( 'build-tasks', () => {
+	let sandbox, tasks, rollupBundleMock, rollupBundleWriteMock;
+	const config = {
+		ROOT_DIR: '.',
+		BUILD_DIR: 'build',
+		BUNDLE_DIR: 'bundle',
+		MAIN_FILE: 'ckeditor.js'
+	};
+
+	beforeEach( () => {
+		mockery.enable( {
+			warnOnReplace: false,
+			warnOnUnregistered: false
+		} );
+
+		sandbox = sinon.sandbox.create();
+
+		rollupBundleWriteMock = sandbox.spy();
+		rollupBundleMock = {
+			write: rollupBundleWriteMock
+		};
+
+		mockery.registerMock( 'rollup', {
+			rollup: () => {
+				return {
+					then: ( resolve ) => {
+						resolve( rollupBundleMock );
+					}
+				};
+			}
+		} );
+
+		tasks = require( '../../tasks/bundle/tasks' )( config );
+	} );
+
+	afterEach( () => {
+		mockery.disable();
+		sandbox.restore();
+	} );
+
+	describe( 'generate', () => {
+		it( 'should use rollup to generate js bundle and save bundled file', () => {
+			tasks.generate();
+
+			sinon.assert.calledWithExactly( rollupBundleWriteMock, {
+				dest: 'bundle/ckeditor.js',
+				format: 'iife',
+				moduleName: 'createEditor'
+			} );
+		} );
+	} );
+} );

+ 80 - 0
dev/tests/bundle/utils.js

@@ -0,0 +1,80 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* global describe, it, beforeEach, afterEach */
+
+'use strict';
+
+const chai = require( 'chai' );
+const expect = chai.expect;
+const sinon = require( 'sinon' );
+const gutil = require( 'gulp-util' );
+const path = require( 'path' );
+const fs = require( 'fs' );
+const mainUtils = require( '../../tasks/utils' );
+
+describe( 'bundle-utils', () => {
+	const utils = require( '../../tasks/bundle/utils' );
+	let sandbox;
+
+	beforeEach( () => {
+		sandbox = sinon.sandbox.create();
+	} );
+
+	afterEach( () => {
+		sandbox.restore();
+	} );
+
+	it( 'should be extended by level utils', () => {
+		expect( utils.clean ).to.be.equal( mainUtils.clean );
+	} );
+
+	describe( 'getFileSize', () => {
+		it( 'should return human readable file size', () => {
+			let filePath = 'path/to/file';
+			let statSyncMock = sandbox.stub( fs, 'statSync', () => {
+				return { size: 102400 };
+			} );
+
+			expect( utils.getFileSize( filePath ) ).to.be.equal( '100 KB' );
+			sinon.assert.calledWithExactly( statSyncMock, filePath );
+		} );
+	} );
+
+	describe( 'logFilesSize', () => {
+		let gutilLogSpy;
+
+		beforeEach( () => {
+			gutilLogSpy = sandbox.stub( gutil, 'log' );
+			sandbox.stub( utils, 'getFileSize', () => '1 MB' );
+		} );
+
+		it( 'should log only files base name with file size separate by new line character', () => {
+			const expected = gutil.colors.green( `\nfile1.js: 1 MB\nfile2.js: 1 MB` );
+
+			utils.logFilesSize( [ 'sub/dir/file1.js', 'other/sub/dir/file2.js' ] , 'root/path' );
+
+			sinon.assert.calledWithExactly( gutilLogSpy, expected );
+		} );
+
+		it( 'should get files from root directory', () => {
+			let basenameSpy = sandbox.spy( path, 'basename' );
+
+			utils.logFilesSize( [ 'sub/dir/file1.js', 'other/sub/dir/file2.js' ] , 'root/path' );
+
+			sinon.assert.calledWithExactly( basenameSpy.firstCall, 'root/path/sub/dir/file1.js' );
+			sinon.assert.calledWithExactly( basenameSpy.secondCall, 'root/path/other/sub/dir/file2.js' );
+		} );
+
+		it( 'should get files if root directory is not specified', () => {
+			let basenameSpy = sandbox.spy( path, 'basename' );
+
+			utils.logFilesSize( [ 'sub/dir/file1.js', 'file2.js' ] );
+
+			sinon.assert.calledWithExactly( basenameSpy.firstCall, 'sub/dir/file1.js' );
+			sinon.assert.calledWithExactly( basenameSpy.secondCall, 'file2.js' );
+		} );
+	} );
+} );