Comparing version 0.0.6 to 0.0.7
#!/usr/bin/env node | ||
(function (program, logDriver, util, lib, getGitData, Q) { | ||
(function (program, logger, util, lib, getGitData, Q) { | ||
'use strict'; | ||
@@ -7,11 +7,14 @@ process.stdin.resume(); | ||
var input = ''; | ||
var input = '', | ||
loggerImpl; | ||
process.stdin.on('data', function (chunk) { | ||
input += chunk; | ||
logDriver.logger.trace('Got chunk'); | ||
if (loggerImpl) { | ||
loggerImpl.trace('Got chunk'); | ||
} | ||
}); | ||
program | ||
.version('0.0.6') | ||
.version('0.0.7') | ||
.usage('[options]') | ||
@@ -26,3 +29,3 @@ .option('-f, --format [value]', 'Coverage input format') | ||
logDriver({ | ||
loggerImpl = logger({ | ||
verbose: program.verbose, | ||
@@ -32,6 +35,6 @@ debug: program.debug | ||
logDriver.logger.info(util.format('Started with: token [%j], commitId [%j], endpoint [%j], format [%j], verbose [%j], debug [%j]', program.token, program.commit, program.endpoint, program.format, program.verbose, program.debug)); | ||
loggerImpl.info(util.format('Started with: token [%j], commitId [%j], endpoint [%j], format [%j], verbose [%j], debug [%j]', program.token, program.commit, program.endpoint, program.format, program.verbose, program.debug)); | ||
process.stdin.on('end', function () { | ||
logDriver.logger.trace('Received file through stdin'); | ||
loggerImpl.trace('Received file through stdin'); | ||
@@ -46,17 +49,23 @@ if (program.help === true) { | ||
if (!token) { | ||
return loggerImpl.error(new Error('Token is required')); | ||
} | ||
// Parse the coverage data for the given format and retrieve the commit id if we don't have it. | ||
return Q.all([lib.getParser(format).parse(input), getGitData.getCommitId(commitId)]).spread(function (parsedCoverage, commitId) { | ||
logDriver.logger.trace(parsedCoverage); | ||
// Now that we've parse the coverage data to the correct format, send it to Codacy. | ||
loggerImpl.trace(parsedCoverage); | ||
lib.reporter({ | ||
endpoint: program.endpoint | ||
}).sendCoverage(token, commitId, parsedCoverage).then(function () { | ||
logDriver.logger.debug('Successfully sent coverage'); | ||
loggerImpl.debug('Successfully sent coverage'); | ||
}, function (err) { | ||
logDriver.logger.error('Error sending coverage'); | ||
logDriver.logger.error(err); | ||
loggerImpl.error('Error sending coverage'); | ||
loggerImpl.error(err); | ||
}); | ||
}, function (err) { | ||
logDriver.logger.error(err); | ||
loggerImpl.error(err); | ||
}); | ||
}); | ||
}(require('commander'), require('log-driver'), require('util'), require('../index'), require('../lib/getGitData'), require('q'))); | ||
}(require('commander'), require('../lib/logger'), require('util'), require('../index'), require('../lib/getGitData'), require('q'))); |
@@ -1,7 +0,8 @@ | ||
(function (parser, reporter) { | ||
(function (parser, reporter, getGitData) { | ||
'use strict'; | ||
module.exports = { | ||
getParser: parser.getParser, | ||
reporter: reporter | ||
reporter: reporter, | ||
getGitData: getGitData | ||
}; | ||
}(require('./lib/coverageParser'), require('./lib/reporter'))); | ||
}(require('./lib/coverageParser'), require('./lib/reporter'), require('./lib/getGitData'))); |
@@ -15,12 +15,6 @@ (function (Joi, util, logger) { | ||
try { | ||
logger.debug('Creating coverage parser for: ' + coverageFormat); | ||
return require('./impl/' + coverageFormat); | ||
} catch (err) { | ||
logger.error('Error creating coverage parser for: ' + coverageFormat); | ||
logger.error(err); | ||
throw err; | ||
} | ||
logger.debug('Creating coverage parser for: ' + coverageFormat); | ||
return require('./impl/' + coverageFormat); | ||
} | ||
}; | ||
}(require('joi'), require('util'), require('log-driver').logger)); | ||
}(require('joi'), require('util'), require('./logger')())); |
@@ -31,2 +31,2 @@ (function (logger, exec, Q) { | ||
}; | ||
}(require('log-driver').logger, require('child_process').exec, require('q'))); | ||
}(require('./logger')(), require('child_process').exec, require('q'))); |
@@ -1,4 +0,4 @@ | ||
(function (lcovParse, Q, Joi, logger) { | ||
(function (lcovParse, Q, Joi, logger, path) { | ||
'use strict'; | ||
var lcovStringValidation = Joi.string(), | ||
var lcovStringValidation = Joi.string().required(), | ||
optionsValidation = Joi.object().keys().optional(); | ||
@@ -10,6 +10,2 @@ module.exports = { | ||
process.nextTick(function () { | ||
if (!lcovString) { | ||
return deferred.reject(new Error('Coverage data required')); | ||
} | ||
var validLcov = Joi.validate(lcovString, lcovStringValidation), | ||
@@ -28,2 +24,4 @@ validOptions = Joi.validate(options, optionsValidation, { | ||
if (err) { | ||
err = new Error(err); | ||
logger.error(err); | ||
@@ -43,23 +41,31 @@ return deferred.reject(err); | ||
var fileStats = { | ||
filename: stats.file, | ||
// The API expects the filenames to be relative to the project, ex. codacy/lib/reporter.js | ||
filename: stats.file ? path.relative(process.cwd() + '/..', stats.file) : '', | ||
coverage: {} | ||
}; | ||
if (stats.lines) { | ||
totalLines += stats.lines.found; | ||
totalHits += stats.lines.hit; | ||
totalLines += stats.lines.found; | ||
totalHits += stats.lines.hit; | ||
fileStats.total = Math.floor((stats.lines.hit / stats.lines.found) * 100); | ||
// The API uses integers only, so convert accordingly. | ||
fileStats.total = Math.floor((stats.lines.hit / stats.lines.found) * 100); | ||
//TODO: Convert to reduce function | ||
stats.lines.details.forEach(function (detail) { | ||
//TODO: Convert to reduce function | ||
stats.lines.details.forEach(function (detail) { | ||
// If a line is not sent to the service then it is considered to be 0, so no need to be redundant in the payload. | ||
// We also can't have a negative number of hits on a line, so exclude those. | ||
if (detail.hit >= 1) { | ||
fileStats.coverage[detail.line] = detail.hit; | ||
}); | ||
} | ||
} | ||
}); | ||
logger.trace('Successfully parsed ' + stats.file); | ||
result.fileReports.push(fileStats); | ||
}); | ||
// The API uses integers only, so convert accordingly. | ||
result.total = Math.floor((totalHits / totalLines) * 100); | ||
logger.debug('Successfully Parsed Lcov Data'); | ||
deferred.resolve(result); | ||
@@ -71,2 +77,2 @@ }); | ||
}; | ||
}(require('lcov-parse'), require('q'), require('joi'), require('log-driver').logger)); | ||
}(require('lcov-parse'), require('q'), require('joi'), require('../logger')(), require('path'))); |
(function (logDriver) { | ||
'use strict'; | ||
var logger; | ||
module.exports = function SetupLogger(options) { | ||
return logDriver({level: getLogLevel(options)}); | ||
if (options || !logger) { | ||
options = options || {}; | ||
logger = logDriver({level: getLogLevel(options)}); | ||
return logger; | ||
} else { | ||
return logDriver.logger; | ||
} | ||
}; | ||
function getLogLevel(options) { | ||
var logLevel = 'error'; | ||
var logLevel = 'warn'; | ||
@@ -19,3 +28,3 @@ if (options.verbose) { | ||
// Environment variables don't override options passed in. | ||
if (logLevel === 'error') { | ||
if (logLevel === 'warn') { | ||
if (process.env.CODACY_VERBOSE) { | ||
@@ -26,3 +35,3 @@ logLevel = 'debug'; | ||
if (process.env.CODACY_DEBUG) { | ||
logLevel = 'debug'; | ||
logLevel = 'trace'; | ||
} | ||
@@ -29,0 +38,0 @@ } |
@@ -14,3 +14,3 @@ (function (request, Joi, Q, util, logger) { | ||
total: Joi.number().integer().required().min(0).max(100), | ||
coverage: Joi.object().pattern(/\d/, Joi.number().integer().min(0)) | ||
coverage: Joi.object().pattern(/\d/, Joi.number().integer().min(1)) | ||
}).optional()) | ||
@@ -62,5 +62,3 @@ }).example({total: 50, fileReports: [{filename: 'filename', total: 10, coverage: {1: 1, 2: 3}}]}); | ||
var err = new Error(util.format('Expected Status Code of 200, but got [%s]', res.statusCode)); | ||
err.response = res; | ||
err.body = res.body; | ||
logger.error(res); | ||
logger.error(util.format('Status Code [%s] - Error [%j]', res.statusCode, res.error)); | ||
return deferred.reject(err); | ||
@@ -80,2 +78,2 @@ } | ||
}; | ||
}(require('request-promise'), require('joi'), require('q'), require('util'), require('log-driver').logger)); | ||
}(require('request-promise'), require('joi'), require('q'), require('util'), require('./logger')())); |
{ | ||
"name": "codacy", | ||
"version": "0.0.6", | ||
"description": "Code Coverage reporter for Codacy", | ||
"version": "0.0.7", | ||
"description": "Code Coverage reporter for Codacy.com", | ||
"keywords": [ | ||
@@ -36,8 +36,8 @@ "codacy", | ||
"dependencies": { | ||
"commander": "^2.6.0", | ||
"commander": "^2.x", | ||
"joi": "^5.x", | ||
"lcov-parse": "0.0.8", | ||
"log-driver": "^1.2.5", | ||
"q": "^1.1.x", | ||
"request-promise": "^0.3.x" | ||
"lcov-parse": "0.x", | ||
"log-driver": "^1.x", | ||
"q": "^1.x", | ||
"request-promise": "^0.x" | ||
}, | ||
@@ -51,3 +51,3 @@ "devDependencies": { | ||
"mocha": "^2.x", | ||
"nock": "^0.57.0", | ||
"nock": "^0.x", | ||
"istanbul": "^0.x", | ||
@@ -54,0 +54,0 @@ "jscs": "^1.x", |
@@ -1,8 +0,12 @@ | ||
# codacy | ||
Code Coverage reporter for Codacy | ||
# Codacy | ||
[Codacy](https://codacy.com/) support for Node.js. Get coverage reporting and code analysis for Node.js from Codacy. | ||
[![Build Status](https://travis-ci.org/DavidTPate/codacy.svg?branch=master)](https://travis-ci.org/DavidTPate/codacy) | ||
[![npm](https://img.shields.io/npm/v/codacy.svg)](https://www.npmjs.com/package/codacy) | ||
[![npm](https://img.shields.io/npm/dm/codacy.svg)](https://www.npmjs.com/package/codacy) | ||
[![Codacy](https://www.codacy.com/project/badge/d1bfdf020cc044bb8a2020d009378733)](https://www.codacy.com/public/davidtpate/codacy) | ||
[![David](https://img.shields.io/david/DavidTPate/codacy.svg)](https://david-dm.org/DavidTPate/codacy) | ||
[![David](https://img.shields.io/david/dev/DavidTPate/codacy.svg)](https://david-dm.org/DavidTPate/codacy) | ||
[![David](https://img.shields.io/david/peer/DavidTPate/codacy.svg)](https://david-dm.org/DavidTPate/codacy) | ||
[Codacy](https://codacy.com/) support for Node.js. Get coverage reporting and code analysis for Node.js from Codacy. | ||
##Installation: | ||
@@ -9,0 +13,0 @@ Add the latest version of `codacy` to your package.json: |
@@ -84,3 +84,3 @@ (function (chai, Q, exec, Joi, parser, helper) { | ||
helper.setupMockEndpoint('1234', '4321', Joi.compile(bodyObject)).then(function () { | ||
exec('cat ./test/mock/lcov.info | node ./bin/codacy.js --debug --token 1234 --commit 4321', function (err, res) { | ||
exec('cat ./test/mock/lcov.info | node ./bin/codacy.js --token 1234 --commit 4321', function (err, res) { | ||
if (err) { | ||
@@ -90,3 +90,3 @@ return done(err); | ||
expect(res).to.match(/Error: Expected Successful Status Code, but got \[404\]/); | ||
expect(res).to.match(/Status Code \[400\] - Error \[{"error":"Unauthorized request"}\]/); | ||
console.log(res); | ||
@@ -93,0 +93,0 @@ //nock.done(); //TODO: Need to figure out how to use nock here. Since it's a separate process, it's not tied together. |
@@ -23,4 +23,13 @@ (function (Joi, chai, Q, util, parser) { | ||
}); | ||
it('shouldn\'t be able to parse a blank coverage file for ' + format, function () { | ||
return expect(parser.getParser(format).parse()).to.eventually.be.rejectedWith(Error, 'value is required'); | ||
}); | ||
it('shouldn\'t be able to parse invalid coverage for ' + format, function () { | ||
return expect(parser.getParser(format).parse('There is no Dana, only Zuul')).to.eventually.be.rejectedWith(Error, 'Failed to parse string'); | ||
}); | ||
it('shouldn\'t be able to parse a non-existent coverage file for ' + format, function () { | ||
return expect(parser.getParser(format).parse('/no-exist/lcov')).to.eventually.be.rejectedWith(Error, 'Failed to parse string'); | ||
}); | ||
}); | ||
}); | ||
}(require('joi'), require('chai'), require('q'), require('util'), require('../lib/coverageParser'))); |
@@ -5,3 +5,6 @@ (function (Joi, chai, Q, fs, parser) { | ||
var expect = chai.expect, | ||
lcovData = fs.readFileSync(__dirname + '/mock/lcov.info').toString(); | ||
lcovData = fs.readFileSync(__dirname + '/mock/lcov.info').toString(), | ||
noStatsLcovData = fs.readFileSync(__dirname + '/mock/no-lines.info').toString(), | ||
nadaLcovData = fs.readFileSync(__dirname + '/mock/nada.info').toString(); | ||
chai.use(require('chai-as-promised')); | ||
@@ -19,3 +22,3 @@ chai.use(require('dirty-chai')); | ||
{ | ||
filename: '/Users/david.pate/Git/codacy-coverage/lib/reporter.js', | ||
filename: 'codacy/lib/reporter.js', | ||
coverage: { | ||
@@ -27,3 +30,2 @@ 1: 1, | ||
44: 3, | ||
45: 0, | ||
48: 3, | ||
@@ -36,3 +38,2 @@ 50: 3, | ||
63: 3, | ||
64: 0, | ||
67: 3, | ||
@@ -58,3 +59,35 @@ 73: 2, | ||
}); | ||
it('should be able to parse lcov data without lines', function () { | ||
return expect(parser.getParser('lcov').parse(noStatsLcovData)) | ||
.to.eventually.satisfy(function (data) { | ||
expect(JSON.stringify(data)).to.equal(JSON.stringify({ | ||
total: null, | ||
fileReports: [ | ||
{ | ||
filename: 'codacy/lib/reporter.js', | ||
coverage: {}, | ||
total: null | ||
} | ||
] | ||
})); | ||
return true; | ||
}); | ||
}); | ||
it('should be able to parse lcov data without anything', function () { | ||
return expect(parser.getParser('lcov').parse(nadaLcovData)) | ||
.to.eventually.satisfy(function (data) { | ||
expect(JSON.stringify(data)).to.equal(JSON.stringify({ | ||
total: null, | ||
fileReports: [ | ||
{ | ||
filename: '', | ||
coverage: {}, | ||
total: null | ||
} | ||
] | ||
})); | ||
return true; | ||
}); | ||
}); | ||
}); | ||
}(require('joi'), require('chai'), require('q'), require('fs'), require('../lib/coverageParser'))); |
@@ -10,3 +10,7 @@ (function (Joi, request, chai, Q, reporter, helper) { | ||
describe('Codacy Reporter', function () { | ||
var bodyValidator = Joi.object({ | ||
var bodyValidator, | ||
sampleCoverageData; | ||
beforeEach(function () { | ||
bodyValidator = Joi.object({ | ||
total: Joi.number().valid(50), | ||
@@ -21,3 +25,4 @@ fileReports: Joi.array().includes(Joi.object({ | ||
})) | ||
}), | ||
}); | ||
sampleCoverageData = { | ||
@@ -36,2 +41,3 @@ total: 50, | ||
}; | ||
}); | ||
@@ -52,6 +58,18 @@ it('should be able to use the mock end-point', function () { | ||
}); | ||
it('shouldn\'t be able to send coverage with 0 hits on a line', function () { | ||
sampleCoverageData.fileReports[0].coverage['3'] = 0; | ||
return expect(reporter({}) | ||
.sendCoverage('1234', '4321', sampleCoverageData)) | ||
.to.eventually.be.rejectedWith(Error, 'fileReports at position 0 fails because 3 must be larger than or equal to 1'); | ||
}); | ||
it('shouldn\'t be able to create a reporter with invalid options', function () { | ||
expect(function () { | ||
reporter({endpoint: 1}); | ||
}).to.throw(Error, 'endpoint must be a string'); | ||
}); | ||
it('should be able to use the reporter to send coverage data', function () { | ||
return helper.setupMockEndpoint('1234', '4321', bodyValidator) | ||
.then(function () { | ||
return expect(reporter({endpoint: 'https://www.codacy.com/api/coverage/:token/:commitId'}) | ||
return expect(reporter({}) | ||
.sendCoverage('1234', '4321', sampleCoverageData)) | ||
@@ -64,3 +82,3 @@ .to.eventually.be.fulfilled; | ||
.then(function () { | ||
return expect(reporter({endpoint: 'https://www.codacy.com/api/coverage/:token/:commitId'}) | ||
return expect(reporter({}) | ||
.sendCoverage('1234', '4321', sampleCoverageData)) | ||
@@ -73,3 +91,3 @@ .to.eventually.be.rejectedWith(Error, 'Expected Status Code of 200, but got [204]'); | ||
.then(function () { | ||
return expect(reporter({endpoint: 'https://www.codacy.com/api/coverage/:token/:commitId'}) | ||
return expect(reporter({}) | ||
.sendCoverage('1234', '4321', sampleCoverageData)) | ||
@@ -76,0 +94,0 @@ .to.eventually.be.rejectedWith(Error, 'Expected Successful Status Code, but got [418]'); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44563
27
695
75
33
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedlcov-parse@0.0.10(transitive)
+ Addedlodash@3.10.1(transitive)
+ Addedrequest-promise@0.4.3(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedsupports-color@2.0.0(transitive)
- Removedansi-regex@0.2.1(transitive)
- Removedansi-styles@1.1.0(transitive)
- Removedchalk@0.5.1(transitive)
- Removedhas-ansi@0.1.0(transitive)
- Removedlcov-parse@0.0.8(transitive)
- Removedlodash@2.4.2(transitive)
- Removedrequest-promise@0.3.3(transitive)
- Removedstrip-ansi@0.3.0(transitive)
- Removedsupports-color@0.2.0(transitive)
Updatedcommander@^2.x
Updatedlcov-parse@0.x
Updatedlog-driver@^1.x
Updatedq@^1.x
Updatedrequest-promise@^0.x