ソースを参照

Merge pull request #11 from cksource/t/1

t/1: Introduce tests and Bender.js
Grzegorz Pabian 11 年 前
コミット
21b0cf9fe8

+ 1 - 0
.gitignore

@@ -9,3 +9,4 @@
 
 node_modules/**
 build/**
+coverage/**

+ 48 - 0
bender.js

@@ -0,0 +1,48 @@
+/* jshint browser: false, node: true */
+
+'use strict';
+
+var config = {
+	plugins: [
+		// Uncomment to enable code coverage.
+		// 'benderjs-coverage',
+
+		'benderjs-mocha',
+		'benderjs-chai',
+		'benderjs-sinon',
+		'dev/bender/plugins/ckeditor5'
+	],
+
+	framework: 'mocha',
+
+	applications: {
+		ckeditor: {
+			path: '.',
+			files: [
+				'node_modules/requirejs/require.js',
+				'ckeditor.js'
+			]
+		}
+	},
+
+	tests: {
+		all: {
+			applications: [ 'ckeditor' ],
+			paths: [
+				'tests/**',
+				'node_modules/ckeditor5-*/tests/**'
+			]
+		}
+	},
+
+	coverage: {
+		paths: [
+			'ckeditor.js',
+			'src/**/*.js',
+			'node_modules/ckeditor5-*/src/**/*.js',
+			'!node_modules/ckeditor5-*/src/lib/**'
+		]
+	}
+};
+
+module.exports = config;

+ 3 - 12
ckeditor.js

@@ -3,7 +3,7 @@
  * For licensing, see LICENSE.md.
  */
 
-/* global requirejs, define, require, window, document, location */
+/* global requirejs, define, require, window, document */
 
 'use strict';
 
@@ -73,10 +73,9 @@
 
 	// Define a new "ckeditor" module, which overrides the core one with the above and the dev stuff.
 	define( 'ckeditor', [ 'ckeditor-core', 'ckeditor-dev', 'utils' ], function( core, dev, utils ) {
-		utils.extend( core, root.CKEDITOR, ( dev || {} ) );
-		root.CKEDITOR = core;
+		root.CKEDITOR = utils.extend( {}, core, root.CKEDITOR, ( dev || /* istanbul ignore next */ {} ) );
 
-		return core;
+		return root.CKEDITOR;
 	} );
 
 	function getBasePath() {
@@ -99,14 +98,6 @@
 			}
 		} );
 
-		if ( path.indexOf( ':/' ) == -1 && path.slice( 0, 2 ) != '//' ) {
-			if ( path[ 0 ] == '/' ) {
-				path = location.href.match( /^.*?:\/\/[^\/]*/ )[ 0 ] + path;
-			} else {
-				path = location.href.match( /^[^\?]*\/(?:)/ )[ 0 ] + path;
-			}
-		}
-
 		return path;
 	}
 } )( window );

+ 20 - 0
dev/bender/plugins/ckeditor5/lib/index.js

@@ -0,0 +1,20 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* jshint node: true */
+
+'use strict';
+
+var path = require( 'path' );
+var files = [
+	path.join( __dirname, '../static/extensions.js' )
+];
+
+module.exports = {
+	name: 'bender-ckeditor5',
+
+	files: files,
+	include: files
+};

+ 5 - 0
dev/bender/plugins/ckeditor5/package.json

@@ -0,0 +1,5 @@
+{
+  "name": "benderjs-ckeditor5",
+  "description": "CKEditor 5 plugin for Bender.js",
+  "main": "lib/index.js"
+}

+ 46 - 0
dev/bender/plugins/ckeditor5/static/extensions.js

@@ -0,0 +1,46 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals bender, CKEDITOR */
+
+'use strict';
+
+( function() {
+	// Make Bender wait to start running tests.
+	var done = bender.defer();
+
+	// Wait for the "ckeditor" module to be ready to start testing.
+	CKEDITOR.require( [ 'ckeditor' ], done );
+
+	/**
+	 * AMD tools related to CKEditor.
+	 */
+	bender.amd = {
+		/**
+		 * Gets an object which holds the CKEditor modules guaranteed to be loaded before tests start.
+		 *
+		 * @params {...String} module The name of the module to load.
+		 * @returns {Object} The object that will hold the loaded modules.
+		 */
+		require: function() {
+			var modules = {};
+
+			var done = bender.defer();
+
+			var names = [].slice.call( arguments );
+
+			CKEDITOR.require( names, function() {
+				for ( var i = 0; i < names.length; i++ ) {
+					modules[ names[ i ] ] = arguments[ i ] ;
+				}
+
+				// Finally give green light for tests to start.
+				done();
+			} );
+
+			return modules;
+		}
+	};
+} )();

+ 3 - 0
gruntfile.js

@@ -18,6 +18,9 @@ module.exports = function( grunt ) {
 
 		jshint: {
 			options: {
+				globals: {
+					'bender': false
+				},
 				ignores: ignoreFiles
 			}
 		},

+ 5 - 0
package.json

@@ -16,6 +16,11 @@
     "del": "~1.1",
     "ncp": "~1.0",
     "replace": "~0.3.0",
+    "benderjs": "~0.2",
+    "benderjs-mocha": "~0.1",
+    "benderjs-chai": "~0.2",
+    "benderjs-sinon": "~0.2",
+    "benderjs-coverage": "~0.2",
     "grunt": "~0",
     "grunt-jscs": "~1",
     "grunt-contrib-jshint": "~0",

+ 8 - 0
src/ckeditor-dev.js

@@ -9,6 +9,14 @@
 
 define( 'ckeditor-dev', function() {
 	return {
+		/**
+		 * A flag specifying whether CKEditor is running in development mode (original source code).
+		 *
+		 * This property is not defined in production (compiled, build code).
+		 */
+		isDev: true,
+
+		// Documented in ckeditor-core/ckeditor.
 		getPluginPath: function( name ) {
 			return this.basePath + 'node_modules/ckeditor-plugin-' + name + '/src/';
 		}

+ 30 - 0
tests/amd/amd.js

@@ -0,0 +1,30 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals describe, it, expect, CKEDITOR */
+
+'use strict';
+
+CKEDITOR.define( 'testModule', [ 'ckeditor' ], function( ckeditor ) {
+	return {
+		test: ( ckeditor && ( typeof ckeditor == 'object' ) )
+	};
+} );
+
+describe( 'CKEDITOR.require()', function() {
+	it( 'should work with a defined module', function( done ) {
+		CKEDITOR.require( [ 'testModule' ], function( testModule ) {
+			expect( testModule ).to.have.property( 'test' ).to.be.true();
+			done();
+		} );
+	} );
+
+	it( 'should work with a core module', function( done ) {
+		CKEDITOR.require( [ 'utils' ], function( utils ) {
+			expect( utils ).to.be.an( 'object' );
+			done();
+		} );
+	} );
+} );

+ 71 - 0
tests/ckeditor/basepath.js

@@ -0,0 +1,71 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals beforeEach, describe, it, expect, window, document */
+
+'use strict';
+
+var modules = bender.amd.require( 'ckeditor' );
+
+beforeEach( function() {
+	// Ensure that no CKEDITOR_BASEPATH global is available.
+	delete window.CKEDITOR_BASEPATH;
+
+	// Remove all script elements from the document.
+	removeScripts();
+} );
+
+describe( 'basePath', function() {
+	it( 'should work with script tags', function() {
+		var CKEDITOR = modules.ckeditor;
+
+		addScript( 'http://bar.com/ckeditor/ckeditor.js' );
+		expect( CKEDITOR._getBasePath() ).to.equal( 'http://bar.com/ckeditor/' );
+	} );
+
+	it( 'should work with the CKEDITOR_BASEPATH global', function() {
+		var CKEDITOR = modules.ckeditor;
+
+		window.CKEDITOR_BASEPATH = 'http://foo.com/ckeditor/';
+		expect( CKEDITOR._getBasePath() ).to.equal( 'http://foo.com/ckeditor/' );
+	} );
+} );
+
+describe( 'This browser', function() {
+	it( 'should not keep script URLs absolute or relative', function() {
+		// Browsers should convert absolute and relative URLs to full URLs.
+		// If this test fails in any browser, _getBasePath() must be reviewed to deal with such case (v4 does it).
+
+		test( '/absolute/url/ckeditor.js' );
+		test( '../relative/url/ckeditor.js' );
+
+		function test( url ) {
+			removeScripts();
+
+			var script = addScript( url );
+
+			// Test if the src now contains '://'.
+			expect( /:\/\//.test( script.src ) ).to.be.true();
+		}
+	} );
+} );
+
+function addScript( url ) {
+	var script = document.createElement( 'script' );
+
+	script.src = url;
+	document.head.appendChild( script );
+
+	return script;
+}
+
+function removeScripts() {
+	var scripts = [].slice.call( document.getElementsByTagName( 'script' ) );
+	var script;
+
+	while ( ( script = scripts.shift() ) ) {
+		script.parentNode.removeChild( script );
+	}
+}

+ 44 - 0
tests/ckeditor/ckeditor.js

@@ -0,0 +1,44 @@
+/**
+ * @license Copyright (c) 2003-2015, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md.
+ */
+
+/* globals describe, it, expect */
+
+'use strict';
+
+var modules = bender.amd.require( 'ckeditor', 'ckeditor-core' );
+
+describe( 'getPluginPath()', function() {
+	it( 'should return a proper path', function() {
+		var CKEDITOR = modules.ckeditor;
+
+		var basePath = CKEDITOR.basePath;
+		var path = CKEDITOR.getPluginPath( 'test' );
+
+		if ( CKEDITOR.isDev ) {
+			expect( path ).to.equal( basePath + 'node_modules/ckeditor-plugin-test/src/' );
+		} else {
+			expect( path ).to.equal( basePath + 'plugins/test/' );
+		}
+	} );
+
+	it( '(the production version) should work even when in dev', function() {
+		var CKEDITOR = modules.ckeditor;
+		var core = modules[ 'ckeditor-core' ];
+
+		// To be able to run this test on both dev and production code, we need to override getPluginPath with the
+		// core version of it and restore it after testing.
+		var originalGetPluginPath = CKEDITOR.getPluginPath;
+		CKEDITOR.getPluginPath = core.getPluginPath;
+
+		// This test is good for both the development and production codes.
+		var basePath = CKEDITOR.basePath;
+		var path = CKEDITOR.getPluginPath( 'test' );
+
+		// Revert the override before assertions or it will not do it in case of errors.
+		CKEDITOR.getPluginPath = originalGetPluginPath;
+
+		expect( path ).to.equal( basePath + 'plugins/test/' );
+	} );
+} );