diff --git a/.travis.yml b/.travis.yml index 2dd45ea0..1a4a046f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,9 @@ language: node_js node_js: - - "4" - - "5" - - "6" + - "10" before_script: - npm install -g grunt-cli - - mkdir ~/bin + - mkdir -p ~/bin - export PATH=~/bin:$PATH - npm install diff --git a/Gruntfile.js b/Gruntfile.js index 11b039ea..ab5b4512 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -83,7 +83,7 @@ module.exports = function(grunt) { grunt.loadNpmTasks('grunt-contrib-nodeunit'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-casper'); + // grunt.loadNpmTasks('grunt-casper'); grunt.registerTask('runtest',function(){ var done = this.async(); @@ -136,7 +136,8 @@ module.exports = function(grunt) { grunt.registerTask('optimize', ['uglify']); // Default task. - grunt.registerTask('test', ['jshint', 'nodeunit', 'runtest', 'runbin', 'casper']); + // grunt.registerTask('test', ['jshint', 'nodeunit', 'runtest', 'runbin', 'casper']); + grunt.registerTask('test', ['jshint', 'nodeunit', 'runtest', 'runbin']); grunt.registerTask('default', ['test']); }; diff --git a/README.md b/README.md index 988e21f4..ade24844 100644 --- a/README.md +++ b/README.md @@ -45,18 +45,29 @@ Usage : plato [options] -d Time to use as the report date (seconds, > 9999999999 assumed to be ms) -n, --noempty Skips empty lines from line count + -X, --extensions : Array (default: .js) + Specify JavaScript file extensions ``` __Example__ -```shell -plato -r -d report src +```console +$ plato -r -d report src ``` __Extended example__ +```console +$ plato -r -d report -l .jshintrc -t "My Awesome App" -x .json routes/*.js ``` -plato -r -d report -l .jshintrc -t "My Awesome App" -x .json routes/*.js + +__Extended example (Specify JavaScript file extensions)__ + +```console +$ plato -r -d report -X .jsx src +$ plato -r -d report --extensions=.jsx src +$ plato -r -d report -X .js,.jsx src +$ plato -r -d report -X .js -X .jsx src ``` ### From scripts diff --git a/lib/assets/scripts/plato-overview.js b/lib/assets/scripts/plato-overview.js index d568849f..9d5034ba 100644 --- a/lib/assets/scripts/plato-overview.js +++ b/lib/assets/scripts/plato-overview.js @@ -100,16 +100,16 @@ $(function(){ reports.forEach(function(report){ // @todo shouldn't need this, 'auto [num]' doesn't seem to work : https://github.com/oesmith/morris.js/issues/201 - sloc.ymax = Math.max(sloc.ymax, report.complexity.methodAggregate.sloc.physical); - bugs.ymax = Math.max(bugs.ymax, report.complexity.methodAggregate.halstead.bugs.toFixed(2)); + sloc.ymax = Math.max(sloc.ymax, report.complexity.aggregate.sloc.physical); + bugs.ymax = Math.max(bugs.ymax, report.complexity.aggregate.halstead.bugs.toFixed(2)); sloc.data.push({ - value : report.complexity.methodAggregate.sloc.physical, + value : report.complexity.aggregate.sloc.physical, label : report.info.fileShort }); bugs.data.push({ - value : report.complexity.methodAggregate.halstead.bugs.toFixed(2), + value : report.complexity.aggregate.halstead.bugs.toFixed(2), label : report.info.fileShort }); maintainability.data.push({ diff --git a/lib/cli.js b/lib/cli.js index a88928a6..cdc67ef7 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -30,7 +30,9 @@ exports.exec = function(options, done) { q: !!exports.args.q, title : exports.args.t && exports.args.t.value, exclude : exports.args.x && new RegExp(exports.args.x.value), - date : exports.args.D && exports.args.D.value + date : exports.args.D && exports.args.D.value, + eslint: exports.args.e && exports.args.e.value, + extensions: exports.args.X && exports.args.X.value }; var json; var jshintrc = {}; @@ -43,11 +45,6 @@ exports.exec = function(options, done) { platoOptions.jshint = { globals : jshintrc.globals || {} }; delete jshintrc.globals; platoOptions.jshint.options = jshintrc; - - } else if (exports.args.e) { - json = fs.readFileSync(exports.args.e.value).toString(); - jshintrc = JSON.parse(util.stripComments(json)); - platoOptions.eslint = jshintrc; } plato.inspect(files, outputDir, platoOptions, done); @@ -66,7 +63,7 @@ function parseArgs(options) {// \/\\*(?:(?!\\*\/)|.|\\n)*?\\*\/ Object.keys(options).forEach(function(option){ var def = options[option]; optionString += option; - if (def.type === 'String') optionString += ':'; + if (def.type === 'String' || def.type === "Array") optionString += ':'; if (def.long) optionString += '(' + def.long + ')'; if (def.required) required.push(option); }); @@ -74,10 +71,14 @@ function parseArgs(options) {// \/\\*(?:(?!\\*\/)|.|\\n)*?\\*\/ var parser = new getopt.BasicParser(optionString, process.argv); var args = {}, option; - while ((option = parser.getopt())) { - var arg = args[option.option] || { count : 0}; + while ((option = parser.getopt()) !== undefined && !option.error) { + var arg = args[option.option] || { count : 0, value : [] }; arg.count++; - arg.value = option.optarg || true; + if (options[option.option].type === "Array") { + arg.value = arg.value.concat(option.optarg.split(",")); + } else { + arg.value = option.optarg || true; + } args[option.option] = arg; @@ -98,5 +99,10 @@ function parseArgs(options) {// \/\\*(?:(?!\\*\/)|.|\\n)*?\\*\/ // what's left in argv args.files = process.argv.slice(parser.optind()); + if (args.files.length < 1) { + console.log("One or more files ​​are required."); + info.help(); + process.exit(1); + } return args; } diff --git a/lib/cli/options.json b/lib/cli/options.json index 787650b2..eab70622 100644 --- a/lib/cli/options.json +++ b/lib/cli/options.json @@ -56,5 +56,11 @@ "long": "noempty", "desc": "Skips empty lines from line count", "type": "Boolean" + }, + "X": { + "long": "extensions", + "desc": "Specify JavaScript file extensions", + "type": "Array", + "default": ".js" } } diff --git a/lib/info.js b/lib/info.js index edc1478c..790852bb 100644 --- a/lib/info.js +++ b/lib/info.js @@ -15,11 +15,12 @@ exports.help = function() { Object.keys(options).forEach(function(shortOption){ var option = options[shortOption]; console.log( - ' -%s%s%s%s', + ' -%s%s%s%s%s', shortOption, option.long ? ', --' + option.long : '', option.type !== 'Boolean' ? ' : ' + option.type : '', - option.required ? ' *required*' : '' + option.required ? ' *required*' : '', + option.default ? ' (default: ' + option.default + ')' : '' ); console.log(' %s', option.desc); }); diff --git a/lib/logger.js b/lib/logger.js index b443b6ad..f33d7975 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -14,10 +14,17 @@ var levels = [ 'WARNING', 'ERROR' ]; +var apiMap = { + 'TRACE': 'trace', + 'DEBUG': 'log', + 'INFO': 'info', + 'WARNING': 'warn', + 'ERROR': 'error' +}; levels.forEach(function(level, i){ Logger[level] = i; Logger.prototype[level.toLowerCase()] = function() { - if (i >= this.level) console.log.apply(console,arguments); + if (i >= this.level) console[apiMap[level]].apply(console,arguments); }; }); diff --git a/lib/models/FileHistory.js b/lib/models/FileHistory.js index a9cd488d..e1ea3c25 100644 --- a/lib/models/FileHistory.js +++ b/lib/models/FileHistory.js @@ -16,11 +16,11 @@ FileHistory.prototype.addReport = function(report, date) { date = date || report.date || new Date().toUTCString(); this.push({ date : date, - sloc : report.complexity.methodAggregate.sloc.physical, - lloc : report.complexity.methodAggregate.sloc.logical, + sloc : report.complexity.aggregate.sloc.physical, + lloc : report.complexity.aggregate.sloc.logical, functions : report.complexity.methods.length, - deliveredBugs : report.complexity.methodAggregate.halstead.bugs, - difficulty: report.complexity.methodAggregate.halstead.difficulty, + deliveredBugs : report.complexity.aggregate.halstead.bugs, + difficulty: report.complexity.aggregate.halstead.difficulty, maintainability: report.complexity.maintainability, lintErrors : (report.jshint && report.jshint.messages.length) || [] }); diff --git a/lib/plato.js b/lib/plato.js index 59ec8a63..03988cc5 100644 --- a/lib/plato.js +++ b/lib/plato.js @@ -49,6 +49,8 @@ exports.inspect = function(files, outputDir, options, done) { files = files instanceof Array ? files : [files]; files = _.flatten(files.map(unary(glob.sync))); + options.extensions = options.extensions || [".js"]; + var flags = { complexity : { commonjs : true, @@ -61,11 +63,25 @@ exports.inspect = function(files, outputDir, options, done) { jshint : {} // use jshint defaults }; + // TODO: separate jshint and eslint on running `runReports` if (options.eslint) { - options.jshint = options.eslint; - reporters.jshint = reporters.eslint; + if (typeof options.eslint === "string") { + options.jshint = { + configFile: path.resolve(options.eslint) + }; + } else { + options.eslint.baseConfig = options.eslint.baseConfig || {}; + ["extends", "overrides", "settings"].forEach(function(configKey){ + if (options.eslint[configKey]) { + options.eslint.baseConfig[configKey] = options.eslint[configKey]; + delete options.eslint[configKey]; + } + }); + options.jshint = options.eslint; + } delete options.eslint; - delete reporters.eslint; + reporters.jshint = reporters.eslint; + // delete reporters.eslint; // NOTE: don't delete because can't reuse `inspect` } Object.keys(flags).forEach(function(flag){ @@ -95,20 +111,20 @@ exports.inspect = function(files, outputDir, options, done) { return path.join(file,innerFile); }); runReports(files); - } else if (file.match(/\.js$/)) { + } else if (options.extensions.includes(path.extname(file))) { log.info('Reading "%s"', file); var fileShort = file.replace(commonBasePath, ''); var fileSafe = fileShort.replace(/[^a-zA-Z0-9]/g,'_'); - var source = fs.readFileSync(file).toString().trim(); - if (!source) { + var source = fs.readFileSync(file).toString(); + if (!source.trim()) { log.info('Not parsing empty file "%s"', file); return; } // if skip empty line option if(options.noempty) { - source = source.replace(/^\s*[\r\n]/gm ,""); + source = source.replace(/^\s*[\r\n]/gm ,"").trim(); } // if begins with shebang @@ -195,10 +211,10 @@ exports.getOverviewReport = function (reports) { reports.forEach(function(report) { // clone objects so we don't have to worry about side effects - summary.total.sloc += report.complexity.methodAggregate.sloc.physical; + summary.total.sloc += report.complexity.aggregate.sloc.physical; summary.total.maintainability += report.complexity.maintainability; - var methodAggregate = _.cloneDeep(report.complexity.methodAggregate); + var aggregate = _.cloneDeep(report.complexity.aggregate); var reportItem = {}; reportItem.info = report.info; if (report.jshint) { @@ -209,7 +225,7 @@ exports.getOverviewReport = function (reports) { } if (report.complexity) { reportItem.complexity = { - methodAggregate : methodAggregate, + aggregate : aggregate, module : report.complexity.module, module_safe : report.complexity.module_safe, maintainability : _.cloneDeep(report.complexity.maintainability) diff --git a/lib/reporters/eslint/index.js b/lib/reporters/eslint/index.js index c40275db..4b4957aa 100644 --- a/lib/reporters/eslint/index.js +++ b/lib/reporters/eslint/index.js @@ -1,6 +1,8 @@ "use strict"; -var ESLINT = require("eslint"); +// @see http://www.phpied.com/using-eslint-in-a-script/ +// @see https://eslint.org/docs/developer-guide/nodejs-api#cliengine +var CLIEngine = require("eslint").CLIEngine; exports.process = function (source, options/*, reportInfo */) { var results = lint(source, options); @@ -36,7 +38,8 @@ function lint(source, config) { // Remove potential Unicode BOM. source = source.replace(/^\uFEFF/, ""); - var messages = ESLINT.linter.verify(source, config); + var cli = new CLIEngine(config); + var messages = cli.executeOnText(source).results[0].messages; results = results.concat(messages); return { diff --git a/lib/reporters/jshint/index.js b/lib/reporters/jshint/index.js index 66a2eeac..e401ef7a 100644 --- a/lib/reporters/jshint/index.js +++ b/lib/reporters/jshint/index.js @@ -6,10 +6,10 @@ var jsHintCli = require("jshint/src/cli.js"); // Provides a regexp to test for ES6 / ES Modules. If the pass tests then esversion is set to 6 if not already specified. var esmRegex = /(^\s*|[}\);\n]\s*)(import\s*(['"]|(\*\s+as\s+)?[^"'\(\)\n;]+\s*from\s*['"]|\{)|export\s+\*\s+from\s+["']|export\s* (\{|default|function|class|var|const|let|async\s+function))/; -exports.process = function (source, options/*, reportInfo */) { +exports.process = function (source, options, reportInfo) { if (options == null || Object.getOwnPropertyNames(options).length === 0) { options = { options : {}, globals : {}}; - var jsHintOptions = jsHintCli.getConfig(source); + var jsHintOptions = jsHintCli.getConfig(reportInfo.file || ""); delete jsHintOptions.dirname; if (jsHintOptions != null && Object.getOwnPropertyNames(jsHintOptions).length > 0) { diff --git a/lib/templates/display.html b/lib/templates/display.html index a2a347a4..75e75fc2 100644 --- a/lib/templates/display.html +++ b/lib/templates/display.html @@ -65,9 +65,9 @@

Worst Maintainability Scores

Largest Files

@@ -62,11 +62,11 @@

Lines of code

Difficulty

-

<%= report.complexity.methodAggregate.halstead.difficulty.toFixed(2) %>

+

<%= report.complexity.aggregate.halstead.difficulty.toFixed(2) %>

Estimated Errors

-

<%= report.complexity.methodAggregate.halstead.bugs.toFixed(2) %>

+

<%= report.complexity.aggregate.halstead.bugs.toFixed(2) %>

diff --git a/lib/templates/overview.html b/lib/templates/overview.html index 53cd5e1e..436ad829 100644 --- a/lib/templates/overview.html +++ b/lib/templates/overview.html @@ -121,9 +121,9 @@

Files

<%= item.info.fileShort %> diff --git a/lib/util.js b/lib/util.js index 31e638ae..1da7e428 100644 --- a/lib/util.js +++ b/lib/util.js @@ -11,7 +11,7 @@ var log = new Logger(Logger.WARNING); var path = require('path'); exports.findCommonBase = function(files) { - if (!files || files.length === 1) return ''; + if (!files || files.length < 2) return ''; var lastSlash = files[0].lastIndexOf(path.sep); if (!lastSlash) return ''; var first = files[0].substr(0, lastSlash + 1); diff --git a/package.json b/package.json index d93b10b5..d54ae980 100644 --- a/package.json +++ b/package.json @@ -25,18 +25,17 @@ ], "main": "lib/plato", "engines": { - "node": ">= 4.4.5" + "node": ">= 10.16.0" }, "scripts": { "test": "grunt test" }, "devDependencies": { "grunt": "~1.0.1", - "grunt-casper": "~0.4.0", "grunt-contrib-jshint": "~1.0.0", - "grunt-contrib-nodeunit": "~1.0.0", + "grunt-contrib-nodeunit": "^2.0.0", "grunt-contrib-uglify": "~1.0.1", - "grunt-contrib-watch": "~1.0.0" + "grunt-contrib-watch": "^1.1.0" }, "keywords": [ "halstead", @@ -48,12 +47,12 @@ "analyze" ], "dependencies": { - "typhonjs-escomplex": "0.0.9", + "eslint": "6.0.1", "fs-extra": "~0.30.0", "glob": "~7.0.5", - "jshint": "~2.9.2", - "lodash": "~4.13.1", + "jshint": "2.10.2", + "lodash": "^4.17.11", "posix-getopt": "~1.2.0", - "eslint": "~3.0.1" + "typhonjs-escomplex": "0.1.0" } } diff --git a/test/fixtures/.eslintrc.json b/test/fixtures/.eslintrc.json new file mode 100644 index 00000000..1bdec37f --- /dev/null +++ b/test/fixtures/.eslintrc.json @@ -0,0 +1,24 @@ +{ + "rules": { + "indent": [ + 2, + 4 + ], + "quotes": [ + 2, + "single" + ], + "linebreak-style": [ + 2 + ], + "semi": [ + 2, + "always" + ], + "no-console": 0 + }, + "env": { + "node": true + }, + "extends": "eslint:recommended" +} diff --git a/test/fixtures/.jshintrc b/test/fixtures/.jshintrc index a76ff7b6..1ab84ce7 100644 --- a/test/fixtures/.jshintrc +++ b/test/fixtures/.jshintrc @@ -15,7 +15,7 @@ "boss": true, "eqnull": true, "node": true, - "es5": true + "maxparams": 3 } /* foo */ diff --git a/test/fixtures/.jshintrc.json b/test/fixtures/.jshintrc.json new file mode 100644 index 00000000..6435619b --- /dev/null +++ b/test/fixtures/.jshintrc.json @@ -0,0 +1,14 @@ +{ + "curly": false, + "eqeqeq": true, + "immed": true, + "latedef": false, + "newcap": true, + "noarg": true, + "sub": true, + "undef": true, + "unused": true, + "boss": true, + "eqnull": true, + "node": true +} diff --git a/test/fixtures/c-es6 b/test/fixtures/c-es6 new file mode 100644 index 00000000..f63d53ce --- /dev/null +++ b/test/fixtures/c-es6 @@ -0,0 +1,21 @@ + +const a = 1; + +class C +{ + static classMethodA(arg) { + return arg; + } + + static classMethodB(arg) { + return arg; + } +} + +function moduleMethod(arg) { + return arg; +} + +const b = moduleMethod(0) + C.classMethodB(1) + C.classMethodA(2); + +export default C; diff --git a/test/fixtures/c-es6.es b/test/fixtures/c-es6.es new file mode 100644 index 00000000..f63d53ce --- /dev/null +++ b/test/fixtures/c-es6.es @@ -0,0 +1,21 @@ + +const a = 1; + +class C +{ + static classMethodA(arg) { + return arg; + } + + static classMethodB(arg) { + return arg; + } +} + +function moduleMethod(arg) { + return arg; +} + +const b = moduleMethod(0) + C.classMethodB(1) + C.classMethodA(2); + +export default C; diff --git a/test/fixtures/issue_182.js b/test/fixtures/issue_182.js new file mode 100644 index 00000000..fac363e1 --- /dev/null +++ b/test/fixtures/issue_182.js @@ -0,0 +1,8 @@ +/** + * exceeded maxparams(3) + */ +function foo(a, b, c, d) { + return a + b + c + d; +} + +foo(); diff --git a/test/fixtures/issue_217.js b/test/fixtures/issue_217.js new file mode 100644 index 00000000..12136ffd --- /dev/null +++ b/test/fixtures/issue_217.js @@ -0,0 +1,9 @@ +class Foo { + constructor() { + this.$onInit = async() => { + await this.initPage(); + }; + } + initPage() { + } +} diff --git a/test/fixtures/model_history.json b/test/fixtures/model_history.json index b3132b3c..bb27b9c2 100644 --- a/test/fixtures/model_history.json +++ b/test/fixtures/model_history.json @@ -7,7 +7,7 @@ }, "complexity":{ "lineStart":1, - "methodAggregate":{ + "aggregate":{ "sloc":{ "physical":22, "logical":10 diff --git a/test/issues/issue_16_test.js b/test/issues/issue_16_test.js index 5e57316d..503b4972 100644 --- a/test/issues/issue_16_test.js +++ b/test/issues/issue_16_test.js @@ -26,9 +26,8 @@ exports['issue_16'] = { var file = "test/fixtures/issue_16.js", source = fs.readFileSync(file).toString().trim(), - config = {}, - globals = [], - report = linter.process(source, config, globals); + options = {}, + report = linter.process(source, options, {}); test.equal(report.messages.length, 0, "Report returned with messages"); test.done(); diff --git a/test/issues/issue_182_test.js b/test/issues/issue_182_test.js new file mode 100644 index 00000000..75d9e281 --- /dev/null +++ b/test/issues/issue_182_test.js @@ -0,0 +1,36 @@ +'use strict'; +/** + * #182 the default behavior of JSHint is to look for ".jshintsrc" up the processed file's hierarchy. + * The difference between `.jshintrc` and `test/fixtures/.jshintrc` is maxparams. + * if jshint finds `test/fixtures/.jshintrc` then a maxparams error should occur. + */ +var fs = require('fs-extra'), + linter = require('../../lib/reporters/jshint'); + +exports['issue_182'] = { + setUp: function(done) { + done(); + }, + + 'look for ".jshintsrc" up the processed file hierarchy': function(test) { + + var file = "test/fixtures/issue_182.js", + source = fs.readFileSync(file).toString().trim(), + options = {}, + reportInfo = { + file : 'test/fixtures/issue_182.js', + fileShort : '', + fileSafe : '', + link : '' + }, + report; + + report = linter.process(source, options, reportInfo); + test.equal(report.messages.length, 1, "a maxparams error should occur"); + + report = linter.process(source, options, {}); + test.equal(report.messages.length, 0, "no error"); + + test.done(); + } +}; diff --git a/test/issues/issue_217_test.js b/test/issues/issue_217_test.js new file mode 100644 index 00000000..18123a0e --- /dev/null +++ b/test/issues/issue_217_test.js @@ -0,0 +1,27 @@ +'use strict'; + +var fs = require('fs-extra'), + linter = require('../../lib/reporters/jshint'); + +exports['issue_217'] = { + setUp: function(done) { + done(); + }, + + 'expect async/await supported in jshint': function(test) { + + var file = "test/fixtures/issue_217.js", + source = fs.readFileSync(file).toString().trim(), + options = require('../fixtures/.jshintrc.json'), + config = { + options: Object.assign(options, { + "esversion": 8, + "unused": false + }) + }, + report = linter.process(source, config, {}); + + test.equal(report.messages.length, 0, "Report returned with messages"); + test.done(); + } +}; diff --git a/test/logger_test.js b/test/logger_test.js new file mode 100644 index 00000000..fc7a8700 --- /dev/null +++ b/test/logger_test.js @@ -0,0 +1,133 @@ +'use strict'; +var Logger = require('../lib/logger'); + +exports['logger'] = { + setUp: function(done) { + // setup here + this._console = console; + console = { + msg: {}, + trace: function(msg) { + this.msg.trace = msg; + }, + log: function(msg) { + this.msg.log = msg; + }, + info: function(msg) { + this.msg.info = msg; + }, + warn: function(msg) { + this.msg.warn = msg; + }, + error: function(msg) { + this.msg.error = msg; + } + }; + done(); + }, + tearDown: function (done) { + // clean up + console = this._console; + done(); + }, + 'TRACE LEVEL': function(test) { + var message = "called"; + var log = new Logger(Logger.TRACE); + + test.expect(5); + + log.trace(message); + log.debug(message); + log.info(message); + log.warning(message); + log.error(message); + + test.equal(console.msg.trace, message, 'should trace message'); + test.equal(console.msg.log, message, 'should log message'); + test.equal(console.msg.info, message, 'should info message'); + test.equal(console.msg.warn, message, 'should warn message'); + test.equal(console.msg.error, message, 'should error message'); + + test.done(); + }, + 'DEBUG LEVEL': function(test) { + var message = "called"; + var log = new Logger(Logger.DEBUG); + + test.expect(5); + + log.trace(message); + log.debug(message); + log.info(message); + log.warning(message); + log.error(message); + + test.equal(console.msg.trace, undefined, 'should not trace message'); + test.equal(console.msg.log, message, 'should log message'); + test.equal(console.msg.info, message, 'should info message'); + test.equal(console.msg.warn, message, 'should warn message'); + test.equal(console.msg.error, message, 'should error message'); + + test.done(); + }, + 'INFO LEVEL': function(test) { + var message = "called"; + var log = new Logger(Logger.INFO); + + test.expect(5); + + log.trace(message); + log.debug(message); + log.info(message); + log.warning(message); + log.error(message); + + test.equal(console.msg.trace, undefined, 'should not trace message'); + test.equal(console.msg.log, undefined, 'should not log message'); + test.equal(console.msg.info, message, 'should info message'); + test.equal(console.msg.warn, message, 'should warn message'); + test.equal(console.msg.error, message, 'should error message'); + + test.done(); + }, + 'WARNING LEVEL': function(test) { + var message = "called"; + var log = new Logger(Logger.WARNING); + + test.expect(5); + + log.trace(message); + log.debug(message); + log.info(message); + log.warning(message); + log.error(message); + + test.equal(console.msg.trace, undefined, 'should not trace message'); + test.equal(console.msg.log, undefined, 'should not log message'); + test.equal(console.msg.info, undefined, 'should not info message'); + test.equal(console.msg.warn, message, 'should warn message'); + test.equal(console.msg.error, message, 'should error message'); + + test.done(); + }, + 'ERROR LEVEL': function(test) { + var message = "called"; + var log = new Logger(Logger.ERROR); + + test.expect(5); + + log.trace(message); + log.debug(message); + log.info(message); + log.warning(message); + log.error(message); + + test.equal(console.msg.trace, undefined, 'should not trace message'); + test.equal(console.msg.log, undefined, 'should not log message'); + test.equal(console.msg.info, undefined, 'should not info message'); + test.equal(console.msg.warn, undefined, 'should not warn message'); + test.equal(console.msg.error, message, 'should error message'); + + test.done(); + } +}; diff --git a/test/model_filehistory_test.js b/test/model_filehistory_test.js index 05b8f077..e56188e0 100644 --- a/test/model_filehistory_test.js +++ b/test/model_filehistory_test.js @@ -32,10 +32,10 @@ exports['FileHistory'] = { var newReport = require('./fixtures/model_history.json'); history.addReport(newReport); - test.equal(history[0].sloc, newReport.complexity.methodAggregate.sloc.physical); - test.equal(history[0].lloc, newReport.complexity.methodAggregate.sloc.logical); - test.equal(history[0].deliveredBugs, newReport.complexity.methodAggregate.halstead.bugs); - test.equal(history[0].difficulty, newReport.complexity.methodAggregate.halstead.difficulty); + test.equal(history[0].sloc, newReport.complexity.aggregate.sloc.physical); + test.equal(history[0].lloc, newReport.complexity.aggregate.sloc.logical); + test.equal(history[0].deliveredBugs, newReport.complexity.aggregate.halstead.bugs); + test.equal(history[0].difficulty, newReport.complexity.aggregate.halstead.difficulty); test.equal(history[0].maintainability, newReport.complexity.maintainability); test.equal(history[0].functions, newReport.complexity.methods.length); test.equal(history[0].lintErrors, newReport.jshint.messages.length); diff --git a/test/plato_test.js b/test/plato_test.js index 202d939b..755a3a09 100644 --- a/test/plato_test.js +++ b/test/plato_test.js @@ -49,7 +49,7 @@ exports['plato'] = { var files = './test/fixtures/*.js'; plato.inspect(files, null, {}, function(reports) { - test.equal(reports.length, 7, 'Should properly test against the array produced by the glob'); + test.equal(reports.length, 9, 'Should properly test against the array produced by the glob'); test.done(); }); }, @@ -141,5 +141,115 @@ exports['plato'] = { test.ok(overview.summary.total.jshint === 4, 'Should contain total jshint issues'); test.done(); }); + }, + + 'should run eslint with config file' : function(test) { + // #166 test-case + var options = { + eslint: 'test/fixtures/.eslintrc.json' + }; + var files = [ + 'test/fixtures/a.js', + 'test/fixtures/b.js' + ]; + + test.expect(1); + + plato.inspect(files, null, options, function(reports) { + var overview = plato.getOverviewReport(reports); + test.ok(overview.summary.total.jshint === 8, 'Should contain total eslint issues'); + test.done(); + }); + }, + + 'should run eslint with config object' : function(test) { + // #211 test-case + var options = { + eslint: require('./fixtures/.eslintrc.json') + }; + var files = [ + 'test/fixtures/a.js', + 'test/fixtures/b.js' + ]; + + test.expect(1); + + plato.inspect(files, null, options, function(reports) { + var overview = plato.getOverviewReport(reports); + test.ok(overview.summary.total.jshint === 8, 'Should contain total eslint issues'); + test.done(); + }); + }, + + 'test extensions option that default value is .js' : function(test) { + var options = { + eslint: 'test/fixtures/.eslintrc.json' + }; + var files = [ + 'test/fixtures/c-es6.js' + ]; + + test.expect(1); + + plato.inspect(files, null, options, function(reports) { + var overview = plato.getOverviewReport(reports); + test.ok(overview.summary.total.jshint === 1, 'Should contain total eslint issues'); + test.done(); + }); + }, + + 'test extensions option with .es' : function(test) { + var options = { + extensions: [".es"], + eslint: 'test/fixtures/.eslintrc.json' + }; + var files = [ + 'test/fixtures/c-es6.es' + ]; + + test.expect(1); + + plato.inspect(files, null, options, function(reports) { + var overview = plato.getOverviewReport(reports); + test.ok(overview.summary.total.jshint === 1, 'Should contain total eslint issues'); + test.done(); + }); + }, + + 'test extensions option with empty string' : function(test) { + var options = { + extensions: [""], + eslint: 'test/fixtures/.eslintrc.json' + }; + var files = [ + 'test/fixtures/c-es6' + ]; + + test.expect(1); + + plato.inspect(files, null, options, function(reports) { + var overview = plato.getOverviewReport(reports); + test.ok(overview.summary.total.jshint === 1, 'Should contain total eslint issues'); + test.done(); + }); + }, + + 'test extensions option with multi values' : function(test) { + var options = { + extensions: [".es", ".js"], + eslint: 'test/fixtures/.eslintrc.json' + }; + var files = [ + 'test/fixtures/c-es6.es', + 'test/fixtures/c-es6.js' + ]; + + test.expect(1); + + plato.inspect(files, null, options, function(reports) { + var overview = plato.getOverviewReport(reports); + test.ok(overview.summary.total.jshint === 2, 'Should contain total eslint issues'); + test.done(); + }); } }; diff --git a/test/util_test.js b/test/util_test.js index 27fa2760..85848585 100644 --- a/test/util_test.js +++ b/test/util_test.js @@ -35,7 +35,7 @@ exports['util'] = { // Store value of current path separator (environment-specific) var sep = path.sep; - test.expect(6); + test.expect(7); // Explicitly set path for OSX/*nix environment path prefixing path.sep = '/'; @@ -71,6 +71,10 @@ exports['util'] = { ]; test.equal(util.findCommonBase(files), '', 'should not find a prefix for files in the current directory'); + files = []; + test.equal(util.findCommonBase(files), '', 'should not cause an error for no files'); + + // Explicitly set path for Windows environment path prefixing path.sep = '\\';