Skip to content

Commit

Permalink
Merge pull request #15 from bchr02/add-tests
Browse files Browse the repository at this point in the history
**Changes:**
* adds test\test.js with over 97% line coverage.
* added a test and coverage section to package.json's scripts property.
* added some dev dependencies to package.json which are needed for testing and code coverage.
* removed some unneeded dependencies from package.json
* removed some unneeded modules that were required in index.js
* ```NodePreGypGithub.prototype.github = new GitHubApi(..)``` now happens immediatelly instead of within ```NodePreGypGithub.prototype.init()```. The main reason for this was so I could provide a  replacement mock to use within unit tests.
* added some missing escape characters, so ```/{version}/g``` is now ```/\{version\}/g```
  • Loading branch information
bchr02 committed Jun 1, 2016
2 parents 0803481 + 40c7f40 commit 73e8be3
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 32 deletions.
55 changes: 28 additions & 27 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
"use strict";

var request = require('request'),
path = require("path"),
fs = require('fs'),
mime = require('mime'),
GitHubApi = require("github"),
cwd = process.cwd();
var path = require("path");
var fs = require('fs');
var GitHubApi = require("github");
var cwd = process.cwd();

function NodePreGypGithub() {}

NodePreGypGithub.prototype.github;
NodePreGypGithub.prototype.owner;
NodePreGypGithub.prototype.repo;
NodePreGypGithub.prototype.github = new GitHubApi({ // set defaults
// required
version: "3.0.0",
// optional
debug: false,
protocol: "https",
host: "api.github.com",
pathPrefix: "", // for some GHEs; none for GitHub
timeout: 5000,
headers: {}
});

NodePreGypGithub.prototype.owner = "";
NodePreGypGithub.prototype.repo = "";
NodePreGypGithub.prototype.package_json = {};
NodePreGypGithub.prototype.release = {};
NodePreGypGithub.prototype.stage_dir = path.join(cwd,"build","stage");
Expand Down Expand Up @@ -42,19 +51,8 @@ NodePreGypGithub.prototype.init = function() {
throw new Error('binary.host in package.json should begin with: "' + hostPrefix + '"');
}

this.github = new GitHubApi({ // set defaults
// required
version: "3.0.0",
// optional
debug: false,
protocol: "https",
host: "api.github.com",
pathPrefix: "", // for some GHEs; none for GitHub
timeout: 5000,
headers: {
"user-agent": (this.package_json.name) ? this.package_json.name : "node-pre-gyp-github" // GitHub is happy with a unique user agent
}
});
this.github.headers = {"user-agent": (this.package_json.name) ? this.package_json.name : "node-pre-gyp-github"}; // GitHub is happy with a unique user agent

};

NodePreGypGithub.prototype.authenticate_settings = function(){
Expand Down Expand Up @@ -141,18 +139,21 @@ NodePreGypGithub.prototype.publish = function(options) {

// when remote_path is set expect files to be in stage_dir / remote_path after substitution
if (this.package_json.binary.remote_path) {
options.tag_name = this.package_json.binary.remote_path.replace(/{version}/g, this.package_json.version);
options.tag_name = this.package_json.binary.remote_path.replace(/\{version\}/g, this.package_json.version);
this.stage_dir = path.join(this.stage_dir, options.tag_name);
} else {
// This is here for backwards compatibility for before binary.remote_path support was added in version 1.2.0.
options.tag_name = this.package_json.version;
}

release = (function(){ // create a new array containing only those who have a matching version.
data = data.filter(function(element, index, array){
return element.tag_name === options.tag_name;
}.bind(this));
return data;
if(data) {
data = data.filter(function(element, index, array){
return element.tag_name === options.tag_name;
}.bind(this));
return data;
}
else return [];
}.bind(this))();

this.release = release[0];
Expand Down
14 changes: 9 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"name": "node-pre-gyp-github",
"version": "1.2.1",
"version": "1.2.2",
"description": "A node-pre-gyp module which provides the ability to publish to GitHub releases.",
"bin": "./bin/node-pre-gyp-github.js",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "mocha test",
"coverage": "istanbul cover ./node_modules/mocha/bin/_mocha --report lcovonly -- -R spec"
},
"repository": {
"type": "git",
Expand All @@ -25,9 +26,12 @@
],
"dependencies": {
"github": "^0.2.4",
"commander": "^2.9.0",
"mime": "^1.3.4",
"request": "^2.67.0"
"commander": "^2.9.0"
},
"devDependencies": {
"chai": "^3.5.0",
"istanbul": "^0.4.3",
"mocha": "^2.5.3"
},
"author": "Bill Christo",
"license": "MIT",
Expand Down
132 changes: 132 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
"use strict";

var expect = require("chai").expect;
var fs = require("fs");
var Index = require('../index.js');
var index = new Index();
var stage_dir = index.stage_dir;
var reset_index = function(index_string_ref) {
delete require.cache[require.resolve(index_string_ref)];
return require(index_string_ref);
};
var reset_mocks = function() {
process.env['NODE_PRE_GYP_GITHUB_TOKEN'] = "secret";
fs = reset_index('fs');
fs.readFileSync = function(){return '{"name":"test","version":"0.0.1","repository": {"url":"git+https://github.com/test/test.git"},"binary":{"host":"https://github.com/test/test/releases/download/","remote_path":"{version}"}}';};
index.stage_dir = stage_dir;
index.github.authenticate = function(){};
index.github.releases.listReleases = function(options, cb){
cb(null, [{"tag_name":"0.0.0","assets":[{"name":"filename"}]}]);
};
index.github.releases.createRelease = function(options, cb){
cb(null,{"tag_name":"0.0.1","assets":[{}]});
};
index.github.releases.uploadAsset = function(cfg,cb){cb();};
};

describe("Publishes packages to GitHub Releases", function() {
describe("Throws an Error when node-pre-gyp-github is not configured properly", function() {

it("should throw an error when missing repository.url in package.json", function() {
reset_mocks();
fs.readFileSync = function(){return '{}';};
expect(function(){ index.publish(); }).to.throw("Missing repository.url in package.json");
});

it("should throw an error when a correctly formatted GitHub repository.url is not found in package.json", function() {
reset_mocks();
fs.readFileSync = function(){return '{"repository": {"url":"bad_format_url"}}';};
expect(function(){ index.publish(); }).to.throw("A correctly formatted GitHub repository.url was not found within package.json");
});

it("should throw an error when missing binary.host in package.json", function() {
reset_mocks();
fs.readFileSync = function(){return '{"repository": {"url":"git+https://github.com/test/test.git"}}';};
expect(function(){ index.publish(); }).to.throw("Missing binary.host in package.json");
});

it("should throw an error when binary.host does not begin with the correct url", function() {
reset_mocks();
fs.readFileSync = function(){return '{"repository": {"url":"git+https://github.com/test/test.git"},"binary":{"host":"bad_format_binary"}}';};
expect(function(){ index.publish(); }).to.throw(/^binary.host in package.json should begin with:/i);
});

it("should throw an error when the NODE_PRE_GYP_GITHUB_TOKEN environment variable is not found", function() {
reset_mocks();
process.env['NODE_PRE_GYP_GITHUB_TOKEN'] = "";
expect(function(){ index.publish(); }).to.throw("NODE_PRE_GYP_GITHUB_TOKEN environment variable not found");
});

it("should throw an error when github.releases.listReleases returns an error", function() {
reset_mocks();
index.github.releases.listReleases = function(options, cb){
cb(new Error('listReleases error'));
};
expect(function(){ index.publish(); }).to.throw('listReleases error');
});

it("should throw an error when github.releases.createRelease returns an error", function() {
var options = {'draft': true};
reset_mocks();
index.github.releases.listReleases = function(options, cb){
cb(null,null);
};
index.github.releases.createRelease = function(options, cb){
cb(new Error('createRelease error'));
};
expect(function(){ index.publish(options); }).to.throw('createRelease error');
});

it("should throw an error when the stage directory structure is missing", function() {
var options = {'draft': true};
reset_mocks();
fs.readdir = function(filename, cb) {
cb(new Error('readdir Error'));
};
expect(function(){ index.publish(options); }).to.throw('readdir Error');
});

it("should throw an error when there are no files found within the stage directory", function() {
var options = {'draft': true};
reset_mocks();
fs.readdir = function(filename, cb) {
cb(null,[]);
};
expect(function(){ index.publish(options); }).to.throw(/^No files found within the stage directory:/i);
});

it("should throw an error when a staged file already exists in the current release", function() {
var options = {'draft': true};
reset_mocks();
fs.readdir = function(filename, cb) {
cb(null,["filename"]);
};
index.github.releases.listReleases = function(options, cb){
cb(null, [{"tag_name":"0.0.1","assets":[{"name":"filename"}]}]);
};
expect(function(){ index.publish(options); }).to.throw(/^Staged file .* found but it already exists in release .*. If you would like to replace it, you must first manually delete it within GitHub./i);
});

it("should throw an error when github.releases.uploadAsset returns an error", function() {
var options = {'draft': true};
reset_mocks();
fs.readdir = function(filename, cb) {
cb(null,["filename"]);
};
index.github.releases.uploadAsset = function(cfg,cb){
cb(new Error('uploadAsset error'));
};
expect(function(){ index.publish(options); }).to.throw("uploadAsset error");
});

it("should publish without an error", function() {
var options = {'draft': true};
reset_mocks();
fs.readdir = function(filename, cb) {
cb(null,["filename"]);
};
expect(function(){ index.publish(options); }).to.not.throw();
});

});
});

0 comments on commit 73e8be3

Please sign in to comment.