It has been a while.. sorry

This commit is contained in:
spalger 2015-07-20 15:29:48 -07:00
parent 7f8b1de8b2
commit 15864363d5
166 changed files with 1204 additions and 13434 deletions

View file

@ -10,14 +10,13 @@ module.exports = function (grunt) {
plugins: __dirname + '/src/plugins',
server: __dirname + '/src/server',
target: __dirname + '/target', // location of the compressed build targets
testUtilsDir: __dirname + '/src/testUtils',
configFile: __dirname + '/src/config/kibana.yml',
nodeVersion: '0.10.35',
platforms: ['darwin-x64', 'linux-x64', 'linux-x86', 'windows'],
services: [ [ 'launchd', '10.9'], [ 'upstart', '1.5'], [ 'systemd', 'default'], [ 'sysv', 'lsb-3.1' ] ],
unitTestDir: __dirname + '/test/unit',
testUtilsDir: __dirname + '/test/utils',
bowerComponentsDir: __dirname + '/bower_components',
devPlugins: 'devMode',
@ -33,8 +32,7 @@ module.exports = function (grunt) {
'Gruntfile.js',
'<%= root %>/tasks/**/*.js',
'<%= src %>/**/*.js',
'<%= unitTestDir %>/**/*.js',
'!<%= unitTestDir %>/specs/vislib/fixture/**/*'
'!<%= src %>/fixtures/**/*.js'
]
};

View file

@ -39,16 +39,20 @@
"url": "https://github.com/elastic/kibana.git"
},
"dependencies": {
"Nonsense": "^0.1.2",
"angular-mocks": "^1.4.3",
"angular-nvd3": "panda01/angular-nvd3#kibana",
"ansicolors": "^0.3.2",
"auto-preload-rjscommon-deps-loader": "^1.0.1",
"autoprefixer-loader": "^2.0.0",
"babel-jscs": "^1.0.3",
"base64-js": "0.0.8",
"bluebird": "^2.9.27",
"body-parser": "^1.10.1",
"boom": "^2.8.0",
"bootstrap": "^3.3.5",
"bunyan": "^1.2.3",
"chokidar": "^1.0.4",
"commander": "^2.8.1",
"compression": "^1.3.0",
"cookie-parser": "^1.3.3",
@ -56,19 +60,22 @@
"d3": "^3.5.6",
"debug": "^2.1.1",
"elasticsearch": "^5.0.0",
"expiry-js": "^0.1.7",
"exports-loader": "^0.6.2",
"expose-loader": "^0.7.0",
"expiry-js": "^0.1.7",
"express": "^4.10.6",
"extract-text-webpack-plugin": "^0.8.2",
"file-loader": "^0.8.4",
"font-awesome": "^4.3.0",
"gaze": "^0.5.1",
"glob": "^4.3.2",
"good": "^6.2.0",
"good-squeeze": "^2.1.0",
"hapi": "^8.6.1",
"ieee754": "^1.1.6",
"imports-loader": "^0.6.4",
"is-array": "^1.0.1",
"jade": "^1.8.2",
"jade-loader": "^0.7.1",
"joi": "^6.4.3",
"js-yaml": "^3.2.5",
"json-stringify-safe": "^5.0.1",
@ -76,6 +83,7 @@
"less-loader": "^2.2.0",
"loader-utils": "^0.2.10",
"lodash": "^3.10.0",
"memory-fs": "^0.2.0",
"minimatch": "^2.0.8",
"mkdirp": "^0.5.1",
"moment": "^2.10.3",
@ -89,12 +97,14 @@
"semver": "^4.3.6",
"serve-favicon": "^2.2.0",
"style-loader": "^0.12.3",
"tempfile": "^1.1.1",
"through": "^2.3.6",
"url-loader": "^0.5.6",
"webpack": "^1.10.0",
"webpack-directory-name-as-main": "^1.0.0"
},
"devDependencies": {
"auto-release-sinon": "^1.0.1",
"bower": "^1.4.1",
"bower-license": "^0.2.6",
"event-stream": "^3.1.5",
@ -104,7 +114,6 @@
"grunt-contrib-clean": "^0.6.0",
"grunt-contrib-compress": "^0.13.0",
"grunt-contrib-copy": "^0.8.0",
"grunt-contrib-jade": "^0.14.0",
"grunt-contrib-jshint": "^0.11",
"grunt-contrib-watch": "^0.6.1",
"grunt-esvm": "^1.0.1",
@ -118,13 +127,13 @@
"http-proxy": "^1.8.1",
"husky": "^0.8.1",
"istanbul": "^0.3.15",
"jade": "^1.8.2",
"libesvm": "^1.0.1",
"license-checker": "^3.1.0",
"load-grunt-config": "^0.7.0",
"marked": "^0.3.3",
"marked-text-renderer": "^0.1.0",
"mocha": "^2.2.5",
"mocha-loader": "^0.7.1",
"nock": "^2.7.0",
"npm": "^2.11.0",
"opn": "^1.0.0",

View file

@ -17,7 +17,7 @@ cluster.setupMaster({
});
module.exports = class Worker extends EventEmitter {
constructor(gaze, opts) {
constructor(opts) {
opts = opts || {};
super();

View file

@ -3,7 +3,7 @@
let cluster = require('cluster');
let join = require('path').join;
let _ = require('lodash');
let Gaze = require('gaze').Gaze;
var chokidar = require('chokidar');
let Log = require('../Log');
let fromRoot = require('../../utils/fromRoot');
@ -11,21 +11,23 @@ let Worker = require('./Worker');
module.exports = function (opts) {
let gaze = new Gaze([
'src/{cli,commands,server,utils}/**/*',
let watcher = chokidar.watch([
'src/cli',
'src/fixtures',
'src/server',
'src/utils',
'src/plugins/*/*', // files at the root of a plugin
'src/plugins/*/lib/**/*', // files within a lib directory for a plugin
'config/**/*',
], {
cwd: fromRoot('.'),
debounceDelay: 200
cwd: fromRoot('.')
});
let log = new Log(opts.quiet, opts.silent);
let customLogging = opts.quiet || opts.silent || opts.verbose;
let workers = [
new Worker(gaze, {
new Worker({
type: 'optmzr',
title: 'optimizer',
log: log,
@ -40,7 +42,7 @@ module.exports = function (opts) {
}
}),
new Worker(gaze, {
new Worker({
type: 'server',
log: log,
argv: [
@ -58,18 +60,31 @@ module.exports = function (opts) {
});
});
gaze.on('all', function (e, path) {
_.invoke(workers, 'onChange', path);
});
gaze.on('ready', function (watcher) {
log.good('Watching for changes', `(${_.size(watcher.watched())} files)`);
var addedCount = 0;
function onAddBeforeReady() {
addedCount += 1;
}
function onReady() {
// start sending changes to workers
watcher.removeListener('add', onAddBeforeReady);
watcher.on('all', onAnyChangeAfterReady);
log.good('Watching for changes', `(${addedCount} files)`);
_.invoke(workers, 'start');
});
}
gaze.on('error', function (err) {
function onAnyChangeAfterReady(e, path) {
_.invoke(workers, 'onChange', path);
}
function onError(err) {
log.bad('Failed to watch files!\n', err.stack);
process.exit(1);
});
}
watcher.on('add', onAddBeforeReady);
watcher.on('ready', onReady);
watcher.on('error', onError);
};

View file

@ -1,6 +1,6 @@
define(function (require) {
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
return function (Private, Promise) {
var indexPatterns = Private(require('fixtures/stubbed_logstash_index_pattern'));

View file

@ -1,6 +1,6 @@
define(function (require) {
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
function MockState(defaults) {
this.on = _.noop;

View file

@ -1,6 +1,6 @@
define(function (require) {
return function stubbedLogstashIndexPatternService(Private) {
var StubIndexPattern = Private(require('test_utils/stub_index_pattern'));
var StubIndexPattern = Private(require('testUtils/stubIndexPattern'));
var fieldTypes = Private(require('ui/index_patterns/_field_types'));
var mockLogstashFields = Private(require('fixtures/logstash_fields'));

View file

@ -1,5 +1,5 @@
define(function (require) {
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var searchResponse = require('fixtures/search_response');
return function stubSearchSource(Private, $q) {

View file

@ -1,5 +1,5 @@
define(function (require) {
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
function MockMap(container, chartData, params) {
this.container = container;

View file

@ -6,11 +6,9 @@ module.exports = function (kibana) {
main: 'plugins/appSwitcher/appSwitcher',
hidden: true,
defaultModules: {
autoload: {
angular: [],
require: [
'ui/chrome'
]
require: []
.concat(kibana.autoload.styles)
}
}

View file

@ -0,0 +1,101 @@
'use strict';
module.exports = function (kbnServer) {
let _ = require('lodash');
let resolve = require('path').resolve;
let promify = require('bluebird').promisify;
let glob = promify(require('glob'));
let createHash = require('crypto').createHash;
let pathContains = require('../../utils/pathContains');
let LiveOptimizer = require('../../server/optimize/LiveOptimizer');
let readFileSync = require('fs').readFileSync;
let testEntryFileTemplate = _.template(readFileSync(resolve(__dirname, './testEntry.js.tmpl')));
let hash = function (prefix) {
return createHash('sha1').update(prefix).digest('hex');
};
class TestHarnessBuilder {
constructor(prefix) {
this.id = hash(prefix).slice(0, 8);
this.prefix = prefix;
this.bundleDir = kbnServer.config.get('optimize.bundleDir');
this.plugin = _.find(kbnServer.plugins, function (plugin) {
return pathContains(plugin.publicDir, prefix);
});
this.init = _.once(this.init);
_.bindAll(this, ['init', 'findTestFiles', 'setupOptimizer', 'render']);
}
init() {
return this.findTestFiles().then(this.setupOptimizer);
}
findTestFiles() {
let prefix = this.prefix;
return glob(
'**/__tests__/**/*.js',
{
cwd: prefix,
ignore: ['**/_*.js']
}
)
.map(function (testFile) {
return resolve(prefix, testFile);
});
}
setupOptimizer(testFiles) {
let deps = [];
let modules = {
angular: [],
require: [
'angular-mocks'
]
};
if (testFiles) {
modules.require = modules.require.concat(testFiles);
}
let app = this.plugin && this.plugin.app;
if (app) {
deps = deps.concat(app.getRelatedPlugins());
let appModules = app.getModules();
modules.angular = appModules.angular.concat(modules.angular);
modules.require = appModules.require.concat(modules.require);
}
this.optimizer = new LiveOptimizer({
sourceMaps: true,
bundleDir: this.bundleDir,
entries: [
{
id: this.id,
deps: deps,
modules: modules,
template: testEntryFileTemplate
}
],
plugins: kbnServer.plugins
});
return this.optimizer.init();
}
render() {
let self = this;
return self.init()
.then(function () {
return self.optimizer.get(self.id);
});
}
}
return TestHarnessBuilder;
};

View file

@ -1,45 +0,0 @@
'use strict';
module.exports = function devModePlugin(kibana) {
let _ = require('lodash');
let istanbul = require('./istanbul');
let kibanaSrcFilter = require('./kibanaSrcFilter');
let fromRoot = require('../../utils/fromRoot');
const ROOT = fromRoot('.');
const SRC = fromRoot('src');
const UI = fromRoot('src/ui');
// return new kibana.Plugin({
// init: function (server, options) {
// server.ext('onPreHandler', istanbul({ root: SRC, displayRoot: SRC, filter: kibanaSrcFilter }));
// server.ext('onPreHandler', istanbul({ root: UI, displayRoot: SRC, filter: kibanaSrcFilter }));
// let activeBundle = null;
// server.route({
// path: '/specs',
// method: 'GET',
// handler: function (request, reply) {
// if (!activeBundle) {
// activeBundle = bundle().finally(function () {
// activeBundle = null;
// });
// }
// activeBundle.then(function (path) {
// return reply.file(path);
// }, reply);
// }
// });
// },
// uiExports: {
// spyModes: [
// 'plugins/devMode/visDebugSpyPanel'
// ]
// }
// });
};

View file

@ -0,0 +1,139 @@
'use strict';
module.exports = function devModePlugin(kibana) {
let _ = require('lodash');
let webpack = require('webpack');
// let bundle = require('../../server/optimize/testBundler');
let istanbul = require('./istanbul');
let kibanaSrcFilter = require('./kibanaSrcFilter');
let resolve = require('path').resolve;
let extname = require('path').extname;
let relative = require('path').relative;
let Boom = require('boom');
let fromRoot = require('../../utils/fromRoot');
let pathContains = require('../../utils/pathContains');
const SRC = fromRoot('src');
const UI = fromRoot('src/ui');
// if (!kibana.config.get('env.dev')) return;
return new kibana.Plugin({
init: function (server, options) {
server.ext('onPreHandler', istanbul({ root: SRC, displayRoot: SRC, filter: kibanaSrcFilter }));
server.ext('onPreHandler', istanbul({ root: UI, displayRoot: SRC, filter: kibanaSrcFilter }));
server.setupViews(__dirname);
let TestHarnessBuilder; // initialized in mixin below
let currentBuilder = null;
function getBuilder(path) {
if (!currentBuilder || currentBuilder.path !== path) {
currentBuilder = new TestHarnessBuilder(path);
}
return currentBuilder;
}
server.decorate('reply', 'renderTestHarness', function (path) {
let reply = this;
getBuilder(path).render().then(function (output) {
if (!output || !output.bundle) {
return reply(Boom.create(500, 'failed to build test bundle'));
}
return reply(output.bundle).type('application/javascript');
});
});
server.decorate('reply', 'renderTestHarnessSourceMap', function (path) {
let reply = this;
getBuilder(path).render().then(function (output) {
if (!output) {
return reply(Boom.create(500, 'failed to build test bundle'));
}
if (!output.map) {
return reply(Boom.notFound());
}
reply(output.map);
});
});
server.redirectToSlash('/tests/plugins/{pluginId}');
server.route({
path: '/tests/plugins/{pluginId}/',
method: 'GET',
config: {
pre: [
'kbnPluginById(params.pluginId)'
],
handler: function (req, reply) {
return reply.view('testHarness.jade', {
bundlePath: `/testBundle/plugins/${req.params.pluginId}/`,
});
}
}
});
server.route({
path: '/testBundle/plugins/{pluginId}/',
method: 'GET',
config: {
pre: [
'kbnPluginById(params.pluginId)'
],
handler: function (req, reply) {
return reply.renderTestHarness(req.pre.kbnPluginById.publicDir);
}
}
});
server.route({
path: '/testBundle/plugins/{pluginId}/*.map',
method: 'GET',
config: {
pre: [
'kbnPluginById(params.pluginId)'
],
handler: function (req, reply) {
return reply.renderTestHarnessSourceMap(req.pre.kbnPluginById.publicDir);
}
}
});
return kibana.mixin(function (kbnServer) {
TestHarnessBuilder = require('./TestHarnessBuilder')(kbnServer);
});
},
uiExports: {
spyModes: [
'plugins/devMode/visDebugSpyPanel'
],
modules: {
sinon$: {
path: fromRoot('node_modules/sinon/pkg/sinon.js'),
parse: false
},
fixtures: fromRoot('src/fixtures'),
testUtils: fromRoot('src/testUtils'),
mocha$: {
path: fromRoot('node_modules/mocha/mocha.js'),
exports: 'window.mocha'
},
'angular-mocks': {
path: require.resolve('angular-mocks'),
imports: 'angular,mocha'
},
}
}
});
};

View file

@ -1,5 +1,4 @@
{
"name": "devMode",
"main": "./devMode.js",
"version": "1.0.0"
}

90
src/plugins/devMode/public/bootstrap.js vendored Normal file
View file

@ -0,0 +1,90 @@
var COVERAGE = window.COVERAGE = !!(/coverage/i.test(window.location.search));
var DISABLE_RESIZE_CHECKER = window.DISABLE_RESIZE_CHECKER = true;
var SEED = parseFloat((window.location.search.match(/[&?]SEED=([^&]+)(?:&|$)/) || [])[1]);
if (isNaN(SEED)) SEED = Date.now();
console.log('Random-ness seed: ' + SEED);
var Nonsense = require('nonsense');
Math.nonsense = new Nonsense(SEED);
Math.random = function () {
return Math.nonsense.frac();
};
var mocha = require('mocha');
mocha.setup({
ui: 'bdd',
timeout: 5000,
reporter: 'html'
});
var angular = require('angular-mocks');
function setupCoverage(done) {
document.title = document.title.replace('Tests', 'Coverage');
mocha.reporter(require('testUtils/istanbul_reporter/reporter'));
}
exports.bootstrap = function (kibana, sinon) {
var $ = require('jquery');
var _ = require('lodash');
$(function () {
var _desc = window.describe;
window.describe = _.wrap(_desc, unwindDescribeArrays);
window.describe.only = _.wrap(_desc.only, unwindDescribeArrays);
if (COVERAGE) {
setupCoverage();
}
kibana.load(startMocha);
function startMocha() {
var xhr = sinon.useFakeXMLHttpRequest();
window.mochaRunner = mocha.run().on('end', function () {
window.mochaResults = this.stats;
window.mochaResults.details = getFailedTests(this);
xhr.restore();
});
mocha.run();
}
function getFailedTests(runner) {
var fails = [];
var suiteStack = [];
(function recurse(suite) {
suiteStack.push(suite);
(suite.tests || [])
.filter(function (test) {
return test.state && test.state !== 'passed' && test.state !== 'pending';
})
.forEach(function (test) {
fails.push({
title: suiteStack.concat(test).reduce(function (title, suite) {
if (suite.title) {
return (title ? title + ' ' : '') + suite.title;
} else {
return title;
}
}, ''),
err: test.err ? (test.err.stack || test.err.message) : 'unknown error'
});
});
(suite.suites || []).forEach(recurse);
suiteStack.pop();
}(runner.suite));
return fails;
}
function unwindDescribeArrays(fn, name, body) {
if (!body && name && name instanceof Array) {
body = name[1];
name = name[0];
}
return fn.call(this, name, body);
}
});
};

View file

@ -0,0 +1,20 @@
/**
* Optimized application entry file
*
* This is programatically created and updated, do not modify
*
* built using: <%= optimizerTagline %>
* includes code from:
<%
entry.deps.sort().forEach(function (plugin) {
print(` * - ${plugin}\n`);
})
%> *
*/
require('plugins/devMode/bootstrap');
<%
entry.modules.require.forEach(function (id) {
print(`require('${id}');\n`);
});
%>require('plugins/devMode/bootstrap').bootstrap();

View file

@ -0,0 +1,7 @@
doctype html
html
head
title Kibana4 Tests
script(async, src=bundlePath)
body
#mocha Loading tests, please wait.

View file

@ -1,8 +1,8 @@
var root = require('requirefrom')('');
var expect = require('expect.js');
var Kibana = root('src/server');
var findPort = root('test/utils/find_port');
root('test/utils/ensure_elasticsearch');
var findPort = require('./findPort');
require('./_ensure_elasticsearch');
var util = require('util');
var format = util.format;

View file

@ -32,7 +32,6 @@ module.exports = function (kibana) {
// Expose the client to the server
exposeClient(server);
createProxy(server, 'GET', '/elasticsearch/{paths*}');
createProxy(server, 'POST', '/elasticsearch/_mget');
createProxy(server, 'POST', '/elasticsearch/_msearch');

View file

@ -2,12 +2,12 @@ define(function (require) {
var angular = require('angular');
var $ = require('jquery');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
// Load the kibana app dependencies.
require('ui/private');
require('plugins/discover/components/field_chooser/discover_field');
require('plugins/kibana/discover/components/field_chooser/discover_field');
var $parentScope, $scope, indexPattern;

View file

@ -1,6 +1,6 @@
define(function (require) {
var _ = require('lodash');
var fieldCalculator = require('plugins/discover/components/field_chooser/lib/field_calculator');
var fieldCalculator = require('plugins/kibana/discover/components/field_chooser/lib/field_calculator');
var expect = require('expect.js');
// Load the kibana app dependencies.

View file

@ -2,12 +2,12 @@ define(function (require) {
var angular = require('angular');
var $ = require('jquery');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
// Load the kibana app dependencies.
require('ui/private');
require('plugins/discover/components/field_chooser/field_chooser');
require('plugins/kibana/discover/components/field_chooser/field_chooser');
var $parentScope;
var $scope;

View file

@ -9,7 +9,7 @@ define(function (require) {
beforeEach(module('hitSortFunctionTests'));
beforeEach(inject(function (Private) {
createHitSortFn = Private(require('plugins/discover/_hit_sort_fn'));
createHitSortFn = Private(require('plugins/kibana/discover/_hit_sort_fn'));
}));

View file

@ -3,7 +3,7 @@ define(function (require) {
// Load the kibana app dependencies.
require('angular-route');
var expect = require('expect.js');
require('plugins/doc/index');
require('plugins/kibana/doc/index');
var $scope, createController, timefilter;

View file

@ -1,5 +1,5 @@
define(function (require) {
var getValType = require('plugins/settings/sections/advanced/lib/get_val_type');
var getValType = require('plugins/kibana/settings/sections/advanced/lib/get_val_type');
var expect = require('expect.js');
describe('Settings', function () {

View file

@ -5,7 +5,7 @@ define(function (require) {
var expect = require('expect.js');
require('plugins/visualize/editor/agg');
require('plugins/kibana/visualize/editor/agg');
describe('Vis-Editor-Agg plugin directive', function () {

View file

@ -6,7 +6,7 @@ module.exports = function (kibana) {
main: 'plugins/statusPage/statusPage',
hidden: true,
defaultModules: {
autoload: {
angular: [],
require: [
'ui/chrome',

View file

@ -3,7 +3,7 @@ define(function (require) {
var $ = require('jquery');
var _ = require('lodash');
var expect = require('expect.js');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var $rootScope;
var TableGroup;

View file

@ -3,7 +3,7 @@ define(function (require) {
var $ = require('jquery');
var _ = require('lodash');
var expect = require('expect.js');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var $rootScope;
var TableGroup;

View file

@ -3,7 +3,7 @@
let _ = require('lodash');
let EventEmitter = require('events').EventEmitter;
let promify = require('bluebird').promisify;
let each = require('bluebird').each;
let resolve = require('bluebird').resolve;
let Hapi = require('hapi');
let rootDir = require('../utils/fromRoot')('.');
@ -22,7 +22,7 @@ module.exports = class KbnServer extends EventEmitter {
this.server = new Hapi.Server();
require('./config')(this, this.server);
let config = this.server.config();
this.config = this.server.config();
this.ready = _.constant(this.mixin(
require('./http'),
@ -34,7 +34,7 @@ module.exports = class KbnServer extends EventEmitter {
));
this.listen = _.once(this.listen);
if (config.get('server.autoListen')) {
if (this.config.get('server.autoListen')) {
this.listen();
}
}
@ -54,7 +54,7 @@ module.exports = class KbnServer extends EventEmitter {
let self = this;
let server = self.server;
return each(fns, function (fn) {
return resolve(fns).each(function (fn) {
return fn.call(self, self, server, server.config());
})
.then(_.noop); // clear the return value

View file

@ -1,8 +1,11 @@
'use strict';
module.exports = function (kbnServer, server, config) {
var Boom = require('boom');
var parse = require('url').parse;
var format = require('url').format;
var getDefaultRoute = require('./getDefaultRoute');
let _ = require('lodash');
let Boom = require('boom');
let parse = require('url').parse;
let format = require('url').format;
let getDefaultRoute = require('./getDefaultRoute');
// Create a new connection
server.connection({
@ -36,9 +39,31 @@ module.exports = function (kbnServer, server, config) {
});
});
// helper for creating view managers for servers
server.decorate('server', 'setupViews', function (path, engines) {
this.views({
path: path,
isCached: config.get('optimize.viewCaching'),
engines: _.assign({ jade: require('jade') }, engines || {})
});
});
server.decorate('server', 'redirectToSlash', function (route) {
this.route({
path: route,
method: 'GET',
handler: function (req, reply) {
return reply.redirect(format({
search: req.url.search,
pathname: req.url.pathname + '/',
}));
}
});
});
// attach the app name to the server, so we can be sure we are actually talking to kibana
server.ext('onPreResponse', function (req, reply) {
var response = req.response;
let response = req.response;
if (response.isBoom) {
response.output.headers['x-app-name'] = kbnServer.name;
@ -63,7 +88,7 @@ module.exports = function (kbnServer, server, config) {
method: 'GET',
path: '/{p*}',
handler: function (req, reply) {
var path = req.path;
let path = req.path;
if (path === '/' || path.charAt(path.length - 1) !== '/') {
return reply(Boom.notFound());
}

View file

@ -0,0 +1,82 @@
'use strict';
let EventEmitter = require('events').EventEmitter;
let inherits = require('util').inherits;
let _ = require('lodash');
let join = require('path').join;
let write = require('fs').writeFileSync;
let webpack = require('webpack');
let DirectoryNameAsMain = require('webpack-directory-name-as-main');
let ExtractTextPlugin = require('extract-text-webpack-plugin');
let assets = require('../ui/assets');
let fromRoot = require('../../utils/fromRoot');
let OptmzBundles = require('./OptmzBundles');
let OptmzUiModules = require('./OptmzUiModules');
let kbnTag = `Kibana ${ require('../../utils/closestPackageJson').getSync().version }`;
class BaseOptimizer extends EventEmitter {
constructor(opts) {
super();
this.sourceMaps = opts.sourceMaps || false;
this.modules = new OptmzUiModules(opts.plugins);
this.bundles = new OptmzBundles(
opts,
`${kbnTag} ${this.constructor.name} ${ this.sourceMaps ? ' (with source maps)' : ''}`
);
_.bindAll(this, 'getConfig');
}
getConfig() {
return {
context: fromRoot('.'),
entry: this.bundles.getEntriesConfig(),
devtool: this.sourceMaps ? '#source-map' : false,
output: {
path: this.bundles.dir,
filename: '[name].bundle.js',
sourceMapFilename: '[file].map',
publicPath: '/bundles/',
devtoolModuleFilenameTemplate: '[resource-path]'
},
plugins: [
new webpack.ResolverPlugin([
new DirectoryNameAsMain()
]),
new webpack.optimize.DedupePlugin(),
new ExtractTextPlugin('[name].style.css', {
allChunks: true
})
],
module: {
loaders: [
{ test: /\.less$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap!less?sourceMap') },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap') },
{ test: /\.jade$/, loader: 'jade' },
{ test: /\.(html|tmpl)$/, loader: 'raw' },
{ test: /\.png$/, loader: 'url?limit=2048!file?name=[path][name].[ext]' },
{ test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file?name=[path][name].[ext]' },
{ test: /\/src\/(plugins|ui)\/.+\.js$/, loader: 'auto-preload-rjscommon-deps' },
{ test: /\/__tests__\//, loader: 'mocha' }
].concat(this.modules.loaders),
noParse: this.modules.noParse,
},
resolve: {
extensions: ['', '.js', '.less'],
modulesDirectories: [ fromRoot('node_modules'), assets.root ],
root: fromRoot(),
alias: this.modules.aliases
}
};
}
}
module.exports = BaseOptimizer;

View file

@ -0,0 +1,49 @@
'use strict';
let _ = require('lodash');
let webpack = require('webpack');
let BaseOptimizer = require('./BaseOptimizer');
module.exports = class CachedOptimizer extends BaseOptimizer {
constructor(opts) {
super(opts);
_.bindAll(this, 'init', 'setupCompiler', 'run');
}
init(autoRun) {
return this.bundles.synchronize(true).then(autoRun ? this.run : this.setupCompiler);
}
setupCompiler(autoRun) {
this.entries = this.bundles.getMissingEntries();
if (!this.entries.length) return;
this.compilerConfig = this.getConfig();
this.compiler = webpack(this.compilerConfig);
if (autoRun) this.run();
}
run() {
if (!this.compiler) {
return this.setupCompiler(true);
}
var self = this;
let entries = self.entries;
self.emit('build-start', entries);
self.compiler.run(function (err, stats) {
if (err) {
self.emit('error', entries, err);
}
else if (stats.hasErrors() || stats.hasWarnings()) {
self.emit('error', entries, new Error('Optimization must not produce errors or warnings'), stats);
}
else {
self.emit('done', entries, stats);
}
});
}
};

View file

@ -0,0 +1,53 @@
'use strict';
let _ = require('lodash');
let join = require('path').join;
let promify = require('bluebird').promisify;
let webpack = require('webpack');
let MemoryFileSystem = require('memory-fs');
let BaseOptimizer = require('./BaseOptimizer');
module.exports = class LiveOptimizer extends BaseOptimizer {
constructor(opts) {
super(opts);
this.compilerConfig = this.getConfig();
this.compiler = webpack(this.compilerConfig);
this.outFs = this.compiler.outputFileSystem = new MemoryFileSystem();
_.bindAll(this, 'get', 'init');
this.compile = promify(this.compiler.run, this.compiler);
}
init() {
this.bundles.synchronize();
}
get(id) {
let self = this;
let fs = self.outFs;
let filename = join(self.compiler.outputPath, `${id}.bundle.js`);
let mapFilename = filename + '.map';
self.active = (self.active || self.compile().finally(function () {
self.active = null;
}));
return self.active.then(function (stats) {
if (stats.hasErrors() || stats.hasWarnings()) {
console.log(stats.toString({ colors: true }));
return null;
}
try {
return {
bundle: fs.readFileSync(filename),
map: self.sourceMaps ? fs.readFileSync(mapFilename) : false
};
} catch (e) {
return null;
}
});
}
};

View file

@ -1,120 +0,0 @@
'use strict';
var EventEmitter = require('events').EventEmitter;
var inherits = require('util').inherits;
var _ = require('lodash');
var join = require('path').join;
var write = require('fs').writeFileSync;
var webpack = require('webpack');
var assets = require('../ui/assets');
var fromRoot = require('../../utils/fromRoot');
var OptmzBundles = require('./OptmzBundles');
var OptmzUiModules = require('./OptmzUiModules');
var DirectoryNameAsMain = require('webpack-directory-name-as-main');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
class Optimizer extends EventEmitter {
constructor(opts) {
super();
this.verbose = opts.verbose;
this.watch = opts.watch || false;
this.sourceMaps = opts.sourceMaps || false;
this.modules = new OptmzUiModules(opts.plugins);
this.bundles = new OptmzBundles(opts);
}
init() {
return this.bundles.init(this.watch).then(_.bindKey(this, 'startCompiler'));
}
startCompiler() {
var self = this;
var modules = self.modules;
var bundles = self.bundles;
this.webpackConfig = {
entry: bundles.getEntriesToCompile(),
devtool: this.sourceMaps ? '#source-map' : false,
output: {
path: bundles.dir,
filename: '[name].js',
sourceMapFilename: '[file].map',
publicPath: '/bundles/',
devtoolModuleFilenameTemplate: '[resource-path]'
},
plugins: [
new webpack.ResolverPlugin([
new DirectoryNameAsMain()
]),
new webpack.NoErrorsPlugin(),
new webpack.optimize.DedupePlugin(),
new ExtractTextPlugin('[name].style.css', {
allChunks: true
})
],
module: {
loaders: [
{ test: /\.less$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap!less?sourceMap') },
{ test: /\.css$/, loader: ExtractTextPlugin.extract('style', 'css?sourceMap') },
{ test: /\.(html|tmpl)$/, loader: 'raw' },
{ test: /\.png$/, loader: 'url?limit=2048!file?name=[path][name].[ext]' },
{ test: /\.(woff|woff2|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file?name=[path][name].[ext]' },
{ test: /\/src\/(plugins|ui)\/.+\.js$/, loader: 'auto-preload-rjscommon-deps' }
].concat(modules.loaders),
noParse: modules.noParse,
},
resolve: {
extensions: ['', '.js', '.less'],
modulesDirectories: [ fromRoot('node_modules'), assets.root ],
root: fromRoot(),
alias: modules.aliases
}
};
var compiler = webpack(this.webpackConfig);
compiler.plugin('watch-run', function (compiler, cb) {
self.emit('watch-run');
cb();
});
compiler.plugin('done', function (stats) {
var errCount = _.size(stats.compilation.errors);
if (errCount) {
self.emit('error', stats, new Error('Failed to compile bundle'));
} else {
self.emit('done', stats);
}
});
compiler.plugin('failed', onFail);
function onFail(err) {
self.emit('error', err);
}
process.nextTick(function () {
if (self.watch) {
compiler.watch({
aggregateTimeout: 300
}, _.noop);
} else {
self.emit('build-start');
compiler.run(function (err) {
err && onFail(err);
});
}
});
return compiler;
}
}
module.exports = Optimizer;

View file

@ -14,69 +14,70 @@ let unlink = promify(require('fs').unlink);
let readdir = promify(require('fs').readdir);
let readSync = require('fs').readFileSync;
let appEntryTmpl = _.template(readSync(join(__dirname, 'OptmzAppEntry.js.tmpl')));
let serverVersion = require('../../utils/closestPackageJson').getSync().version;
let entryFileTemplate = _.template(readSync(join(__dirname, 'entry.js.tmpl')));
class OptmzBundles {
constructor(opts) {
let dir = _.get(opts, 'bundleDir');
let apps = _.get(opts, 'apps');
let versionTag = _.get(opts, 'sourceMaps') ? ' (with source maps)' : '';
this.dir = dir;
constructor(opts, optimizerTagline) {
this.dir = _.get(opts, 'bundleDir');
if (!_.isString(this.dir)) {
throw new TypeError('Optimizer requires a working directory');
}
this.entries = _.map(apps, function (app) {
this.sourceMaps = _.get(opts, 'sourceMaps');
this.entries = _.get(opts, 'entries', []).map(function (spec) {
let entry = {
id: app.id,
app: app,
modules: app.getModules(),
deps: app.relatedPlugins(),
path: join(dir, app.id + '.entry.js'),
bundlePath: join(dir, app.id + '.js')
id: spec.id,
deps: _.get(spec, 'deps', []),
modules: _.get(spec, 'modules', []),
path: join(this.dir, spec.id + '.entry.js'),
bundlePath: join(this.dir, spec.id + '.bundle.js'),
exists: undefined,
content: undefined
};
entry.content = appEntryTmpl(_.defaults({
version: `${serverVersion}${versionTag}`
}, entry));
entry.content = _.get(spec, 'template', entryFileTemplate)({
entry: entry,
optimizerTagline: optimizerTagline
});
return entry;
});
}, this);
_.bindAll(this, [
'init',
'cleanBundles',
'ensureBundleDir',
'syncBundleDir',
'cleanDir',
'ensureDir',
'synchronize',
'collectGarbage',
'syncBundle',
'clean',
'dirContents',
'getUnkownBundleFiles',
'getEntriesToCompile'
'getMissingEntries',
'getEntriesConfig'
]);
}
init(fresh) {
return resolve()
.then(fresh ? this.cleanBundles : _.noop)
.then(this.ensureBundleDir)
.then(this.syncBundleDir);
}
cleanBundles() {
cleanDir() {
return rimraf(this.dir);
}
ensureBundleDir() {
ensureDir() {
return mkdirp(this.dir);
}
syncBundleDir() {
let ensure = this.entries.map(this.syncBundle);
let collectGarbage = this.getUnkownBundleFiles().then(this.clean);
return resolve(ensure.concat(collectGarbage)).all().then(_.noop);
synchronize(collectGarbage) {
return this.ensureDir()
.return(this.entries)
.map(this.syncBundle)
.then(collectGarbage ? this.collectGarbage : _.noop)
.return(undefined);
}
collectGarbage() {
return this.getUnkownBundleFiles().then(this.clean);
}
syncBundle(entry) {
@ -94,8 +95,7 @@ class OptmzBundles {
entry.exists = existingEntry && bundleExists && (existingEntry === entry.content);
if (entry.exists) return;
return clean([entry.path, entry.bundlePath])
.then(function () {
return clean([entry.path, entry.bundlePath]).then(function () {
return write(entry.path, entry.content, { encoding: 'utf8' });
});
});
@ -109,7 +109,7 @@ class OptmzBundles {
})
)
.settle()
.then(_.noop);
.return(undefined);
}
dirContents() {
@ -135,9 +135,17 @@ class OptmzBundles {
.then(this.clean);
}
getEntriesToCompile() {
return _.transform(this.entries, function (map, entry) {
if (!entry.exists) map[entry.id] = entry.path;
hasMissingEntries() {
return this.getMissingEntries().length;
}
getMissingEntries() {
return _.reject(this.entries, 'exists');
}
getEntriesConfig() {
return _.transform(this.getMissingEntries(), function (map, entry) {
map[entry.id] = entry.path;
}, {});
}
}

View file

@ -0,0 +1,78 @@
'use strict';
let _ = require('lodash');
let webpack = require('webpack');
let BaseOptimizer = require('./BaseOptimizer');
module.exports = class CachedOptimizer extends BaseOptimizer {
constructor(opts) {
super(opts);
this.bundleStatus = null; // options: null, 'built', 'needs rebuild'
_.bindAll(this, 'init', 'setupCompiler', 'enable', 'disable');
}
init(autoRun) {
return this.bundles.cleanDir().then(autoRun ? this.enable : this.setupCompiler);
}
setupCompiler(autoRun) {
if (!_.size(this.bundles.entries)) return;
this.compilerConfig = this.getConfig();
this.compiler = webpack(this.compilerConfig);
this.compiler.plugin('done', _.bindKey(this, 'setStatus', 'done'));
this.compiler.plugin('failed', _.bindKey(this, 'setStatus', 'error'));
this.compiler.plugin('invalid', _.bindKey(this, 'setStatus', 'needs rebuild'));
this.compiler.plugin('watch-run', _.bindKey(this, 'setStatus', 'rebuilding'));
if (autoRun) this.enable();
}
setStatus(status) {
let entries = this.bundles.entries;
let stats;
let error;
switch (status) {
case 'done':
stats = this.watcher.stats;
error = null;
if (stats.hasErrors()) {
error = new Error('Optimization must not produce errors or warnings');
status = 'error';
}
break;
case 'error':
stats = this.watcher.stats;
error = this.watcher.error;
}
this.emit(this.bundleStatus = status, entries, stats, error);
}
enable() {
if (!this.compiler) {
return this.setupCompiler(true);
}
if (this.watcher) {
throw new Error('WatchingOptimizer already watching!');
}
this.watcher = this.compiler.watch(_.noop);
}
disable() {
if (!this.compiler) return;
if (!this.watcher) return;
this.watcher.close();
this.watcher = null;
this.compiler = null;
}
};

View file

@ -3,10 +3,10 @@
*
* This is programatically created and updated, do not modify
*
* built using: Kibana <%= version %>
* built using: <%= optimizerTagline %>
* includes code from:
<%
deps.sort().forEach(function (plugin) {
entry.deps.sort().forEach(function (plugin) {
print(` * - ${plugin}\n`);
})
%> *
@ -14,7 +14,7 @@
require('ui/chrome');
<%
modules.require.forEach(function (id) {
entry.modules.require.forEach(function (id) {
if (id !== 'ui/chrome') print(`require('${id}');\n`);
});
%>require('ui/chrome').bootstrap(<%= JSON.stringify(modules.angular) %>);
%>require('ui/chrome').bootstrap(<%= JSON.stringify(entry.modules.angular) %>);

View file

@ -5,45 +5,14 @@ module.exports = function (kbnServer, server, config) {
var resolve = require('path').resolve;
var fromRoot = require('../../utils/fromRoot');
var Optimizer = require('./Optimizer');
var CachedOptimizer = require('./CachedOptimizer');
var WatchingOptimizer = require('./WatchingOptimizer');
var bundleDir = resolve(config.get('optimize.bundleDir'));
var status = kbnServer.status.create('optimize');
server.exposeStaticDir('/bundles/{path*}', bundleDir);
function start() {
kbnServer.optimizer = new Optimizer({
watch: config.get('optimize.watch'),
sourceMaps: config.get('optimize.sourceMaps'),
bundleDir: bundleDir,
apps: [].concat(
kbnServer.uiExports.apps,
kbnServer.uiExports.apps.hidden
),
plugins: kbnServer.plugins
});
kbnServer.optimizer
.on('build-start', function () {
status.yellow('Optimizing and caching application source files');
})
.on('watch-run', _.before(2, function () {
status.yellow('Optimizing and watching application source files');
}))
.on('watch-run', _.after(2, function () {
status.yellow('Source file change detected, reoptimizing source files');
}))
.on('done', function (stats) {
logStats('debug', stats);
status.green('Optimization complete');
})
.on('error', function (stats, err) {
logStats('fatal', stats);
status.red('Optimization failure! ' + err.message);
})
.init();
}
function logStats(tag, stats) {
if (config.get('logging.json')) {
server.log(['optimize', tag], _.pick(stats.toJson(), 'errors', 'warnings'));
@ -52,6 +21,11 @@ module.exports = function (kbnServer, server, config) {
}
}
function describeEntries(entries) {
let ids = _.pluck(entries, 'id').join('", "');
return `application${ entries.length === 1 ? '' : 's'} "${ids}"`;
}
function onMessage(handle, filter) {
filter = filter || _.constant(true);
process.on('message', function (msg) {
@ -80,7 +54,55 @@ module.exports = function (kbnServer, server, config) {
send();
}
if (!role || role === 'send') {
start();
}
let watching = config.get('optimize.watch');
let Optimizer = watching ? WatchingOptimizer : CachedOptimizer;
let optmzr = kbnServer.optimizer = new Optimizer({
sourceMaps: config.get('optimize.sourceMaps'),
bundleDir: bundleDir,
entries: _.map(
[].concat(
kbnServer.uiExports.apps,
kbnServer.uiExports.apps.hidden
),
function (app) {
return {
id: app.id,
deps: app.getRelatedPlugins(),
modules: app.getModules()
};
}
),
plugins: kbnServer.plugins
});
optmzr.on('rebuilding', function () {
status.yellow('Source file change detected, reoptimizing source files');
});
optmzr.on('done', function (entries, stats) {
logStats('debug', stats);
status.green(`Optimization of ${describeEntries(entries)} complete`);
});
optmzr.on('error', function (entries, err, stats) {
if (stats) logStats('fatal', stats);
status.red('Optimization failure! ' + err.message);
});
return optmzr.init(!role || role === 'send').then(function () {
let entries = optmzr.bundles.getMissingEntries();
if (entries.length && watching) {
status.yellow(`Optimizing and watching application source files`);
}
else if (entries.length) {
status.yellow(`Optimizing and caching ${describeEntries(entries)}`);
}
else if (watching) {
status.red('No optimizable applications found');
}
else {
status.green('Reusing previously cached application source files');
}
});
};

View file

@ -1,8 +1,9 @@
'use strict';
var Plugin = require('./Plugin');
var basename = require('path').basename;
var join = require('path').join;
let _ = require('lodash');
let Plugin = require('./Plugin');
let basename = require('path').basename;
let join = require('path').join;
module.exports = class PluginApi {
constructor(kibana, pluginPath) {
@ -11,5 +12,6 @@ module.exports = class PluginApi {
this.package = require(join(pluginPath, 'package.json'));
this.autoload = require('../ui/autoload');
this.Plugin = Plugin.scoped(kibana, pluginPath, this.package);
this.mixin = _.bindKey(kibana, 'mixin');
}
};

View file

@ -10,6 +10,14 @@ module.exports = function (kbnServer, server, config) {
return (plugin && plugin.publicDir) ? plugin.publicDir : Boom.notFound();
});
server.method('kbnPluginById', function (id, next) {
if (kbnServer.plugins.byId[id]) {
next(null, kbnServer.plugins.byId[id]);
} else {
next(Boom.notFound(`no plugin with the id "${id}"`));
}
});
return kbnServer.mixin(
require('./scan'),
require('./load')

View file

@ -42,8 +42,8 @@ class UiApp {
};
}
relatedPlugins() {
var pluginsById = _.indexBy(this.uiExports.kbnServer.plugins, 'id');
getRelatedPlugins() {
var pluginsById = this.uiExports.kbnServer.plugins.byId;
return _.transform(this.getModules().require, function (plugins, id) {
var matches = id.match(/^plugins\/([^\/]+)(?:\/|$)/);
if (!matches) return;

View file

@ -2,19 +2,13 @@ module.exports = function (kbnServer, server, config) {
var _ = require('lodash');
var join = require('path').join;
// setup jade for templates
server.views({
path: join(__dirname, 'views'),
isCached: config.get('optimize.viewCaching'),
engines: {
jade: require('jade')
}
});
return kbnServer.mixin(
require('./exports'),
require('./helpers'),
require('./statics'),
function () {
server.setupViews(join(__dirname, 'views'));
server.exposeStaticDir('/ui/{path*}', require('./assets').root);
},
require('./apps')
);

View file

@ -1,3 +0,0 @@
module.exports = function (kbnServer, server, config) {
server.exposeStaticDir('/ui/{path*}', require('./assets').root);
};

0
src/server/ui/views.js Normal file
View file

View file

@ -11,4 +11,4 @@ html(lang='en')
link(rel='stylesheet', href='/bundles/#{app.id}.style.css')
body(kbn-chrome)
script window.__KBN__ = !{j(kibanaPayload)};
script(src='/bundles/#{app.id}.js')
script(src='/bundles/#{app.id}.bundle.js')

View file

@ -0,0 +1,238 @@
// fake process obejct to make browserify-path happy
window.process = window.process || { cwd: function () { return '.'; }};
var _ = require('lodash');
var $ = require('jquery');
var InsertionText = require('istanbul/lib/util/insertion-text.js');
var objUtils = require('istanbul/lib/object-utils.js');
// var annotate = require('istanbul/lib/annotate.js');
var Progress = require('mocha/lib/browser/progress.js');
var path = require('path-browserify/index.js');
var template = require('./report.jade');
var Base = window.Mocha.reporters.Base;
var covGrepQueryParamRE = /cov_grep=([^&]+)/;
var afterDraw = window.requestAnimationFrame || function (cb) { setTimeout(cb, 500); };
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');
console.log(JSON.stringify(stats, null, ' '));
linkNav();
if (gotoFile) {
afterDraw(function () {
window.location.hash = gotoFile;
});
}
});
}
function createReport() {
var covResults = window.__coverage__;
var grep = window.location.search.match(covGrepQueryParamRE);
if (grep) {
grep = decodeURIComponent(grep[1]);
covResults = _.transform(covResults, function (results, cov, filename) {
if (~filename.indexOf(grep)) {
results[filename] = cov;
}
});
}
var summary = objUtils.summarizeCoverage(covResults);
var dirs = _(covResults)
.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();
// when scrolling, highlight the related menu item
$(window).scroll(function (e) {
var heading = find(window.scrollY);
if (!heading) return;
var links = document.querySelectorAll('#menu a');
var link;
for (var i = 0, len = links.length; i < len; ++i) {
link = links[i];
link.className = link.getAttribute('href') === '#' + heading.id
? 'active'
: '';
}
});
// find the file they are probably looking at
function find(y) {
var i = headings.length;
var heading;
while (i--) {
heading = headings[i];
if (y >= heading.offsetTop) {
return heading;
}
}
}
$('#menu').on('click', '.dirname .cov', function () {
var dir = $(this).parent()[0].childNodes[0].textContent;
var loc = window.location;
var proto = loc.protocol;
var host = loc.host;
var path = loc.pathname;
var search = loc.search;
var hash = loc.hash;
var grep = 'cov_grep=' + encodeURIComponent(dir);
if (search && search.match(covGrepQueryParamRE)) {
search = search.replace(covGrepQueryParamRE, grep);
} else {
search = (search ? search + '&' : '?') + grep;
}
window.location = path + search + hash;
});
}
function toSec(stats, prop) {
return stats[prop] = (stats[prop] / 1000).toFixed(2) + ' sec';
}
module.exports = IstanbulReporter;

View file

@ -3,7 +3,7 @@ define(['angular', 'bluebird', 'services/promises'], function (angular, Bluebird
* replace the Promise service with Bluebird so that tests
* can use promises without having to call $rootScope.apply()
*
* var nonDigestPromises = require('test_utils/non_digest_promises');
* var nonDigestPromises = require('testUtils/non_digest_promises');
*
* describe('some module that does complex shit with promises', function () {
* beforeEach(nonDigestPromises.activate);

View file

@ -1,7 +1,7 @@
define(function (require) {
return function (Private) {
var _ = require('lodash');
var sinon = require('sinon/sinon');
var sinon = require('sinon');
var IndexedArray = require('ui/indexed_array/index');
var IndexPattern = require('ui/index_patterns/_index_pattern');
var fieldFormats = Private(require('registry/field_formats'));

View file

@ -1,7 +1,7 @@
define(function (require) {
var _ = require('lodash');
var fixtures = require('fixtures/fake_hierarchical_data');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var Vis;

View file

@ -2,7 +2,7 @@ define(function (require) {
return ['orderedDateAxis', function () {
var moment = require('moment');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var baseArgs = {

View file

@ -1,7 +1,7 @@
define(function (require) {
return ['ResponseWriter class', function () {
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var Vis;

View file

@ -4,7 +4,7 @@ define(function (require) {
var $ = require('jquery');
var expect = require('expect.js');
var fixtures = require('fixtures/fake_hierarchical_data');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var $rootScope;
var $compile;

View file

@ -2,7 +2,7 @@ define(function (require) {
return ['AggType Class', function () {
var _ = require('lodash');
var expect = require('expect.js');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var AggType;
var AggParams;
var AggConfig;

View file

@ -26,7 +26,7 @@ define(function (require) {
beforeEach(module('kibana'));
beforeEach(inject(function (Private) {
var AggParamWriter = Private(require('test_utils/agg_param_writer'));
var AggParamWriter = Private(require('../aggParamWriter'));
paramWriter = new AggParamWriter({ aggType: 'histogram' });
}));

View file

@ -3,7 +3,7 @@ define(function (require) {
describe('date_histogram', function () {
var _ = require('lodash');
var moment = require('moment');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var aggResp = require('fixtures/agg_resp/date_histogram');
var expect = require('expect.js');

View file

@ -14,7 +14,7 @@ define(function (require) {
beforeEach(module('kibana'));
beforeEach(inject(function (Private, $injector) {
var AggParamWriter = Private(require('test_utils/agg_param_writer'));
var AggParamWriter = Private(require('../../aggParamWriter'));
var indexPattern = Private(require('fixtures/stubbed_logstash_index_pattern'));
var timefilter = $injector.get('timefilter');

View file

@ -3,7 +3,7 @@ define(function (require) {
var $ = require('jquery');
var _ = require('lodash');
var expect = require('expect.js');
var simulateKeys = require('test_utils/simulate_keys');
var simulateKeys = require('testUtils/simulateKeys');
require('ui/number_list/number_list');

View file

@ -1,6 +1,6 @@
define(function (require) {
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
function ParamClassStub(parent, body) {
var stub = sinon.spy(body || function () {

View file

@ -1,6 +1,6 @@
define(function (require) {
describe('$scope.$bind', function () {
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var $rootScope;

View file

@ -7,7 +7,6 @@ define(function (require) {
require('ui/timefilter/timefilter');
require('ui/private');
require('ui/promises');
require('ui/style_compile');
var TabCollection = require('ui/chrome/TabCollection');
@ -17,7 +16,7 @@ define(function (require) {
var tabs = new TabCollection();
var rootController = null;
var rootTemplate = null;
var showAppsLink = payload.appCount > 1;
var showAppsLink = null;
var brand = null;
var chrome = {
@ -185,7 +184,7 @@ define(function (require) {
};
chrome.getShowAppsLink = function () {
return showAppsLink;
return showAppsLink == null ? payload.appCount > 1 : showAppsLink;
};
chrome.getBrand = function () {

View file

@ -1,7 +1,7 @@
define(function (require) {
var angular = require('angular');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var $ = require('jquery');

View file

@ -1,6 +1,6 @@
define(function (require) {
describe('Courier DocFetchRequest class', function () {
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var storage;

View file

@ -1,5 +1,5 @@
define(function (require) {
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var debounce;

View file

@ -1,7 +1,7 @@
define(function (require) {
var angular = require('angular');
var $ = require('jquery');
var sinon = require('sinon/sinon');
var sinon = require('sinon');
var expect = require('expect.js');
require('ui/directives/confirm_click');
@ -9,7 +9,7 @@ define(function (require) {
// Load the kibana app dependencies.
require('angular-route');
require('plugins/discover/index');
require('plugins/kibana/discover/index');
var $parentScope, $scope, $elem;

View file

@ -4,7 +4,7 @@ define(function (require) {
var expect = require('expect.js');
require('angular-route');
require('plugins/discover/index');
require('plugins/kibana/discover/index');
var $parentScope, $scope, $elem;

View file

@ -4,7 +4,7 @@ define(function (require) {
describe('FixedScroll directive', function () {
var $ = require('jquery');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var Promise = require('bluebird');
var compile;

View file

@ -6,7 +6,7 @@ define(function (require) {
// Load the kibana app dependencies.
require('angular-route');
require('plugins/discover/index');
require('plugins/kibana/discover/index');
var $parentScope, $scope, $elem;

View file

@ -4,17 +4,17 @@ define(function (require) {
var expect = require('expect.js');
var _ = require('lodash');
var $ = require('jquery');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
// Load the kibana app dependencies.
require('angular-route');
require('plugins/visualize/index');
require('plugins/dashboard/index');
require('plugins/kibana/visualize/index');
require('plugins/kibana/dashboard/index');
// TODO: This should not be needed, timefilter is only included here, it should move
require('plugins/discover/index');
require('plugins/kibana/discover/index');
var $parentScope, $scope, $elem;
var anchor = '2014-01-01T06:06:06.666Z';

View file

@ -6,7 +6,7 @@ define(function (require) {
// Load the kibana app dependencies.
require('angular-route');
require('plugins/discover/index');
require('plugins/kibana/discover/index');
var $parentScope, $scope, $elem;

View file

@ -1,6 +1,6 @@
define(function (require) {
var angular = require('angular');
var sinon = require('sinon/sinon');
var sinon = require('sinon');
var expect = require('expect.js');
// Load the kibana app dependencies.
@ -8,7 +8,7 @@ define(function (require) {
require('ui/typeahead/typeahead');
// TODO: This should not be needed, timefilter is only included here, it should move
require('plugins/discover/index');
require('plugins/kibana/discover/index');
var typeaheadHistoryCount = 10;
var typeaheadName = 'unittest';

View file

@ -1,6 +1,6 @@
define(function (require) {
var angular = require('angular');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
// Load the kibana app dependencies.

View file

@ -3,7 +3,7 @@ define(function (require) {
var expect = require('expect.js');
var $ = require('jquery');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var searchResponse = require('fixtures/search_response');
// Load the kibana app dependencies.

View file

@ -2,7 +2,7 @@ define(function (require) {
var angular = require('angular');
var $ = require('jquery');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var getFakeRow = require('fixtures/fake_row');
@ -11,7 +11,7 @@ define(function (require) {
// Load the kibana app dependencies.
require('angular-route');
require('plugins/discover/index');
require('plugins/kibana/discover/index');
var $parentScope, $scope, config;

View file

@ -1,7 +1,7 @@
define(function (require) {
describe('docTitle Service', function () {
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var initialDocTitle;
var MAIN_TITLE = 'Kibana 4';
@ -19,8 +19,8 @@ define(function (require) {
});
beforeEach(module('kibana', function ($provide) {
$provide.decorator('docTitle', sinon.decorateWithSpy('update'));
$provide.decorator('$rootScope', sinon.decorateWithSpy('$on'));
$provide.decorator('docTitle', decorateWithSpy('update'));
$provide.decorator('$rootScope', decorateWithSpy('$on'));
}));
beforeEach(inject(function ($injector, Private) {
@ -80,5 +80,12 @@ define(function (require) {
});
});
function decorateWithSpy(prop) {
return function ($delegate) {
sinon.spy($delegate, prop);
return $delegate;
};
}
});
});

View file

@ -2,7 +2,7 @@ define(function (require) {
var angular = require('angular');
var $ = require('jquery');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
var hit = {
'_index': 'logstash-2014.09.09',

View file

@ -1,7 +1,7 @@
define(function (require) {
var angular = require('angular');
var _ = require('lodash');
var sinon = require('sinon/sinon');
var sinon = require('sinon');
var expect = require('expect.js');
require('ui/private');

View file

@ -1,12 +1,12 @@
define(function (require) {
var angular = require('angular');
var _ = require('lodash');
var sinon = require('test_utils/auto_release_sinon');
var sinon = require('auto-release-sinon/mocha');
var expect = require('expect.js');
require('ui/private');
describe('Events', function () {
require('test_utils/no_digest_promises').activateForSuite();
require('testUtils/noDigestPromises').activateForSuite();
var $rootScope;
var Events;

Some files were not shown because too many files have changed in this diff Show more