From 7c870b5faee077dd6ae73da1ee637d26ba9f09c7 Mon Sep 17 00:00:00 2001 From: Jez Ng Date: Sun, 9 Sep 2012 05:49:17 -0400 Subject: Add JSCoverage support. --- Cakefile | 89 ++++++++++++++++++++++++++--------- README.markdown | 5 ++ tests/dom_tests/phantom_runner.coffee | 16 ++++--- 3 files changed, 82 insertions(+), 28 deletions(-) diff --git a/Cakefile b/Cakefile index 97927f03..bf096e3f 100644 --- a/Cakefile +++ b/Cakefile @@ -1,6 +1,7 @@ fs = require "fs" path = require "path" child_process = require "child_process" +{Utils} = require './lib/utils' spawn = (procName, optArray, silent=false) -> proc = child_process.spawn procName, optArray @@ -9,29 +10,41 @@ spawn = (procName, optArray, silent=false) -> proc.stderr.on 'data', (data) -> process.stderr.write data proc -optArrayFromDict = (opts) -> "--#{key}=#{value}" for key, value of opts +optArrayFromDict = (opts) -> + result = [] + for key, value of opts + if value instanceof Array + result.push "--#{key}=#{v}" for v in value + else + result.push "--#{key}=#{value}" + result + +# visitor will get passed the file path as a parameter +visitDirectory = (directory, visitor) -> + fs.readdirSync(directory).forEach (filename) -> + filepath = path.join directory, filename + if (fs.statSync filepath).isDirectory() + return visitDirectory filepath, visitor + + return unless (fs.statSync filepath).isFile() + visitor(filepath) task "build", "compile all coffeescript files to javascript", -> coffee = spawn "coffee", ["-c", __dirname] task "clean", "removes any js files which were compiled from coffeescript", -> - visit = (directory) -> - fs.readdirSync(directory).forEach (filename) -> - filepath = path.join directory, filename - if (fs.statSync filepath).isDirectory() - return visit filepath - - return unless (path.extname filename) == ".js" and (fs.statSync filepath).isFile() + visitDirectory __dirname, (filepath) -> + return unless (path.extname filepath) == ".js" - # Check if there exists a corresponding .coffee file - try - coffeeFile = fs.statSync path.join directory, "#{path.basename filepath, ".js"}.coffee" - catch _ - return + directory = path.dirname filepath - fs.unlinkSync filepath if coffeeFile.isFile() + # Check if there exists a corresponding .coffee file + try + coffeeFile = fs.statSync path.join directory, "#{path.basename filepath, ".js"}.coffee" + catch _ + return - visit __dirname + fs.unlinkSync filepath if coffeeFile.isFile() task "autobuild", "continually rebuild coffeescript files using coffee --watch", -> coffee = spawn "coffee", ["-cw", __dirname] @@ -54,17 +67,49 @@ task "package", "build .crx file", -> crxmake.on "exit", -> fs.writeFileSync "manifest.json", origManifestText -task "test", "run all tests", -> +runUnitTests = (projectDir=".") -> console.log "Running unit tests..." - basedir = "tests/unit_tests/" + basedir = path.join projectDir, "/tests/unit_tests/" test_files = fs.readdirSync(basedir).filter((filename) -> filename.indexOf("_test.js") > 0) test_files = test_files.map((filename) -> basedir + filename) - test_files.forEach (file) -> require "./" + file + test_files.forEach (file) -> require (if file[0] == '/' then '' else './') + file Tests.run() - returnCode = if Tests.testsFailed > 0 then 1 else 0 + return Tests.testsFailed + +task "test", "run all tests", -> + unitTestsFailed = runUnitTests() console.log "Running DOM tests..." phantom = spawn "phantomjs", ["./tests/dom_tests/phantom_runner.js"] - phantom.on 'exit', (code) -> - returnCode += code - process.exit returnCode + phantom.on 'exit', (returnCode) -> + if returnCode > 0 or unitTestsFailed > 0 + process.exit 1 + else + process.exit 0 + +task "coverage", "generate coverage report", -> + temp = require 'temp' + tmpDir = temp.mkdirSync null + jscoverage = spawn "jscoverage", [".", tmpDir].concat optArrayFromDict + "exclude": [".git", "node_modules"] + "no-instrument": "tests" + + jscoverage.on 'exit', (returnCode) -> + process.exit 1 unless returnCode == 0 + + console.log "Running DOM tests..." + phantom = spawn "phantomjs", [path.join(tmpDir, "tests/dom_tests/phantom_runner.js"), "--coverage"] + phantom.on 'exit', -> + # merge the coverage counts from the DOM tests with those from the unit tests + global._$jscoverage = JSON.parse fs.readFileSync path.join(tmpDir, + 'tests/dom_tests/dom_tests_coverage.json') + runUnitTests(tmpDir) + + # marshal the counts into a form that the JSCoverage front-end expects + result = {} + for fname, coverage of _$jscoverage + result[fname] = + coverage: coverage + source: (Utils.escapeHtml fs.readFileSync fname, 'utf-8').split '\n' + + fs.writeFileSync 'jscoverage.json', JSON.stringify(result) diff --git a/README.markdown b/README.markdown index 46d28609..ceb741de 100644 --- a/README.markdown +++ b/README.markdown @@ -146,6 +146,11 @@ the tests: 2. [Install PhantomJS.](http://phantomjs.org/download.html) 3. `cake test` to run the tests. +Coverage reporting uses [JSCoverage](http://siliconforks.com/jscoverage/) and requires +[node-temp](https://github.com/bruce/node-temp). `cake coverage` will generate a coverage report in the form +of a JSON blob, which can then be viewed using [jscoverage-report](https://github.com/int3/jscoverage-report). +See jscoverage-report's README for more details. + When you're done, send us a pull request on Github. Feel free to include a change to the CREDITS file with your patch. diff --git a/tests/dom_tests/phantom_runner.coffee b/tests/dom_tests/phantom_runner.coffee index 9036b8f3..91eeb526 100644 --- a/tests/dom_tests/phantom_runner.coffee +++ b/tests/dom_tests/phantom_runner.coffee @@ -1,3 +1,5 @@ +system = require 'system' +fs = require 'fs' page = require('webpage').create() page.settings.userAgent = 'phantom' @@ -10,12 +12,10 @@ page.viewportSize = page.onConsoleMessage = (msg) -> console.log msg -system = require 'system' -fs = require 'fs' - -pathParts = system.args[0].split(fs.separator) -pathParts[pathParts.length - 1] = '' -dirname = pathParts.join(fs.separator) +dirname = do -> + pathParts = system.args[0].split(fs.separator) + pathParts[pathParts.length - 1] = '' + pathParts.join(fs.separator) page.open dirname + 'dom_tests.html', (status) -> if status != 'success' @@ -26,6 +26,10 @@ page.open dirname + 'dom_tests.html', (status) -> Tests.run() return Tests.testsFailed + if system.args[1] == '--coverage' + data = page.evaluate -> JSON.stringify _$jscoverage + fs.write dirname + 'dom_tests_coverage.json', data, 'w' + if testsFailed > 0 phantom.exit 1 else -- cgit v1.2.3