Initial commit

This commit is contained in:
WatermelonModders
2022-05-31 12:35:46 -04:00
commit fc5cb0c32c
4097 changed files with 447075 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
node_modules/
coverage/
lib-cov/
coverage.json
npm-debug.log
+1
View File
@@ -0,0 +1 @@
version: v1
+11
View File
@@ -0,0 +1,11 @@
language: node_js
node_js:
- "node"
- "iojs"
- "6.0"
- "5.0"
- "4.2"
- "0.12"
- "0.10"
script: make test-coveralls
sudo: false
+20
View File
@@ -0,0 +1,20 @@
REPORTER = spec
test:
@$(MAKE) lint
@echo TRAVIS_JOB_ID $(TRAVIS_JOB_ID)
@NODE_ENV=test ./node_modules/.bin/mocha -b --reporter $(REPORTER)
lint:
./node_modules/.bin/jshint ./lib ./test ./index.js
test-cov:
$(MAKE) lint
@NODE_ENV=test ./node_modules/.bin/istanbul cover \
./node_modules/mocha/bin/_mocha -- -R spec
test-coveralls:
@NODE_ENV=test ./node_modules/.bin/istanbul cover \
./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && \
cat ./coverage/lcov.info | ./bin/coveralls.js --verbose
.PHONY: test
+156
View File
@@ -0,0 +1,156 @@
#node-coveralls
[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Codeship Build Status][codeship-image]][codeship-url]
[![Known Vulnerabilities](https://snyk.io/test/github/nickmerwin/node-coveralls/badge.svg)](https://snyk.io/test/github/nickmerwin/node-coveralls)
[Coveralls.io](https://coveralls.io/) support for node.js. Get the great coverage reporting of coveralls.io and add a cool coverage button ( like the one above ) to your README.
Supported CI services: [travis-ci](https://travis-ci.org/), [codeship](https://www.codeship.io/), [circleci](https://circleci.com/), [jenkins](http://jenkins-ci.org/), [Gitlab CI](http://gitlab.com/)
##Installation:
Add the latest version of `coveralls` to your package.json:
```
npm install coveralls --save-dev
```
If you're using mocha, add `mocha-lcov-reporter` to your package.json:
```
npm install mocha-lcov-reporter --save-dev
```
##Usage:
This script ( `bin/coveralls.js` ) can take standard input from any tool that emits the lcov data format (including [mocha](http://mochajs.org/)'s [LCov reporter](https://npmjs.org/package/mocha-lcov-reporter)) and send it to coveralls.io to report your code coverage there.
Once your app is instrumented for coverage, and building, you need to pipe the lcov output to `./node_modules/coveralls/bin/coveralls.js`.
This library currently supports [travis-ci](https://travis-ci.org/) with no extra effort beyond piping the lcov output to coveralls. However, if you're using a different build system, there are a few environment variables that are necessary:
* COVERALLS_SERVICE_NAME (the name of your build system)
* COVERALLS_REPO_TOKEN (the secret repo token from coveralls.io)
There are optional environment variables for other build systems as well:
* COVERALLS_SERVICE_JOB_ID (an id that uniquely identifies the build job)
* COVERALLS_RUN_AT (a date string for the time that the job ran. RFC 3339 dates work. This defaults to your
build system's date/time if you don't set it.)
* COVERALLS_PARALLEL (more info here: https://coveralls.zendesk.com/hc/en-us/articles/203484329)
### [Mocha](http://mochajs.org/) + [Blanket.js](https://github.com/alex-seville/blanket)
- Install [blanket.js](http://blanketjs.org/)
- Configure blanket according to [docs](https://github.com/alex-seville/blanket/blob/master/docs/getting_started_node.md).
- Run your tests with a command like this:
```sh
NODE_ENV=test YOURPACKAGE_COVERAGE=1 ./node_modules/.bin/mocha \
--require blanket \
--reporter mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
```
### [Mocha](http://mochajs.org/) + [JSCoverage](https://github.com/fishbar/jscoverage)
Instrumenting your app for coverage is probably harder than it needs to be (read [here](http://www.seejohncode.com/2012/03/13/setting-up-mocha-jscoverage/)), but that's also a necessary step.
In mocha, if you've got your code instrumented for coverage, the command for a travis build would look something like this:
```sh
YOURPACKAGE_COVERAGE=1 ./node_modules/.bin/mocha test -R mocha-lcov-reporter | ./node_modules/coveralls/bin/coveralls.js
```
Check out an example [Makefile](https://github.com/cainus/urlgrey/blob/master/Makefile) from one of my projects for an example, especially the test-coveralls build target. Note: Travis runs `npm test`, so whatever target you create in your Makefile must be the target that `npm test` runs (This is set in package.json's 'scripts' property).
### [Istanbul](https://github.com/gotwarlost/istanbul)
**With Mocha:**
```sh
istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage
```
**With Jasmine:**
```sh
istanbul cover jasmine-node --captureExceptions spec/ && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage
```
### [Nodeunit](https://github.com/caolan/nodeunit) + [JSCoverage](https://github.com/fishbar/jscoverage)
Depend on nodeunit, jscoverage and coveralls:
```sh
npm install nodeunit jscoverage coveralls --save-dev
```
Add a coveralls script to "scripts" in your `package.json`:
```javascript
"scripts": {
"test": "nodeunit test",
"coveralls": "jscoverage lib && YOURPACKAGE_COVERAGE=1 nodeunit --reporter=lcov test | coveralls"
}
```
Ensure your app requires instrumented code when `process.env.YOURPACKAGE_COVERAGE` variable is defined.
Run your tests with a command like this:
```sh
npm run coveralls
```
For detailed instructions on requiring instrumented code, running on Travis and submitting to coveralls [see this guide](https://github.com/alanshaw/nodeunit-lcov-coveralls-example).
### [Poncho](https://github.com/deepsweet/poncho)
Client-side JS code coverage using [PhantomJS](https://github.com/ariya/phantomjs), [Mocha](http://mochajs.org/) and [Blanket](https://github.com/alex-seville/blanket):
- [Configure](http://visionmedia.github.io/mocha/#browser-support) Mocha for browser
- [Mark](https://github.com/deepsweet/poncho#usage) target script(s) with `data-cover` html-attribute
- Run your tests with a command like this:
```sh
./node_modules/.bin/poncho -R lcov test/test.html | ./node_modules/coveralls/bin/coveralls.js
```
### [Lab](https://github.com/hapijs/lab)
```sh
lab -r lcov | ./node_modules/.bin/coveralls
```
### [nyc](https://github.com/bcoe/nyc)
works with almost any testing framework. Simply execute
`npm test` with the `nyc` bin followed by running its reporter:
```
nyc npm test && nyc report --reporter=text-lcov | coveralls
```
### [TAP](https://github.com/isaacs/node-tap)
Simply run your tap tests with the `COVERALLS_REPO_TOKEN` environment
variable set and tap will automatically use `nyc` to report
coverage to coveralls.
### Command Line Parameters
Usage: coveralls.js [-v] filepath
#### Optional arguments:
-v, --verbose
filepath - optionally defines the base filepath of your source files.
## Running locally
If you're running locally, you must have a `.coveralls.yml` file, as documented in [their documentation](https://coveralls.io/docs/ruby), with your `repo_token` in it; or, you must provide a `COVERALLS_REPO_TOKEN` environment-variable on the command-line.
If you want to send commit data to coveralls, you can set the `COVERALLS_GIT_COMMIT` environment-variable to the commit hash you wish to reference. If you don't want to use a hash, you can set it to `HEAD` to supply coveralls with the latest commit data. This requires git to be installed and executable on the current PATH.
[travis-image]: https://travis-ci.org/nickmerwin/node-coveralls.svg?branch=master
[travis-url]: https://travis-ci.org/nickmerwin/node-coveralls
[codeship-image]: https://www.codeship.io/projects/de6fb440-dea9-0130-e7d9-122ca7ee39d3/status
[codeship-url]: https://www.codeship.io/projects/5622
[coveralls-image]: https://coveralls.io/repos/nickmerwin/node-coveralls/badge.svg?branch=master&service=github
[coveralls-url]: https://coveralls.io/github/nickmerwin/node-coveralls?branch=master
## Contributing
I generally don't accept pull requests that are untested, or break the build, because I'd like to keep the quality high (this is a coverage tool afterall!).
I also don't care for "soft-versioning" or "optimistic versioning" (dependencies that have ^, x, > in them, or anything other than numbers and dots). There have been too many problems with bad semantic versioning in dependencies, and I'd rather have a solid library than a bleeding edge one.
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env node
var handleInput = require('../lib/handleInput');
var logger = require('../lib/logger');
process.stdin.resume();
process.stdin.setEncoding('utf8');
var input = '';
process.stdin.on('data', function(chunk) {
input += chunk;
});
process.stdin.on('end', function() {
handleInput(input, function(err) {
if (err) {
throw err;
}
});
});
+131
View File
@@ -0,0 +1,131 @@
TN:
SF:/Users/deepsweet/Dropbox/projects/svgo/lib/svgo/config.js
FN:14,(anonymous_1)
FN:51,preparePluginsArray
FN:56,(anonymous_3)
FN:101,extendConfig
FN:108,(anonymous_5)
FN:115,(anonymous_6)
FN:161,optimizePluginsArray
FN:165,(anonymous_8)
FN:169,(anonymous_9)
FNF:9
FNH:9
FNDA:87,(anonymous_1)
FNDA:87,preparePluginsArray
FNDA:141,(anonymous_3)
FNDA:1,extendConfig
FNDA:3,(anonymous_5)
FNDA:84,(anonymous_6)
FNDA:87,optimizePluginsArray
FNDA:141,(anonymous_8)
FNDA:141,(anonymous_9)
DA:1,1
DA:3,1
DA:5,1
DA:14,1
DA:16,87
DA:18,87
DA:20,85
DA:22,85
DA:23,85
DA:24,85
DA:29,2
DA:31,2
DA:33,2
DA:34,1
DA:37,2
DA:41,87
DA:51,1
DA:53,87
DA:56,87
DA:59,141
DA:61,85
DA:62,85
DA:65,85
DA:66,0
DA:67,0
DA:70,85
DA:71,0
DA:74,85
DA:75,85
DA:78,85
DA:83,56
DA:84,56
DA:88,141
DA:101,1
DA:103,1
DA:106,1
DA:108,1
DA:111,3
DA:113,3
DA:115,3
DA:117,84
DA:119,3
DA:120,2
DA:121,2
DA:124,1
DA:125,1
DA:128,0
DA:129,0
DA:142,1
DA:143,0
DA:147,1
DA:148,0
DA:151,1
DA:161,1
DA:163,87
DA:165,87
DA:166,141
DA:169,87
DA:171,141
DA:172,44
DA:173,44
DA:176,97
DA:178,97
DA:182,87
LF:64
LH:57
BRDA:18,1,0,85
BRDA:18,1,1,2
BRDA:18,2,0,87
BRDA:18,2,1,86
BRDA:22,3,0,85
BRDA:22,3,1,0
BRDA:33,4,0,1
BRDA:33,4,1,1
BRDA:59,5,0,85
BRDA:59,5,1,56
BRDA:65,6,0,0
BRDA:65,6,1,85
BRDA:66,7,0,0
BRDA:66,7,1,0
BRDA:70,8,0,0
BRDA:70,8,1,85
BRDA:74,9,0,85
BRDA:74,9,1,0
BRDA:106,10,0,1
BRDA:106,10,1,0
BRDA:111,11,0,3
BRDA:111,11,1,0
BRDA:117,12,0,3
BRDA:117,12,1,81
BRDA:119,13,0,2
BRDA:119,13,1,1
BRDA:120,14,0,2
BRDA:120,14,1,1
BRDA:124,15,0,1
BRDA:124,15,1,0
BRDA:128,16,0,0
BRDA:128,16,1,0
BRDA:142,17,0,0
BRDA:142,17,1,1
BRDA:147,18,0,0
BRDA:147,18,1,1
BRDA:171,19,0,44
BRDA:171,19,1,97
BRDA:171,20,0,141
BRDA:171,20,1,54
BRF:40
BRH:27
end_of_record
+131
View File
@@ -0,0 +1,131 @@
TN:
SF:/Users/deepsweet/Dropbox/projects/svgo/node_modules/angular2-template-loader/index.js!/Users/deepsweet/Dropbox/projects/svgo/node_modules/tslint-loader/index.js!/Users/deepsweet/Dropbox/projects/svgo/lib/svgo/config.js
FN:14,(anonymous_1)
FN:51,preparePluginsArray
FN:56,(anonymous_3)
FN:101,extendConfig
FN:108,(anonymous_5)
FN:115,(anonymous_6)
FN:161,optimizePluginsArray
FN:165,(anonymous_8)
FN:169,(anonymous_9)
FNF:9
FNH:9
FNDA:87,(anonymous_1)
FNDA:87,preparePluginsArray
FNDA:141,(anonymous_3)
FNDA:1,extendConfig
FNDA:3,(anonymous_5)
FNDA:84,(anonymous_6)
FNDA:87,optimizePluginsArray
FNDA:141,(anonymous_8)
FNDA:141,(anonymous_9)
DA:1,1
DA:3,1
DA:5,1
DA:14,1
DA:16,87
DA:18,87
DA:20,85
DA:22,85
DA:23,85
DA:24,85
DA:29,2
DA:31,2
DA:33,2
DA:34,1
DA:37,2
DA:41,87
DA:51,1
DA:53,87
DA:56,87
DA:59,141
DA:61,85
DA:62,85
DA:65,85
DA:66,0
DA:67,0
DA:70,85
DA:71,0
DA:74,85
DA:75,85
DA:78,85
DA:83,56
DA:84,56
DA:88,141
DA:101,1
DA:103,1
DA:106,1
DA:108,1
DA:111,3
DA:113,3
DA:115,3
DA:117,84
DA:119,3
DA:120,2
DA:121,2
DA:124,1
DA:125,1
DA:128,0
DA:129,0
DA:142,1
DA:143,0
DA:147,1
DA:148,0
DA:151,1
DA:161,1
DA:163,87
DA:165,87
DA:166,141
DA:169,87
DA:171,141
DA:172,44
DA:173,44
DA:176,97
DA:178,97
DA:182,87
LF:64
LH:57
BRDA:18,1,0,85
BRDA:18,1,1,2
BRDA:18,2,0,87
BRDA:18,2,1,86
BRDA:22,3,0,85
BRDA:22,3,1,0
BRDA:33,4,0,1
BRDA:33,4,1,1
BRDA:59,5,0,85
BRDA:59,5,1,56
BRDA:65,6,0,0
BRDA:65,6,1,85
BRDA:66,7,0,0
BRDA:66,7,1,0
BRDA:70,8,0,0
BRDA:70,8,1,85
BRDA:74,9,0,85
BRDA:74,9,1,0
BRDA:106,10,0,1
BRDA:106,10,1,0
BRDA:111,11,0,3
BRDA:111,11,1,0
BRDA:117,12,0,3
BRDA:117,12,1,81
BRDA:119,13,0,2
BRDA:119,13,1,1
BRDA:120,14,0,2
BRDA:120,14,1,1
BRDA:124,15,0,1
BRDA:124,15,1,0
BRDA:128,16,0,0
BRDA:128,16,1,0
BRDA:142,17,0,0
BRDA:142,17,1,1
BRDA:147,18,0,0
BRDA:147,18,1,1
BRDA:171,19,0,44
BRDA:171,19,1,97
BRDA:171,20,0,141
BRDA:171,20,1,54
BRF:40
BRH:27
end_of_record
+172
View File
@@ -0,0 +1,172 @@
var nodeUrl = require('url');
var querystring = require('querystring');
var _ = require('underscore');
var UrlGrey = function(url){
this.url = url;
this._parsed = null;
};
UrlGrey.prototype.parsed = function(){
if (!this._parsed){
this._parsed = nodeUrl.parse(this.url);
var p = this._parsed;
if (p.protocol){
p.protocol = p.protocol.slice(0,-1);
} else {
p.protocol = 'http';
}
if (p.hash){
p.hash = p.hash.substring(1);
}
p.username = '';
p.password = '';
if (!p.hostname){
p.hostname = 'localhost';
}
if (!p.port){
p.port = 80;
} else {
p.port = parseInt(p.port, 10);
}
if (p.auth){
var auth = p.auth.split(':');
p.username = auth[0];
p.password = auth[1];
}
}
return this._parsed;
};
UrlGrey.prototype.query = function(mergeObject){
var path;
if (mergeObject === false){
// clear the query entirely if the input === false
return this.queryString('');
}
var url = this.url;
if (!mergeObject){
var parsed = nodeUrl.parse(url);
if (!!parsed.search){
var qstr = parsed.search.substring(1);
return querystring.parse(qstr);
}
return {};
} else {
// read the object out
var oldQuery = querystring.parse(this.queryString());
_.each(mergeObject, function(v, k){
if (v === null){
delete oldQuery[k];
} else {
oldQuery[k] = v;
}
});
var newString = querystring.stringify(oldQuery, '&', '=');
return this.queryString(newString);
}
};
addPropertyGetterSetter('protocol');
addPropertyGetterSetter('port');
addPropertyGetterSetter('username');
addPropertyGetterSetter('password');
addPropertyGetterSetter('hostname');
addPropertyGetterSetter('hash');
// add a method called queryString that manipulates 'query'
addPropertyGetterSetter('query', 'queryString');
addPropertyGetterSetter('pathname', 'path');
UrlGrey.prototype.path = function(){
var args = _.toArray(arguments);
if (args.length !== 0){
var obj = new UrlGrey(this.toString());
var str = _.flatten(args).join('/');
str = str.replace(/\/+/g, '/'); // remove double slashes
str = str.replace(/\/$/, ''); // remove all trailing slashes
if (str[0] !== '/'){ str = '/' + str; }
obj.parsed().pathname = str;
return obj;
}
return this.parsed().pathname;
};
UrlGrey.prototype.encode = function(str){
return querystring.escape(str);
};
UrlGrey.prototype.decode = function(str){
return querystring.unescape(str);
};
UrlGrey.prototype.parent = function(){
// read-only. (can't SET parent)
var pieces = this.path().split("/");
var popped = pieces.pop();
if (popped === ''){ // ignore trailing slash
pieces.pop();
}
return this.path(pieces.join("/"));
};
UrlGrey.prototype.child = function(suffix){
if (suffix){
suffix = encodeURIComponent(suffix);
return this.path(this.path(), suffix);
} else {
// if no suffix, return the child
var pieces = this.path().split("/");
var last = _.last(pieces);
if ((pieces.length > 1) && (last === '')){
// ignore trailing slashes
pieces.pop();
last = _.last(pieces);
}
return last;
}
};
UrlGrey.prototype.toJSON = function(){
return this.toString();
};
UrlGrey.prototype.toString = function(){
var p = this.parsed();
var userinfo = p.username + ':' + p.password;
var retval = this.protocol() + '://';
if (userinfo != ':'){
retval += userinfo + '@';
}
retval += p.hostname;
if (this.port() !== 80){
retval += ':' + this.port();
}
retval += this.path() === '/' ? '' : this.path();
var qs = this.queryString();
if (qs){
retval += '?' + qs;
}
if (p.hash){
retval += '#' + p.hash;
}
return retval;
};
module.exports = function(url){ return new UrlGrey(url); };
function addPropertyGetterSetter(propertyName, methodName){
if (!methodName){
methodName = propertyName;
}
UrlGrey.prototype[methodName] = function(str){
if (!!str || str === ''){
var obj = new UrlGrey(this.toString());
obj.parsed()[propertyName] = str;
return obj;
}
return this.parsed()[propertyName];
};
}
+116
View File
@@ -0,0 +1,116 @@
make[1]: Entering directory `/home/cainus/urlgrey'
SF:index.js
DA:1,1
DA:2,1
DA:3,1
DA:5,1
DA:6,66
DA:7,66
DA:10,1
DA:11,323
DA:12,63
DA:13,63
DA:14,63
DA:15,60
DA:17,3
DA:19,63
DA:20,32
DA:22,63
DA:23,63
DA:24,63
DA:25,3
DA:27,63
DA:28,60
DA:30,3
DA:32,63
DA:33,27
DA:34,27
DA:35,27
DA:38,323
DA:41,1
DA:42,5
DA:43,5
DA:45,2
DA:48,3
DA:49,3
DA:50,1
DA:51,1
DA:52,1
DA:53,1
DA:55,0
DA:58,2
DA:59,2
DA:60,2
DA:61,0
DA:63,2
DA:66,2
DA:67,2
DA:72,1
DA:73,1
DA:74,1
DA:75,1
DA:76,1
DA:77,1
DA:79,1
DA:80,1
DA:82,1
DA:83,87
DA:84,87
DA:85,6
DA:86,6
DA:87,6
DA:88,6
DA:89,9
DA:90,6
DA:91,6
DA:93,81
DA:97,1
DA:98,1
DA:101,1
DA:102,1
DA:105,1
DA:107,2
DA:108,2
DA:109,2
DA:110,1
DA:112,2
DA:115,1
DA:116,3
DA:117,1
DA:118,1
DA:121,2
DA:122,2
DA:123,2
DA:125,1
DA:126,1
DA:128,2
DA:132,1
DA:133,1
DA:136,1
DA:137,50
DA:138,50
DA:139,50
DA:140,50
DA:141,20
DA:143,50
DA:144,50
DA:145,2
DA:147,50
DA:148,50
DA:149,50
DA:150,31
DA:152,50
DA:153,24
DA:155,50
DA:210,40
DA:212,1
DA:213,8
DA:214,6
DA:216,8
DA:217,186
DA:218,21
DA:219,21
DA:220,21
DA:222,165
end_of_record
make[1]: Leaving directory `/home/cainus/urlgrey'
+16
View File
@@ -0,0 +1,16 @@
var minimist = require('minimist');
// this needs to go before the other require()s so that
// the other files can already use index.options
exports.options = minimist(process.argv.slice(2), {
boolean: ['verbose', 'stdout'],
alias: { 'v': 'verbose', 's': 'stdout' }
});
var dir = './lib/';
exports.convertLcovToCoveralls = require(dir + 'convertLcovToCoveralls');
exports.sendToCoveralls = require(dir + 'sendToCoveralls');
exports.getBaseOptions = require(dir + 'getOptions').getBaseOptions;
exports.getOptions = require(dir + 'getOptions').getOptions;
exports.handleInput = require(dir + 'handleInput');
exports.logger = require(dir + 'logger');
+133
View File
@@ -0,0 +1,133 @@
var TRAVIS_JOB_ID = process.env.TRAVIS_JOB_ID || 'unknown';
var fs = require('fs');
var lcovParse = require('lcov-parse');
var path = require('path');
var logger = require('./logger')();
var detailsToCoverage = function(length, details){
var coverage = new Array(length);
details.forEach(function(obj){
coverage[obj.line - 1] = obj.hit;
});
return coverage;
};
var convertLcovFileObject = function(file, filepath){
var rootpath = filepath;
filepath = path.resolve(rootpath, file.file);
var source = fs.readFileSync(filepath, 'utf8');
var lines = source.split("\n");
var coverage = detailsToCoverage(lines.length, file.lines.details);
return { name : path.relative(rootpath, path.resolve(rootpath, file.file)).split( path.sep ).join( "/" ),
source : source,
coverage : coverage };
};
var cleanFilePath = function(file) {
if (file.indexOf('!') > -1) {
var regex = /^(.*!)(.*)$/g;
var matches = regex.exec(file);
return matches[matches.length-1];
}
return file;
};
var convertLcovToCoveralls = function(input, options, cb){
var filepath = options.filepath || '';
logger.debug("in: ", filepath);
filepath = path.resolve(process.cwd(), filepath);
lcovParse(input, function(err, parsed){
if (err){
logger.error("error from lcovParse: ", err);
logger.error("input: ", input);
return cb(err);
}
var postJson = {
source_files : []
};
if (options.git){
postJson.git = options.git;
}
if (options.run_at){
postJson.run_at = options.run_at;
}
if (options.service_name){
postJson.service_name = options.service_name;
}
if (options.service_job_id){
postJson.service_job_id = options.service_job_id;
}
if (options.service_pull_request) {
postJson.service_pull_request = options.service_pull_request;
}
if (options.repo_token) {
postJson.repo_token = options.repo_token;
}
if (options.parallel) {
postJson.parallel = options.parallel;
}
if (options.service_pull_request) {
postJson.service_pull_request = options.service_pull_request;
}
parsed.forEach(function(file){
file.file = cleanFilePath(file.file);
var currentFilePath = path.resolve(filepath, file.file);
if (fs.existsSync(currentFilePath)) {
postJson.source_files.push(convertLcovFileObject(file, filepath));
}
});
return cb(null, postJson);
});
};
module.exports = convertLcovToCoveralls;
/* example coveralls json file
{
"service_job_id": "1234567890",
"service_name": "travis-ci",
"source_files": [
{
"name": "example.rb",
"source": "def four\n 4\nend",
"coverage": [null, 1, null]
},
{
"name": "two.rb",
"source": "def seven\n eight\n nine\nend",
"coverage": [null, 1, 0, null]
}
]
}
example output from lcov parser:
[
{
"file": "index.js",
"lines": {
"found": 0,
"hit": 0,
"details": [
{
"line": 1,
"hit": 1
},
{
"line": 2,
"hit": 1
},
{
"line": 3,
"hit": 1
},
{
"line": 5,
"hit": 1
},
*/
+28
View File
@@ -0,0 +1,28 @@
var fs = require('fs');
var path = require('path');
// branch naming only has a few excluded characters, see git-check-ref-format(1)
var REGEX_BRANCH = /^ref: refs\/heads\/([^?*\[\\~^:]+)$/;
module.exports = function detectLocalGit() {
var dir = process.cwd(), gitDir;
while (path.resolve('/') !== dir) {
gitDir = path.join(dir, '.git');
var existsSync = fs.existsSync || path.existsSync;
if (existsSync(path.join(gitDir, 'HEAD')))
break;
dir = path.dirname(dir);
}
if (path.resolve('/') === dir)
return;
var head = fs.readFileSync(path.join(dir, '.git', 'HEAD'), 'utf-8').trim();
var branch = (head.match(REGEX_BRANCH) || [])[1];
if (!branch)
return { git_commit: head };
var commit = fs.readFileSync(path.join(dir, '.git', 'refs', 'heads', branch), 'utf-8').trim();
return { git_commit: commit, git_branch: branch };
};
+108
View File
@@ -0,0 +1,108 @@
var exec = require('child_process').exec;
var logger = require('./logger')();
function fetchGitData(git, cb) {
if (!cb){
throw new Error("fetchGitData requires a callback");
}
//-- Malformed/undefined git object
if ('undefined' === typeof git) {
return cb(new Error('No options passed'));
}
if (!git.hasOwnProperty('head')) {
return cb(new Error('You must provide the head'));
}
if (!git.head.hasOwnProperty('id')) {
return cb(new Error('You must provide the head.id'));
}
//-- Set required properties of git if they weren"t provided
if (!git.hasOwnProperty("branch")) {
git.branch = "";
}
if (!git.hasOwnProperty("remotes")) {
git.remotes = [];
}
//-- Assert the property types
if ("string" !== typeof git.branch) {
git.branch = "";
}
if (!(git.remotes instanceof Array)) {
git.remotes = [];
}
//-- Use git?
exec("git rev-parse --verify " + git.head.id, function(err, response){
if (err){
// git is not available...
git.head.author_name = git.head.author_name || "Unknown Author";
git.head.author_email = git.head.author_email || "";
git.head.committer_name = git.head.committer_name || "Unknown Committer";
git.head.committer_email = git.head.committer_email || "";
git.head.message = git.head.message || "Unknown Commit Message";
return cb(null, git);
}
fetchHeadDetails(git, cb);
});
}
function fetchBranch(git, cb) {
exec("git branch", function(err, branches){
if (err)
return cb(err);
git.branch = (branches.match(/^\* (\w+)/) || [])[1];
fetchRemotes(git, cb);
});
}
var REGEX_COMMIT_DETAILS = /\nauthor (.+?) <([^>]*)>.+\ncommitter (.+?) <([^>]*)>.+[\S\s]*?\n\n(.*)/m;
function fetchHeadDetails(git, cb) {
exec('git cat-file -p ' + git.head.id, function(err, response) {
if (err)
return cb(err);
var items = response.match(REGEX_COMMIT_DETAILS).slice(1);
var fields = ['author_name', 'author_email', 'committer_name', 'committer_email', 'message'];
fields.forEach(function(field, index) {
git.head[field] = items[index];
});
if (git.branch) {
fetchRemotes(git, cb);
} else {
fetchBranch(git, cb);
}
});
}
function fetchRemotes(git, cb) {
exec("git remote -v", function(err, remotes){
if (err)
return cb(err);
var processed = {};
remotes.split("\n").forEach(function(remote) {
if (!/\s\(push\)$/.test(remote))
return;
remote = remote.split(/\s+/);
saveRemote(processed, git, remote[0], remote[1]);
});
cb(null, git);
});
}
function saveRemote(processed, git, name, url) {
var key = name + "-" + url;
if (processed.hasOwnProperty(key))
return;
processed[key] = true;
git.remotes.push({ name: name, url: url });
}
module.exports = fetchGitData;
+177
View File
@@ -0,0 +1,177 @@
var fs = require('fs');
var path = require('path');
var yaml = require('js-yaml');
var index = require('../index');
var logger = require('./logger')();
var fetchGitData = require('./fetchGitData');
var getBaseOptions = function(cb){
var options = {};
var git_commit = process.env.COVERALLS_GIT_COMMIT;
var git_branch = process.env.COVERALLS_GIT_BRANCH;
var git_committer_name, git_committer_email, git_message;
var match = (process.env.CI_PULL_REQUEST || "").match(/(\d+)$/);
if (match) {
options.service_pull_request = match[1];
}
if (process.env.TRAVIS){
options.service_name = 'travis-ci';
options.service_job_id = process.env.TRAVIS_JOB_ID;
git_commit = 'HEAD';
git_branch = process.env.TRAVIS_BRANCH;
}
/*
if (process.env.DRONE){
options.service_name = 'drone';
options.service_job_id = process.env.DRONE_BUILD_NUMBER;
git_commit = process.env.DRONE_COMMIT;
git_branch = process.env.DRONE_BRANCH;
}
*/
if (process.env.JENKINS_URL){
options.service_name = 'jenkins';
options.service_job_id = process.env.BUILD_ID;
options.service_pull_request = process.env.ghprbPullId;
git_commit = process.env.GIT_COMMIT;
git_branch = process.env.GIT_BRANCH;
}
if (process.env.CIRCLECI){
options.service_name = 'circleci';
options.service_job_id = process.env.CIRCLE_BUILD_NUM;
if (process.env.CI_PULL_REQUEST) {
var pr = process.env.CI_PULL_REQUEST.split('/pull/');
options.service_pull_request = pr[1];
}
git_commit = process.env.CIRCLE_SHA1;
git_branch = process.env.CIRCLE_BRANCH;
}
if (process.env.CI_NAME && process.env.CI_NAME === 'codeship'){
options.service_name = 'codeship';
options.service_job_id = process.env.CI_BUILD_NUMBER;
git_commit = process.env.CI_COMMIT_ID;
git_branch = process.env.CI_BRANCH;
git_committer_name = process.env.CI_COMMITTER_NAME;
git_committer_email = process.env.CI_COMMITTER_EMAIL;
git_message = process.env.CI_COMMIT_MESSAGE;
}
if (process.env.WERCKER){
options.service_name = 'wercker';
options.service_job_id = process.env.WERCKER_BUILD_ID;
git_commit = process.env.WERCKER_GIT_COMMIT;
git_branch = process.env.WERCKER_GIT_BRANCH;
}
if (process.env.GITLAB_CI){
options.service_name = 'gitlab-ci';
options.service_job_number = process.env.CI_BUILD_NAME;
options.service_job_id = process.env.CI_BUILD_ID;
git_commit = process.env.CI_BUILD_REF;
git_branch = process.env.CI_BUILD_REF_NAME;
}
if(process.env.APPVEYOR){
options.service_name = 'appveyor';
options.service_job_number = process.env.APPVEYOR_BUILD_NUMBER;
options.service_job_id = process.env.APPVEYOR_BUILD_ID;
git_commit = process.env.APPVEYOR_REPO_COMMIT;
git_branch = process.env.APPVEYOR_REPO_BRANCH;
}
if(process.env.SURF_SHA1){
options.service_name = 'surf';
git_commit = process.env.SURF_SHA1;
git_branch = process.env.SURF_REF;
}
options.run_at = process.env.COVERALLS_RUN_AT || JSON.stringify(new Date()).slice(1, -1);
if (process.env.COVERALLS_SERVICE_NAME){
options.service_name = process.env.COVERALLS_SERVICE_NAME;
}
if (process.env.COVERALLS_SERVICE_JOB_ID){
options.service_job_id = process.env.COVERALLS_SERVICE_JOB_ID;
}
if (!git_commit || !git_branch) {
var data = require('./detectLocalGit')();
if (data) {
git_commit = git_commit || data.git_commit;
git_branch = git_branch || data.git_branch;
}
}
if (process.env.COVERALLS_PARALLEL) {
options.parallel = true;
}
// try to get the repo token as an environment variable
if (process.env.COVERALLS_REPO_TOKEN) {
options.repo_token = process.env.COVERALLS_REPO_TOKEN;
} else {
// try to get the repo token from a .coveralls.yml file
var yml = path.join(process.cwd(), '.coveralls.yml');
try {
if (fs.statSync(yml).isFile()) {
var coveralls_yaml_conf = yaml.safeLoad(fs.readFileSync(yml, 'utf8'));
options.repo_token = coveralls_yaml_conf.repo_token;
if(coveralls_yaml_conf.service_name) {
options.service_name = coveralls_yaml_conf.service_name;
}
}
} catch(ex){
logger.warn("Repo token could not be determined. Continuing without it." +
"This is necessary for private repos only, so may not be an issue at all.");
}
}
if (git_commit){
fetchGitData({
head: {
id: git_commit,
committer_name: git_committer_name,
committer_email: git_committer_email,
message: git_message
},
branch: git_branch
}, function(err, git){
if (err){
logger.warn('there was an error getting git data: ', err);
} else {
options.git = git;
}
return cb(err, options);
});
} else {
return cb(null, options);
}
};
var getOptions = function(cb, _userOptions){
if (!cb){
throw new Error('getOptions requires a callback');
}
var userOptions = _userOptions || {};
getBaseOptions(function(err, options){
// minimist populates options._ with non-option command line arguments
var firstNonOptionArgument = index.options._[0];
if (firstNonOptionArgument)
options.filepath = firstNonOptionArgument;
// lodash or else would be better, but no need for the extra dependency
for (var option in userOptions) {
options[option] = userOptions[option];
}
cb(err, options);
});
};
module.exports.getBaseOptions = getBaseOptions;
module.exports.getOptions = getOptions;
+40
View File
@@ -0,0 +1,40 @@
var index = require('../index');
var logger = require('./logger')();
function handleInput(input, cb, userOptions) {
logger.debug(input);
logger.debug('user options ' + userOptions);
index.getOptions(function(err, options){
if (err){
logger.error("error from getOptions");
cb(err);
return;
}
logger.debug(options);
index.convertLcovToCoveralls(input, options, function(err, postData){
if (err){
logger.error("error from convertLcovToCoveralls");
cb(err);
return;
}
logger.info("sending this to coveralls.io: ", JSON.stringify(postData));
index.sendToCoveralls(postData, function(err, response, body){
if (err){
cb(err);
return;
}
if (response.statusCode >= 400){
cb("Bad response: " + response.statusCode + " " + body);
return;
}
logger.debug(response.statusCode);
logger.debug(body);
cb(null);
});
});
}, userOptions);
}
module.exports = handleInput;
+16
View File
@@ -0,0 +1,16 @@
var index = require('../index');
module.exports = function(){
return require('log-driver')({level : getLogLevel()});
};
function getLogLevel(){
if (index.options.verbose || hasDebugEnvVariable()) {
return 'warn';
}
return 'error';
}
function hasDebugEnvVariable(){
return process.env.NODE_COVERALLS_DEBUG == 1;
}
+23
View File
@@ -0,0 +1,23 @@
var request = require('request');
var index = require('../index');
var sendToCoveralls = function(obj, cb){
var urlBase = 'https://coveralls.io';
if (process.env.COVERALLS_ENDPOINT) {
urlBase = process.env.COVERALLS_ENDPOINT;
}
var str = JSON.stringify(obj);
var url = urlBase + '/api/v1/jobs';
if (index.options.stdout) {
process.stdout.write(str);
cb(null, { statusCode: 200 }, '');
} else {
request.post({url : url, form : { json : str}}, function(err, response, body){
cb(err, response, body);
});
}
};
module.exports = sendToCoveralls;
+150
View File
@@ -0,0 +1,150 @@
{
"_args": [
[
"coveralls@^2.11.9",
"/home/xor/shared_vm/git/node-sunwell"
]
],
"_from": "coveralls@>=2.11.9 <3.0.0",
"_id": "coveralls@2.11.15",
"_inCache": true,
"_installable": true,
"_location": "/coveralls",
"_nodeVersion": "0.12.7",
"_npmOperationalInternal": {
"host": "packages-12-west.internal.npmjs.com",
"tmp": "tmp/coveralls-2.11.15.tgz_1478882102489_0.5062202303670347"
},
"_npmUser": {
"email": "n@mer.fm",
"name": "nickmerwin"
},
"_npmVersion": "3.8.5",
"_phantomChildren": {},
"_requested": {
"name": "coveralls",
"raw": "coveralls@^2.11.9",
"rawSpec": "^2.11.9",
"scope": null,
"spec": ">=2.11.9 <3.0.0",
"type": "range"
},
"_requiredBy": [
"#DEV:/"
],
"_resolved": "https://registry.npmjs.org/coveralls/-/coveralls-2.11.15.tgz",
"_shasum": "37d3474369d66c14f33fa73a9d25cee6e099fca0",
"_shrinkwrap": null,
"_spec": "coveralls@^2.11.9",
"_where": "/home/xor/shared_vm/git/node-sunwell",
"author": {
"name": "Gregg Caines"
},
"bin": {
"coveralls": "./bin/coveralls.js"
},
"bugs": {
"url": "https://github.com/nickmerwin/node-coveralls/issues"
},
"contributors": [
{
"name": "Gregg Caines",
"email": "gregg@caines.ca",
"url": "http://caines.ca"
},
{
"name": "Joshua Ma",
"email": "github@joshma.com",
"url": "http://joshma.com"
},
{
"name": "Alan Gutierrez",
"email": "alan@prettyrobots.com",
"url": "http://www.prettyrobots.com/"
},
{
"name": "Kir Belevich",
"url": "https://github.com/svg"
},
{
"name": "elliotcable",
"email": "github@elliottcable.name",
"url": "http://elliottcable.name/"
},
{
"name": "Slotos",
"email": "slotos@gmail.com",
"url": "http://slotos.net"
},
{
"name": "mattjmorrison",
"email": "mattjmorrison@mattjmorrison.com",
"url": "http://mattjmorrison.com"
},
{
"name": "Arpad Borsos",
"email": "arpad.borsos@googlemail.com",
"url": "http://swatinem.de/"
},
{
"name": "Adam Moss",
"url": "https://github.com/adam-moss"
}
],
"dependencies": {
"js-yaml": "3.6.1",
"lcov-parse": "0.0.10",
"log-driver": "1.2.5",
"minimist": "1.2.0",
"request": "2.75.0"
},
"description": "takes json-cov output into stdin and POSTs to coveralls.io",
"devDependencies": {
"istanbul": "0.4.4",
"jshint": "2.9.3",
"mocha": "2.5.3",
"mocha-lcov-reporter": "1.2.0",
"should": "9.0.2",
"sinon-restore": "1.0.1",
"snyk": "1.17.0"
},
"directories": {
"test": "test"
},
"dist": {
"shasum": "37d3474369d66c14f33fa73a9d25cee6e099fca0",
"tarball": "https://registry.npmjs.org/coveralls/-/coveralls-2.11.15.tgz"
},
"engines": {
"node": ">=0.8.6"
},
"gitHead": "c81c084fc7280c68e8dc470c31e7291eea183c22",
"homepage": "https://github.com/nickmerwin/node-coveralls#readme",
"keywords": [
"coverage",
"coveralls"
],
"license": "BSD-2-Clause",
"main": "index.js",
"maintainers": [
{
"name": "cainus",
"email": "gregg@caines.ca"
},
{
"name": "nickmerwin",
"email": "n@mer.fm"
}
],
"name": "coveralls",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git://github.com/nickmerwin/node-coveralls.git"
},
"scripts": {
"test": "snyk test && make test"
},
"version": "2.11.15"
}
+149
View File
@@ -0,0 +1,149 @@
var convertLcovToCoveralls = require('../index').convertLcovToCoveralls;
var getOptions = require('../index').getOptions;
var should = require('should');
var fs = require('fs');
var logger = require('../lib/logger');
var path = require('path');
logger = require('log-driver')({level : false});
describe("convertLcovToCoveralls", function(){
it ("should convert a simple lcov file", function(done){
process.env.TRAVIS_JOB_ID = -1;
var lcovpath = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(lcovpath, "utf8");
var libpath = __dirname + "/../fixtures/lib";
convertLcovToCoveralls(input, {filepath: libpath}, function(err, output){
should.not.exist(err);
output.source_files[0].name.should.equal("index.js");
output.source_files[0].source.split("\n").length.should.equal(173);
output.source_files[0].coverage[54].should.equal(0);
output.source_files[0].coverage[60].should.equal(0);
done();
});
});
it ("should pass on all appropriate parameters from the environment", function(done){
process.env.TRAVIS_JOB_ID = -1;
process.env.COVERALLS_GIT_COMMIT = "GIT_HASH";
process.env.COVERALLS_GIT_BRANCH = "master";
process.env.COVERALLS_SERVICE_NAME = "SERVICE_NAME";
process.env.COVERALLS_SERVICE_JOB_ID = "SERVICE_JOB_ID";
process.env.COVERALLS_REPO_TOKEN = "REPO_TOKEN";
process.env.CI_PULL_REQUEST = "https://github.com/fake/fake/pulls/123";
process.env.COVERALLS_PARALLEL = "true";
getOptions(function(err, options){
var lcovpath = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(lcovpath, "utf8");
var libpath = "fixtures/lib";
options.filepath = libpath;
convertLcovToCoveralls(input, options, function(err, output){
should.not.exist(err);
output.service_pull_request.should.equal("123");
output.parallel.should.equal(true);
//output.git.should.equal("GIT_HASH");
done();
});
});
});
it ("should work with a relative path as well", function(done){
process.env.TRAVIS_JOB_ID = -1;
var lcovpath = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(lcovpath, "utf8");
var libpath = "fixtures/lib";
convertLcovToCoveralls(input, {filepath: libpath}, function(err, output){
should.not.exist(err);
output.source_files[0].name.should.equal("index.js");
output.source_files[0].source.split("\n").length.should.equal(173);
done();
});
});
it ("should convert absolute input paths to relative", function(done){
process.env.TRAVIS_JOB_ID = -1;
var lcovpath = __dirname + "/../fixtures/istanbul.lcov";
var input = fs.readFileSync(lcovpath, "utf8");
var libpath = "/Users/deepsweet/Dropbox/projects/svgo/lib";
var sourcepath = path.resolve(libpath, "svgo/config.js");
var originalReadFileSync = fs.readFileSync;
fs.readFileSync = function(filepath) {
if (filepath === sourcepath) {
return '';
}
return originalReadFileSync.apply(fs, arguments);
};
var originalExistsSync = fs.existsSync;
fs.existsSync = function () { return true; };
convertLcovToCoveralls(input, {filepath: libpath}, function(err, output){
fs.readFileSync = originalReadFileSync;
fs.existsSync = originalExistsSync;
should.not.exist(err);
output.source_files[0].name.should.equal(path.join("svgo", "config.js"));
done();
});
});
it ("should ignore files that do not exists", function(done){
process.env.TRAVIS_JOB_ID = -1;
var lcovpath = __dirname + "/../fixtures/istanbul.lcov";
var input = fs.readFileSync(lcovpath, "utf8");
var libpath = "/Users/deepsweet/Dropbox/projects/svgo/lib";
var sourcepath = path.resolve(libpath, "svgo/config.js");
var originalReadFileSync = fs.readFileSync;
fs.readFileSync = function(filepath) {
if (filepath === sourcepath) {
return '';
}
return originalReadFileSync.apply(fs, arguments);
};
var originalExistsSync = fs.existsSync;
fs.existsSync = function () { return false; };
convertLcovToCoveralls(input, {filepath: libpath}, function(err, output){
fs.readFileSync = originalReadFileSync;
fs.existsSync = originalExistsSync;
should.not.exist(err);
output.source_files.should.be.empty();
done();
});
});
it ("should parse file paths concatenated by typescript and ng 2", function(done) {
process.env.TRAVIS_JOB_ID = -1;
var lcovpath = __dirname + "/../fixtures/istanbul.remap.lcov";
var input = fs.readFileSync(lcovpath, "utf8");
var libpath = "/Users/deepsweet/Dropbox/projects/svgo/lib";
var sourcepath = path.resolve(libpath, "svgo/config.js");
var originalReadFileSync = fs.readFileSync;
fs.readFileSync = function(filepath) {
if (filepath === sourcepath) {
return '';
}
return originalReadFileSync.apply(fs, arguments);
};
var originalExistsSync = fs.existsSync;
fs.existsSync = function () { return true; };
convertLcovToCoveralls(input, {filepath: libpath}, function(err, output){
fs.readFileSync = originalReadFileSync;
fs.existsSync = originalExistsSync;
should.not.exist(err);
output.source_files[0].name.should.equal(path.join("svgo", "config.js"));
done();
});
});
});
+182
View File
@@ -0,0 +1,182 @@
var should = require('should');
var fetchGitData = require('../lib/fetchGitData');
var getOptions = require('../index').getOptions;
describe("fetchGitData", function(){
beforeEach(function(){
process.env = {PATH: process.env.PATH};
});
it("should throw an error when no data is passed", function() {
fetchGitData.should.throw(/fetchGitData requires a callback/);
});
it('should throw an error when no git context is provided', function(done) {
fetchGitData(undefined, function(err){
err.should.match(/No options passed/);
done();
});
});
it("should throw an error if no head is provided", function(done) {
fetchGitData({
}, function(err){
err.should.match(/You must provide the head/);
done();
});
});
it("should throw an error if no head.id is provided", function(done) {
fetchGitData({
head: {}
}, function(err){
err.should.match(/You must provide the head.id/);
done();
});
});
it("should return default values", function(done) {
var options = fetchGitData({
head: {
id: "COMMIT_HASH"
}
}, function(err, options){
options.should.eql({
"head": {
"id": "COMMIT_HASH",
"author_name": "Unknown Author",
"author_email": "",
"committer_name": "Unknown Committer",
"committer_email": "",
"message": "Unknown Commit Message"
},
"branch": "",
"remotes": []
});
done();
});
});
it("should override default values", function(done) {
var options = fetchGitData({
"head": {
"id": "COMMIT_HASH",
"author_name": "MY AUTHOR",
"author_email": "",
"committer_name": "MY COMMITTER",
"committer_email": "",
"message": "MY COMMIT MESSAGE"
},
"branch": "TEST",
"remotes": [
{
"name": "TEST",
"url": "test-url"
}
]
}, function(err, options){
options.should.eql({
"head": {
"id": "COMMIT_HASH",
"author_name": "MY AUTHOR",
"author_email": "",
"committer_name": "MY COMMITTER",
"committer_email": "",
"message": "MY COMMIT MESSAGE"
},
"branch": "TEST",
"remotes": [
{
"name": "TEST",
"url": "test-url"
}
]
});
done();
});
});
it("should convert git.branch to a string", function(done) {
fetchGitData({
"head": {
"id": "COMMIT_HASH"
},
"branch": {
"covert": "to a string"
}
}, function(err, str){
str.branch.should.be.String();
fetchGitData({
"head": {
"id": "COMMIT_HASH"
},
"branch": ["convert", "to", "a", "string"]
}, function(err, str){
str.branch.should.be.String();
done();
});
});
});
it("should convert git.remotes to an array", function(done) {
fetchGitData({
"head": {
"id": "COMMIT_HASH"
},
"remotes": "convert from string to an array"
}, function(err, arr){
arr.remotes.should.be.instanceof(Array);
fetchGitData({
"head": {
"id": "COMMIT_HASH"
},
"remotes": {
"convert": "from object to an array"
}
}, function(err, arr){
arr.remotes.should.be.instanceof(Array);
done();
});
});
});
it("should save passed remotes", function(done) {
fetchGitData({
"head": {
"id": "COMMIT_HASH"
},
"remotes": [
{
"name": "test",
"url": "https://my.test.url"
}
]
}, function(err, options){
options.should.eql({
"head": {
"id": "COMMIT_HASH",
"author_name": "Unknown Author",
"author_email": "",
"committer_name": "Unknown Committer",
"committer_email": "",
"message": "Unknown Commit Message"
},
"branch": "",
"remotes": [
{
"name": "test",
"url": "https://my.test.url"
}
]
});
done();
});
});
it("should execute git commands when a valid commit hash is given", function(done) {
process.env.COVERALLS_GIT_COMMIT = "HEAD";
process.env.COVERALLS_GIT_BRANCH = "master";
getOptions(function(err, options){
options = options.git;
options.head.should.be.Object();
options.head.author_name.should.not.equal("Unknown Author");
options.head.committer_name.should.not.equal("Unknown Committer");
options.head.message.should.not.equal("Unknown Commit Message");
options.branch.should.be.String();
options.should.have.property("remotes");
options.remotes.should.be.instanceof(Array);
options.remotes.length.should.be.above(0);
done();
});
});
});
+513
View File
@@ -0,0 +1,513 @@
var should = require('should');
var index = require('../index');
var getOptions = index.getOptions;
var getBaseOptions = index.getBaseOptions;
describe("getBaseOptions", function(){
beforeEach(function(){
process.env = {PATH: process.env.PATH};
});
it ("should set service_job_id if it exists", function(done){
testServiceJobId(getBaseOptions, done);
});
it ("should set git hash if it exists", function(done){
testGitHash(getBaseOptions, done);
});
it ("should set git branch if it exists", function(done){
testGitBranch(getBaseOptions, done);
});
it ("should detect current git hash if not passed in", function(done) {
testGitHashDetection(getBaseOptions, done);
});
it ("should detect current git branch if not passed in", function(done) {
testGitBranchDetection(getBaseOptions, done);
});
it ("should detect detached git head if no hash passed in", function(done) {
testGitDetachedHeadDetection(getBaseOptions, done);
});
it ("should fail local Git detection if no .git directory", function(done) {
testNoLocalGit(getBaseOptions, done);
});
it ("should set repo_token if it exists", function(done){
testRepoToken(getBaseOptions, done);
});
it ("should detect repo_token if not passed in", function(done){
testRepoTokenDetection(getBaseOptions, done);
});
it ("should set service_name if it exists", function(done){
testServiceName(getBaseOptions, done);
});
it ("should set service_name and service_job_id if it's running on travis-ci", function(done){
testTravisCi(getBaseOptions, done);
});
it ("should set service_name and service_job_id if it's running on jenkins", function(done){
testJenkins(getBaseOptions, done);
});
it ("should set service_name and service_job_id if it's running on circleci", function(done){
testCircleCi(getBaseOptions, done);
});
it ("should set service_name and service_job_id if it's running on codeship", function(done){
testCodeship(getBaseOptions, done);
});
/*
it ("should set service_name and service_job_id if it's running on drone", function(done){
testDrone(getBaseOptions, done);
});
*/
it ("should set service_name and service_job_id if it's running on wercker", function(done){
testWercker(getBaseOptions, done);
});
});
describe("getOptions", function(){
beforeEach(function(){
process.env = {PATH: process.env.PATH};
});
it ("should require a callback", function(done) {
(function() {
getOptions();
}).should.throw();
done();
});
it ("should get a filepath if there is one", function(done){
index.options._ = ["somepath"];
getOptions(function(err, options){
options.filepath.should.equal("somepath");
done();
});
});
it ("should get a filepath if there is one, even in verbose mode", function(done){
index.options.verbose = "true";
index.options._ = ["somepath"];
getOptions(function(err, options){
options.filepath.should.equal("somepath");
done();
});
});
it ("should set service_job_id if it exists", function(done){
testServiceJobId(getOptions, done);
});
it ("should set git hash if it exists", function(done){
testGitHash(getOptions, done);
});
it ("should set git branch if it exists", function(done){
testGitBranch(getOptions, done);
});
it ("should detect current git hash if not passed in", function(done) {
testGitHashDetection(getOptions, done);
});
it ("should detect current git branch if not passed in", function(done) {
testGitBranchDetection(getOptions, done);
});
it ("should detect detached git head if no hash passed in", function(done) {
testGitDetachedHeadDetection(getOptions, done);
});
it ("should fail local Git detection if no .git directory", function(done) {
testNoLocalGit(getOptions, done);
});
it ("should set repo_token if it exists", function(done){
testRepoToken(getOptions, done);
});
it ("should detect repo_token if not passed in", function(done){
testRepoTokenDetection(getOptions, done);
});
it ("should set paralell if env var set", function(done){
testParallel(getOptions, done);
});
it ("should set service_name if it exists", function(done){
testServiceName(getOptions, done);
});
it("should set service_pull_request if it exists", function(done){
testServicePullRequest(getOptions, done);
});
it ("should set service_name and service_job_id if it's running on travis-ci", function(done){
testTravisCi(getOptions, done);
});
it ("should set service_name and service_job_id if it's running on jenkins", function(done){
testJenkins(getOptions, done);
});
it ("should set service_name and service_job_id if it's running on circleci", function(done){
testCircleCi(getOptions, done);
});
it ("should set service_name and service_job_id if it's running on codeship", function(done){
testCodeship(getOptions, done);
});
/*
it ("should set service_name and service_job_id if it's running on drone", function(done){
testDrone(getBaseOptions, done);
});
*/
it ("should set service_name and service_job_id if it's running on wercker", function(done){
testWercker(getOptions, done);
});
it ("should set service_name and service_job_id if it's running on Gitlab", function(done){
testGitlab(getOptions, done);
});
it ("should set service_name and service_job_id if it's running via Surf", function(done){
testSurf(getOptions, done);
});
it ("should override set options with user options", function(done){
var userOptions = {service_name: 'OVERRIDDEN_SERVICE_NAME'};
process.env.COVERALLS_SERVICE_NAME = "SERVICE_NAME";
getOptions(function(err, options){
options.service_name.should.equal("OVERRIDDEN_SERVICE_NAME");
done();
}, userOptions);
});
});
var testServiceJobId = function(sut, done){
process.env.COVERALLS_SERVICE_JOB_ID = "SERVICE_JOB_ID";
sut(function(err, options){
options.service_job_id.should.equal("SERVICE_JOB_ID");
done();
});
};
var testGitHash = function(sut, done){
process.env.COVERALLS_GIT_COMMIT = "e3e3e3e3e3e3e3e3e";
sut(function(err, options){
options.git.head.id.should.equal("e3e3e3e3e3e3e3e3e");
done();
});
};
var testGitDetachedHeadDetection = function(sut, done){
var localGit = ensureLocalGitContext({ detached: true });
sut(function(err, options) {
options.git.head.id.should.equal(localGit.id);
localGit.wrapUp();
done();
});
};
var testGitHashDetection = function(sut, done){
var localGit = ensureLocalGitContext();
sut(function(err, options) {
options.git.head.id.should.equal(localGit.id);
localGit.wrapUp();
done();
});
};
var testGitBranch = function(sut, done){
process.env.COVERALLS_GIT_COMMIT = "e3e3e3e3e3e3e3e3e";
process.env.COVERALLS_GIT_BRANCH = "master";
sut(function(err, options){
options.git.branch.should.equal("master");
done();
});
};
var testGitBranchDetection = function(sut, done){
var localGit = ensureLocalGitContext();
sut(function(err, options) {
if (localGit.branch)
options.git.branch.should.equal(localGit.branch);
else
options.git.should.not.have.key('branch');
localGit.wrapUp();
done();
});
};
var testNoLocalGit = function(sut, done){
var localGit = ensureLocalGitContext({ noGit: true });
sut(function(err, options) {
options.should.not.have.property('git');
localGit.wrapUp();
done();
});
};
var testRepoToken = function(sut, done){
process.env.COVERALLS_REPO_TOKEN = "REPO_TOKEN";
sut(function(err, options){
options.repo_token.should.equal("REPO_TOKEN");
done();
});
};
var testParallel = function(sut, done){
process.env.COVERALLS_PARALLEL = "true";
sut(function(err, options){
options.parallel.should.equal(true);
done();
});
};
var testRepoTokenDetection = function(sut, done) {
var fs = require('fs');
var path = require('path');
var file = path.join(process.cwd(), '.coveralls.yml'), token, service_name, synthetic = false;
if (fs.exists(file)) {
var yaml = require('js-yaml');
var coveralls_yml_doc = yaml.safeLoad(fs.readFileSync(yml, 'utf8'));
token = coveralls_yml_doc.repo_token;
if(coveralls_yml_doc.service_name) {
service_name = coveralls_yml_doc.service_name;
}
} else {
token = 'REPO_TOKEN';
service_name = 'travis-pro';
fs.writeFileSync(file, 'repo_token: ' + token+'\nservice_name: ' + service_name);
synthetic = true;
}
sut(function(err, options) {
options.repo_token.should.equal(token);
if(service_name) {
options.service_name.should.equal(service_name);
}
if (synthetic)
fs.unlink(file);
done();
});
};
var testServiceName = function(sut, done){
process.env.COVERALLS_SERVICE_NAME = "SERVICE_NAME";
sut(function(err, options){
options.service_name.should.equal("SERVICE_NAME");
done();
});
};
var testServicePullRequest = function(sut, done){
process.env.CI_PULL_REQUEST = "https://github.com/fake/fake/pulls/123";
sut(function(err, options){
options.service_pull_request.should.equal("123");
done();
});
};
var testTravisCi = function(sut, done){
process.env.TRAVIS = "TRUE";
process.env.TRAVIS_JOB_ID = "1234";
sut(function(err, options){
options.service_name.should.equal("travis-ci");
options.service_job_id.should.equal("1234");
done();
});
};
var testJenkins = function(sut, done){
process.env.JENKINS_URL = "something";
process.env.BUILD_ID = "1234";
process.env.GIT_COMMIT = "a12s2d3df4f435g45g45g67h5g6";
process.env.GIT_BRANCH = "master";
sut(function(err, options){
options.service_name.should.equal("jenkins");
options.service_job_id.should.equal("1234");
options.git.should.eql({ head:
{ id: 'a12s2d3df4f435g45g45g67h5g6',
author_name: 'Unknown Author',
author_email: '',
committer_name: 'Unknown Committer',
committer_email: '',
message: 'Unknown Commit Message' },
branch: 'master',
remotes: [] });
done();
});
};
var testCircleCi = function(sut, done){
process.env.CIRCLECI = true;
process.env.CIRCLE_BRANCH = "master";
process.env.CIRCLE_BUILD_NUM = "1234";
process.env.CIRCLE_SHA1 = "e3e3e3e3e3e3e3e3e";
process.env.CI_PULL_REQUEST = 'http://github.com/node-coveralls/pull/3';
sut(function(err, options){
options.service_name.should.equal("circleci");
options.service_job_id.should.equal("1234");
options.service_pull_request.should.equal('3');
options.git.should.eql({ head:
{ id: 'e3e3e3e3e3e3e3e3e',
author_name: 'Unknown Author',
author_email: '',
committer_name: 'Unknown Committer',
committer_email: '',
message: 'Unknown Commit Message' },
branch: 'master',
remotes: [] });
done();
});
};
var testCodeship = function(sut, done) {
process.env.CI_NAME = 'codeship';
process.env.CI_BUILD_NUMBER = '1234';
process.env.CI_COMMIT_ID = "e3e3e3e3e3e3e3e3e";
process.env.CI_BRANCH = "master";
process.env.CI_COMMITTER_NAME = "John Doe";
process.env.CI_COMMITTER_EMAIL = "jd@example.com";
process.env.CI_COMMIT_MESSAGE = "adadadadadadadadadad";
sut(function(err, options){
options.service_name.should.equal("codeship");
options.service_job_id.should.equal("1234");
options.git.should.eql({ head:
{ id: 'e3e3e3e3e3e3e3e3e',
author_name: 'Unknown Author',
author_email: '',
committer_name: 'John Doe',
committer_email: 'jd@example.com',
message: 'adadadadadadadadadad' },
branch: 'master',
remotes: [] });
done();
});
};
var testDrone = function(sut, done) {
process.env.DRONE = true;
process.env.DRONE_BUILD_NUMBER = '1234';
process.env.DRONE_COMMIT = "e3e3e3e3e3e3e3e3e";
process.env.DRONE_BRANCH = "master";
sut(function(err, options){
options.service_name.should.equal("drone");
options.service_job_id.should.equal("1234");
options.git.should.eql({ head:
{ id: 'e3e3e3e3e3e3e3e3e',
author_name: 'Unknown Author',
author_email: '',
committer_name: 'Unknown Committer',
committer_email: '',
message: 'Unknown Commit Message' },
branch: 'master',
remotes: [] });
done();
});
};
var testWercker = function(sut, done) {
process.env.WERCKER = true;
process.env.WERCKER_BUILD_ID = '1234';
process.env.WERCKER_GIT_COMMIT = "e3e3e3e3e3e3e3e3e";
process.env.WERCKER_GIT_BRANCH = "master";
sut(function(err, options){
options.service_name.should.equal("wercker");
options.service_job_id.should.equal("1234");
options.git.should.eql({ head:
{ id: 'e3e3e3e3e3e3e3e3e',
author_name: 'Unknown Author',
author_email: '',
committer_name: 'Unknown Committer',
committer_email: '',
message: 'Unknown Commit Message' },
branch: 'master',
remotes: [] });
done();
});
};
var testGitlab = function(sut, done) {
process.env.GITLAB_CI = true;
process.env.CI_BUILD_NAME = 'spec:one';
process.env.CI_BUILD_ID = "1234";
process.env.CI_BUILD_REF = "e3e3e3e3e3e3e3e3e";
process.env.CI_BUILD_REF_NAME = "feature";
sut(function(err, options){
options.service_name.should.equal("gitlab-ci");
options.service_job_id.should.equal("1234");
options.git.should.eql({ head:
{ id: 'e3e3e3e3e3e3e3e3e',
author_name: 'Unknown Author',
author_email: '',
committer_name: 'Unknown Committer',
committer_email: '',
message: 'Unknown Commit Message' },
branch: 'feature',
remotes: [] });
done();
});
};
var testSurf = function(sut, done) {
process.env.CI_NAME = 'surf';
process.env.SURF_SHA1 = "e3e3e3e3e3e3e3e3e";
process.env.SURF_REF = "feature";
sut(function(err, options){
options.service_name.should.equal("surf");
options.git.should.eql({ head:
{ id: 'e3e3e3e3e3e3e3e3e',
author_name: 'Unknown Author',
author_email: '',
committer_name: 'Unknown Committer',
committer_email: '',
message: 'Unknown Commit Message' },
branch: 'feature',
remotes: [] });
done();
});
};
function ensureLocalGitContext(options) {
var path = require('path');
var fs = require('fs');
var baseDir = process.cwd(), dir = baseDir, gitDir;
while (path.resolve('/') !== dir) {
gitDir = path.join(dir, '.git');
var existsSync = fs.existsSync || path.existsSync;
if (existsSync(path.join(gitDir, 'HEAD')))
break;
dir = path.dirname(dir);
}
options = options || {};
var synthetic = path.resolve('/') === dir;
var gitHead, content, branch, id, wrapUp = function() {};
if (synthetic) {
branch = 'synthetic';
id = '424242424242424242';
gitHead = path.join('.git', 'HEAD');
var gitBranch = path.join('.git', 'refs', 'heads', branch);
fs.mkdirSync('.git');
if (options.detached) {
fs.writeFileSync(gitHead, id, { encoding: 'utf8' });
} else {
fs.mkdirSync(path.join('.git', 'refs'));
fs.mkdirSync(path.join('.git', 'refs', 'heads'));
fs.writeFileSync(gitHead, "ref: refs/heads/" + branch, { encoding: 'utf8' });
fs.writeFileSync(gitBranch, id, { encoding: 'utf8' });
}
wrapUp = function() {
fs.unlinkSync(gitHead);
if (!options.detached) {
fs.unlinkSync(gitBranch);
fs.rmdirSync(path.join('.git', 'refs', 'heads'));
fs.rmdirSync(path.join('.git', 'refs'));
}
fs.rmdirSync('.git');
};
} else if (options.noGit) {
fs.renameSync(gitDir, gitDir + '.bak');
wrapUp = function() {
fs.renameSync(gitDir + '.bak', gitDir);
};
} else if (options.detached) {
gitHead = path.join(gitDir, 'HEAD');
content = fs.readFileSync(gitHead, 'utf8').trim();
var b = (content.match(/^ref: refs\/heads\/(\S+)$/) || [])[1];
if (!b) {
id = content;
} else {
id = fs.readFileSync(path.join(gitDir, 'refs', 'heads', b), 'utf8').trim();
fs.writeFileSync(gitHead, id, 'utf8');
wrapUp = function() {
fs.writeFileSync(gitHead, content, 'utf8');
};
}
} else {
content = fs.readFileSync(path.join(gitDir, 'HEAD'), 'utf8').trim();
branch = (content.match(/^ref: refs\/heads\/(\S+)$/) || [])[1];
id = branch ? fs.readFileSync(path.join(gitDir, 'refs', 'heads', branch), 'utf8').trim() : content;
}
return { id: id, branch: branch, wrapUp: wrapUp };
}
+78
View File
@@ -0,0 +1,78 @@
var should = require('should');
var sinon = require('sinon-restore');
var index = require('../index');
var fs = require('fs');
logger = require('log-driver')({level : false});
describe("handleInput", function(){
afterEach(function() {
sinon.restoreAll();
});
it ("returns an error when there's an error getting options", function(done){
sinon.stub(index, 'getOptions', function(cb){
return cb("some error", {});
});
var path = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(path, "utf8");
index.handleInput(input, function(err){
err.should.equal("some error");
done();
});
});
it ("returns an error when there's an error converting", function(done){
sinon.stub(index, 'getOptions', function(cb){
return cb(null, {});
});
sinon.stub(index, 'convertLcovToCoveralls', function(input, options, cb){
cb("some error");
});
var path = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(path, "utf8");
index.handleInput(input, function(err){
err.should.equal("some error");
done();
});
});
it ("returns an error when there's an error sending", function(done){
sinon.stub(index, 'getOptions', function(cb){
return cb(null, {});
});
sinon.stub(index, 'sendToCoveralls', function(postData, cb){
cb("some error");
});
var path = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(path, "utf8");
index.handleInput(input, function(err){
err.should.equal("some error");
done();
});
});
it ("returns an error when there's a bad status code", function(done){
sinon.stub(index, 'getOptions', function(cb){
return cb(null, {});
});
sinon.stub(index, 'sendToCoveralls', function(postData, cb){
cb(null, {statusCode : 500}, "body");
});
var path = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(path, "utf8");
index.handleInput(input, function(err){
err.should.equal("Bad response: 500 body");
done();
});
});
it ("completes successfully when there are no errors", function(done){
sinon.stub(index, 'getOptions', function(cb){
return cb(null, {});
});
sinon.stub(index, 'sendToCoveralls', function(postData, cb){
cb(null, {statusCode : 200}, "body");
});
var path = __dirname + "/../fixtures/onefile.lcov";
var input = fs.readFileSync(path, "utf8");
index.handleInput(input, function(err){
(err === null).should.equal(true);
done();
});
});
});
+32
View File
@@ -0,0 +1,32 @@
var should = require('should');
var sinon = require('sinon-restore');
var index = require('../index');
describe("logger", function(){
it ("should log at debug level when --verbose is set", function(){
index.options.verbose = true;
var logger = require('../index').logger();
logger.level.should.equal('warn');
});
it ("should log at debug level when NODE_COVERALLS_DEBUG is set in env", function(){
index.options.verbose = false;
process.env.NODE_COVERALLS_DEBUG = 1;
var logger = require('../index').logger();
logger.level.should.equal('warn');
});
it ("should log at debug level when NODE_COVERALLS_DEBUG is set in env as a string", function(){
index.options.verbose = false;
process.env.NODE_COVERALLS_DEBUG = '1';
var logger = require('../index').logger();
logger.level.should.equal('warn');
});
it ("should log at warn level when NODE_COVERALLS_DEBUG not set and no --verbose", function(){
index.options.verbose = false;
process.env.NODE_COVERALLS_DEBUG = 0;
var logger = require('../index').logger();
logger.level.should.equal('error');
});
});
+75
View File
@@ -0,0 +1,75 @@
var should = require('should');
var request = require('request');
var sinon = require('sinon-restore');
var index = require('../index');
logger = require('log-driver')({level : false});
describe("sendToCoveralls", function(){
var realCoverallsHost;
beforeEach(function() {
realCoverallsHost = process.env.COVERALLS_ENDPOINT;
});
afterEach(function() {
sinon.restoreAll();
if (realCoverallsHost !== undefined) {
process.env.COVERALLS_ENDPOINT = realCoverallsHost;
} else {
delete process.env.COVERALLS_ENDPOINT;
}
});
it ("passes on the correct params to request.post", function(done){
sinon.stub(request, 'post', function(obj, cb){
obj.url.should.equal('https://coveralls.io/api/v1/jobs');
obj.form.should.eql({json : '{"some":"obj"}'});
cb('err', 'response', 'body');
});
var obj = {"some":"obj"};
index.sendToCoveralls(obj, function(err, response, body){
err.should.equal('err');
response.should.equal('response');
body.should.equal('body');
done();
});
});
it ("allows sending to enterprise url", function(done){
process.env.COVERALLS_ENDPOINT = 'https://coveralls-ubuntu.domain.com';
sinon.stub(request, 'post', function(obj, cb){
obj.url.should.equal('https://coveralls-ubuntu.domain.com/api/v1/jobs');
obj.form.should.eql({json : '{"some":"obj"}'});
cb('err', 'response', 'body');
});
var obj = {"some":"obj"};
index.sendToCoveralls(obj, function(err, response, body){
err.should.equal('err');
response.should.equal('response');
body.should.equal('body');
done();
});
});
it ("writes output to stdout when --stdout is passed", function(done) {
var obj = {"some":"obj"};
// set up mock process.stdout.write temporarily
var origStdoutWrite = process.stdout.write;
process.stdout.write = function(string) {
if (string == JSON.stringify(obj)) {
process.stdout.write = origStdoutWrite;
return done();
}
origStdoutWrite.apply(this, arguments);
};
index.options.stdout = true;
index.sendToCoveralls(obj, function(err, response, body) {
response.statusCode.should.equal(200);
});
});
});