Browse Source

Merge pull request #60 from ckeditor/t/25

T/25 - Tests for the builder.
Piotrek Koszuliński 10 years ago
parent
commit
5607dce038
4 changed files with 384 additions and 3 deletions
  1. 1 1
      dev/tasks/gulp/build/utils.js
  2. 142 0
      dev/tests/build/tasks.js
  3. 237 0
      dev/tests/build/utils.js
  4. 4 2
      package.json

+ 1 - 1
dev/tasks/gulp/build/utils.js

@@ -154,7 +154,7 @@ const utils = {
 	 */
 	wrapCKEditor5Package() {
 		return rename( ( file ) => {
-			file.dirname = path.join( file.dirname, 'ckeditor5' );
+			file.dirname = path.join( 'ckeditor5', file.dirname );
 		} );
 	},
 

+ 142 - 0
dev/tests/build/tasks.js

@@ -0,0 +1,142 @@
+/**
+ * @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' );
+const Vinyl = require( 'vinyl' );
+const utils = require( '../../tasks/gulp/build/utils' );
+const babel = require( 'babel-core' );
+const chai = require( 'chai' );
+const expect = chai.expect;
+const gutil = require( 'gulp-util' );
+const gulp = require( 'gulp' );
+const path = require( 'path' );
+
+describe( 'build-tasks', () => {
+	let sandbox, tasks;
+	const config = {
+		ROOT_DIR: '.',
+		DIST_DIR: 'dist'
+	};
+
+	beforeEach( () => {
+		mockery.enable( {
+			warnOnReplace: false,
+			warnOnUnregistered: false
+		} );
+
+		sandbox = sinon.sandbox.create();
+
+		mockery.registerMock( 'minimist', () => {
+			return {
+				formats: 'amd',
+				watch: false
+			};
+		} );
+
+		tasks = require( '../../tasks/gulp/build/tasks' )( config );
+	} );
+
+	afterEach( () => {
+		mockery.disable();
+		sandbox.restore();
+	} );
+
+	describe( 'packages', () => {
+		it( 'should return stream with correct packages as src', () => {
+			const fs = require( 'fs' );
+			const readDirStub = sandbox.stub( fs, 'readdirSync', () => [ 'ckeditor5-core', 'ckeditor5-toolbar' ] );
+			const statStub = sandbox.stub( fs, 'lstatSync', () => {
+				return {
+					isDirectory() {
+						return true;
+					},
+					isSymbolicLink() {
+						return false;
+					}
+				};
+			} );
+			const gulpSrcSpy = sandbox.spy( gulp, 'src' );
+			tasks.src.packages( false );
+
+			sinon.assert.calledOnce( readDirStub );
+			sinon.assert.calledTwice( gulpSrcSpy );
+			sinon.assert.calledTwice( statStub );
+
+			expect( gulpSrcSpy.firstCall.args[ 0 ] ).to.equal( path.join( 'node_modules', 'ckeditor5-core', 'src/**/*.js' ) );
+			expect( gulpSrcSpy.secondCall.args[ 0 ] ).to.equal( path.join( 'node_modules', 'ckeditor5-toolbar', 'src/**/*.js' ) );
+		} );
+
+		it( 'should skip files and resolve symbolic links', () => {
+			const fs = require( 'fs' );
+			const readDirStub = sandbox.stub( fs, 'readdirSync', () => [ 'ckeditor5-file.js' ] );
+			const statStub = sandbox.stub( fs, 'lstatSync', () => {
+				return {
+					isDirectory() {
+						return false;
+					},
+					isSymbolicLink() {
+						return true;
+					}
+				};
+			} );
+			const realPathStub = sandbox.stub( fs, 'realpathSync', () => '/real/path' );
+			const gulpSrcSpy = sandbox.spy( gulp, 'src' );
+			tasks.src.packages( false );
+
+			sinon.assert.calledOnce( readDirStub );
+			sinon.assert.calledOnce( realPathStub );
+			sinon.assert.notCalled( gulpSrcSpy );
+			sinon.assert.calledTwice( statStub );
+		} );
+	} );
+
+	describe( 'build', () => {
+		it( 'should return build stream', ( done ) => {
+			const code = 'export default {};';
+			sandbox.stub( gutil, 'log' );
+
+			const build = tasks.build;
+			const stream = require( 'stream' );
+			const files = [
+				new Vinyl( {
+					cwd: './',
+					path: './src/file.js',
+					contents: new Buffer( code )
+				} )
+			];
+
+			// Stub input stream.
+			sandbox.stub( tasks.src, 'all', () => {
+				const fakeInputStream = new stream.Readable( { objectMode: true } );
+				fakeInputStream._read = () => {
+					fakeInputStream.push( files.pop() || null );
+				};
+
+				return fakeInputStream;
+			} );
+
+			// Stub output stream.
+			sandbox.stub( utils, 'dist', () => {
+				const fakeOutputStream = new stream.Writable( { objectMode: true } );
+				fakeOutputStream._write = ( file, encoding, done ) => {
+					const result = babel.transform( code, { plugins: [ 'transform-es2015-modules-amd' ] } );
+					// Check if provided code was transformed by babel.
+					expect( file.contents.toString() ).to.equal( result.code );
+					done();
+				};
+
+				return fakeOutputStream;
+			} );
+
+			const conversionStream = build();
+			conversionStream.on( 'finish', () => done() );
+		} );
+	} );
+} );

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

@@ -0,0 +1,237 @@
+/**
+ * @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 gulp = require( 'gulp' );
+const gutil = require( 'gulp-util' );
+const path = require( 'path' );
+const stream = require( 'stream' );
+const Vinyl = require( 'vinyl' );
+
+describe( 'build-utils', () => {
+	const utils = require( '../../tasks/gulp/build/utils' );
+	let sandbox;
+
+	beforeEach( () => {
+		sandbox = sinon.sandbox.create();
+	} );
+
+	afterEach( () => {
+		sandbox.restore();
+	} );
+
+	describe( 'noop', () => {
+		it( 'should return PassTrough stream', () => {
+			const PassThrough = stream.PassThrough;
+			const ret = utils.noop();
+			expect( ret instanceof PassThrough ).to.equal( true );
+		} );
+	} );
+
+	describe( 'dist', () => {
+		it( 'should return stream created with gulp.dest', () => {
+			const distDir = 'dist/';
+			const format = 'amd';
+			const destSpy = sandbox.spy( gulp, 'dest' );
+			const stream = utils.dist( distDir, format );
+
+			sinon.assert.calledOnce( destSpy );
+			sinon.assert.calledWithExactly( destSpy, path.join( distDir, format ) );
+			expect( stream ).to.equal( destSpy.firstCall.returnValue );
+		} );
+	} );
+
+	describe( 'transpile', () => {
+		it( 'should throw an exception when incorrect format is provided', () => {
+			const transpileSpy = sandbox.spy( utils, 'transpile' );
+			const format = 'incorrect-format';
+
+			expect( () => {
+				transpileSpy( format );
+			} ).to.throw( Error, `Incorrect format: ${ format }` );
+		} );
+
+		it( 'should return babel transform stream', ( done ) => {
+			const modulePath = '../files/utils/lib';
+			const babelStream = utils.transpile( 'amd' );
+			const Stream = stream.Stream;
+			const appendModuleExtensionSpy = sandbox.spy( utils, 'appendModuleExtension' );
+
+			expect( babelStream instanceof Stream ).to.equal( true );
+			expect( babelStream.readable ).to.equal( true );
+			expect( babelStream.writable ).to.equal( true );
+
+			babelStream.on( 'finish', ( ) => {
+				sinon.assert.calledOnce( appendModuleExtensionSpy );
+				sinon.assert.calledWithExactly( appendModuleExtensionSpy, modulePath );
+				expect( appendModuleExtensionSpy.firstCall.returnValue ).to.equal( modulePath + '.js' );
+				done();
+			} );
+
+			babelStream.write( new Vinyl( {
+				cwd: '/',
+				base: '/test/',
+				path: '/test/file.js',
+				contents: new Buffer( `import * as lib from '${ modulePath }'` )
+			} ) );
+
+			babelStream.end();
+		} );
+
+		it( 'should report error when transpiling fails', ( done ) => {
+			const babelStream = utils.transpile( 'amd' );
+			const utilLogStub = sandbox.stub( gutil, 'log' );
+			const consoleLogStub = sandbox.stub( console, 'log' );
+
+			babelStream.once( 'finish', () => {
+				sinon.assert.calledTwice( utilLogStub );
+				sinon.assert.calledOnce( consoleLogStub );
+				done();
+			} );
+
+			babelStream.write( new Vinyl( {
+				cwd: '/',
+				base: '/test/',
+				path: '/test/file.js',
+				contents: new Buffer( 'class ;' )
+			} ) );
+
+			babelStream.end();
+		} );
+	} );
+
+	describe( 'getConversionStreamGenerator', () => {
+		it( 'should return function that can be used for creating conversion streams', () => {
+			const distDir = 'dist/';
+			const formats = [ 'amd', 'cjs', 'esnext' ];
+			const fn = utils.getConversionStreamGenerator( distDir );
+			const streams = formats.reduce( fn, [] );
+
+			expect( streams.length ).to.equal( formats.length );
+		} );
+	} );
+
+	describe( 'pickVersionedFile', () => {
+		it( 'should rename file for provided format', ( done ) => {
+			const rename = utils.pickVersionedFile( 'amd' );
+
+			rename.once( 'finish', () => {
+				done();
+			} );
+
+			rename.on( 'data', ( data ) => {
+				expect( data.basename ).to.equal( 'load.js' );
+			} );
+
+			rename.write(  new Vinyl( {
+				cwd: '/',
+				base: '/test/',
+				path: '/test/load__amd.js',
+				contents: new Buffer( '' )
+			} ) );
+
+			rename.end();
+		} );
+	} );
+
+	describe( 'unpackPackages', () => {
+		it( 'should move files to correct directories', ( done ) => {
+			const rename = utils.unpackPackages();
+
+			rename.once( 'finish', () => {
+				done();
+			} );
+
+			rename.on( 'data', ( data ) => {
+				expect( data.path ).to.equal( 'ckeditor5-core/file.js' );
+			} );
+
+			rename.write( new Vinyl( {
+				cwd: './',
+				path: 'ckeditor5-core/src/file.js',
+				contents: new Buffer( '' )
+			} ) );
+
+			rename.end();
+		} );
+
+		it( 'should throw error when wrong path provided 1', () => {
+			const rename = utils.unpackPackages();
+
+			expect( () => {
+				rename.write( new Vinyl( {
+					cwd: './',
+					path: 'plugin/src/file.js',
+					contents: new Buffer( '' )
+				} ) );
+			} ).to.throw( Error );
+		} );
+
+		it( 'should throw error when wrong path provided 2', () => {
+			const rename = utils.unpackPackages();
+
+			expect( () => {
+				rename.write( new Vinyl( {
+					cwd: './',
+					path: 'ckeditor5-core/file.js',
+					contents: new Buffer( '' )
+				} ) );
+			} ).to.throw( Error );
+		} );
+	} );
+
+	describe( 'wrapCKEditor5Package', () => {
+		it( 'should add `ckeditor5/` to a file path', ( done ) => {
+			const rename = utils.wrapCKEditor5Package();
+			const filePath = './test/file.js';
+			const path = require( 'path' );
+
+			rename.once( 'finish', () => {
+				done();
+			} );
+
+			rename.on( 'data', ( data ) => {
+				expect( data.path ).to.equal( path.join( 'ckeditor5', filePath ) );
+			} );
+
+			rename.write(  new Vinyl( {
+				cwd: './',
+				path: filePath,
+				contents: new Buffer( '' )
+			} ) );
+
+			rename.end();
+		} );
+	} );
+
+	describe( 'appendModuleExtension', (  ) => {
+		it( 'appends module extension when path provided', () => {
+			const filePath = './path/to/file';
+			const source = utils.appendModuleExtension( filePath );
+
+			expect( source ).to.equal( filePath + '.js' );
+		} );
+
+		it( 'appends module extension when URL is provided', () => {
+			const url = 'http://example.com/lib';
+			const source = utils.appendModuleExtension( url );
+
+			expect( source ).to.equal( url + '.js' );
+		} );
+
+		it( 'returns unchanged if module is provided', () => {
+			const module = 'lib/module';
+			const source = utils.appendModuleExtension( module );
+
+			expect( source ).to.equal( module );
+		} );
+	} );
+} );

+ 4 - 2
package.json

@@ -13,6 +13,7 @@
   },
   "devDependencies": {
     "almond": "^0.3.0",
+    "babel-core": "^6.4.0",
     "babel-plugin-transform-es2015-modules-amd": "^6.1.18",
     "babel-plugin-transform-es2015-modules-commonjs": "^6.2.0",
     "benderjs": "^0.4.1",
@@ -40,6 +41,7 @@
     "merge-stream": "^1.0.0",
     "minimist": "^1.2.0",
     "mocha": "^2.2.5",
+    "mockery": "^1.4.0",
     "multipipe": "^0.2.1",
     "ncp": "^2.0.0",
     "replace": "^0.3.0",
@@ -55,7 +57,7 @@
     "url": "https://github.com/ckeditor/ckeditor5.git"
   },
   "scripts": {
-    "test": "mocha dev/tests",
-    "coverage": "istanbul cover _mocha dev/tests/"
+    "test": "mocha dev/tests --recursive",
+    "coverage": "istanbul cover _mocha dev/tests/ -- --recursive"
   }
 }