From c5945e3b83b27cb4184b0ca126e3a28c6b18bb1b Mon Sep 17 00:00:00 2001 From: Simon Elliott Date: Wed, 13 Nov 2013 12:36:50 +0000 Subject: [PATCH] plugin tests, grunt test task, clean up --- Gruntfile.js | 30 ++++++++++++++++++++++-------- karma.conf.js | 3 ++- package.json | 2 +- src/core.js | 37 +++++++++++++++++++------------------ test/fixture/dep1.js | 15 +++++++++++++++ test/fixture/dep2.js | 15 +++++++++++++++ test/fixture/example.js | 11 +++++++++-- test/fixture/promise.js | 11 +++++++++-- test/spec/core.js | 19 ++++++++++++++++--- 9 files changed, 108 insertions(+), 35 deletions(-) create mode 100644 test/fixture/dep1.js create mode 100644 test/fixture/dep2.js diff --git a/Gruntfile.js b/Gruntfile.js index af3aaa8..bad9066 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -44,12 +44,10 @@ module.exports = function(grunt) { baseUrl: "src", out: 'dist/<%= bower.name %>.js', paths: { - almond: 'lib/almond/almond', requirejs: 'lib/requirejs/require', domReady: 'lib/requirejs-domready/domReady', }, include: ['requirejs', 'sqwidget'], - // Wrapper for AMD wrap: { startFile: 'src/_wrapper/top.js', endFile: 'src/_wrapper/bottom.js' @@ -63,20 +61,35 @@ module.exports = function(grunt) { } } }, + karma: { + options: { + configFile: './karma.conf.js', + browsers: ['Chrome', 'Firefox'] + }, + unit: { + background: true + }, + //continuous integration mode: run tests once in PhantomJS browser. + continuous: { + singleRun: true, + browsers: ['PhantomJS'] + }, + }, shell: { build_example: { command: "./build_example.sh" - }, - test: { - command: "npm test" } }, watch: { + test: { + files: ["test/fixture/*.js", "src/*.js", "test/spec/*.js"], + tasks: ["karma:unit:run"] + }, sqwidget: { - files: ["src/*.js"], - tasks: ["shell:test", "build"] + files: ["src/*.js", "test/spec/*.js"], + tasks: ["karma:unit:run", "build"] }, scaffold: { files: ["grunt-scaffold/root/main.js", "grunt-scaffold/root/app/**/*.js", "grunt-scaffold/**/*.tmpl"], @@ -100,6 +113,7 @@ module.exports = function(grunt) { }); grunt.registerTask("build", ["requirejs:compile"]); grunt.registerTask("default", ["clean", "build", "connect", "watch"]); - grunt.registerTask("dist", ["clean", "build"]); + grunt.registerTask("dist", ["clean", "build", "karma:unit"]); + grunt.registerTask("test", ["clean", "karma:unit", "watch:test"]); grunt.registerTask("release", ["dist", "bowerRelease:stable"]); }; diff --git a/karma.conf.js b/karma.conf.js index 42069ab..c75e3aa 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -26,6 +26,7 @@ module.exports = function(config) { browsers: ['PhantomJS'], // If singleRun is set to true, Karma will start and capture all // configured browsers, run tests and then exit with an exit code of 0 or 1. - singleRun: false + singleRun: false, + reporters: 'dots' }); }; diff --git a/package.json b/package.json index 2d7b582..9652dd3 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "scripts": { "prepublish": "make dist", "postinstall": "./grunt-scaffold/install.sh", - "test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS" + "test": "grunt test:continuous" }, "dependencies": { "grunt-bower-release": "0.0.2" diff --git a/src/core.js b/src/core.js index 1f19189..e6eb64d 100644 --- a/src/core.js +++ b/src/core.js @@ -68,9 +68,9 @@ define(['require', 'lib/bonzo/bonzo', 'lib/qwery/qwery', 'lib/bean/bean', 'domRe }); //bus events - bean.fire(this, "rendered:" + pkg.url); - bean.fire(this, "rendered:" + pkg.id); - bean.fire(pkg, "rendered"); + bean.fire(this, "rendered:" + pkg.url, [bundle]); + bean.fire(this, "rendered:" + pkg.id,[bundle]); + bean.fire(pkg, "rendered", [bundle]); } else { throw("controller not found for " + bundle.location); } @@ -84,13 +84,10 @@ define(['require', 'lib/bonzo/bonzo', 'lib/qwery/qwery', 'lib/bean/bean', 'domRe }; SqwidgetCore.prototype.initialize = function() { - var names = [], - _this = this; - for(var id in _this.packages) { - var pkg = _this.packages[id]; + for(var id in this.packages) { - (function(pkg,id) { + (function(pkg, id, _this) { //parse out script name from path var parts = pkg.url.split("/"); var name = "./" + parts.pop(); @@ -105,14 +102,15 @@ define(['require', 'lib/bonzo/bonzo', 'lib/qwery/qwery', 'lib/bean/bean', 'domRe //the outer bundle can define some config, like packages it would like //loading before running its 'main' function - //todo fix dumb closing out on vars here - var loadMain = function(require,pkg,_this) { + //load the 'main' function inside the widget bundle when we have + //finished with dependencies + var loadMain = function() { require(["main"], function(loaded) { //if the bundle is a promise, wait for it to resolve, otherwise handle //immediately if("then" in loaded) { var resolve = function(bundle) { - return _this.initializeWidget.apply(_this, [pkg, bundle]); }; + _this.initialiseWidget.apply(_this, [pkg, bundle]); }; loaded.then(resolve); } else { _this.initialiseWidget(pkg, loaded); @@ -120,6 +118,7 @@ define(['require', 'lib/bonzo/bonzo', 'lib/qwery/qwery', 'lib/bean/bean', 'domRe }, function(err) { throw err; } ); }; + // preload a library the widget bundle requires if(bundle_config && bundle_config.packages) { //create a new config for the lib loader @@ -141,18 +140,20 @@ define(['require', 'lib/bonzo/bonzo', 'lib/qwery/qwery', 'lib/bean/bean', 'domRe //config allowing both to be loaded simultaneously var preloads = bundle_config.preloads || []; - //there must be a better way to do this... we could - //iterate context.registry() but that also seems insane. - require(preloads,function() { - loadMain(require,pkg,_this); - }); + //at the moment the bundle config passes things we need to preload + //however, since its an optimized bundle they are *all* loaded + //already they are just sat inside registry() + //we could iterate context.registry() instead to force them into + //the current require context + require(preloads,function() { loadMain(); }); + }, function(err) { throw err; } ); } else { - loadMain(require,pkg, _this); + loadMain(); } }, function(err) { throw err; } ); - })(pkg,id); + })(this.packages[id], id, this); } }; diff --git a/test/fixture/dep1.js b/test/fixture/dep1.js new file mode 100644 index 0000000..001047c --- /dev/null +++ b/test/fixture/dep1.js @@ -0,0 +1,15 @@ +//outer define is namespaced and passed the contextualised require +sqwidget.define(["require"], function(require) { + var define = sqwidget.define; + + define("dep1/helper", function() { + return true; + }); + + define("dep1/helper2", function() { + return true; + }); + + return {}; +}); + diff --git a/test/fixture/dep2.js b/test/fixture/dep2.js new file mode 100644 index 0000000..61a61fe --- /dev/null +++ b/test/fixture/dep2.js @@ -0,0 +1,15 @@ +//outer define is namespaced and passed the contextualised require +sqwidget.define(["require"], function(require) { + var define = sqwidget.define; + + define("dep2/helper", function() { + return true; + }); + + define("dep2/helper2", function() { + return true; + }); + + return {}; +}); + diff --git a/test/fixture/example.js b/test/fixture/example.js index ea2e53d..458f6ef 100644 --- a/test/fixture/example.js +++ b/test/fixture/example.js @@ -5,10 +5,17 @@ sqwidget.define(["require"], function(require) { return { Controller: function (opts) { opts.config.el.append("
TEST
"); - } + }, + require: require }; }); - return {}; + return { + packages: [ + { name: "dep1", location: '/base/test/fixture', main:"dep1" }, + { name: "dep2", location: '/base/test/fixture', main:"dep2" } + ], + preloads: ["dep1/helper", "dep1/helper2"] + }; }); diff --git a/test/fixture/promise.js b/test/fixture/promise.js index 50107b6..1bead56 100644 --- a/test/fixture/promise.js +++ b/test/fixture/promise.js @@ -7,14 +7,21 @@ sqwidget.define(['require', '../../src/lib/when/when'] ,function(require, when) var pkg = { Controller: function (opts) { opts.config.el.append("
PROMISE
"); - } + }, + require: require }; deferred.resolve(pkg); }); return deferred.promise; }); - return {}; + + return { + packages: [ + { name: "dep2", location: '/base/test/fixture', main:"dep2" } + ], + preloads: ["dep2/helper", "dep2/helper2"] + }; }); diff --git a/test/spec/core.js b/test/spec/core.js index addebec..ccc42a2 100644 --- a/test/spec/core.js +++ b/test/spec/core.js @@ -57,14 +57,25 @@ define(['chai', 'lib/async/lib/async', 'core', 'lib/bonzo/bonzo', 'lib/bean/bean async.parallel([ function(cb) { - bean.on(widget, 'rendered', function() { + bean.on(widget, 'rendered', function(bundle) { + assert.isTrue(bundle.require("dep1/helper")); + assert.isTrue(bundle.require("dep1/helper2")); + try { + bundle.require("dep2/helper"); + assert.fail(true, false, "loaded"); + } catch (e) { + assert.ok(e, "failed to load"); + } + assert.ok("Triggered event on package"); + //check we have mixed in plugin + cb(); }); }, function(cb) { - bean.on(sqwidgetCore, 'rendered:' + widget.id, function() { + bean.on(sqwidgetCore, 'rendered:' + widget.id, function(bundle) { assert.ok("Triggered event"); assert.equal(bonzo(w1).html(), '
TEST
', 'Rendered correctly'); cb(); @@ -72,7 +83,9 @@ define(['chai', 'lib/async/lib/async', 'core', 'lib/bonzo/bonzo', 'lib/bean/bean }, function(cb) { - bean.on(sqwidgetCore, 'rendered:' + w2r.id, function() { + bean.on(sqwidgetCore, 'rendered:' + w2r.id, function(bundle) { + assert.isTrue(bundle.require("dep2/helper")); + assert.isTrue(bundle.require("dep2/helper2")); assert.ok("Triggered event"); assert.equal(bonzo(w2).html(), '
PROMISE
', 'Rendered correctly'); cb();