mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
Merge pull request #18 from spenceralger/master
Implemented code coverage
This commit is contained in:
commit
93488cf46c
25 changed files with 1334 additions and 128 deletions
|
@ -17,7 +17,9 @@
|
||||||
"grunt-contrib-watch": "~0.5.3",
|
"grunt-contrib-watch": "~0.5.3",
|
||||||
"grunt-contrib-jade": "~0.10.0",
|
"grunt-contrib-jade": "~0.10.0",
|
||||||
"grunt-contrib-less": "~0.9.0",
|
"grunt-contrib-less": "~0.9.0",
|
||||||
"grunt-cli": "~0.1.13"
|
"grunt-cli": "~0.1.13",
|
||||||
|
"istanbul": "~0.2.4",
|
||||||
|
"path-browserify": "0.0.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "grunt test",
|
"test": "grunt test",
|
||||||
|
|
|
@ -286,5 +286,17 @@ define(function (require) {
|
||||||
this.fetch('doc');
|
this.fetch('doc');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// get the list of open data source objects
|
||||||
|
// primarily for testing purposes
|
||||||
|
Courier.prototype._openSources = function (type) {
|
||||||
|
if (!type) {
|
||||||
|
return _.transform(this._refs, function (open, refs) {
|
||||||
|
[].push.apply(open, refs);
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._refs[type] || [];
|
||||||
|
};
|
||||||
|
|
||||||
return Courier;
|
return Courier;
|
||||||
});
|
});
|
|
@ -15,7 +15,8 @@ require.config({
|
||||||
lodash: '../bower_components/lodash/dist/lodash',
|
lodash: '../bower_components/lodash/dist/lodash',
|
||||||
moment: '../bower_components/moment/moment',
|
moment: '../bower_components/moment/moment',
|
||||||
gridster: '../bower_components/gridster/dist/jquery.gridster',
|
gridster: '../bower_components/gridster/dist/jquery.gridster',
|
||||||
config: '../config'
|
configFile: '../config',
|
||||||
|
bower_components: '../bower_components'
|
||||||
},
|
},
|
||||||
shim: {
|
shim: {
|
||||||
angular: {
|
angular: {
|
||||||
|
|
|
@ -1,20 +1,59 @@
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
|
var instrumentationMiddleware = require('../utils/instrumentation');
|
||||||
|
var amdWrapMiddleware = require('../utils/amd-wrapper');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dev: {
|
dev: {
|
||||||
options: {
|
options: {
|
||||||
base: '<%= src %>'
|
middleware: function (connect, options, stack) {
|
||||||
|
stack = stack || [];
|
||||||
|
|
||||||
|
var root = grunt.config.get('root');
|
||||||
|
|
||||||
|
// when a request for an intrumented file comes in (?instrument=true)
|
||||||
|
// and it is included in `pattern`, it will be handled
|
||||||
|
// by this middleware
|
||||||
|
stack.push(instrumentationMiddleware({
|
||||||
|
// root that files should be served from
|
||||||
|
root: root,
|
||||||
|
|
||||||
|
// make file names easier to read
|
||||||
|
displayRoot: grunt.config.get('src'),
|
||||||
|
|
||||||
|
// filter the filenames that will be served
|
||||||
|
filter: function (filename) {
|
||||||
|
// return true if the filename should be
|
||||||
|
// included in the coverage report (results are cached)
|
||||||
|
return grunt.file.isMatch([
|
||||||
|
'**/src/**/*.js',
|
||||||
|
'!**/src/bower_components/**/*',
|
||||||
|
'!**/src/kibana/utils/{event_emitter,next_tick}.js'
|
||||||
|
], filename);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// minimize code duplication (especially in the istanbul reporter)
|
||||||
|
// by allowing node_modules to be requested in an AMD wrapper
|
||||||
|
stack.push(amdWrapMiddleware({
|
||||||
|
root: root
|
||||||
|
}));
|
||||||
|
|
||||||
|
// standard static middleware reading from the root
|
||||||
|
stack.push(connect.static(root));
|
||||||
|
|
||||||
|
// allow browsing directories
|
||||||
|
stack.push(connect.directory(root));
|
||||||
|
|
||||||
|
// redirect requests for '/' to '/src/'
|
||||||
|
stack.push(function (req, res, next) {
|
||||||
|
if (req.url !== '/') return next();
|
||||||
|
res.statusCode = 303;
|
||||||
|
res.setHeader('Location', '/src/');
|
||||||
|
res.end();
|
||||||
|
});
|
||||||
|
|
||||||
|
return stack;
|
||||||
}
|
}
|
||||||
},
|
|
||||||
test: {
|
|
||||||
options: {
|
|
||||||
base: [
|
|
||||||
'<%= unitTestDir %>',
|
|
||||||
'<%= testUtilsDir %>',
|
|
||||||
'<%= src %>',
|
|
||||||
'<%= root %>/node_modules/mocha',
|
|
||||||
'<%= root %>/node_modules/expect.js'
|
|
||||||
],
|
|
||||||
port: 8001
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,24 +1,41 @@
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
options: {
|
||||||
|
compileDebug: false
|
||||||
|
},
|
||||||
test: {
|
test: {
|
||||||
src: [
|
files: {
|
||||||
'<%= unitTestDir %>/**/*.jade',
|
'<%= unitTestDir %>/index.html': '<%= unitTestDir %>/index.jade'
|
||||||
'<%= app %>/partials/**/*.jade',
|
},
|
||||||
'<%= app %>/apps/**/*.jade'
|
|
||||||
],
|
|
||||||
expand: true,
|
|
||||||
ext: '.html',
|
|
||||||
options: {
|
options: {
|
||||||
data: function (src, dest) {
|
data: function (src, dest) {
|
||||||
var pattern = grunt.config.process('<%= unitTestDir %>/**/*.js');
|
var unitTestDir = grunt.config.get('unitTestDir');
|
||||||
var tests = grunt.file.expand({}, pattern).map(function (filename) {
|
|
||||||
return filename.replace(grunt.config.get('unitTestDir'), '');
|
// filter for non unit test related files
|
||||||
});
|
if (!~path.dirname(src).indexOf(unitTestDir)) return;
|
||||||
return { tests: JSON.stringify(tests) };
|
|
||||||
|
var pattern = unitTestDir + '/specs/**/*.js';
|
||||||
|
var appdir = grunt.config.get('app');
|
||||||
|
|
||||||
|
return {
|
||||||
|
tests: grunt.file.expand({}, pattern).map(function (filename) {
|
||||||
|
return path.relative(appdir, filename).replace(/\.js$/, '');
|
||||||
|
})
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
client: false
|
clientside: {
|
||||||
|
files: {
|
||||||
|
'<%= testUtilsDir %>/istanbul_reporter/report.jade.js': '<%= testUtilsDir %>/istanbul_reporter/report.clientside-jade'
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
client: true,
|
||||||
|
amd: true,
|
||||||
|
namespace: false // return the template directly in the amd wrapper
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,12 @@ module.exports = function (config) {
|
||||||
// just lint the source dir
|
// just lint the source dir
|
||||||
source: {
|
source: {
|
||||||
files: {
|
files: {
|
||||||
src: ['Gruntfile.js', '<%= src %>/**/*.js', '<%= unitTestDir %>/**/*.js', '<%= root %>/tasks/**/*.js']
|
src: [
|
||||||
|
'Gruntfile.js',
|
||||||
|
'<%= src %>/**/*.js',
|
||||||
|
'<%= unitTestDir %>/**/*.js',
|
||||||
|
'<%= root %>/tasks/**/*.js'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
src: {
|
src: {
|
||||||
src: [
|
src: [
|
||||||
'<%= app %>/styles/**/*.less',
|
'<%= app %>/**/styles/**/*.less',
|
||||||
'<%= app %>/apps/**/*.less',
|
|
||||||
'!<%= src %>/**/_*.less'
|
'!<%= src %>/**/_*.less'
|
||||||
],
|
],
|
||||||
expand: true,
|
expand: true,
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
module.exports = {
|
module.exports = {
|
||||||
unit: {
|
|
||||||
options: {
|
options: {
|
||||||
log: true,
|
log: true,
|
||||||
logErrors: true,
|
logErrors: true,
|
||||||
urls: [
|
|
||||||
'http://localhost:8001/'
|
|
||||||
],
|
|
||||||
run: false
|
run: false
|
||||||
|
},
|
||||||
|
unit: {
|
||||||
|
options: {
|
||||||
|
urls: [
|
||||||
|
'http://localhost:8000/test/unit/'
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -1,23 +1,29 @@
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
return {
|
return {
|
||||||
test: {
|
test: {
|
||||||
files: ['<%= unitTestDir %>/*.jade', '<%= unitTestDir %>/**/*.js'],
|
files: [
|
||||||
tasks: ['jade:test', 'mocha:unit']
|
'<%= unitTestDir %>/**/*.js'
|
||||||
|
],
|
||||||
|
tasks: ['mocha:unit']
|
||||||
},
|
},
|
||||||
less: {
|
less: {
|
||||||
files: [
|
files: [
|
||||||
'<%= app %>/**/*.less',
|
'<%= app %>/**/styles/**/*.less',
|
||||||
'<%= src %>/courier/**/*.less'
|
'!<%= src %>/**/_*.less'
|
||||||
],
|
],
|
||||||
tasks: ['less']
|
tasks: ['less']
|
||||||
},
|
},
|
||||||
jade: {
|
jade: {
|
||||||
files: [
|
files: [
|
||||||
'<%= app %>/**/*.jade',
|
'<%= unitTestDir %>/index.jade'
|
||||||
'<%= src %>/courier/**/*.jade',
|
|
||||||
'!<%= unitTestDir %>/**/*.jade'
|
|
||||||
],
|
],
|
||||||
tasks: ['jade']
|
tasks: ['jade:test']
|
||||||
|
},
|
||||||
|
clientside_jade: {
|
||||||
|
files: [
|
||||||
|
'<%= testUtilsDir %>/istanbul_reporter/report.clientside-jade'
|
||||||
|
],
|
||||||
|
tasks: ['jade:clientside']
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
grunt.registerTask('dev', ['less', 'jade', 'connect:dev', 'watch']);
|
grunt.registerTask('dev', [
|
||||||
|
'less',
|
||||||
|
'jade',
|
||||||
|
'connect:dev',
|
||||||
|
'watch'
|
||||||
|
]);
|
||||||
};
|
};
|
|
@ -1,4 +1,3 @@
|
||||||
module.exports = function (grunt) {
|
module.exports = function (grunt) {
|
||||||
grunt.registerTask('server', ['connect:dev:keepalive']);
|
grunt.registerTask('server', ['connect:dev:keepalive']);
|
||||||
grunt.registerTask('test_server', ['connect:test:keepalive']);
|
|
||||||
};
|
};
|
|
@ -2,13 +2,19 @@ module.exports = function (grunt) {
|
||||||
/* jshint scripturl:true */
|
/* jshint scripturl:true */
|
||||||
grunt.registerTask('test', [
|
grunt.registerTask('test', [
|
||||||
'jshint',
|
'jshint',
|
||||||
'connect:test',
|
'connect:dev',
|
||||||
'jade:test',
|
'jade',
|
||||||
'mocha:unit'
|
'mocha:unit'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
grunt.registerTask('coverage', [
|
||||||
|
'blanket',
|
||||||
|
'connect:dev',
|
||||||
|
'mocha:coverage'
|
||||||
|
]);
|
||||||
|
|
||||||
grunt.registerTask('test:watch', [
|
grunt.registerTask('test:watch', [
|
||||||
'connect:test',
|
'connect:dev',
|
||||||
'watch:test'
|
'watch:test'
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
26
tasks/utils/amd-wrapper.js
Normal file
26
tasks/utils/amd-wrapper.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module.exports = function amdWrapMiddleware(opts) {
|
||||||
|
opts = opts || {};
|
||||||
|
|
||||||
|
var root = opts.root || '/';
|
||||||
|
var path = require('path');
|
||||||
|
var fs = require('fs');
|
||||||
|
var pathPrefix = opts.pathPrefix || '/amd-wrap/';
|
||||||
|
|
||||||
|
return function (req, res, next) {
|
||||||
|
// only allow prefixed requests
|
||||||
|
if (req.url.substring(0, pathPrefix.length) !== pathPrefix) return next();
|
||||||
|
|
||||||
|
// strip the prefix and form the filename
|
||||||
|
var filename = path.join(root, req._parsedUrl.pathname.replace('/amd-wrap/', ''));
|
||||||
|
|
||||||
|
fs.readFile(filename, 'utf8', function (err, contents) {
|
||||||
|
// file does not exist
|
||||||
|
if (err) return next(err.code === 'ENOENT' ? void 0 : err);
|
||||||
|
|
||||||
|
// respond with the wrapped code
|
||||||
|
res.statusCode = 200;
|
||||||
|
res.setHeader('Content-Type', 'application/javascript');
|
||||||
|
res.end('define(function (require, exports, module) {\n' + contents + '\n});');
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
77
tasks/utils/instrumentation.js
Normal file
77
tasks/utils/instrumentation.js
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
var Istanbul = require('istanbul');
|
||||||
|
var i = new Istanbul.Instrumenter({
|
||||||
|
embedSource: true,
|
||||||
|
preserveComments: true,
|
||||||
|
noAutoWrap: true
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = function instrumentationMiddleware(opts) {
|
||||||
|
var fs = require('fs');
|
||||||
|
var path = require('path');
|
||||||
|
|
||||||
|
// for root directory that files will be served from
|
||||||
|
var root = opts.root || '/';
|
||||||
|
|
||||||
|
// the root directory used to create a relative file path
|
||||||
|
// for display in coverage reports
|
||||||
|
var displayRoot = opts.displayRoot || null;
|
||||||
|
|
||||||
|
// filter the files in root that can be instrumented
|
||||||
|
var filter = opts.filter || function (filename) {
|
||||||
|
// by default only instrument *.js files
|
||||||
|
return /\.js$/.test(filename);
|
||||||
|
};
|
||||||
|
|
||||||
|
// cache filename resolution
|
||||||
|
var fileMap = {};
|
||||||
|
|
||||||
|
function filenameForReq(req) {
|
||||||
|
if (!~req.url.indexOf('instrument=true')) return false;
|
||||||
|
|
||||||
|
// expected absolute path to the file
|
||||||
|
var filename = path.join(root, req._parsedUrl.pathname);
|
||||||
|
|
||||||
|
// shortcut for dev where we could be reloading on every save
|
||||||
|
if (fileMap[filename] !== void 0) return fileMap[filename];
|
||||||
|
|
||||||
|
var ret = filename;
|
||||||
|
|
||||||
|
if (!fs.existsSync(filename) || !opts.filter(filename)) {
|
||||||
|
ret = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cache the return value for next time
|
||||||
|
fileMap[filename] = ret;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
return function (req, res, next) {
|
||||||
|
// resolve the request to a readable filename
|
||||||
|
var filename = filenameForReq(req);
|
||||||
|
// the file either doesn't exist of it was filtered out by opts.filter
|
||||||
|
if (!filename) return next();
|
||||||
|
|
||||||
|
fs.readFile(filename, 'utf8', function (err, content) {
|
||||||
|
if (err) {
|
||||||
|
if (err.code !== 'ENOENT') {
|
||||||
|
// other issue, report!
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
// file was deleted, clear cache and move on
|
||||||
|
delete fileMap[filename];
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
res.statusCode = 200;
|
||||||
|
res.setHeader('Content-Type', 'application/javascript');
|
||||||
|
res.end(i.instrumentSync(
|
||||||
|
content,
|
||||||
|
// make file names easier to read
|
||||||
|
displayRoot ? path.relative(displayRoot, filename) : filename
|
||||||
|
));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
};
|
|
@ -1,8 +1,6 @@
|
||||||
{
|
{
|
||||||
"extends": "../src/.jshintrc",
|
"extends": "../src/.jshintrc",
|
||||||
|
|
||||||
"white": false,
|
|
||||||
|
|
||||||
"globals": {
|
"globals": {
|
||||||
"module": false,
|
"module": false,
|
||||||
"inject": false,
|
"inject": false,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
<!DOCTYPE html><html><head><title>Kibana4 Tests</title><link rel="stylesheet" href="mocha.css"></head><body><div id="mocha"></div><script src="expect.js"></script><script src="mocha.js"></script><script>mocha.setup('bdd');
|
<!DOCTYPE html><html><head><title>Kibana4 Tests</title><link rel="stylesheet" href="/node_modules/mocha/mocha.css"></head><body><div id="mocha"></div><script src="/node_modules/expect.js/expect.js"></script><script src="/node_modules/mocha/mocha.js"></script><script src="/src/bower_components/requirejs/require.js"></script><script src="/src/kibana/require.config.js"></script><script type="text/javascript">window.COVERAGE = !!(/coverage=true/i.test(location.search));
|
||||||
// sauce labs & selenium inject global variables that break this
|
mocha.setup('bdd');
|
||||||
// mocha.checkLeaks();
|
|
||||||
// mocha.globals(['mochaRunner', 'angular']);</script><script src="bower_components/requirejs/require.js"></script><script src="kibana/require.config.js"></script><script type="text/javascript">require.config({
|
require.config({
|
||||||
|
baseUrl: '/src/kibana',
|
||||||
paths: {
|
paths: {
|
||||||
sinon: '../sinon'
|
sinon: '../../test/utils/sinon',
|
||||||
|
istanbul_reporter: '../../test/utils/istanbul_reporter'
|
||||||
},
|
},
|
||||||
shim: {
|
shim: {
|
||||||
'sinon/sinon': {
|
'sinon/sinon': {
|
||||||
|
@ -12,10 +14,29 @@
|
||||||
],
|
],
|
||||||
exports: 'sinon'
|
exports: 'sinon'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
// mark all requested files with instrument query param
|
||||||
|
urlArgs: COVERAGE ? 'instrument=true' : void 0
|
||||||
});
|
});
|
||||||
require(["/fixtures/field_mapping.js","/specs/apps/dashboard/index.js","/specs/apps/dashboard/mocks/modules.js","/specs/calculate_indices.js","/specs/courier.js","/specs/data_source.js","/specs/mapper.js"], function () {
|
|
||||||
|
function setupCoverage(done) {
|
||||||
|
document.title = document.title.replace('Tests', 'Coverage');
|
||||||
|
require(['istanbul_reporter/reporter'], function (IstanbulReporter) {
|
||||||
|
mocha.reporter(IstanbulReporter);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
require(["../../test/unit/specs/apps/dashboard/index","../../test/unit/specs/apps/dashboard/mocks/modules","../../test/unit/specs/calculate_indices","../../test/unit/specs/courier","../../test/unit/specs/data_source","../../test/unit/specs/mapper"], function () {
|
||||||
window.mochaRunner = mocha.run().on('end', function () {
|
window.mochaRunner = mocha.run().on('end', function () {
|
||||||
window.mochaResults = this.stats;
|
window.mochaResults = this.stats;
|
||||||
});
|
});
|
||||||
});</script></body></html>
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COVERAGE) {
|
||||||
|
setupCoverage(runTests);
|
||||||
|
} else {
|
||||||
|
runTests();
|
||||||
|
}</script></body></html>
|
|
@ -2,22 +2,22 @@ doctype html
|
||||||
html
|
html
|
||||||
head
|
head
|
||||||
title Kibana4 Tests
|
title Kibana4 Tests
|
||||||
link(rel="stylesheet", href="mocha.css")
|
link(rel="stylesheet", href='/node_modules/mocha/mocha.css')
|
||||||
body
|
body
|
||||||
#mocha
|
#mocha
|
||||||
script(src="expect.js")
|
script(src='/node_modules/expect.js/expect.js')
|
||||||
script(src="mocha.js")
|
script(src='/node_modules/mocha/mocha.js')
|
||||||
script.
|
script(src='/src/bower_components/requirejs/require.js')
|
||||||
mocha.setup('bdd');
|
script(src='/src/kibana/require.config.js')
|
||||||
// sauce labs & selenium inject global variables that break this
|
|
||||||
// mocha.checkLeaks();
|
|
||||||
// mocha.globals(['mochaRunner', 'angular']);
|
|
||||||
script(src="bower_components/requirejs/require.js")
|
|
||||||
script(src="kibana/require.config.js")
|
|
||||||
script(type="text/javascript").
|
script(type="text/javascript").
|
||||||
|
window.COVERAGE = !!(/coverage=true/i.test(location.search));
|
||||||
|
mocha.setup('bdd');
|
||||||
|
|
||||||
require.config({
|
require.config({
|
||||||
|
baseUrl: '/src/kibana',
|
||||||
paths: {
|
paths: {
|
||||||
sinon: '../sinon'
|
sinon: '../../test/utils/sinon',
|
||||||
|
istanbul_reporter: '../../test/utils/istanbul_reporter'
|
||||||
},
|
},
|
||||||
shim: {
|
shim: {
|
||||||
'sinon/sinon': {
|
'sinon/sinon': {
|
||||||
|
@ -26,10 +26,29 @@ html
|
||||||
],
|
],
|
||||||
exports: 'sinon'
|
exports: 'sinon'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
// mark all requested files with instrument query param
|
||||||
|
urlArgs: COVERAGE ? 'instrument=true' : void 0
|
||||||
});
|
});
|
||||||
require(!{tests}, function () {
|
|
||||||
|
function setupCoverage(done) {
|
||||||
|
document.title = document.title.replace('Tests', 'Coverage');
|
||||||
|
require(['istanbul_reporter/reporter'], function (IstanbulReporter) {
|
||||||
|
mocha.reporter(IstanbulReporter);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests() {
|
||||||
|
require(!{JSON.stringify(tests)}, function () {
|
||||||
window.mochaRunner = mocha.run().on('end', function () {
|
window.mochaRunner = mocha.run().on('end', function () {
|
||||||
window.mochaResults = this.stats;
|
window.mochaResults = this.stats;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (COVERAGE) {
|
||||||
|
setupCoverage(runTests);
|
||||||
|
} else {
|
||||||
|
runTests();
|
||||||
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ define(function (require) {
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var $ = require('jquery');
|
var $ = require('jquery');
|
||||||
var sinon = require('sinon/sinon');
|
var sinon = require('sinon/sinon');
|
||||||
var configFile = require('../../../config.js');
|
var configFile = require('configFile');
|
||||||
|
|
||||||
// Load the kibana app dependencies.
|
// Load the kibana app dependencies.
|
||||||
require('angular-route');
|
require('angular-route');
|
||||||
|
@ -19,13 +19,13 @@ define(function (require) {
|
||||||
describe('Mapper', function () {
|
describe('Mapper', function () {
|
||||||
var $scope;
|
var $scope;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
|
|
||||||
// Start the kibana module
|
// Start the kibana module
|
||||||
module('kibana');
|
module('kibana');
|
||||||
|
|
||||||
// Create the scope
|
// Create the scope
|
||||||
inject(function($rootScope, $controller) {
|
inject(function ($rootScope, $controller) {
|
||||||
$scope = $rootScope.$new();
|
$scope = $rootScope.$new();
|
||||||
var dashCtrl = $controller('dashboard', {
|
var dashCtrl = $controller('dashboard', {
|
||||||
$scope: $scope
|
$scope: $scope
|
||||||
|
|
|
@ -2,23 +2,23 @@ define(function (require) {
|
||||||
|
|
||||||
var angular = require('angular');
|
var angular = require('angular');
|
||||||
|
|
||||||
angular.module('app/dashboard',[]);
|
angular.module('app/dashboard', []);
|
||||||
|
|
||||||
// Need this because the controller requires it
|
// Need this because the controller requires it
|
||||||
angular.module('kibana/directives',[]);
|
angular.module('kibana/directives', []);
|
||||||
|
|
||||||
// create mock service for courier
|
// create mock service for courier
|
||||||
var mock = {
|
var mock = {
|
||||||
getvalue: function () {}
|
getvalue: function () {}
|
||||||
};
|
};
|
||||||
|
|
||||||
angular.module('kibana/services',[])
|
angular.module('kibana/services', [])
|
||||||
.service('courier',function () {
|
.service('courier', function () {
|
||||||
return mock;
|
return mock;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Could probably get rid of ngRoute if you want to stub it
|
// Could probably get rid of ngRoute if you want to stub it
|
||||||
angular.module('kibana',['ngRoute','kibana/services','app/dashboard']);
|
angular.module('kibana', ['ngRoute', 'kibana/services', 'app/dashboard']);
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
|
@ -4,19 +4,19 @@ define(function (require) {
|
||||||
|
|
||||||
describe('calculateIndices()', function () {
|
describe('calculateIndices()', function () {
|
||||||
|
|
||||||
describe('error checking', function() {
|
describe('error checking', function () {
|
||||||
it('should throw an error if start is > end', function () {
|
it('should throw an error if start is > end', function () {
|
||||||
expect(function () { calculateIndices(moment().add('day', 1), moment()); }).to.throwError();
|
expect(function () { calculateIndices(moment().add('day', 1), moment()); }).to.throwError();
|
||||||
});
|
});
|
||||||
it('should throw an error if interval is not [ hour, day, week, year ]', function () {
|
it('should throw an error if interval is not [ hour, day, week, year ]', function () {
|
||||||
expect(function () { calculateIndices(moment().subtract('day', 1), moment(), 'century' ); }).to.throwError();
|
expect(function () { calculateIndices(moment().subtract('day', 1), moment(), 'century'); }).to.throwError();
|
||||||
});
|
});
|
||||||
it('should throw an error if pattern is not set', function () {
|
it('should throw an error if pattern is not set', function () {
|
||||||
expect(function () { calculateIndices(moment().subtract('day', 1), moment(), 'hour' ); }).to.throwError();
|
expect(function () { calculateIndices(moment().subtract('day', 1), moment(), 'hour'); }).to.throwError();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('hourly interval', function() {
|
describe('hourly interval', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var date = '2014-01-15 04:30:10';
|
var date = '2014-01-15 04:30:10';
|
||||||
this.start = moment.utc(date).subtract('hours', 4);
|
this.start = moment.utc(date).subtract('hours', 4);
|
||||||
|
@ -36,7 +36,7 @@ define(function (require) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('daily interval', function() {
|
describe('daily interval', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var date = '2014-01-15 04:30:10';
|
var date = '2014-01-15 04:30:10';
|
||||||
this.start = moment.utc(date).subtract('days', 4);
|
this.start = moment.utc(date).subtract('days', 4);
|
||||||
|
@ -56,7 +56,7 @@ define(function (require) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('weekly interval', function() {
|
describe('weekly interval', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var date = '2014-01-15 04:30:10';
|
var date = '2014-01-15 04:30:10';
|
||||||
this.start = moment.utc(date).subtract('week', 4);
|
this.start = moment.utc(date).subtract('week', 4);
|
||||||
|
@ -76,7 +76,7 @@ define(function (require) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('yearly interval', function() {
|
describe('yearly interval', function () {
|
||||||
beforeEach(function () {
|
beforeEach(function () {
|
||||||
var date = '2014-01-15 04:30:10';
|
var date = '2014-01-15 04:30:10';
|
||||||
this.start = moment.utc(date).subtract('years', 4);
|
this.start = moment.utc(date).subtract('years', 4);
|
||||||
|
|
|
@ -13,7 +13,18 @@ define(function (require) {
|
||||||
expect(courier).to.be.a(Courier);
|
expect(courier).to.be.a(Courier);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('knows when a DataSource object has event listeners for the results event');
|
it('knows when a DataSource object has event listeners for the results event', function () {
|
||||||
|
var courier = new Courier();
|
||||||
|
var ds = courier.createSource('doc');
|
||||||
|
|
||||||
|
expect(courier._openSources('doc')).to.have.length(0);
|
||||||
|
ds.on('results', function () {});
|
||||||
|
expect(courier._openSources('doc')).to.have.length(1);
|
||||||
|
ds.removeAllListeners('results');
|
||||||
|
expect(courier._openSources('doc')).to.have.length(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('executes queries on the interval for searches that have listeners for results');
|
it('executes queries on the interval for searches that have listeners for results');
|
||||||
|
|
||||||
describe('events', function () {
|
describe('events', function () {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
define(function (require) {
|
define(function (require) {
|
||||||
var elasticsearch = require('../bower_components/elasticsearch/elasticsearch.js');
|
var elasticsearch = require('bower_components/elasticsearch/elasticsearch');
|
||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
var sinon = require('sinon/sinon');
|
var sinon = require('sinon/sinon');
|
||||||
var Courier = require('courier/courier');
|
var Courier = require('courier/courier');
|
||||||
var DataSource = require('courier/data_source/data_source');
|
var DataSource = require('courier/data_source/data_source');
|
||||||
var Mapper = require('courier/mapper');
|
var Mapper = require('courier/mapper');
|
||||||
var fieldMapping = require('../fixtures/field_mapping.js');
|
var fieldMapping = require('../fixtures/field_mapping');
|
||||||
|
|
||||||
var client = new elasticsearch.Client({
|
var client = new elasticsearch.Client({
|
||||||
host: 'localhost:9200',
|
host: 'localhost:9200',
|
||||||
|
@ -18,30 +18,32 @@ define(function (require) {
|
||||||
describe('Mapper', function () {
|
describe('Mapper', function () {
|
||||||
var server, source, mapper;
|
var server, source, mapper;
|
||||||
|
|
||||||
beforeEach(function() {
|
beforeEach(function () {
|
||||||
source = courier.createSource('search')
|
source = courier.createSource('search')
|
||||||
.index('valid')
|
.index('valid')
|
||||||
.size(5);
|
.size(5);
|
||||||
mapper = new Mapper(courier);
|
mapper = new Mapper(courier);
|
||||||
|
|
||||||
// Stub out a mini mapping response.
|
// Stub out a mini mapping response.
|
||||||
sinon.stub(client.indices, 'getFieldMapping',function (params, callback) {
|
sinon.stub(client.indices, 'getFieldMapping', function (params, callback) {
|
||||||
if(params.index === 'valid') {
|
if (params.index === 'valid') {
|
||||||
setTimeout(callback(undefined, fieldMapping),0);
|
setTimeout(callback(undefined, fieldMapping), 0);
|
||||||
} else {
|
} else {
|
||||||
setTimeout(callback('Error: Not Found',undefined));
|
setTimeout(callback('Error: Not Found', undefined));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
sinon.stub(client, 'getSource', function (params, callback) {
|
sinon.stub(client, 'getSource', function (params, callback) {
|
||||||
if(params.id === 'valid') {
|
if (params.id === 'valid') {
|
||||||
setTimeout(callback(undefined,{'foo.bar': {'type': 'string'}}),0);
|
setTimeout(callback(undefined, {'foo.bar': {'type': 'string'}}), 0);
|
||||||
} else {
|
} else {
|
||||||
setTimeout(callback('Error: Not Found',undefined),0);
|
setTimeout(callback('Error: Not Found', undefined), 0);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
sinon.stub(client, 'delete', function (params, callback) {callback(undefined,true);});
|
sinon.stub(client, 'delete', function (params, callback) {
|
||||||
|
callback(undefined, true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(function () {
|
afterEach(function () {
|
||||||
|
@ -57,7 +59,7 @@ define(function (require) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has getFieldsFromMapping function that returns a mapping', function (done) {
|
it('has getFieldsFromMapping function that returns a mapping', function (done) {
|
||||||
mapper.getFieldsFromMapping(source,function (err, mapping) {
|
mapper.getFieldsFromMapping(source, function (err, mapping) {
|
||||||
expect(client.indices.getFieldMapping.called).to.be(true);
|
expect(client.indices.getFieldMapping.called).to.be(true);
|
||||||
expect(mapping['foo.bar'].type).to.be('string');
|
expect(mapping['foo.bar'].type).to.be('string');
|
||||||
done();
|
done();
|
||||||
|
@ -69,7 +71,7 @@ define(function (require) {
|
||||||
.index('invalid')
|
.index('invalid')
|
||||||
.size(5);
|
.size(5);
|
||||||
|
|
||||||
mapper.getFieldsFromCache(source,function (err, mapping) {
|
mapper.getFieldsFromCache(source, function (err, mapping) {
|
||||||
expect(client.getSource.called).to.be(true);
|
expect(client.getSource.called).to.be(true);
|
||||||
expect(err).to.be('Error: Not Found');
|
expect(err).to.be('Error: Not Found');
|
||||||
done();
|
done();
|
||||||
|
@ -77,7 +79,7 @@ define(function (require) {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has getFieldsFromCache that returns a mapping', function (done) {
|
it('has getFieldsFromCache that returns a mapping', function (done) {
|
||||||
mapper.getFieldsFromCache(source,function (err, mapping) {
|
mapper.getFieldsFromCache(source, function (err, mapping) {
|
||||||
expect(client.getSource.called).to.be(true);
|
expect(client.getSource.called).to.be(true);
|
||||||
expect(mapping['foo.bar'].type).to.be('string');
|
expect(mapping['foo.bar'].type).to.be('string');
|
||||||
done();
|
done();
|
||||||
|
|
398
test/utils/istanbul_reporter/report.clientside-jade
Normal file
398
test/utils/istanbul_reporter/report.clientside-jade
Normal file
File diff suppressed because one or more lines are too long
322
test/utils/istanbul_reporter/report.jade.js
Normal file
322
test/utils/istanbul_reporter/report.jade.js
Normal file
File diff suppressed because one or more lines are too long
239
test/utils/istanbul_reporter/reporter.js
Normal file
239
test/utils/istanbul_reporter/reporter.js
Normal file
|
@ -0,0 +1,239 @@
|
||||||
|
/**
|
||||||
|
* TODO: move this into it's own module, with it's own dependencies
|
||||||
|
*/
|
||||||
|
|
||||||
|
require.config({
|
||||||
|
paths: {
|
||||||
|
// jade runtime is required by the AMD wrapped jade templates as "jade"
|
||||||
|
jade: '/amd-wrap/node_modules/grunt-contrib-jade/node_modules/jade/runtime'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// fake fs module to make jade/runtime.js happy
|
||||||
|
define('fs', function () {});
|
||||||
|
|
||||||
|
// fake process obejct to make browserify-path happy
|
||||||
|
window.process = window.process || { cwd: function () { return '.'; }};
|
||||||
|
|
||||||
|
// the actual reporter module
|
||||||
|
define(function (require) {
|
||||||
|
|
||||||
|
var _ = require('lodash');
|
||||||
|
var $ = require('jquery');
|
||||||
|
|
||||||
|
var InsertionText = require('/amd-wrap/node_modules/istanbul/lib/util/insertion-text.js');
|
||||||
|
var objUtils = require('/amd-wrap/node_modules/istanbul/lib/object-utils.js');
|
||||||
|
// var annotate = require('/amd-wrap/node_modules/istanbul/lib/annotate.js');
|
||||||
|
var Progress = require('/amd-wrap/node_modules/mocha/lib/browser/progress.js');
|
||||||
|
var path = require('/amd-wrap/node_modules/path-browserify/index.js');
|
||||||
|
|
||||||
|
var template = require('./report.jade');
|
||||||
|
|
||||||
|
var Base = window.Mocha.reporters.Base;
|
||||||
|
|
||||||
|
function IstanbulReporter(runner) {
|
||||||
|
// "inherit" the base reporters characteristics
|
||||||
|
Base.call(this, runner);
|
||||||
|
|
||||||
|
var stats = this.stats;
|
||||||
|
var gotoFile = window.location.hash;
|
||||||
|
if (gotoFile) window.location.hash = '';
|
||||||
|
|
||||||
|
$(document.body)
|
||||||
|
.html('<center><canvas width="40" height="40"></canvas></center>');
|
||||||
|
|
||||||
|
var canvas = document.getElementsByTagName('canvas')[0];
|
||||||
|
var ctx;
|
||||||
|
var progress;
|
||||||
|
if (canvas.getContext) {
|
||||||
|
var ratio = window.devicePixelRatio || 1;
|
||||||
|
canvas.style.width = canvas.width;
|
||||||
|
canvas.style.height = canvas.height;
|
||||||
|
canvas.width *= ratio;
|
||||||
|
canvas.height *= ratio;
|
||||||
|
ctx = canvas.getContext('2d');
|
||||||
|
ctx.scale(ratio, ratio);
|
||||||
|
progress = new Progress();
|
||||||
|
progress.size(40);
|
||||||
|
}
|
||||||
|
|
||||||
|
runner.on('test end', function () {
|
||||||
|
if (progress) {
|
||||||
|
progress
|
||||||
|
.update((stats.tests / this.total) * 100 || 0)
|
||||||
|
.draw(ctx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
runner.on('end', function () {
|
||||||
|
var stats = _.omit(this.stats, 'start', 'end', 'suites');
|
||||||
|
|
||||||
|
stats['create report'] = Date.now();
|
||||||
|
$(document.body).empty().append($(createReport())); // attempt to force parsing immediately
|
||||||
|
stats['create report'] = Date.now() - stats['create report'];
|
||||||
|
|
||||||
|
toSec(stats, 'create report');
|
||||||
|
toSec(stats, 'duration');
|
||||||
|
|
||||||
|
linkNav();
|
||||||
|
show(stats);
|
||||||
|
if (gotoFile) {
|
||||||
|
var header = document.getElementById(gotoFile.substring(1));
|
||||||
|
if (header) {
|
||||||
|
window.location.hash = gotoFile;
|
||||||
|
document.body.scrollTop = header.offsetTop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createReport() {
|
||||||
|
var summary = objUtils.summarizeCoverage(window.__coverage__);
|
||||||
|
|
||||||
|
var dirs = _(window.__coverage__)
|
||||||
|
.map(convertFile)
|
||||||
|
.groupBy(function (file) {
|
||||||
|
var dir = path.dirname(file.filename);
|
||||||
|
return dir === '.' ? '' : dir;
|
||||||
|
})
|
||||||
|
.transform(function (dirs, files, dirname) {
|
||||||
|
_.each(files, function (file) {
|
||||||
|
file.relname = dirname ? path.relative(dirname, file.filename) : file.filename;
|
||||||
|
});
|
||||||
|
|
||||||
|
dirs.push({
|
||||||
|
name: dirname,
|
||||||
|
files: files,
|
||||||
|
coverage: _.reduce(files, function (sum, file) {
|
||||||
|
return sum + file.coverage;
|
||||||
|
}, 0) / files.length
|
||||||
|
});
|
||||||
|
}, [])
|
||||||
|
.sortBy('name')
|
||||||
|
.value();
|
||||||
|
|
||||||
|
return template({
|
||||||
|
cov: {
|
||||||
|
dirs: dirs,
|
||||||
|
coverage: summary.lines.pct,
|
||||||
|
sloc: summary.lines.total,
|
||||||
|
hits: summary.lines.covered,
|
||||||
|
misses: summary.lines.total - summary.lines.covered
|
||||||
|
},
|
||||||
|
dirname: path.dirname,
|
||||||
|
relative: path.relative,
|
||||||
|
coverageClass: function (coverage) {
|
||||||
|
if (coverage >= 75) return 'high';
|
||||||
|
if (coverage >= 50) return 'medium';
|
||||||
|
if (coverage >= 25) return 'low';
|
||||||
|
return 'terrible';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertFile(file) {
|
||||||
|
var summary = objUtils.summarizeFileCoverage(file);
|
||||||
|
var count = 0;
|
||||||
|
var structured = file.code.map(function (str) {
|
||||||
|
count += 1;
|
||||||
|
return {
|
||||||
|
line: count,
|
||||||
|
covered: null,
|
||||||
|
text: new InsertionText(str, true)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
var html = '';
|
||||||
|
|
||||||
|
structured.unshift({
|
||||||
|
line: 0,
|
||||||
|
covered: null,
|
||||||
|
text: new InsertionText('')
|
||||||
|
});
|
||||||
|
|
||||||
|
_.forOwn(file.l, function (count, lineNumber) {
|
||||||
|
structured[lineNumber].covered = count > 0 ? true : false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// annotate.Lines(file, structured);
|
||||||
|
//note: order is important, since statements typically result in spanning the whole line and doing branches late
|
||||||
|
//causes mismatched tags
|
||||||
|
// annotate.Branches(file, structured);
|
||||||
|
// annotate.Functions(file, structured);
|
||||||
|
// annotate.Statements(file, structured);
|
||||||
|
|
||||||
|
structured.shift();
|
||||||
|
|
||||||
|
var context = {
|
||||||
|
filename: file.path,
|
||||||
|
sloc: summary.lines.total,
|
||||||
|
coverage: summary.lines.pct,
|
||||||
|
hits: summary.lines.covered,
|
||||||
|
misses: summary.lines.total - summary.lines.covered,
|
||||||
|
source: _.map(structured, function (line, lineNumber) {
|
||||||
|
return {
|
||||||
|
coverage: file.l[line.line],
|
||||||
|
source: line.text + ''
|
||||||
|
};
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
return context;
|
||||||
|
|
||||||
|
// writer.write(detailTemplate(context));
|
||||||
|
// writer.write('</table></pre>\n');
|
||||||
|
// writer.write(footerTemplate(templateData));
|
||||||
|
}
|
||||||
|
|
||||||
|
function linkNav() {
|
||||||
|
var headings = $('h2').toArray();
|
||||||
|
|
||||||
|
$(window).scroll(function (e) {
|
||||||
|
var heading = find(window.scrollY);
|
||||||
|
if (!heading) return;
|
||||||
|
var links = document.querySelectorAll('#menu a')
|
||||||
|
, link;
|
||||||
|
|
||||||
|
for (var i = 0, len = links.length; i < len; ++i) {
|
||||||
|
link = links[i];
|
||||||
|
link.className = link.getAttribute('href') === '#' + heading.id
|
||||||
|
? 'active'
|
||||||
|
: '';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function find(y) {
|
||||||
|
var i = headings.length
|
||||||
|
, heading;
|
||||||
|
|
||||||
|
while (i--) {
|
||||||
|
heading = headings[i];
|
||||||
|
if (y >= heading.offsetTop) {
|
||||||
|
return heading;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toSec(stats, prop) {
|
||||||
|
return stats[prop] = (stats[prop] / 1000).toFixed(2) + ' sec';
|
||||||
|
}
|
||||||
|
|
||||||
|
function show(info) {
|
||||||
|
var width = _(info).keys().sortBy('length').pop().length;
|
||||||
|
|
||||||
|
$('<pre>')
|
||||||
|
.addClass('coverage-stats')
|
||||||
|
.appendTo('#menu')
|
||||||
|
.text(
|
||||||
|
_.map(info, function (val, name) {
|
||||||
|
var row = val + ' - ' + name;
|
||||||
|
if (width - name.length) {
|
||||||
|
row += (new Array(width - name.length + 1)).join(' ');
|
||||||
|
}
|
||||||
|
return row;
|
||||||
|
}).join('\n')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return IstanbulReporter;
|
||||||
|
});
|
Loading…
Add table
Add a link
Reference in a new issue