-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from nightshiftjs/setup
Setup
- Loading branch information
Showing
11 changed files
with
415 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules | ||
npm-debug.log | ||
build | ||
.grunt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
{ | ||
"bitwise": true, | ||
"camelcase": true, | ||
"curly": true, | ||
"eqeqeq": true, | ||
"esnext": true, | ||
"forin": true, | ||
"globals": {}, | ||
"immed": true, | ||
"jasmine": true, | ||
"latedef": "nofunc", | ||
"maxdepth": 2, | ||
"maxstatements": 50, | ||
"newcap": true, | ||
"noarg": true, | ||
"node": true, | ||
"noempty": true, | ||
"nonew": true, | ||
"quotmark": "single", | ||
"strict": true, | ||
"undef": true, | ||
"unused": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Change Log | ||
All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http.semver.org). | ||
|
||
## 0.1.0 - 2016-04-14 | ||
### Added | ||
- Created the NightShift core object |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
'use strict'; | ||
|
||
module.exports = function (grunt) { | ||
|
||
// project's configuration | ||
grunt.initConfig({ | ||
pkg: grunt.file.readJSON('package.json'), | ||
src: 'src', | ||
tests: 'tests', | ||
build: 'build', | ||
coverage: '<%= build %>/coverage', | ||
coverage_tmp: '<%= coverage %>/tmp', | ||
|
||
clean: { | ||
build: { | ||
src: ['<%= build %>'] | ||
}, | ||
coverage: { | ||
src: ['<%= coverage %>'] | ||
}, | ||
coverage_tmp: { | ||
src: ['<%= coverage_tmp %>'] | ||
} | ||
}, | ||
|
||
// JSHint's configuration (see http://jshint.com/docs/options/ for the list of available options) | ||
jshint: { | ||
productionCode: { | ||
options: {jshintrc: '.jshintrc'}, | ||
src: ['<%= src %>/**/*.js'] | ||
}, | ||
testCode: { | ||
options: {jshintrc: '.jshintrc'}, | ||
src: ['<%= tests %>/**/*.js'] | ||
} | ||
}, | ||
|
||
runTests: { | ||
unit: { | ||
delegate: 'jasmine_nodejs:unit' | ||
}, | ||
unitWithCoverage: { | ||
delegate: 'jasmine_nodejs:unitWithCoverage' | ||
} | ||
}, | ||
|
||
jasmine_nodejs: { | ||
unit: { | ||
specs: ['<%= tests %>/**'] | ||
}, | ||
unitWithCoverage: { | ||
specs: ['<%= coverage_tmp %>/<%= tests %>/**'] | ||
} | ||
}, | ||
|
||
instrument: { | ||
files: ['<%= src %>/**/*.js'], | ||
options: { | ||
lazy: true, | ||
basePath: '<%= coverage_tmp %>' | ||
} | ||
}, | ||
|
||
storeCoverage: { | ||
options: { | ||
dir: '<%= coverage_tmp %>' | ||
} | ||
}, | ||
|
||
makeReport: { | ||
src: '<%= coverage_tmp %>/coverage.json', | ||
options: { | ||
type: 'html', | ||
dir: '<%= coverage %>', | ||
print: 'detail' | ||
} | ||
}, | ||
|
||
copy: { | ||
toCoverageTmp: { | ||
files: [ | ||
{ | ||
expand: true, | ||
src: '<%= tests %>/**', | ||
dest: '<%= coverage_tmp %>' | ||
} | ||
] | ||
} | ||
} | ||
}); | ||
|
||
// plugin for deleting files (see https://github.com/gruntjs/grunt-contrib-clean) | ||
grunt.loadNpmTasks('grunt-contrib-clean'); | ||
|
||
// plugin for validating files (see https://github.com/gruntjs/grunt-contrib-jshint) | ||
grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
|
||
// plugin for testing files (see https://github.com/onury/grunt-jasmine-nodejs) | ||
grunt.loadNpmTasks('grunt-jasmine-nodejs'); | ||
|
||
// plugin for computing test coverage (see https://github.com/taichi/grunt-istanbul) | ||
grunt.loadNpmTasks('grunt-istanbul'); | ||
|
||
// plugin for copying files (see https://github.com/gruntjs/grunt-contrib-copy) | ||
grunt.loadNpmTasks('grunt-contrib-copy'); | ||
|
||
// If a file is not required, then it won't be included in the coverage report. Actually, that report does not show | ||
// the coverage of the code but the coverage of the specs, which can be misleading. The workaround is to require the | ||
// instrumented files before running the tests. | ||
grunt.task.registerTask('requireInstrumentedFiles', function () { | ||
var _ = require('lodash'); | ||
var glob = require('glob'); | ||
_.forEach(glob.sync(grunt.config.get('coverage_tmp') + '/**/!(di.js|*.di.js|*.spec.js).js'), function (file) { | ||
require('./' + file); | ||
}); | ||
}); | ||
|
||
grunt.task.registerMultiTask('runTests', function runTests() { | ||
var data = this.data; | ||
|
||
// improve the logging of the errors | ||
require('pretty-error').start(); | ||
|
||
return grunt.task.run(data.delegate); | ||
}); | ||
|
||
grunt.task.registerTask('default', ['build']); | ||
|
||
grunt.task.registerTask('build', [ | ||
'clean:build', | ||
'jshint', | ||
'build-coverage']); | ||
|
||
grunt.task.registerTask('build-coverage', [ | ||
'clean:coverage', | ||
'instrument', | ||
'requireInstrumentedFiles', | ||
'copy:toCoverageTmp', | ||
'runTests:unitWithCoverage', | ||
'storeCoverage', | ||
'makeReport', | ||
'clean:coverage_tmp' | ||
]); | ||
|
||
grunt.task.registerTask('test', ['runTests:unit']); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,86 @@ | ||
# nightshift-core | ||
The core of NightShiftJS | ||
NightShift has been designed to be configurable and extendable. | ||
|
||
## Configurability | ||
The configurability allows you to use only the features that you need and to avoid undesired dependencies. For example, if you are only interested in [dependency injection](https://github.com/nightshiftjs/nightshift-dependency-injection), then you can configure NightShift as below. | ||
|
||
```javascript | ||
var nightShift = require('nightshift-core'); | ||
var di = require('nightshift-dependency-injection'); | ||
|
||
nightShift.plugin(di); | ||
``` | ||
|
||
NightShift is exactly what you want it to be! | ||
|
||
## Extendability | ||
The extendability allows you to enrich NightShift with your own plugins. A NightShift plugin is nothing more than a function that enriches the NightShift core object. For example, the plugin below adds logging capabilities to NightShift. | ||
|
||
```javascript | ||
module.exports = function plugin(nightShift) { | ||
nightShift.logger = {...}; | ||
}; | ||
``` | ||
|
||
A plugin can rely on the availability of other plugins at runtime. However, it is recommended not to make a plugin explicitly dependent on another plugin, so different versions or implementations of the same plugins can be combined. | ||
|
||
## Demo | ||
Discover what you can do with NightShift in this [demo](https://github.com/nightshiftjs/nightshift-demo)! | ||
|
||
## Utilities | ||
The NightShift core object provides some utilities. | ||
|
||
### functions | ||
#### factoryOf(ConstructorFn) | ||
The usage of the `new` keyword prevents a module from being testable in isolation. Using `new` makes it impossible to test a module without (re-)testing the delegate it instantiates. A solution is to encapsulate the instantiation in a factory which can then be injected in the module and mocked for the testing. | ||
|
||
The method `nightShift.functions.factoryOf(ConstructorFn)` creates a factory that can instantiate objects by invoking the given constructor function with the parameters it receives. | ||
|
||
```javascript | ||
it('should return a factory for the given constructor function', function () { | ||
var Point = function (x, y) { | ||
this.x = x; | ||
this.y = y; | ||
}; | ||
var factory = nightShift.functions.factoryOf(Point); | ||
expect(factory(10, 20)).toEqual(new Point(10, 20)); | ||
}); | ||
``` | ||
|
||
### getParamNames(fn) | ||
The method `nightShift.functions.getParamNames(fn)` returns an array listing the names of the parameters of the given function. The array is empty if the function does not expect any parameter. | ||
|
||
```javascript | ||
it('should return the names of the parameters of the given function', function () { | ||
expect(nightShift.functions.getParamNames(function () {})).toEqual([]); | ||
expect(nightShift.functions.getParamNames(function (one) {})).toEqual(['one']); | ||
expect(nightShift.functions.getParamNames(function (one, two) {})).toEqual(['one', 'two']); | ||
}); | ||
``` | ||
|
||
### getNbOfParams(fn) | ||
The method `nightShift.functions.getNbOfParams(fn)` returns the number of parameters which are expected by the given function. | ||
|
||
```javascript | ||
it('should return the number of parameters of the given function', function () { | ||
expect(nightShift.functions.getNbOfParams(function () {})).toEqual(0); | ||
expect(nightShift.functions.getNbOfParams(function (one) {})).toEqual(1); | ||
expect(nightShift.functions.getNbOfParams(function (one, two) {})).toEqual(2); | ||
}); | ||
``` | ||
|
||
## Tests | ||
The tests can be executed by running the command below. | ||
``` | ||
npm install && npm test | ||
``` | ||
|
||
The test coverage can be checked by running the command below. It executes the tests and it generates a coverage report in _build/coverage/index.html_. | ||
``` | ||
npm install && npm build-coverage | ||
``` | ||
|
||
The quality of the code can be checked by running the command below. It detects potential problems in the code with JSHint, it executes the tests and it generates a coverage report. | ||
``` | ||
npm install && npm build | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "nightshift-core", | ||
"description": "The core of NightShift", | ||
"version": "0.1.0", | ||
"main": "src/index.js", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/nightshiftjs/nightshift-core.git" | ||
}, | ||
"scripts": { | ||
"build": "grunt build", | ||
"build-coverage": "grunt build-coverage", | ||
"test": "grunt test" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"glob": "7.0.3", | ||
"grunt": "1.0.1", | ||
"grunt-contrib-clean": "1.0.0", | ||
"grunt-contrib-copy": "1.0.0", | ||
"grunt-contrib-jshint": "1.0.0", | ||
"grunt-istanbul": "0.7.0", | ||
"grunt-jasmine-nodejs": "1.5.2", | ||
"lodash": "4.9.0", | ||
"pretty-error": "2.0.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
'use strict'; | ||
|
||
var functions = require('./utils/functions')(); | ||
|
||
module.exports = require('./nightshift')(functions); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
'use strict'; | ||
|
||
module.exports = function createNightShiftObject(functions) { | ||
|
||
function NightShift() {} | ||
|
||
NightShift.prototype.functions = functions; | ||
|
||
NightShift.prototype.plugin = function(pluginFn) { | ||
return pluginFn(this); | ||
}; | ||
|
||
return new NightShift(); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
'use strict'; | ||
|
||
module.exports = function createFunctionUtils() { | ||
|
||
/** | ||
* The usage of the 'new' keyword prevents a module from being testable in isolation. Using 'new' makes it | ||
* impossible to test a module without (re-)testing the delegate it instantiates. A solution is to encapsulate the | ||
* instantiation in a factory which can then be injected in the module and mocked for the testing. | ||
* | ||
* This method creates a factory that can instantiate objects by invoking the given constructor function with the | ||
* parameters it receives. | ||
* | ||
* @param {function} Constructor the constructor function to use for instantiating objects | ||
* @returns {function} a factory function that expects the same parameters as the given constructor function | ||
*/ | ||
function factoryOf(Constructor) { | ||
return function () { | ||
var args = Array.prototype.slice.call(arguments); | ||
args.unshift(null); | ||
var BoundConstructor = Function.prototype.bind.apply(Constructor, args); | ||
return new BoundConstructor(); | ||
}; | ||
} | ||
|
||
/** | ||
* This method returns an array listing the names of the parameters of the given function. The array is empty if the | ||
* function does not expect any parameter. | ||
* | ||
* @param {function} fn the function to retrieve the parameters names for | ||
* @returns {Array|{index: number, input: string}} an array listing the names of the parameters of the given | ||
* function, or an empty array if the function does not expect any parameter | ||
*/ | ||
function getParamNames(fn) { | ||
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; | ||
var fnString = fn.toString().replace(STRIP_COMMENTS, ''); | ||
var result = fnString.slice(fnString.indexOf('(') + 1, fnString.indexOf(')')).match(/([^\s,]+)/g); | ||
return result || []; | ||
} | ||
|
||
/** | ||
* This method returns the number of parameters which are expected by the given function. | ||
* | ||
* @param {function} fn the function to retrieve the number of parameters for | ||
* @returns {Number} the number of parameters which are expected by the given function | ||
*/ | ||
function getNbOfParams(fn) { | ||
return getParamNames(fn).length; | ||
} | ||
|
||
return { | ||
factoryOf: factoryOf, | ||
getParamNames: getParamNames, | ||
getNbOfParams: getNbOfParams | ||
}; | ||
}; |
Oops, something went wrong.