Merge pull request #4 from AlmirKadric/feature/linting

implmented JSHint and put in mocha structure
This commit is contained in:
Ron Korving
2014-10-29 13:22:12 +09:00
9 changed files with 260 additions and 4 deletions

1
.jshintignore Normal file
View File

@@ -0,0 +1 @@
node_modules/**

96
.jshintrc Normal file
View File

@@ -0,0 +1,96 @@
// Examples: https://github.com/jshint/jshint/blob/master/examples/.jshintrc
// Documentation: http://www.jshint.com/docs/
// In Sublime: https://github.com/victorporof/Sublime-JSHint#using-your-own-jshintrc-options
// In WebStorm: http://www.jetbrains.com/webstorm/webhelp/jshint.html
{
"maxerr" : 100, // {int} Maximum error before stopping
// Enforcing
"bitwise" : false, // true: Prohibit bitwise operators (&, |, ^, etc.)
"camelcase" : true, // true: Identifiers must be in camelCase
"curly" : true, // true: Require {} for every new block or scope
"eqeqeq" : true, // true: Require triple equals (===) for comparison
"forin" : false, // true: Require filtering for..in loops with obj.hasOwnProperty()
"immed" : true, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());`
"indent" : 4, // {int} Number of spaces to use for indentation
"latedef" : true, // true: Require variables/functions to be defined before being used
"newcap" : true, // true: Require capitalization of all constructor functions e.g. `new F()`
"noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee`
"noempty" : true, // true: Prohibit use of empty blocks
"nonbsp" : true, // true: Prohibit use of non-breaking whitespace characters
"nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment)
"plusplus" : false, // true: Prohibit use of `++` & `--`
"quotmark" : false, // Quotation mark consistency:
// false : do nothing (default)
// true : ensure whatever is used is consistent
// "single" : require single quotes
// "double" : require double quotes
"undef" : true, // true: Require all non-global variables to be declared (prevents global leaks)
"unused" : true, // true: Require all defined variables be used
"strict" : false, // true: Requires all functions run in ES5 Strict Mode
"trailing" : true, // true: Prohibit trailing whitespaces
"maxparams" : false, // {int} Max number of formal params allowed per function
"maxdepth" : false, // {int} Max depth of nested blocks (within functions)
"maxstatements" : false, // {int} Max number statements per function
"maxcomplexity" : false, // {int} Max cyclomatic complexity per function
"maxlen" : false, // {int} Max number of characters per line
// Relaxing
"asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons)
"boss" : false, // true: Tolerate assignments where comparisons would be expected
"debug" : true, // true: Allow debugger statements e.g. browser breakpoints.
"eqnull" : false, // true: Tolerate use of `== null`
"esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`)
"moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features)
// (ex: `for each`, multiple try/catch, function expression…)
"evil" : false, // true: Tolerate use of `eval` and `new Function()`
"expr" : false, // true: Tolerate `ExpressionStatement` as Programs
"funcscope" : false, // true: Tolerate defining variables inside control statements"
"globalstrict" : false, // true: Allow global "use strict" (also enables 'strict')
"iterator" : false, // true: Tolerate using the `__iterator__` property
"lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block
"laxbreak" : false, // true: Tolerate possibly unsafe line breakings
"laxcomma" : false, // true: Tolerate comma-first style coding
"loopfunc" : false, // true: Tolerate functions being defined in loops
"multistr" : false, // true: Tolerate multi-line strings
"proto" : false, // true: Tolerate using the `__proto__` property
"scripturl" : false, // true: Tolerate script-targeted URLs
"smarttabs" : true, // true: Tolerate mixed tabs/spaces when used for alignment
"shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;`
"sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation
"supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;`
"validthis" : false, // true: Tolerate using this in a non-constructor function
// Environments
"browser" : false, // Web Browser (window, document, etc)
"couch" : false, // CouchDB
"devel" : false, // Development/debugging (alert, confirm, etc)
"dojo" : false, // Dojo Toolkit
"jquery" : false, // jQuery
"mootools" : false, // MooTools
"node" : true, // Node.js
"nonstandard" : false, // Widely adopted globals (escape, unescape, etc)
"prototypejs" : false, // Prototype and Scriptaculous
"rhino" : false, // Rhino
"worker" : false, // Web Workers
"wsh" : false, // Windows Scripting Host
"yui" : false, // Yahoo User Interface
// Legacy
"nomen" : false, // true: Prohibit dangling `_` in variables
"onevar" : false, // true: Allow only one `var` statement per function
"passfail" : false, // true: Stop on first error
"white" : true, // true: Check against strict whitespace and indentation rules
// Custom Globals
"globals" : { // additional predefined global variables
"phantom": false,
"describe": false,
"it": false,
"before": false,
"beforeEach": false,
"after": false,
"afterEach": false
}
}

67
Makefile Normal file
View File

@@ -0,0 +1,67 @@
##
# node-iap project Makefile
# description : Makefile to install this project and its dependencies along with other helpers
# author : Almir Kadric
# created on : 2014-10-29
##
##
# Global variables
##
# Set default shell
SHELL = /bin/bash
# Function for help
define helpText
######################################
### Node InAppPurchases ###
######################################
make install Install project dependencies
make dev Install & setup project & development dependencies
make test Runs all tests (shortcut for test-lint and test-unit).
make test-unit Run all unit tests
make test-lint Lint the entire project
endef
export helpText
##
# Make Targets
##
# List of target which should be run every time without caching
.PHONY: install dev test test-unit test-lint
# Default make target
%::
@echo "$$helpText"
Default :
@echo "$$helpText"
# Install target
install :
npm install --production
# Dev target
dev :
npm install
./sbin/lint.sh setup
# Test all
test : test-lint test-unit
# Unit test target
test-unit :
./node_modules/.bin/mocha -R spec --recursive ./tests
# Lint target
test-lint :
./sbin/lint.sh ${lintFilter}

View File

@@ -36,8 +36,10 @@ function parseResult(result) {
return {
receipt: receipt,
/* jshint camelcase:false */
transactionId: receipt.transaction_id,
productId: receipt.product_id
/* jshint camelcase:true */
};
}
@@ -49,7 +51,7 @@ function verify(environmentUrl, options, cb) {
}
if (res.statusCode !== 200) {
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + responseData));
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + resultString));
}
var resultObject;
@@ -95,9 +97,11 @@ exports.verifyPayment = function (payment, cb) {
var receipt = result.receipt;
/* jshint camelcase:false */
if (payment.hasOwnProperty('productId') && payment.productId !== receipt.product_id) {
return cb(new Error('Wrong product ID: ' + payment.productId + ' (expected: ' + receipt.product_id + ')'));
}
/* jshint camelcase:true */
if (payment.hasOwnProperty('packageName') && payment.packageName !== receipt.bid) {
return cb(new Error('Wrong bundle ID: ' + payment.packageName + ' (expected: ' + receipt.bid + ')'));

View File

@@ -6,7 +6,7 @@ var https = require('../https');
exports.verifyPayment = function (payment, cb) {
var data, keyObject;
var keyObject;
try {
assert.equal(typeof payment.packageName, 'string', 'Package name must be a string');
@@ -19,17 +19,21 @@ exports.verifyPayment = function (payment, cb) {
keyObject = payment.keyObject;
}
/* jshint camelcase:false */
assert(keyObject, 'Google API key object must be provided');
assert.equal(typeof keyObject, 'object', 'Google API key object must be an object');
assert.equal(typeof keyObject.client_email, 'string', 'Google API client_email must be a string');
assert.equal(typeof keyObject.private_key, 'string', 'Google API private_key must be a string');
/* jshint camelcase:true */
} catch (error) {
return process.nextTick(function () {
cb(error);
});
}
/* jshint camelcase:false */
jwt.getToken(keyObject.client_email, keyObject.private_key, apiUrls.publisherScope, function (error, requestToken) {
/* jshint camelcase:true */
if (error) {
return cb(error);
}
@@ -38,7 +42,9 @@ exports.verifyPayment = function (payment, cb) {
payment.packageName,
payment.productId,
payment.receipt,
/* jshint camelcase:false */
requestToken.access_token
/* jshint camelcase:true */
);
https.get(requestUrl, null, function (error, res, responseString) {

View File

@@ -16,9 +16,11 @@ exports.getToken = function (iss, key, scope, cb) {
}, key, 'RS256');
var formData = {
/* jshint camelcase:false */
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
/* jshint camelcase:true */
assertion: jwtToken
}
};
https.post(apiUrls.tokenRequest, { form: formData }, function (error, res, responseString) {
if (error) {
@@ -26,7 +28,7 @@ exports.getToken = function (iss, key, scope, cb) {
}
if (res.statusCode !== 200) {
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + responseData));
return cb(new Error('Received ' + res.statusCode + ' status code with body: ' + responseString));
}
var responseObject;

View File

@@ -24,5 +24,10 @@
"minimist": "0.0.8",
"jwt-simple": "0.2.0",
"form-urlencoded": "0.0.6"
},
"devDependencies": {
"jsdoc": "3.3.0-alpha4",
"jshint": "2.5.0",
"mocha": "1.20.1"
}
}

75
sbin/lint.sh Executable file
View File

@@ -0,0 +1,75 @@
#!/bin/bash
# Set strict options
set -o errexit
set -o nounset
# Get project directory
PROJECTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)";
# Extract command from arguments
COMMAND=${1:-};
# jshint command with arguments
JSHINT="${PROJECTDIR}/node_modules/.bin/jshint --config ${PROJECTDIR}/.jshintrc"
# Function which updates git hooks
updateGitHooks() {
echo "Updating git hooks";
# Update hook contents
cat >${PROJECTDIR}/.git/hooks/pre-commit <<EOF
#!/bin/bash
PROJECTDIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)";
make -C "${PROJECTDIR}" test lintFilter=staged
EOF
# Update hook permissions
chmod +x ${PROJECTDIR}/.git/hooks/pre-commit
}
# Function which prints error and usage help
function printHelp() {
echo "";
if [ -n "${1:-}" ]; then
echo " ${1:-}";
echo "";
fi
echo " Usage: $0 <command> [options]";
echo "";
echo " Commands:";
echo "";
echo " setup Setup jshint githooks";
echo " staged Lint all staged files";
echo " all Lint all files in the project. This is the default command.";
echo "";
}
# Process command
case ${COMMAND} in
"setup" )
updateGitHooks;
;;
"staged" )
git diff --raw --name-only --cached --diff-filter=ACMR | grep -E '\.js(on)?$' | xargs -I '{}' ${JSHINT} '{}';
;;
"all" )
eval "${JSHINT} ${PROJECTDIR}";
;;
"" )
eval "${JSHINT} ${PROJECTDIR}";
;;
"help" )
printHelp;
;;
* )
printHelp "Invalid command: ${COMMAND}";
;;
esac

0
tests/.placeholder Normal file
View File