Permalink
Browse files

some test for template, tests fo reporter needed

  • Loading branch information...
0 parents commit 88d300fa83f009b7e63824d12baa55f73e6f17d2 @maenu committed Feb 13, 2013
Showing with 329 additions and 0 deletions.
  1. +37 −0 Gruntfile.js
  2. +18 −0 LICENSE.txt
  3. +27 −0 package.json
  4. +7 −0 src/main/js/reporter.js
  5. +43 −0 src/main/js/template.js
  6. +5 −0 src/test/js/Generator.js
  7. +7 −0 src/test/js/GeneratorTest.js
  8. +185 −0 src/test/js/template.js
37 Gruntfile.js
@@ -0,0 +1,37 @@
+module.exports = function(grunt) {
+ grunt.initConfig({
+ meta: {
+ package: grunt.file.readJSON('package.json'),
+ src: {
+ main: 'src/main',
+ test: 'src/test',
+ },
+ bin: {
+ coverage: 'bin/coverage'
+ }
+ },
+ nodeunit: {
+ template: '<%= meta.src.test %>/js/template.js',
+ reporter: '<%= meta.src.test %>/js/reporter.js'
+ },
+ jasmine: {
+ coverage: {
+ src: [],
+ options: {
+ specs: [],
+ template: require('./src/main/js/template.js'),
+ templateOptions: {
+ coverage: '<%= meta.bin.coverage %>/coverage.json',
+ report: '<%= meta.bin.coverage %>',
+ template: 'node_modules/grunt-contrib-jasmine/tasks/jasmine/templates/DefaultRunner.tmpl'
+ }
+ }
+ }
+ }
+ });
+
+ grunt.loadNpmTasks('grunt-contrib-jasmine');
+ grunt.loadNpmTasks('grunt-contrib-nodeunit');
+
+ grunt.registerTask('coverage', ['jasmine:coverage']);
+};
18 LICENSE.txt
@@ -0,0 +1,18 @@
+Copyright (c) 2013 Manuel Leuenberger
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 package.json
@@ -0,0 +1,27 @@
+{
+ "name": "grunt-template-jasmine-istanbul",
+ "description": "Template mix-in for code coverage report generation with istanbul",
+ "version": "0.1.0",
+ "keywords": [
+ "grunt",
+ "template",
+ "jasmine",
+ "istanbul"
+ ],
+ "author": {
+ "name": "Manuel Leuenberger"
+ },
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/maenu/grunt-template-jasmine-istanbul.git"
+ },
+ "main": "src/main/js/template-jasmine-istanbul.js",
+ "dependencies": {
+ "istanbul": "~0.1.30"
+ },
+ "devDependencies": {
+ "grunt": "~0.4.0rc7",
+ "grunt-contrib-jasmine": "~0.3.1",
+ "grunt-contrib-nodeunit": "~0.1.1"
+ }
+}
7 src/main/js/reporter.js
@@ -0,0 +1,7 @@
+(function () {
+ var reporter = new jasmine.Reporter();
+ reporter.reportRunnerResults = function (runner) {
+ phantom.sendMessage('jasmine.coverage', __coverage__);
+ };
+ jasmine.getEnv().addReporter(reporter);
+})();
43 src/main/js/template.js
@@ -0,0 +1,43 @@
+/**
+ * Setup coverage via istanbul.
+ *
+ * @author Manuel Leuenberger
+ */
+
+var REPORTER = __dirname + '/reporter.js';
+var path = require('path');
+var istanbul = require('istanbul');
+
+exports.process = function (grunt, task, context) {
+ var instrumenter = new istanbul.Instrumenter();
+ var reporter = istanbul.Report.create('html', {
+ dir: context.options.report
+ });
+ var collector = new istanbul.Collector();
+ // prepend reporter
+ context.scripts.reporters.unshift(REPORTER);
+ // instrument sources
+ var instrumentedSrc = [];
+ context.scripts.src.forEach(function (src) {
+ var tmpSrc = path.join(context.temp, src);
+ grunt.file.write(tmpSrc, instrumenter.instrumentSync(
+ grunt.file.read(src), src));
+ instrumentedSrc.push(tmpSrc);
+ });
+ context.scripts.src = instrumentedSrc;
+ // listen to coverage event dispatched by reporter added in helper
+ var coverageJson = context.options.coverage;
+ task.phantomjs.on('jasmine.coverage', function (coverage) {
+ grunt.file.write(coverageJson, JSON.stringify(coverage));
+ collector.add(coverage);
+ reporter.writeReport(collector, true);
+ });
+ // use template option to mix in coverage
+ var template = context.options.template;
+ context.options = context.options.templateOptions || {};
+ if (template.process) {
+ return template.process(grunt, task, context);
+ } else {
+ return grunt.util._.template(grunt.file.read(template), context);
+ }
+};
5 src/test/js/Generator.js
@@ -0,0 +1,5 @@
+Generator = {
+ getRandomNumber: function () {
+ return 4;
+ }
+};
7 src/test/js/GeneratorTest.js
@@ -0,0 +1,7 @@
+describe('Generator', function () {
+ describe('getRandomNumber', function () {
+ it('should be chosen by fair dice roll', function () {
+ expect(Generator.getRandomNumber()).toBe(4);
+ });
+ });
+});
185 src/test/js/template.js
@@ -0,0 +1,185 @@
+/**
+ * Nodeunit tests for the basic template functionality.
+ *
+ * @author Manuel Leuenberger
+ */
+
+var TEMP = '.grunt/temp';
+var SRC = 'src/test/js/Generator.js';
+var SPEC = 'src/test/js/GeneratorTest.js';
+var DEFAULT_TEMPLATE = 'node_modules/grunt-contrib-jasmine/tasks/jasmine/'
+ + 'templates/DefaultRunner.tmpl';
+
+var grunt = require('grunt');
+var path = require('path');
+var istanbul = require('istanbul');
+var instrumenter = new istanbul.Instrumenter({
+ noCompact: true
+});
+var reporter = istanbul.Report.create('html', {
+ dir: 'bin/coverage'
+});
+var collector = new istanbul.Collector();
+
+function getContext () {
+ return {
+ temp: TEMP,
+ css: ['style.css'],
+ scripts: {
+ jasmine: ['jasmine.js'],
+ helpers: ['helper.js'],
+ specs: [],
+ src: [],
+ vendor: ['vendor.js'],
+ reporters: ['reporter.js'],
+ start: ['start.js']
+ },
+ options: {
+ template: {
+ process: function () {
+ return '';
+ }
+ }
+ }
+ };
+}
+
+function getTask () {
+ return {
+ writeTempFile: function () {},
+ copyTempFile: function () {},
+ phantomjs: {
+ on: function () {}
+ }
+ };
+}
+
+exports['template'] = {
+ 'setUp': function (callback) {
+ this.context = getContext();
+ this.task = getTask();
+ // instrument and load template
+ grunt.file.write('src/main/js/template-instrumented.js',
+ instrumenter.instrumentSync(
+ grunt.file.read('src/main/js/template.js'),
+ 'src/main/js/template.js'));
+ this.template = require('../../main/js/template-instrumented.js');
+ callback();
+ },
+ 'tearDown': function (callback) {
+ // write report and delete instrumented template
+ collector.add(__coverage__);
+ reporter.writeReport(collector, true);
+ grunt.file.delete('src/main/js/template-instrumented.js');
+ callback();
+ },
+ 'shouldTransitTemplateOptions': function (test) {
+ this.context.options.templateOptions = {
+ transited: true
+ };
+ this.template.process(grunt, this.task, this.context);
+ test.equal(this.context.options.transited, true,
+ 'should transit template options');
+ test.done();
+ },
+ 'report': {
+ 'setUp': function (callback) {
+ this.context.options.coverage = TEMP + '/coverage/coverage.json';
+ this.context.options.report = TEMP + '/coverage';
+ this.registered = {};
+ this.task.phantomjs.on = (function (scope) {
+ return function (event, callback) {
+ scope.registered.event = event;
+ scope.registered.callback = callback;
+ };
+ })(this);
+ this.template.process(grunt, this.task, this.context);
+ callback();
+ },
+ 'shouldRegister': function (test) {
+ test.equal(this.registered.event, 'jasmine.coverage',
+ 'should register for jasmine.coverage');
+ test.done();
+ },
+ 'shouldWriteCoverage': function (test) {
+ this.registered.callback({});
+ test.ok(grunt.file.exists(TEMP + '/coverage/coverage.json'),
+ 'should write coverage.json');
+ grunt.file.delete(TEMP);
+ test.done();
+ },
+ 'shouldWriteReport': function (test) {
+ this.registered.callback({});
+ test.ok(grunt.file.exists(TEMP + '/coverage/index.html'),
+ 'should write report');
+ grunt.file.delete(TEMP);
+ test.done();
+ }
+ },
+ 'instrumentation': {
+ 'setUp': function (callback) {
+ this.context.scripts.src.push(SRC);
+ this.template.process(grunt, this.task, this.context);
+ callback();
+ },
+ 'tearDown': function (callback) {
+ grunt.file.delete(TEMP);
+ callback();
+ },
+ 'shouldIncludeReporter': function (test) {
+ test.equal(this.context.scripts.reporters.length, 2,
+ 'should have added 1 reporter');
+ test.equal(this.context.scripts.reporters[0],
+ path.join(__dirname, '../../main/js/reporter.js'),
+ 'should be the coverage reporter');
+ test.done();
+ },
+ 'shouldInstrumentSource': function (test) {
+ test.equal(this.context.scripts.src.length, 1, 'should have 1 src');
+ test.equal(this.context.scripts.src[0], TEMP + '/' + SRC,
+ 'should store instrumented in temp directory');
+ var instrumented = this.context.scripts.src[0];
+ var found = grunt.file.read(instrumented).split('\n')[0];
+ var expected = 'if (typeof __coverage__ === \'undefined\') '
+ + '{ __coverage__ = {}; }';
+ test.equal(found, expected, 'should be instrumented');
+ test.done();
+ }
+ },
+ 'staticTemplate': {
+ 'setUp': function (callback) {
+ this.context.options.template = DEFAULT_TEMPLATE;
+ this.processed = this.template.process(grunt, this.task,
+ this.context);
+ callback();
+ },
+ 'shouldRender': function (test) {
+ this.expected = grunt.util._.template(
+ grunt.file.read(DEFAULT_TEMPLATE), this.context);
+ test.equal(this.processed, this.expected,
+ 'should render transparently');
+ test.done();
+ }
+ },
+ 'dynamicTemplate': {
+ 'setUp': function (callback) {
+ this.context.options.template = {
+ process: function (grunt, task, context) {
+ return [grunt, task, context];
+ }
+ };
+ this.processed = this.template.process(grunt, this.task,
+ this.context);
+ callback();
+ },
+ 'shouldRender': function (test) {
+ test.strictEqual(this.processed[0], grunt,
+ 'should be called with grunt');
+ test.strictEqual(this.processed[1], this.task,
+ 'should be called with task');
+ test.strictEqual(this.processed[2], this.context,
+ 'should be called with context');
+ test.done();
+ }
+ }
+};

0 comments on commit 88d300f

Please sign in to comment.