diff --git a/Gruntfile.js b/Gruntfile.js index 4af0080..451f9e0 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -23,6 +23,8 @@ module.exports = function(grunt) { files: [ 'example/js/**/*.js', 'example/test/spec/**/*.js', + 'example-requirejs/js/**/*.js', + 'example-requirejs/test/spec/**/*.js', 'phantomjs/*', 'tasks/*', 'Gruntfile.js' @@ -30,21 +32,36 @@ module.exports = function(grunt) { tasks: 'test' } }, - blanket_mocha : { - test: { - src: ['example/test.html'], - options : { - threshold : 50, - globalThreshold : 65, - log : true, - logErrors: true, - moduleThreshold : 60, - modulePattern : "./src/(.*?)/" - } + blanket_mocha : { + test: { + src: ['example/test.html'], + options : { + threshold : 60, + globalThreshold : 65, + log : true, + logErrors: true, + moduleThreshold : 60, + modulePattern : "./src/(.*?)/", + customThreshold: { + './src/spelling/plurals.js': 50 } - + } }, - + test_requirejs: { + src: ['example-requirejs/test.html'], + options : { + threshold : 60, + globalThreshold : 65, + log : true, + logErrors: true, + moduleThreshold : 60, + modulePattern : "./src/(.*?)/", + customThreshold: { + './src/spelling/plurals.js': 50 + } + } + } + }, connect: { testUrls: { options: { @@ -89,5 +106,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-connect'); // By default, lint and run all tests. - grunt.task.registerTask('default', ['jshint', 'blanket_mocha']); + grunt.task.registerTask('default', [ + 'jshint', 'blanket_mocha:test', 'blanket_mocha:test_requirejs' + ]); }; diff --git a/README.md b/README.md index b3aa213..498b1cd 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ grunt.loadNpmTasks('grunt-blanket-mocha'); ## Dependencies -* Blanket.js (tested with v1.1.5) +* Blanket.js (tested with v1.1.5) * Mocha (tested with v1.14.0) ## The "blanket_mocha" task @@ -55,8 +55,7 @@ This plugin is based off of grunt-contrib-mocha. For general config options and ### Demo -See the `example` directory for a fully-working example of the setup, including some of the scaffolding required -to get all the pieces to fit together. The `README` in that directory will walk you through it. +See the `example` and `example-requires` directories for a fully-working examples of the setup, including some of the scaffolding required to get all the pieces to fit together. The `README` in that directory will walk you through it. ### Gruntfile @@ -66,10 +65,10 @@ In your project's Gruntfile, add a section named `blanket_mocha` to the data obj grunt.initConfig({ blanket_mocha: { test: { - src: ['specs/test.html'], - options : { + src: ['specs/test.html'], + options : { threshold : 70 - } + } } } }) diff --git a/example-requirejs/Gruntfile.js b/example-requirejs/Gruntfile.js new file mode 100644 index 0000000..4feb571 --- /dev/null +++ b/example-requirejs/Gruntfile.js @@ -0,0 +1,36 @@ +/*global module*/ +module.exports = function(grunt) { + + "use strict"; + + grunt.initConfig({ + + blanket_mocha : { + test: { + src: ['test.html'], + options : { + threshold : 60, + globalThreshold : 65, + log : true, + logErrors: true, + moduleThreshold : 60, + modulePattern : "./src/(.*?)/", + customThreshold: { + './src/spelling/plurals.js': 50 + } + } + } + + } + }); + + // Loading dependencies + for (var key in grunt.file.readJSON("package.json").devDependencies) { + if (key !== "grunt" && key.indexOf("grunt") === 0) { + grunt.loadNpmTasks(key); + } + } + + grunt.registerTask('coverage', ['blanket_mocha']); + grunt.registerTask('default', ['blanket_mocha']); +}; diff --git a/example-requirejs/README.md b/example-requirejs/README.md new file mode 100644 index 0000000..4861450 --- /dev/null +++ b/example-requirejs/README.md @@ -0,0 +1,6 @@ +# Demo + +1. First, `cd` to the `examples` directory (this directory) +2. Next, run `npm install` +3. Run `grunt` +4. You should see some tests run, and a coverage report which will demonstrate a failure at the "per-module" level. \ No newline at end of file diff --git a/example-requirejs/main.js b/example-requirejs/main.js new file mode 100644 index 0000000..e3e6e9f --- /dev/null +++ b/example-requirejs/main.js @@ -0,0 +1,8 @@ +"use strict"; + +define([ + +], function( +) { + +}); diff --git a/example-requirejs/package.json b/example-requirejs/package.json new file mode 100644 index 0000000..b59c148 --- /dev/null +++ b/example-requirejs/package.json @@ -0,0 +1,22 @@ +{ + "name": "grunt-blanket-mocha-test", + "description": "Test for grunt-blanket-mocha.", + "version": "0.5.1", + "homepage": "https://github.com/ModelN/grunt-blanket-mocha", + "author": { + "name": "Dave Cadwallader", + "email": "dcadwallader@gmail.com" + }, + "main": "Gruntfile.js", + "engines": { + "node": ">= 0.8.0" + }, + "devDependencies": { + "grunt-blanket-mocha": "~0.4.0", + "grunt": "0.4.1", + "mocha": "1.17.1", + "chai": "1.8.1", + "blanket": "1.1.5", + "requirejs": "2.1.10" + } +} diff --git a/example-requirejs/src/math/addition.js b/example-requirejs/src/math/addition.js new file mode 100644 index 0000000..fed82ec --- /dev/null +++ b/example-requirejs/src/math/addition.js @@ -0,0 +1,23 @@ +define([ + +], function(){ + + var addThree = function(addTo) { + return addTo + 3; + }; + + var addFive = function(addTo) { + return addTo + 5; + }; + + var addSeven = function(addTo) { + return addTo + 7; + }; + + return { + addThree: addThree, + addFive: addFive, + addSeven: addSeven + } + +}); \ No newline at end of file diff --git a/example-requirejs/src/math/subtraction.js b/example-requirejs/src/math/subtraction.js new file mode 100644 index 0000000..5bfae62 --- /dev/null +++ b/example-requirejs/src/math/subtraction.js @@ -0,0 +1,23 @@ +define([ + +], function(){ + + var subtractThree = function(subtractFrom) { + return subtractFrom - 3; + }; + + var subtractFive = function(subtractFrom) { + return subtractFrom - 5; + }; + + var subtractSeven = function(subtractFrom) { + return subtractFrom - 7; + }; + + return { + subtractThree: subtractThree, + subtractFive: subtractFive, + subtractSeven: subtractSeven + } + +}); \ No newline at end of file diff --git a/example-requirejs/src/spelling/plurals.js b/example-requirejs/src/spelling/plurals.js new file mode 100644 index 0000000..74436b7 --- /dev/null +++ b/example-requirejs/src/spelling/plurals.js @@ -0,0 +1,40 @@ +define([ + +], function(){ + + var dog = function(howMany) { + var ret; + if (howMany < 0) { + ret = "0 dogs"; + } else if (howMany === 1) { + ret = "1 dog"; + } else { + ret = "" + howMany + " dogs"; + } + + return ret; + }; + + var cat = function(howMany) { + var ret; + if (howMany < 0) { + ret = "0 cats"; + } else if (howMany === 1) { + ret = "1 cat"; + } else { + ret = "" + howMany + " cats"; + } + + return ret; + }; + + var fish = function(howMany) { + return "" + howMany + " fish"; + }; + + return { + cat: cat, + fish: fish + } + +}); \ No newline at end of file diff --git a/example-requirejs/src/spelling/vowels.js b/example-requirejs/src/spelling/vowels.js new file mode 100644 index 0000000..9e13225 --- /dev/null +++ b/example-requirejs/src/spelling/vowels.js @@ -0,0 +1,39 @@ +define([ + +], function(){ + + var isVowel = function ( theLetter ) { + + if ( !theLetter ) { + return false; + } else if ( theLetter.length > 1 ) { + return false; + } + + theLetter = theLetter.toUpperCase(); + + switch(theLetter) { + case "A": + case "E": + case "I": + case "O": + case "U": + return true; + default: + return false; + } + + }; + + var isNotVowel = function(theLetter) { + + var isAVowel = isVowel(theLetter); + + return ! isAVowel; + }; + + return { + isVowel: isVowel + } + +}); \ No newline at end of file diff --git a/example-requirejs/test.html b/example-requirejs/test.html new file mode 100644 index 0000000..3163633 --- /dev/null +++ b/example-requirejs/test.html @@ -0,0 +1,39 @@ + + + + Mocha Tests + + + + + + + + + + + + +
+ + + \ No newline at end of file diff --git a/example-requirejs/test/math/addition-specs.js b/example-requirejs/test/math/addition-specs.js new file mode 100644 index 0000000..942ccca --- /dev/null +++ b/example-requirejs/test/math/addition-specs.js @@ -0,0 +1,19 @@ +define([ + "src/math/addition" +], function( + Math +){ + + describe("Addition test", function() { + + it("should add five to positive numbers", function() { + expect(Math.addFive(2)).to.equal(7); + }); + + it("should add seven to positive numbers", function() { + expect(Math.addSeven(2)).to.equal(9); + }); + + }); + +}); \ No newline at end of file diff --git a/example-requirejs/test/math/subtraction-specs.js b/example-requirejs/test/math/subtraction-specs.js new file mode 100644 index 0000000..f250b52 --- /dev/null +++ b/example-requirejs/test/math/subtraction-specs.js @@ -0,0 +1,15 @@ +define([ + "src/math/subtraction" +], function( + Math +){ + + describe("Subtraction test", function() { + + it("should subtract five from positive numbers", function() { + expect(Math.subtractFive(8)).to.equal(3); + }); + + }); + +}); \ No newline at end of file diff --git a/example-requirejs/test/spelling/plurals-specs.js b/example-requirejs/test/spelling/plurals-specs.js new file mode 100644 index 0000000..b6c03ed --- /dev/null +++ b/example-requirejs/test/spelling/plurals-specs.js @@ -0,0 +1,19 @@ +define([ + "src/spelling/plurals" +], function( + Plurals +){ + + describe("Plurals test", function() { + + it("should not pluralize 1 cat", function() { + expect(Plurals.cat(1 ) ).to.equal("1 cat"); + }); + + it("should not pluralize 2 cats", function() { + expect(Plurals.cat(2) ).to.equal("2 cats"); + }); + + }); + +}); \ No newline at end of file diff --git a/example-requirejs/test/spelling/vowels-specs.js b/example-requirejs/test/spelling/vowels-specs.js new file mode 100644 index 0000000..28f5f8d --- /dev/null +++ b/example-requirejs/test/spelling/vowels-specs.js @@ -0,0 +1,15 @@ +define([ + "src/spelling/vowels" +], function( + Vowels +){ + + describe("Vowels test", function() { + + it("should not consider F to be a vowel", function() { + expect(Vowels.isVowel("F") ).to.be.false; + }); + + }); + +}); \ No newline at end of file diff --git a/example-requirejs/test/test-loader.js b/example-requirejs/test/test-loader.js new file mode 100644 index 0000000..c3efec3 --- /dev/null +++ b/example-requirejs/test/test-loader.js @@ -0,0 +1,23 @@ +define([ + "node_modules/chai/chai", + "test/test-suite" + +], function( + chai +){ + "use strict"; + + chai.Assertion.includeStack = true; + + // http://chaijs.com/api/bdd/ + window.expect = chai.expect; + + + return { + start: function() { + // Once dependencies have been loaded using RequireJS, go ahead and run the tests... + mocha.run(); + } + }; + +}); \ No newline at end of file diff --git a/example-requirejs/test/test-suite.js b/example-requirejs/test/test-suite.js new file mode 100644 index 0000000..5d5a74f --- /dev/null +++ b/example-requirejs/test/test-suite.js @@ -0,0 +1,8 @@ +define([ + "test/math/addition-specs", + "test/math/subtraction-specs", + "test/spelling/plurals-specs", + "test/spelling/vowels-specs" +], function(){ + +}); \ No newline at end of file diff --git a/example/Gruntfile.js b/example/Gruntfile.js index 2fc687c..4feb571 100644 --- a/example/Gruntfile.js +++ b/example/Gruntfile.js @@ -1,23 +1,26 @@ /*global module*/ module.exports = function(grunt) { - + "use strict"; grunt.initConfig({ - blanket_mocha : { + blanket_mocha : { test: { - src: ['test.html'], - options : { - threshold : 50, + src: ['test.html'], + options : { + threshold : 60, globalThreshold : 65, log : true, logErrors: true, moduleThreshold : 60, - modulePattern : "./src/(.*?)/" - } + modulePattern : "./src/(.*?)/", + customThreshold: { + './src/spelling/plurals.js': 50 + } + } } - + } }); @@ -30,4 +33,4 @@ module.exports = function(grunt) { grunt.registerTask('coverage', ['blanket_mocha']); grunt.registerTask('default', ['blanket_mocha']); -}; \ No newline at end of file +}; diff --git a/example/package.json b/example/package.json index b59c148..48e2df7 100644 --- a/example/package.json +++ b/example/package.json @@ -16,7 +16,6 @@ "grunt": "0.4.1", "mocha": "1.17.1", "chai": "1.8.1", - "blanket": "1.1.5", - "requirejs": "2.1.10" + "blanket": "1.1.5" } } diff --git a/example/src/math/addition.js b/example/src/math/addition.js index fed82ec..dc49075 100644 --- a/example/src/math/addition.js +++ b/example/src/math/addition.js @@ -1,23 +1,13 @@ -define([ +window.Math = window.Math || {} -], function(){ +window.Math.addThree = function(addTo) { + return addTo + 3; +}; - var addThree = function(addTo) { - return addTo + 3; - }; - - var addFive = function(addTo) { - return addTo + 5; - }; +window.Math.addFive = function(addTo) { + return addTo + 5; +}; - var addSeven = function(addTo) { - return addTo + 7; - }; - - return { - addThree: addThree, - addFive: addFive, - addSeven: addSeven - } - -}); \ No newline at end of file +window.Math.addSeven = function(addTo) { + return addTo + 7; +}; diff --git a/example/src/math/subtraction.js b/example/src/math/subtraction.js index 5bfae62..2e55fa2 100644 --- a/example/src/math/subtraction.js +++ b/example/src/math/subtraction.js @@ -1,23 +1,13 @@ -define([ +window.Math = window.Math || {} -], function(){ +window.Math.subtractThree = function(subtractFrom) { + return subtractFrom - 3; +}; - var subtractThree = function(subtractFrom) { - return subtractFrom - 3; - }; - - var subtractFive = function(subtractFrom) { - return subtractFrom - 5; - }; +window.Math.subtractFive = function(subtractFrom) { + return subtractFrom - 5; +}; - var subtractSeven = function(subtractFrom) { - return subtractFrom - 7; - }; - - return { - subtractThree: subtractThree, - subtractFive: subtractFive, - subtractSeven: subtractSeven - } - -}); \ No newline at end of file +window.Math.subtractSeven = function(subtractFrom) { + return subtractFrom - 7; +}; diff --git a/example/src/spelling/plurals.js b/example/src/spelling/plurals.js index 74436b7..7f5c823 100644 --- a/example/src/spelling/plurals.js +++ b/example/src/spelling/plurals.js @@ -1,40 +1,31 @@ -define([ +window.Plurals = {} -], function(){ - - var dog = function(howMany) { - var ret; - if (howMany < 0) { - ret = "0 dogs"; - } else if (howMany === 1) { - ret = "1 dog"; - } else { - ret = "" + howMany + " dogs"; - } +window.Plurals.dog = function(howMany) { + var ret; + if (howMany < 0) { + ret = "0 dogs"; + } else if (howMany === 1) { + ret = "1 dog"; + } else { + ret = "" + howMany + " dogs"; + } - return ret; - }; - - var cat = function(howMany) { - var ret; - if (howMany < 0) { - ret = "0 cats"; - } else if (howMany === 1) { - ret = "1 cat"; - } else { - ret = "" + howMany + " cats"; - } - - return ret; - }; + return ret; +}; - var fish = function(howMany) { - return "" + howMany + " fish"; - }; - - return { - cat: cat, - fish: fish +window.Plurals.cat = function(howMany) { + var ret; + if (howMany < 0) { + ret = "0 cats"; + } else if (howMany === 1) { + ret = "1 cat"; + } else { + ret = "" + howMany + " cats"; } - -}); \ No newline at end of file + + return ret; +}; + +window.Plurals.fish = function(howMany) { + return "" + howMany + " fish"; +}; diff --git a/example/src/spelling/vowels.js b/example/src/spelling/vowels.js index 9e13225..7908f01 100644 --- a/example/src/spelling/vowels.js +++ b/example/src/spelling/vowels.js @@ -1,39 +1,31 @@ -define([ +window.Vowels = {} -], function(){ +window.Vowels.isVowel = function ( theLetter ) { - var isVowel = function ( theLetter ) { + if ( !theLetter ) { + return false; + } else if ( theLetter.length > 1 ) { + return false; + } - if ( !theLetter ) { - return false; - } else if ( theLetter.length > 1 ) { + theLetter = theLetter.toUpperCase(); + + switch(theLetter) { + case "A": + case "E": + case "I": + case "O": + case "U": + return true; + default: return false; - } - - theLetter = theLetter.toUpperCase(); - - switch(theLetter) { - case "A": - case "E": - case "I": - case "O": - case "U": - return true; - default: - return false; - } - - }; - - var isNotVowel = function(theLetter) { - - var isAVowel = isVowel(theLetter); - - return ! isAVowel; - }; - - return { - isVowel: isVowel } - -}); \ No newline at end of file + +}; + +window.Vowels.isNotVowel = function(theLetter) { + + var isAVowel = isVowel(theLetter); + + return ! isAVowel; +}; diff --git a/example/test.html b/example/test.html index 3163633..1a5cf30 100644 --- a/example/test.html +++ b/example/test.html @@ -4,8 +4,13 @@ Mocha Tests + - + + + + + - //load main js first, this will load all the - //script dependencies - require(["main"], function(main) { - require(["test/test-loader"], function(TestLoader) { - //start running the mocha tests - TestLoader.start(); - }); - }); + + + + -
- \ No newline at end of file + diff --git a/example/test/math/addition-specs.js b/example/test/math/addition-specs.js index 942ccca..a38e8e8 100644 --- a/example/test/math/addition-specs.js +++ b/example/test/math/addition-specs.js @@ -1,19 +1,11 @@ -define([ - "src/math/addition" -], function( - Math -){ +describe("Addition test", function() { - describe("Addition test", function() { - - it("should add five to positive numbers", function() { - expect(Math.addFive(2)).to.equal(7); - }); + it("should add five to positive numbers", function() { + expect(Math.addFive(2)).to.equal(7); + }); - it("should add seven to positive numbers", function() { - expect(Math.addSeven(2)).to.equal(9); - }); - + it("should add seven to positive numbers", function() { + expect(Math.addSeven(2)).to.equal(9); }); - -}); \ No newline at end of file + +}); diff --git a/example/test/math/subtraction-specs.js b/example/test/math/subtraction-specs.js index f250b52..21e6689 100644 --- a/example/test/math/subtraction-specs.js +++ b/example/test/math/subtraction-specs.js @@ -1,15 +1,7 @@ -define([ - "src/math/subtraction" -], function( - Math -){ +describe("Subtraction test", function() { - describe("Subtraction test", function() { - - it("should subtract five from positive numbers", function() { - expect(Math.subtractFive(8)).to.equal(3); - }); - + it("should subtract five from positive numbers", function() { + expect(Math.subtractFive(8)).to.equal(3); }); - -}); \ No newline at end of file + +}); diff --git a/example/test/spelling/plurals-specs.js b/example/test/spelling/plurals-specs.js index b6c03ed..9267207 100644 --- a/example/test/spelling/plurals-specs.js +++ b/example/test/spelling/plurals-specs.js @@ -1,19 +1,11 @@ -define([ - "src/spelling/plurals" -], function( - Plurals -){ +describe("Plurals test", function() { - describe("Plurals test", function() { - - it("should not pluralize 1 cat", function() { - expect(Plurals.cat(1 ) ).to.equal("1 cat"); - }); + it("should not pluralize 1 cat", function() { + expect(Plurals.cat(1 ) ).to.equal("1 cat"); + }); - it("should not pluralize 2 cats", function() { - expect(Plurals.cat(2) ).to.equal("2 cats"); - }); - + it("should not pluralize 2 cats", function() { + expect(Plurals.cat(2) ).to.equal("2 cats"); }); - -}); \ No newline at end of file + +}); diff --git a/example/test/spelling/vowels-specs.js b/example/test/spelling/vowels-specs.js index 28f5f8d..ce4f876 100644 --- a/example/test/spelling/vowels-specs.js +++ b/example/test/spelling/vowels-specs.js @@ -1,15 +1,7 @@ -define([ - "src/spelling/vowels" -], function( - Vowels -){ +describe("Vowels test", function() { - describe("Vowels test", function() { - - it("should not consider F to be a vowel", function() { - expect(Vowels.isVowel("F") ).to.be.false; - }); - + it("should not consider F to be a vowel", function() { + expect(Vowels.isVowel("F") ).to.be.false; }); - -}); \ No newline at end of file + +}); diff --git a/tasks/blanket_mocha.js b/tasks/blanket_mocha.js index 68fa305..6ab8338 100644 --- a/tasks/blanket_mocha.js +++ b/tasks/blanket_mocha.js @@ -47,8 +47,9 @@ module.exports = function(grunt) { var pass = (percent >= threshold); - //If not passed, check if file is marked for manual exclusion. Else, fail it. - var result = pass ? "PASS" : ( excludedFiles.indexOf(name) === -1 /*File not found*/ ? "FAIL" : "SKIP"); + // If not passed, check if file is marked for manual exclusion. Else, fail it. + var exclude = _(excludedFiles).some(function (o) {return o.test(name);}); + var result = pass ? "PASS" : ( exclude ? "SKIP" : "FAIL"); var percentDisplay = Math.floor(percent); if (percentDisplay < 10) { @@ -105,8 +106,13 @@ module.exports = function(grunt) { var totalLines = thisTotal[1]; var threshold = coverageThreshold; - if (customThreshold[filename]) { - threshold = customThreshold[filename]; + + // Check for a custom threshold + var custom = _.find(customThreshold, function (o) { + return o[0].test(filename); + }); + if (custom !== undefined) { + threshold = custom[1]; } printPassFailMessage(filename, coveredLines, totalLines, threshold); @@ -232,18 +238,26 @@ module.exports = function(grunt) { var grep = grunt.option('grep'); options.mocha = options.mocha || {}; - //Get the array of excludedFiles - //Users should be able to define it in the command-line as an array or include it in the test file. + // Get the array of excludedFiles, normalize and prepare them + // Users should be able to define it in the command-line as an array or include it in the test file. excludedFiles = grunt.option('excludedFiles') || options.excludedFiles || []; + excludedFiles = _(excludedFiles).map(function (o) { + return new RegExp(path.normalize(o) + '$'); + }).value(); + // Get the custom thresholds for files, normalize and prepare the file names customThreshold = grunt.option('customThreshold') || options.customThreshold || {}; + customThreshold = _(customThreshold).pairs().map(function (o) { + return [new RegExp(path.normalize(o[0]) + '$'), o[1]]; + }).value(); + customModuleThreshold = grunt.option('customModuleThreshold') || options.customModuleThreshold|| {}; if (grep) { options.mocha.grep = grep; } - - + + // Output console messages if log == true if (options.log) { phantomjs.removeAllListeners(['console']); @@ -487,4 +501,4 @@ module.exports = function(grunt) { done(); }); }); -}; \ No newline at end of file +};