Permalink
Browse files

Initial commit

  • Loading branch information...
0 parents commit 360ef9b45fdf2c14b3a20f51bbbde627fe580a50 @easternbloc committed Jan 15, 2012
Showing with 7,438 additions and 0 deletions.
  1. +42 −0 README.md
  2. +8 −0 example/dns.js
  3. +23 −0 example/dnsExample.js
  4. +1 −0 index.js
  5. +75 −0 lib/syringe.js
  6. +108 −0 node_modules/.bin/nodeunit
  7. +3 −0 node_modules/nodeunit/.gitignore
  8. +3 −0 node_modules/nodeunit/.npmignore
  9. +60 −0 node_modules/nodeunit/CONTRIBUTORS.md
  10. +19 −0 node_modules/nodeunit/LICENSE
  11. +126 −0 node_modules/nodeunit/Makefile
  12. +433 −0 node_modules/nodeunit/README.md
  13. +108 −0 node_modules/nodeunit/bin/nodeunit
  14. +10 −0 node_modules/nodeunit/bin/nodeunit.json
  15. +623 −0 node_modules/nodeunit/deps/async.js
  16. +125 −0 node_modules/nodeunit/deps/ejs.js
  17. +483 −0 node_modules/nodeunit/deps/json2.js
  18. +60 −0 node_modules/nodeunit/doc/nodeunit.md
  19. +1,757 −0 node_modules/nodeunit/examples/browser/nodeunit.js
  20. +12 −0 node_modules/nodeunit/examples/browser/suite1.js
  21. +13 −0 node_modules/nodeunit/examples/browser/suite2.js
  22. +16 −0 node_modules/nodeunit/examples/browser/test.html
  23. BIN node_modules/nodeunit/img/example_fail.png
  24. BIN node_modules/nodeunit/img/example_pass.png
  25. +3 −0 node_modules/nodeunit/index.js
  26. +316 −0 node_modules/nodeunit/lib/assert.js
  27. +236 −0 node_modules/nodeunit/lib/core.js
  28. +80 −0 node_modules/nodeunit/lib/nodeunit.js
  29. +119 −0 node_modules/nodeunit/lib/reporters/browser.js
  30. +131 −0 node_modules/nodeunit/lib/reporters/default.js
  31. +112 −0 node_modules/nodeunit/lib/reporters/html.js
  32. +9 −0 node_modules/nodeunit/lib/reporters/index.js
  33. +186 −0 node_modules/nodeunit/lib/reporters/junit.js
  34. +117 −0 node_modules/nodeunit/lib/reporters/minimal.js
  35. +110 −0 node_modules/nodeunit/lib/reporters/skip_passed.js
  36. +50 −0 node_modules/nodeunit/lib/track.js
  37. +187 −0 node_modules/nodeunit/lib/types.js
  38. +209 −0 node_modules/nodeunit/lib/utils.js
  39. +95 −0 node_modules/nodeunit/man1/nodeunit.1
  40. +4 −0 node_modules/nodeunit/nodelint.cfg
  41. +53 −0 node_modules/nodeunit/package.json
  42. +19 −0 node_modules/nodeunit/share/junit.xml.ejs
  43. +11 −0 node_modules/nodeunit/share/license.js
  44. +70 −0 node_modules/nodeunit/share/nodeunit.css
  45. +4 −0 node_modules/nodeunit/test/fixtures/coffee/mock_coffee_module.coffee
  46. +1 −0 node_modules/nodeunit/test/fixtures/dir/mock_module3.js
  47. +1 −0 node_modules/nodeunit/test/fixtures/dir/mock_module4.js
  48. +1 −0 node_modules/nodeunit/test/fixtures/mock_module1.js
  49. +1 −0 node_modules/nodeunit/test/fixtures/mock_module2.js
  50. +3 −0 node_modules/nodeunit/test/fixtures/raw_jscode1.js
  51. +3 −0 node_modules/nodeunit/test/fixtures/raw_jscode2.js
  52. +1 −0 node_modules/nodeunit/test/fixtures/raw_jscode3.js
  53. +219 −0 node_modules/nodeunit/test/test-base.js
  54. +114 −0 node_modules/nodeunit/test/test-failing-callbacks.js
  55. +55 −0 node_modules/nodeunit/test/test-httputil.js
  56. +214 −0 node_modules/nodeunit/test/test-runfiles.js
  57. +125 −0 node_modules/nodeunit/test/test-runmodule.js
  58. +46 −0 node_modules/nodeunit/test/test-runtest.js
  59. +31 −0 node_modules/nodeunit/test/test-sandbox.js
  60. +234 −0 node_modules/nodeunit/test/test-testcase.js
  61. +26 −0 node_modules/nodeunit/test/test.html
  62. +20 −0 package.json
  63. +114 −0 test/syringe.test.js
@@ -0,0 +1,42 @@
+Syringe
+=======
+Using modules in node is easy however unit testing code that requires modules is a little more tricky. Syringe aims to assist with this problem by providing a handy set of helpers for injection and watching of module methods.
+
+## Turtles all the way down
+To properly unit test your code you need mock all the modules and methods your module collaborates with. Ideally you keep going till you hit turtles or at least until you've stubbed every method you use. Take the following example:
+
+ var dns = require('dns');
+ var url = require('url');
+
+ module.exports.resolveAddress = function(urlToResolve, callback) {
+ var urlParsed = url.parse(urlToResolve).hostname;
+
+ dns.resolve4(urlParsed, callback);
+ };
+
+In order to unit test this module properly, you need to mock functions in the dns and url modules. Syringe lets you inject directly over the top of modules or selectively mock the methods in them you're using.
+
+ var dns = require('./dns');
+ var syringe = require('syringe');
+
+ var dnsMod = syringe('dns');
+ var urlMod = syringe('url');
+
+ dnsMod.inject('resolve4', function (url, callback) {
+ callback(null, ['127.0.0.1']);
+ });
+
+ urlMod.inject('parse', function() {
+ return {hostname: 'www.google.com'};
+ });
+
+ urlMod.wrap('parse', function() {
+ console.log('yep, that function was called from within the require!');
+ });
+
+ dns.resolveAddress('http://www.google.com/', function(err, result) {
+ if (err) {
+ throw new Error(err);
+ }
+ console.log('Resolved dns list:', result);
+ });
@@ -0,0 +1,8 @@
+var dns = require('dns');
+var url = require('url');
+
+module.exports.resolveAddress = function(urlToResolve, callback) {
+ var urlParsed = url.parse(urlToResolve).hostname;
+
+ dns.resolve4(urlParsed, callback);
+}
@@ -0,0 +1,23 @@
+var dns = require('./dns');
+var syringe = require('../lib/syringe');
+var dnsMod = syringe('dns');
+var urlMod = syringe('url');
+
+dnsMod.inject('resolve4', function (url, callback) {
+ callback(null, ['127.0.0.1']);
+});
+
+urlMod.inject('parse', function() {
+ return {hostname: 'www.google.com'};
+});
+
+urlMod.wrap('parse', function() {
+ console.log('yep, that function was called from within the require!');
+});
+
+dns.resolveAddress('http://www.google.com/', function(err, result) {
+ if (err) {
+ throw new Error(err);
+ }
+ console.log('Resolved dns list:', result);
+});
@@ -0,0 +1 @@
+module.exports = require('./lib/syringe');
@@ -0,0 +1,75 @@
+var modules = {};
+
+function Syringe(moduleName) {
+ var moduleCache = {},
+ module = require(moduleName);
+
+ modules[moduleName] = module;
+
+ this.inject = function(methodName, method) {
+ if(module[methodName]) {
+ this.forceInject(methodName, method);
+ return this;
+ } else {
+ throw new Error(methodName + ' does not exist in the module.');
+ }
+ };
+
+ this.forceInject = function(methodName, method) {
+ if(module[methodName]) {
+ moduleCache[methodName] = module[methodName];
+ }
+ module[methodName] = method;
+ return this;
+ };
+
+ this.restore = function(methodName) {
+ if(moduleCache[methodName]) {
+ module[methodName] = moduleCache[methodName];
+ return this;
+ } else {
+ throw new Error(methodName + ' does not exist in the module so cannot be restored.');
+ }
+ };
+
+ this.wrap = function(methodName, before) {
+ if (module[methodName] && typeof before === 'function') {
+ moduleCache[methodName] = module[methodName];
+
+ module[methodName] = function() {
+ before();
+ return moduleCache[methodName].apply(null, arguments);
+ }
+ } else {
+ throw new Error(methodName + ' does not exist in the module so cannot be wrapped.');
+ }
+ };
+
+ this.unWrap = function(methodName) {
+ this.restore(methodName);
+ };
+
+ this.replaceAll = function(replaceModule) {
+ if (typeof replaceModule === 'object') {
+ for(var methodName in replaceModule) {
+ this.inject(methodName, replaceModule[methodName]);
+ }
+ } else {
+ throw new Error(methodName + ' does not exist in the module so cannot be wrapped.');
+ }
+ };
+
+ this.restoreAll = function(restoreModule) {
+ for(var method in moduleCache) {
+ this.restore(method);
+ };
+ };
+}
+
+module.exports = function(moduleName) {
+ if (!modules[moduleName]) {
+ return new Syringe(moduleName);
+ } else {
+ return modules[moduleName];
+ }
+};
@@ -0,0 +1,108 @@
+#!/usr/bin/env node
+
+var
+ fs = require('fs'),
+ sys = require('sys'),
+ path = require('path');
+
+require.paths.push(process.cwd());
+var args = process.ARGV.slice(2);
+
+var files = [];
+
+var testrunner,
+ config_file,
+ config_param_found = false,
+ output_param_found = false,
+ reporter_file = 'default',
+ reporter_param_found = false;
+
+var usage = "Usage: nodeunit [options] testmodule1.js testfolder [...] \n" +
+ "Options:\n\n" +
+ " --config FILE the path to a JSON file with options\n" +
+ " --reporter FILE optional path to a reporter file to customize the output\n" +
+ " --list-reporters list available build-in reporters\n" +
+ " -h, --help display this help and exit\n" +
+ " -v, --version output version information and exit";
+
+
+// load default options
+var content = fs.readFileSync(__dirname + '/nodeunit.json', 'utf8');
+var options = JSON.parse(content);
+
+// a very basic pseudo --options parser
+args.forEach(function (arg) {
+ if (arg.slice(0, 9) === "--config=") {
+ config_file = arg.slice(9);
+ } else if (arg === '--config') {
+ config_param_found = true;
+ } else if (config_param_found) {
+ config_file = arg;
+ config_param_found = false;
+ } else if (arg.slice(0, 9) === "--output=") {
+ options.output = arg.slice(9);
+ } else if (arg === '--output') {
+ output_param_found = true;
+ } else if (output_param_found) {
+ options.output = arg;
+ output_param_found = false;
+ } else if (arg.slice(0, 11) === "--reporter=") {
+ reporter_file = arg.slice(11);
+ } else if (arg === '--reporter') {
+ reporter_param_found = true;
+ } else if (reporter_param_found) {
+ reporter_file = arg;
+ reporter_param_found = false;
+ } else if (arg === '--list-reporters') {
+ var reporters = fs.readdirSync(__dirname + '/../lib/reporters');
+ reporters = reporters.filter(function (reporter_file) {
+ return (/\.js$/).test(reporter_file);
+ }).map(function (reporter_file) {
+ return reporter_file.replace(/\.js$/, '');
+ }).filter(function (reporter_file) {
+ return reporter_file !== 'index';
+ });
+ sys.puts('Build-in reporters: ');
+ reporters.forEach(function (reporter_file) {
+ var reporter = require('../lib/reporters/' + reporter_file);
+ sys.puts(' * ' + reporter_file + (reporter.info ? ': ' + reporter.info : ''));
+ });
+ process.exit(0);
+ } else if ((arg === '-v') || (arg === '--version')) {
+ var content = fs.readFileSync(__dirname + '/../package.json', 'utf8');
+ var pkg = JSON.parse(content);
+ sys.puts(pkg.version);
+ process.exit(0);
+ } else if ((arg === '-h') || (arg === '--help')) {
+ sys.puts(usage);
+ process.exit(0);
+ } else {
+ files.push(arg);
+ }
+});
+
+if (files.length === 0) {
+ sys.puts('Files required.');
+ sys.puts(usage);
+ process.exit(1);
+}
+
+if (config_file) {
+ content = fs.readFileSync(config_file, 'utf8');
+ var custom_options = JSON.parse(content);
+
+ for (var option in custom_options) {
+ if (typeof option === 'string') {
+ options[option] = custom_options[option];
+ }
+ }
+}
+
+var builtin_reporters = require(__dirname + '/../lib/reporters');
+if (reporter_file in builtin_reporters) {
+ testrunner = builtin_reporters[reporter_file];
+}
+else {
+ testrunner = require(reporter_file);
+}
+testrunner.run(files, options);
@@ -0,0 +1,3 @@
+dist
+stamp-build
+*~
@@ -0,0 +1,3 @@
+dist
+stamp-build
+test/fixtures/dir2
@@ -0,0 +1,60 @@
+Nodeunit contributors (sorted alphabeticaly)
+============================================
+
+* **[Alex Gorbatchev](https://github.com/alexgorbatchev)**
+
+ * Deeper default object inspection
+ * Timeout to ensure flushing of console output (default reporter)
+
+* **[Alex Wolfe](https://github.com/alexkwolfe)**
+
+ * HTML test reporter
+
+* **[Caolan McMahon](https://github.com/caolan)**
+
+ * Author and maintainer
+ * Most features develpopment
+
+* **[Carl Fürstenberg](https://github.com/azatoth)**
+
+ * Debian-friendly Makefile, supports both 'node' and 'nodejs' executables
+ * Sandbox utility
+ * Minimal test reporter
+
+* **[Gerad Suyderhoud](https://github.com/gerad)**
+
+ * First comand-line tool
+
+* **[Kadir Pekel](https://github.com/coffeemate)**
+
+ * Improvements to default test reporter
+ * HTTP test utility
+
+* **[Matthias Lübken](https://github.com/luebken)**
+
+ * Utility functions for tracking incomplete tests on exit
+
+* **[Oleg Efimov](https://github.com/Sannis)**
+
+ * Adding 'make lint' and fixing nodelint errors
+ * Option parsing, --help text and config file support
+ * Reporters option for command-line tool
+
+* **[Orlando Vazquez](https://github.com/orlandov)**
+
+ * Added jUnit XML reporter
+
+* **[Ryan Dahl](https://github.com/ry)**
+
+ * Add package.json
+
+* **[Sam Stephenson](https://github.com/sstephenson)**
+
+ * Coffee-script support
+
+* **[Thomas Mayfield](https://github.com/thegreatape)**
+
+ * Async setUp and tearDown support for testCase
+
+**[Full contributors list](https://github.com/caolan/nodeunit/contributors).**
+
@@ -0,0 +1,19 @@
+Copyright (c) 2010 Caolan McMahon
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
Oops, something went wrong.

0 comments on commit 360ef9b

Please sign in to comment.