Navigation Menu

Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
tj committed May 28, 2010
0 parents commit 9f8de10
Show file tree
Hide file tree
Showing 11 changed files with 404 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
@@ -0,0 +1,2 @@
.DS_Store
lib-cov
3 changes: 3 additions & 0 deletions .gitmodules
@@ -0,0 +1,3 @@
[submodule "deps/jscoverage"]
path = deps/jscoverage
url = git://github.com/visionmedia/node-jscoverage.git
Empty file added History.md
Empty file.
27 changes: 27 additions & 0 deletions Makefile
@@ -0,0 +1,27 @@

BIN = bin/expresso
PREFIX = /usr/local
JSCOV = deps/jscoverage/node-jscoverage

test: $(BIN)
@./$(BIN) -I lib test/*.test.js

test-cov: $(BIN) $(JSCOV) lib-cov
@./$(BIN) -I lib-cov test/*.test.js

lib-cov:
@./$(JSCOV) lib lib-cov

install: $(JSCOV) install-expresso
install $(JSCOV) $(PREFIX)/bin

install-expresso:
install $(BIN) $(PREFIX)/bin

$(JSCOV):
@cd deps/jscoverage && ./configure && make && mv jscoverage node-jscoverage

clean:
@cd deps/jscoverage && git clean -fd

.PHONY: test test-cov install install-expresso clean
Empty file added Readme.md
Empty file.
283 changes: 283 additions & 0 deletions bin/expresso
@@ -0,0 +1,283 @@
#!/usr/bin/env node

/*!
* Expresso
* Copyright(c) TJ Holowaychuk <tj@vision-media.ca>
* (MIT Licensed)
*/

/**
* Module dependencies.
*/

var assert = require('assert'),
childProcess = require('child_process'),
path = require('path'),
sys = require('sys'),
cwd = process.cwd(),
fs = require('fs');

/**
* Expresso version.
*/

var version = '0.0.1';

/**
* Usage documentation.
*/

var usage = [
'usage: expresso [-h|--help] [-v|--version] [-i|-I|--include <path>]',
' [-r|--require <module>] <file ...>'
].join('\n')

// Parse arguments

var files = [],
args = process.argv.slice(2);

while (args.length) {
var arg = args.shift();
switch (arg) {
case '-h':
case '--help':
sys.puts(usage);
process.exit(1);
break;
case '-v':
case '--version':
sys.puts(version);
process.exit(1);
break;
case '-i':
case '-I':
case '--include':
if (arg = args.shift()) {
require.paths.unshift(arg);
} else {
throw new Error('--include requires a path');
}
break;
case '-r':
case '--require':
if (arg = args.shift()) {
require(arg);
} else {
throw new Error('--require requires a path');
}
break;
default:
files.push(arg);
break;
}
}

// Alias deepEqual as eql for complex equality

assert.eql = assert.deepEqual;

// Report test coverage when available

process.addListener('exit', function(){
sys.puts('');
if (typeof _$jscoverage === 'object') {
reportCoverage(_$jscoverage);
}
});

/**
* Pad the given string to the maximum width provided.
*
* @param {String} str
* @param {Number} width
* @return {String}
* @api private
*/

function lpad(str, width) {
str = String(str);
var n = width - str.length;
if (n < 1) return str;
while (n--) str = ' ' + str;
return str;
}

/**
* Pad the given string to the maximum width provided.
*
* @param {String} str
* @param {Number} width
* @return {String}
* @api private
*/

function rpad(str, width) {
str = String(str);
var n = width - str.length;
if (n < 1) return str;
while (n--) str = str + ' ';
return str;
}

/**
* Report test coverage.
*
* @param {Object} cov
* @api private
*/

function reportCoverage(cov) {
populateCoverage(cov);
sys.puts('\n \x1B[1mTest Coverage\x1B[0m');
var sep = ' +--------------------------------+----------+------+------+--------+',
lastSep = ' +----------+------+------+--------+';
sys.puts(sep);
sys.puts(' | filename | coverage | LOC | SLOC | missed |');
sys.puts(sep);
for (var name in cov) {
var file = cov[name];
if (file instanceof Array) {
sys.print(' | ' + rpad(name, 30));
sys.print(' | ' + lpad(file.coverage.toFixed(2), 8));
sys.print(' | ' + lpad(file.LOC, 4));
sys.print(' | ' + lpad(file.SLOC, 4));
sys.print(' | ' + lpad(file.totalMisses, 6));
sys.print(' |\n');
}
}
sys.puts(sep);
sys.print(' ' + rpad('', 30));
sys.print(' | ' + lpad(cov.coverage.toFixed(2), 8));
sys.print(' | ' + lpad(cov.LOC, 4));
sys.print(' | ' + lpad(cov.SLOC, 4));
sys.print(' | ' + lpad(cov.totalMisses, 6));
sys.print(' |\n');
sys.puts(lastSep);
}

/**
* Populate code coverage data.
*
* @param {Object} cov
* @api private
*/

function populateCoverage(cov) {
cov.LOC =
cov.SLOC =
cov.totalFiles =
cov.totalHits =
cov.totalMisses =
cov.coverage = 0;
for (var name in cov) {
var file = cov[name];
if (file instanceof Array) {
++cov.totalFiles;
cov.totalHits += file.totalHits = coverage(file, true);
cov.totalMisses += file.totalMisses = coverage(file, false);
file.totalLines = file.totalHits + file.totalMisses;
cov.SLOC += file.SLOC = file.totalLines;
cov.LOC += file.LOC = file.source.length;
file.coverage = (file.totalHits / file.totalLines) * 100;
}
}
cov.coverage = (cov.totalHits / cov.SLOC) * 100;
};

/**
* Total coverage for the given file data.
*
* @param {Array} data
* @return {Type}
* @api private
*/

function coverage(data, val) {
var n = 0;
for (var i = 0, len = data.length; i < len; ++i) {
if (data[i] !== undefined && data[i] == val) ++n;
}
return n;
};

/**
* Assert that the given array-like object
* is empty (length of 0).
*
* @param {Array} arr
* @api public
*/

assert.empty = function(arr, msg) {
assert.equal(arr.length, 0, msg);
};

/**
* Run all test files.
*
* @param {Array} files
* @api public
*/

function run(files) {
if (files.length) {
files.forEach(function(file){
var title = path.basename(file, '.js')
runSuite(title, require(cwd + '/' + file.replace('.js', '')));
});
}
}

/**
* Run the given tests.
*
* @param {String} title
* @param {Object} tests
* @api private
*/

function runSuite(title, tests) {
var title = ' \x1B[1m' + title + '\x1B[0m ',
keys = Object.keys(tests),
total = keys.length,
start = new Date,
failures = [],
current = 0;
(function next(){
if (keys.length) {
var percent = Math.round(++current / (total + 1) * 100),
key = keys.shift(),
test = tests[key],
async = test.length === 2;
sys.print('\x1B[K %' + percent + ' ' + title + ' ' + key + '\r');
try {
if (async) {
var n = test(assert, function(){
if (!--n) next();
}) || 1;
} else {
test(assert);
next();
}
} catch (err) {
err.test = key;
failures.push(err);
next();
}
} else {
var duration = ((new Date - start) / 1000).toFixed(3),
passes = total - failures.length;
sys.print('\x1B[K %100' + title + '\x1B[32m' + passes + '\x1B[0m'
+ ' \x1B[31m' + failures.length + '\x1B[0m'
+ ' in ' + duration + ' seconds\n');
failures.forEach(function(assertion, i){
sys.puts('\n \x1B[1m' + i + ')\x1B[0m ' + assertion.stack);
});
}
})();
}

// Run test files

run(files);
1 change: 1 addition & 0 deletions deps/jscoverage
Submodule jscoverage added at 0d4608
26 changes: 26 additions & 0 deletions lib/a.js
@@ -0,0 +1,26 @@

exports.upper = function(str){
if (typeof str === 'string') {
return str.toUpperCase();
} else {
return '';
}
}

exports.lower = function(str){
if (typeof str === 'string') {
return str.toLowerCase();
} else {
return '';
}
}

exports.lowerAsync = function(str, fn){
process.nextTick(function(){
if (typeof str === 'string') {
fn(str.toLowerCase());
} else {
fn('');
}
})
}
12 changes: 12 additions & 0 deletions lib/b.js
@@ -0,0 +1,12 @@

exports.selectAsync = function(arr, fn, callback){
process.nextTick(function(){
var selected = [];
for (var i = 0, len = arr.length; i < len; ++i) {
if (fn.call(arr, arr[i], i, arr)) {
selected.push(arr[i]);
}
}
callback(selected);
})
}

0 comments on commit 9f8de10

Please sign in to comment.