├── .npmignore ├── README.org ├── index.js ├── node_modules ├── nodewatch │ ├── docs │ │ ├── docco.css │ │ └── watch.html │ ├── lib │ │ └── watch │ │ │ └── watch.js │ └── package.json ├── simple-logger │ ├── .npmignore │ ├── README.md │ ├── index.js │ └── package.json └── underscore │ ├── .npmignore │ ├── LICENSE │ ├── README │ ├── index.html │ ├── index.js │ ├── package.json │ ├── underscore-min.js │ └── underscore.js ├── package.json ├── samples ├── nodeinterval.js └── nodeinterval.sh └── tests ├── assets └── index.html ├── listen.js ├── node_modules ├── .bin │ └── vows ├── nodeinterval │ ├── index.js │ └── node_modules │ │ ├── nodewatch │ │ ├── docs │ │ │ ├── docco.css │ │ │ └── watch.html │ │ ├── lib │ │ │ └── watch │ │ │ │ └── watch.js │ │ └── package.json │ │ ├── simple-logger │ │ ├── .npmignore │ │ ├── README.md │ │ ├── index.js │ │ └── package.json │ │ └── underscore │ │ ├── .npmignore │ │ ├── LICENSE │ │ ├── README │ │ ├── index.html │ │ ├── index.js │ │ ├── package.json │ │ ├── underscore-min.js │ │ └── underscore.js └── vows │ ├── .gitignore │ ├── LICENSE │ ├── Makefile │ ├── README.md │ ├── bin │ └── vows │ ├── lib │ ├── assert │ │ ├── error.js │ │ ├── macros.js │ │ └── utils.js │ ├── vows.js │ └── vows │ │ ├── console.js │ │ ├── context.js │ │ ├── coverage │ │ ├── file.js │ │ ├── fragments │ │ │ ├── coverage-foot.html │ │ │ └── coverage-head.html │ │ ├── report-html.js │ │ ├── report-json.js │ │ └── report-plain.js │ │ ├── extras.js │ │ ├── reporters │ │ ├── dot-matrix.js │ │ ├── json.js │ │ ├── silent.js │ │ ├── spec.js │ │ ├── watch.js │ │ └── xunit.js │ │ └── suite.js │ ├── package.json │ └── test │ ├── assert-test.js │ ├── fixtures │ └── isolate │ │ ├── failing.js │ │ ├── log.js │ │ ├── passing.js │ │ └── stderr.js │ ├── isolate-test.js │ ├── testInherit.js │ ├── vows-error-test.js │ └── vows-test.js ├── run-tests.js └── src ├── index.html └── templates ├── .bob ├── dir_level_2 ├── .doggies │ └── file1 ├── dir_level_3 │ └── template09.tmpl ├── template07.tmpl └── template08.tmpl ├── template01.tmpl ├── template02.tmpl ├── template03.tmpl ├── template04.tmpl ├── template05.tmpl └── template06.tmpl /.npmignore: -------------------------------------------------------------------------------- 1 | tests 2 | .npmignore 3 | 4 | 5 | -------------------------------------------------------------------------------- /README.org: -------------------------------------------------------------------------------- 1 | : _ _ _ _ 2 | : _ __ ___ __| | ___(_)_ __ | |_ ___ _ ____ ____ _| | 3 | : | '_ \ / _ \ / _` |/ _ \ | '_ \| __/ _ \ '__\ \ / / _` | | 4 | : | | | | (_) | (_| | __/ | | | | || __/ | \ V / (_| | | 5 | : |_| |_|\___/ \__,_|\___|_|_| |_|\__\___|_| \_/ \__,_|_| 6 | : 7 | : Automation for lazy people. 8 | 9 | * What it does 10 | 11 | NodeInterval promotes code organization by allowing you to move your JavaScript 12 | templates out of your html page and into organized files and folders. When ran, 13 | it collects all the files in your templates folders, orders them alphabetically 14 | by script id, and inserts them into a text document(s) of your choice. 15 | 16 | NodeInterval contains a watch option that enables you to leave it running in a 17 | seperate tab to automatically run the above process anytime a template has been 18 | modified. 19 | 20 | NodeInterval is commonly used in [[http://documentcloud.github.com/backbone/][Backbone]], [[http://maccman.github.com/spine/][Spine]], and similiar web application 21 | frameworks that rely heavily on embedded templates. 22 | 23 | Think of it as a simple version of [[http://sass-lang.com/][Sass]] for your JavaScript templates. 24 | 25 | * Features 26 | 27 | 1. Works with all templating solutions including [[http://documentcloud.github.com/underscore/][underscore.js]] and [[http://api.jquery.com/category/plugins/templates/][jQuery templates]]. (The only requirement is that the template needs to have an id property since they are oganized alphabetically.) 28 | 2. Hidden files inside of template folder (files that begin with "." like .git, .svn, and .DS_Store) are automatically ignored. 29 | 3. Profiles the time it takes to render all templates. 30 | 4. Supports multiple sets of input and output files (see example in =sample/nodeinterval.js=). 31 | 5. Can be used with build tools like [[http://www.gnu.org/software/make/][Gnu Make]] and [[http://ant.apache.org/][Apache Ant]]. 32 | 6. Has clean, date-stamped, and color-coded command-line output: 33 | : $ node nodeinterval.js 34 | : 18 Aug 01:47:49 - INFO: NodeInterval is watching for changes. Press Ctrl-C to stop. 35 | : 18 Aug 01:47:49 - INFO: overwrite ../assets/index.html 36 | : 18 Aug 01:47:49 - INFO: Completed in 0.001 seconds. 37 | : 18 Aug 01:48:04 - INFO: >>> Change detected to: ~/git/projectName/src/templates/signon/signon.tmpl 38 | : 18 Aug 01:48:04 - INFO: overwrite ../assets/index.html 39 | : 18 Aug 01:48:04 - INFO: Completed in 0.002 seconds. 40 | 41 | * Requirements 42 | - You must have [[http://nodejs.org/][nodejs]] installed. 43 | - [[http://npmjs.org/][NPM]] (Node package Manager) if you want to install this package using it. 44 | * Installing and using 45 | 46 | Note: Your application should have a clean folders architecture differentiating 47 | compiled vs source files. See the section below on "Sample web application 48 | layout" for a decent one. It's a lot simpler than it sounds. 49 | 50 | There are two ways to install: Cloning this repo or using [[http://npmjs.org/][npm]]. Once you have the 51 | package installed feel free to modify and use the sample script in the =samples= 52 | directory. 53 | 54 | : cd bin # Your scripts directory. 55 | : npm install NodeInterval 56 | : cp node_modules/nodeinterval/samples/nodeinterval.sh . 57 | : emacs nodeinterval.sh # Setup your variable paths with your favorite editor. 58 | : chmod u+x nodeinterval.sh 59 | : ./nodeinterval.sh # Start watching your files 60 | 61 | Alternatively, you can use the sample .js file instead of the .sh version and 62 | run it like so: 63 | 64 | : node nodeinterval.js 65 | 66 | * Usage 67 | 68 | It's best to create a Node or shell script that you can call via command line. A 69 | copy of this example is included in the =samples= directory. 70 | 71 | : var Nodeinterval = require('nodeinterval'), 72 | : ni = new Nodeinterval.Watcher({ 73 | : inputFile: '../path/to/raw/index.html', 74 | : outputFile: '../path/to/rendered/index.html', 75 | : replacementString: '@templates@', 76 | : watchFolder: '../path/to/templates/' 77 | : }).startWatch(); 78 | 79 | Options you can pass to =new Nodeinterval.Watcher= are: 80 | 81 | | Option | Description | default | 82 | |---------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------| 83 | | =inputFile= | is the main template you want to duplicate. | '../src/index.html' | 84 | | =outputFile= | is the relative or absolute path to the file you want to create (that's a copy of =inputFile= with the =replacementString= replaced with all your templates. | '../assets/index.html' | 85 | | =replacementString= | is the string inside of =inputFile= that you want to replace with all your templates. | '@templates@' | 86 | | =watchFolder= | is the relative or absolute path to the folder you want to monitor. | '../src/templates/' | 87 | 88 | Once a new =Nodeinterval.Watcher= is created. It has the additional api methods. Some methods are chainable. 89 | 90 | | Method | Description | 91 | |-------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| 92 | | startWatch | Turns on the monitoring service. All files in =watchFolder= are now being watched for changes. Chainable. | 93 | | stopWatch | All files in =watchFolder= are now not being watched. Chainable. | 94 | | updateIndex | This is called internally anytime a change is detected. Replaces =outputFile= with a version of =inputFile= with =replacementString= replaced with contents of =watchFolder=. | 95 | | | | 96 | 97 | NodeInterval can also watch multiple input and output files. Just use an array 98 | to specify filenames under =inputFile= and =outputFile=. This is good, for 99 | example, where you have two sets of html files, one for uncompressed js and css 100 | and one for compressed css and js, and you want both files to render your 101 | templates on change. 102 | 103 | * Sample web application layout 104 | 105 | If you don't have a good web application layout. Here's a good one to follow: 106 | 107 | : . 108 | : ├── assets <== Your compressed assets, ready for production. 109 | : │   ├── images 110 | : │   ├── index.html <== "Built" html file with your rendered templates. 111 | : │   ├── js 112 | : │   └── css 113 | : ├── bin <== Shell scripts. "npm install nodeinterval" here. 114 | : │   ├── node_modules <== This folder will automatically be created. 115 | : │   │   └── nodeinterval <== nodeinterval and it's dependencies will be 116 | : │   │  installed here. 117 | : │   ├── nodeinterval.sh <== This sample file (and the .js) version is inside 118 | : │   │  of nodeinterval/samples/. Use it if you like. 119 | : │   └── sasswatch.sh <== I like to create a Sass executable for watching 120 | : │   my CSS files as well. (not part of this project) 121 | : └── src <== Raw uncompressed code here, where you should be 122 | : │ editing your codez. 123 | : ├── index.html <== Raw index.html files with "replacementString" 124 | : │ where you want the templates. 125 | : ├── css <== Uncompressed CSS assets. 126 | : ├── js <== Uncompressed JS assets. 127 | : └── templates <== Your .js templates. These can be all in one 128 | : folder or seperated out into many folder deep, 129 | : according to section. Incude the 12 | 13 | 16 | 17 | 20 | 21 | 24 | 25 | 28 | 29 | 32 | 33 | 36 | 37 | 40 | 41 | 42 |

My templates above

43 | 44 | 45 | -------------------------------------------------------------------------------- /tests/listen.js: -------------------------------------------------------------------------------- 1 | var watchFolder = 'src/templates/', 2 | inputFile = 'src/index.html', 3 | replacementString = '@templates@', 4 | outputFile = 'assets/index.html'; 5 | 6 | // Create a NI instance. 7 | ni = new NodeInterval.Watcher({ 8 | watchFolder: watchFolder, 9 | inputFile: inputFile, 10 | outputFile: outputFile 11 | }).startWatch(); 12 | -------------------------------------------------------------------------------- /tests/node_modules/.bin/vows: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var path = require('path'), 4 | fs = require('fs'), 5 | util = require('util'), 6 | events = require('events'); 7 | 8 | // 9 | // Attempt to load Coffee-Script. If it's not available, continue on our 10 | // merry way, if it is available, set it up so we can include `*.coffee` 11 | // scripts and start searching for them. 12 | // 13 | var fileExt, specFileExt; 14 | 15 | try { 16 | var coffee = require('coffee-script'); 17 | if (require.extensions) { 18 | require.extensions['.coffee'] = function (module, filename) { 19 | var content = coffee.compile(fs.readFileSync(filename, 'utf8')); 20 | return module._compile(content, filename); 21 | }; 22 | } else { 23 | require.registerExtension('.coffee', function (content) { return coffee.compile(content) }); 24 | } 25 | fileExt = /\.(js|coffee)$/; 26 | specFileExt = /[.-](test|spec)\.(js|coffee)$/; 27 | } catch (_) { 28 | fileExt = /\.js$/; 29 | specFileExt = /[.-](test|spec)\.js$/; 30 | } 31 | 32 | var inspect = require('eyes').inspector({ 33 | stream: null, 34 | styles: { string: 'grey', regexp: 'grey' } 35 | }); 36 | 37 | var vows = require('../lib/vows'); 38 | var cutils = require('../lib/vows/console'); 39 | var stylize = require('../lib/vows/console').stylize; 40 | var _reporter = require('../lib/vows/reporters/dot-matrix'), reporter = { 41 | name: _reporter.name 42 | }; 43 | var _coverage; 44 | 45 | var help = [ 46 | "usage: vows [FILE, ...] [options]", 47 | "", 48 | "options:", 49 | " -v, --verbose Enable verbose output", 50 | " -w, --watch Watch mode", 51 | " -s, --silent Don't report", 52 | " -i, --isolate Run each test in it's own vows process", 53 | " -m PATTERN Only run tests matching the PATTERN string", 54 | " -r PATTERN Only run tests matching the PATTERN regexp", 55 | " --json Use JSON reporter", 56 | " --spec Use Spec reporter", 57 | " --dot-matrix Use Dot-Matrix reporter", 58 | " --xunit Use xUnit reporter", 59 | " --cover-plain Print plain coverage map if detected", 60 | " --cover-html Write coverage map to \"coverage.html\"", 61 | " --cover-json Write unified coverage map to \"coverage.json\"", 62 | //" --no-color Don't use terminal colors", 63 | " --version Show version", 64 | " -h, --help You're staring at it" 65 | ].join('\n'); 66 | 67 | var options = { 68 | reporter: reporter, 69 | matcher: /.*/, 70 | watch: false, 71 | coverage: false, 72 | isolate: false 73 | }; 74 | 75 | var files = []; 76 | 77 | // Get rid of process runner 78 | // ('node' in most cases) 79 | var arg, args = [], argv = process.argv.slice(2); 80 | 81 | // Current directory index, 82 | // and path of test folder. 83 | var root, testFolder; 84 | 85 | // 86 | // Parse command-line parameters 87 | // 88 | while (arg = argv.shift()) { 89 | if (arg === __filename) { continue } 90 | 91 | if (arg[0] !== '-') { 92 | args.push(arg); 93 | } else { 94 | arg = arg.match(/^--?(.+)/)[1]; 95 | 96 | if (arg[0] === 'r') { 97 | options.matcher = new(RegExp)(argv.shift()); 98 | } else if (arg[0] === 'm') { 99 | options.matcher = (function (str) { // Create an escaped RegExp 100 | var specials = '. * + ? | ( ) [ ] { } \\ ^ ? ! = : $'.split(' ').join('|\\'), 101 | regex = new(RegExp)('(\\' + specials + ')', 'g'); 102 | return new(RegExp)(str.replace(regex, '\\$1')); 103 | })(argv.shift()); 104 | } else if (arg in options) { 105 | options[arg] = true; 106 | } else { 107 | switch (arg) { 108 | case 'json': 109 | _reporter = require('../lib/vows/reporters/json'); 110 | break; 111 | case 'spec': 112 | _reporter = require('../lib/vows/reporters/spec'); 113 | break; 114 | case 'dot-matrix': 115 | _reporter = require('../lib/vows/reporters/dot-matrix'); 116 | break; 117 | case 'silent': 118 | case 's': 119 | _reporter = require('../lib/vows/reporters/silent'); 120 | break; 121 | case 'xunit': 122 | _reporter = require('../lib/vows/reporters/xunit'); 123 | break; 124 | case 'cover-plain': 125 | options.coverage = true; 126 | _coverage = require('../lib/vows/coverage/report-plain'); 127 | break; 128 | case 'cover-html': 129 | options.coverage = true; 130 | _coverage = require('../lib/vows/coverage/report-html'); 131 | break; 132 | case 'cover-json': 133 | options.coverage = true; 134 | _coverage = require('../lib/vows/coverage/report-json'); 135 | break; 136 | case 'verbose': 137 | case 'v': 138 | options.verbose = true; 139 | break; 140 | case 'watch': 141 | case 'w': 142 | options.watch = true; 143 | break; 144 | case 'supress-stdout': 145 | options.supressStdout = true; 146 | break; 147 | case 'isolate': 148 | case 'i': 149 | options.isolate = true; 150 | break; 151 | case 'no-color': 152 | options.nocolor = true; 153 | break; 154 | case 'no-error': 155 | options.error = false; 156 | break; 157 | case 'version': 158 | console.log('vows ' + vows.version); 159 | process.exit(0); 160 | case 'help': 161 | case 'h': 162 | console.log(help); 163 | process.exit(0); 164 | break; 165 | } 166 | } 167 | } 168 | } 169 | 170 | if (options.supressStdout) { 171 | _reporter.setStream && _reporter.setStream(process.stdout); 172 | process.stdout = fs.createWriteStream('/dev/null'); 173 | } 174 | 175 | if (options.watch) { 176 | options.reporter = reporter = require('../lib/vows/reporters/watch'); 177 | } 178 | 179 | msg('bin', 'argv', args); 180 | msg('bin', 'options', { reporter: options.reporter.name, matcher: options.matcher }); 181 | 182 | if (args.length === 0 || options.watch) { 183 | msg('bin', 'discovering', 'folder structure'); 184 | root = fs.readdirSync('.'); 185 | 186 | if (root.indexOf('test') !== -1) { 187 | testFolder = 'test'; 188 | } else if (root.indexOf('spec') !== -1) { 189 | testFolder = 'spec'; 190 | } else { 191 | abort("runner", "couldn't find test folder"); 192 | } 193 | msg('bin', 'discovered', "./" + testFolder); 194 | 195 | if (args.length === 0) { 196 | args = paths(testFolder).filter(function (f) { 197 | return new(RegExp)('-' + testFolder + '.(js|coffee)$').test(f); 198 | }); 199 | 200 | if (options.watch) { 201 | args = args.concat(paths('lib'), 202 | paths('src')); 203 | } 204 | } 205 | } 206 | 207 | if (! options.watch) { 208 | reporter.report = function (data, filename) { 209 | switch (data[0]) { 210 | case 'subject': 211 | case 'vow': 212 | case 'context': 213 | case 'error': 214 | _reporter.report(data, filename); 215 | break; 216 | case 'end': 217 | (options.verbose || _reporter.name === 'json') && 218 | _reporter.report(data); 219 | break; 220 | case 'finish': 221 | options.verbose ? 222 | _reporter.print('\n') 223 | : 224 | _reporter.print(' '); 225 | break; 226 | } 227 | }; 228 | reporter.reset = function () { _reporter.reset && _reporter.reset() }; 229 | reporter.print = _reporter.print; 230 | 231 | files = args.map(function (a) { 232 | return (!a.match(/^\//)) 233 | ? path.join(process.cwd(), a.replace(fileExt, '')) 234 | : a.replace(fileExt, ''); 235 | }); 236 | 237 | runSuites(importSuites(files), function (results) { 238 | var status = results.errored ? 2 : (results.broken ? 1 : 0); 239 | 240 | !options.verbose && _reporter.print('\n'); 241 | msg('runner', 'finish'); 242 | _reporter.report(['finish', results], { 243 | write: function (str) { 244 | util.print(str.replace(/^\n\n/, '\n')); 245 | } 246 | }); 247 | try { 248 | if (options.coverage === true && _$jscoverage !== undefined) { 249 | _coverage.report(_$jscoverage); 250 | } 251 | } catch (err) { 252 | // ignore the undefined jscoverage 253 | } 254 | if (process.stdout.write('')) { // Check if stdout is drained 255 | process.exit(status); 256 | } else { 257 | process.stdout.on('drain', function () { 258 | process.exit(status); 259 | }); 260 | } 261 | }); 262 | } else { 263 | // 264 | // Watch mode 265 | // 266 | (function () { 267 | var pendulum = [ 268 | '. ', '.. ', '... ', ' ...', 269 | ' ..', ' .', ' .', ' ..', 270 | '... ', '.. ', '. ' 271 | ]; 272 | var strobe = ['.', ' ']; 273 | var status, 274 | cue, 275 | current = 0, 276 | running = 0, 277 | lastRun, 278 | colors = ['32m', '33m', '31m'], 279 | timer = setInterval(tick, 100); 280 | 281 | process.on('uncaughtException', cleanup); 282 | process.on('exit', cleanup); 283 | process.on('SIGINT', function () { 284 | process.exit(0); 285 | }); 286 | process.on('SIGQUIT', function () { 287 | changed(); 288 | }); 289 | 290 | cursorHide(); 291 | 292 | // Run every 100ms 293 | function tick() { 294 | if (running && (cue !== strobe)) { 295 | cue = strobe, current = 0; 296 | } else if (!running && (cue !== pendulum)) { 297 | cue = pendulum, current = 0; 298 | } 299 | 300 | eraseLine(); 301 | lastRun && !running && esc(colors[status.errored ? 2 : (status.broken ? 1 : 0)]); 302 | print(cue[current]); 303 | 304 | if (current == cue.length - 1) { current = -1 } 305 | 306 | current ++; 307 | esc('39m'); 308 | cursorRestore(); 309 | } 310 | 311 | // 312 | // Utility functions 313 | // 314 | function print(str) { util.print(str) } 315 | function esc(str) { print("\x1b[" + str) } 316 | function eraseLine() { esc("0K") } 317 | function cursorRestore() { esc("0G") } 318 | function cursorHide() { esc("?25l") } 319 | function cursorShow() { esc("?25h") } 320 | function cleanup() { eraseLine(), cursorShow(), clearInterval(timer), print('\n') } 321 | 322 | // 323 | // Called when a file has been modified. 324 | // Run the matching tests and change the status. 325 | // 326 | function changed(file) { 327 | status = { honored: 0, broken: 0, errored: 0, pending: 0 }; 328 | 329 | msg('watcher', 'detected change in', file); 330 | 331 | file = (specFileExt.test(file) ? path.join(testFolder, file) 332 | : path.join(testFolder, file + '-' + testFolder)); 333 | 334 | try { 335 | fs.statSync(file); 336 | } catch (e) { 337 | msg('watcher', 'no equivalence found, running all tests.'); 338 | file = null; 339 | } 340 | 341 | var files = (specFileExt.test(file) ? [file] : paths(testFolder)).map(function (p) { 342 | return path.join(process.cwd(), p); 343 | }).map(function (p) { 344 | var cache = require.main.moduleCache || require.cache; 345 | if (cache[p]) { delete(cache[p]) } 346 | return p; 347 | }).map(function (p) { 348 | return p.replace(fileExt, ''); 349 | }); 350 | 351 | running ++; 352 | 353 | runSuites(importSuites(files), function (results) { 354 | delete(results.time); 355 | print(cutils.result(results).join('') + '\n\n'); 356 | lastRun = new(Date); 357 | status = results; 358 | running --; 359 | }); 360 | } 361 | 362 | msg('watcher', 'watching', args); 363 | 364 | // 365 | // Watch all relevant files, 366 | // and call `changed()` on change. 367 | // 368 | args.forEach(function (p) { 369 | fs.watchFile(p, function (current, previous) { 370 | if (new(Date)(current.mtime).valueOf() === 371 | new(Date)(previous.mtime).valueOf()) { return } 372 | else { 373 | changed(p); 374 | } 375 | }); 376 | }); 377 | })(); 378 | } 379 | 380 | function runSuites(suites, callback) { 381 | var results = { 382 | honored: 0, 383 | broken: 0, 384 | errored: 0, 385 | pending: 0, 386 | total: 0, 387 | time: 0 388 | }; 389 | reporter.reset(); 390 | 391 | (function run(suites, callback) { 392 | var suite = suites.shift(); 393 | if (suite) { 394 | msg('runner', "running", suite.subject + ' ', options.watch ? false : true); 395 | suite.run(options, function (result) { 396 | Object.keys(result).forEach(function (k) { 397 | results[k] += result[k]; 398 | }); 399 | run(suites, callback); 400 | }); 401 | } else { 402 | callback(results); 403 | } 404 | })(suites, callback); 405 | } 406 | 407 | function importSuites(files) { 408 | msg(options.watcher ? 'watcher' : 'runner', 'loading', files); 409 | 410 | var spawn = require('child_process').spawn; 411 | 412 | function cwdname(f) { 413 | return f.replace(process.cwd() + '/', '') + '.js'; 414 | } 415 | 416 | function wrapSpawn(f) { 417 | f = cwdname(f); 418 | return function (options, callback) { 419 | var args = [process.argv[1], '--json', '--supress-stdout', f], 420 | p = spawn(process.argv[0], args), 421 | result; 422 | 423 | p.on('exit', function (code) { 424 | callback( 425 | !result ? 426 | {errored: 1, total: 1} 427 | : 428 | result 429 | ); 430 | }); 431 | 432 | var buffer = []; 433 | p.stdout.on('data', function (data) { 434 | data = data.toString().split(/\n/g); 435 | if (data.length == 1) { 436 | buffer.push(data[0]); 437 | } else { 438 | data[0] = buffer.concat(data[0]).join(''); 439 | buffer = [data.pop()]; 440 | 441 | data.forEach(function (data) { 442 | if (data) { 443 | data = JSON.parse(data); 444 | if (data && data[0] === 'finish') { 445 | result = data[1]; 446 | } else { 447 | reporter.report(data); 448 | } 449 | } 450 | }); 451 | } 452 | }); 453 | 454 | p.stderr.pipe(process.stderr); 455 | } 456 | } 457 | 458 | return files.reduce(options.isolate ? function (suites, f) { 459 | return suites.concat({ 460 | run: wrapSpawn(f) 461 | }); 462 | } : function (suites, f) { 463 | var obj = require(f); 464 | return suites.concat(Object.keys(obj).map(function (s) { 465 | obj[s]._filename = cwdname(f); 466 | return obj[s]; 467 | })); 468 | }, []) 469 | } 470 | 471 | // 472 | // Recursively traverse a hierarchy, returning 473 | // a list of all relevant .js files. 474 | // 475 | function paths(dir) { 476 | var paths = []; 477 | 478 | try { fs.statSync(dir) } 479 | catch (e) { return [] } 480 | 481 | (function traverse(dir, stack) { 482 | stack.push(dir); 483 | fs.readdirSync(stack.join('/')).forEach(function (file) { 484 | var path = stack.concat([file]).join('/'), 485 | stat = fs.statSync(path); 486 | 487 | if (file[0] == '.' || file === 'vendor') { 488 | return; 489 | } else if (stat.isFile() && fileExt.test(file)) { 490 | paths.push(path); 491 | } else if (stat.isDirectory()) { 492 | traverse(file, stack); 493 | } 494 | }); 495 | stack.pop(); 496 | })(dir || '.', []); 497 | 498 | return paths; 499 | } 500 | 501 | function msg(cmd, subject, str, p) { 502 | if (options.verbose) { 503 | util[p ? 'print' : 'puts']( stylize('vows ', 'green') 504 | + stylize(cmd, 'bold') 505 | + ' ' + subject + ' ' 506 | + (str ? (typeof(str) === 'string' ? str : inspect(str)) : '') 507 | ); 508 | } 509 | } 510 | 511 | function abort(cmd, str) { 512 | console.log(stylize('vows ', 'red') + stylize(cmd, 'bold') + ' ' + str); 513 | console.log(stylize('vows ', 'red') + stylize(cmd, 'bold') + ' exiting'); 514 | process.exit(-1); 515 | } 516 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/index.js: -------------------------------------------------------------------------------- 1 | ../../../index.js -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/nodewatch/docs/docco.css: -------------------------------------------------------------------------------- 1 | /*--------------------- Layout and Typography ----------------------------*/ 2 | body { 3 | font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; 4 | font-size: 15px; 5 | line-height: 22px; 6 | color: #252519; 7 | margin: 0; padding: 0; 8 | } 9 | a { 10 | color: #261a3b; 11 | } 12 | a:visited { 13 | color: #261a3b; 14 | } 15 | p { 16 | margin: 0 0 15px 0; 17 | } 18 | h1, h2, h3, h4, h5, h6 { 19 | margin: 0px 0 15px 0; 20 | } 21 | h1 { 22 | margin-top: 40px; 23 | } 24 | #container { 25 | position: relative; 26 | } 27 | #background { 28 | position: fixed; 29 | top: 0; left: 525px; right: 0; bottom: 0; 30 | background: #f5f5ff; 31 | border-left: 1px solid #e5e5ee; 32 | z-index: -1; 33 | } 34 | #jump_to, #jump_page { 35 | background: white; 36 | -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; 37 | -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; 38 | font: 10px Arial; 39 | text-transform: uppercase; 40 | cursor: pointer; 41 | text-align: right; 42 | } 43 | #jump_to, #jump_wrapper { 44 | position: fixed; 45 | right: 0; top: 0; 46 | padding: 5px 10px; 47 | } 48 | #jump_wrapper { 49 | padding: 0; 50 | display: none; 51 | } 52 | #jump_to:hover #jump_wrapper { 53 | display: block; 54 | } 55 | #jump_page { 56 | padding: 5px 0 3px; 57 | margin: 0 0 25px 25px; 58 | } 59 | #jump_page .source { 60 | display: block; 61 | padding: 5px 10px; 62 | text-decoration: none; 63 | border-top: 1px solid #eee; 64 | } 65 | #jump_page .source:hover { 66 | background: #f5f5ff; 67 | } 68 | #jump_page .source:first-child { 69 | } 70 | table td { 71 | border: 0; 72 | outline: 0; 73 | } 74 | td.docs, th.docs { 75 | max-width: 450px; 76 | min-width: 450px; 77 | min-height: 5px; 78 | padding: 10px 25px 1px 50px; 79 | overflow-x: hidden; 80 | vertical-align: top; 81 | text-align: left; 82 | } 83 | .docs pre { 84 | margin: 15px 0 15px; 85 | padding-left: 15px; 86 | } 87 | .docs p tt, .docs p code { 88 | background: #f8f8ff; 89 | border: 1px solid #dedede; 90 | font-size: 12px; 91 | padding: 0 0.2em; 92 | } 93 | .pilwrap { 94 | position: relative; 95 | } 96 | .pilcrow { 97 | font: 12px Arial; 98 | text-decoration: none; 99 | color: #454545; 100 | position: absolute; 101 | top: 3px; left: -20px; 102 | padding: 1px 2px; 103 | opacity: 0; 104 | -webkit-transition: opacity 0.2s linear; 105 | } 106 | td.docs:hover .pilcrow { 107 | opacity: 1; 108 | } 109 | td.code, th.code { 110 | padding: 14px 15px 16px 25px; 111 | width: 100%; 112 | vertical-align: top; 113 | background: #f5f5ff; 114 | border-left: 1px solid #e5e5ee; 115 | } 116 | pre, tt, code { 117 | font-size: 12px; line-height: 18px; 118 | font-family: Monaco, Consolas, "Lucida Console", monospace; 119 | margin: 0; padding: 0; 120 | } 121 | 122 | 123 | /*---------------------- Syntax Highlighting -----------------------------*/ 124 | td.linenos { background-color: #f0f0f0; padding-right: 10px; } 125 | span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } 126 | body .hll { background-color: #ffffcc } 127 | body .c { color: #408080; font-style: italic } /* Comment */ 128 | body .err { border: 1px solid #FF0000 } /* Error */ 129 | body .k { color: #954121 } /* Keyword */ 130 | body .o { color: #666666 } /* Operator */ 131 | body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ 132 | body .cp { color: #BC7A00 } /* Comment.Preproc */ 133 | body .c1 { color: #408080; font-style: italic } /* Comment.Single */ 134 | body .cs { color: #408080; font-style: italic } /* Comment.Special */ 135 | body .gd { color: #A00000 } /* Generic.Deleted */ 136 | body .ge { font-style: italic } /* Generic.Emph */ 137 | body .gr { color: #FF0000 } /* Generic.Error */ 138 | body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ 139 | body .gi { color: #00A000 } /* Generic.Inserted */ 140 | body .go { color: #808080 } /* Generic.Output */ 141 | body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ 142 | body .gs { font-weight: bold } /* Generic.Strong */ 143 | body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ 144 | body .gt { color: #0040D0 } /* Generic.Traceback */ 145 | body .kc { color: #954121 } /* Keyword.Constant */ 146 | body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ 147 | body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ 148 | body .kp { color: #954121 } /* Keyword.Pseudo */ 149 | body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ 150 | body .kt { color: #B00040 } /* Keyword.Type */ 151 | body .m { color: #666666 } /* Literal.Number */ 152 | body .s { color: #219161 } /* Literal.String */ 153 | body .na { color: #7D9029 } /* Name.Attribute */ 154 | body .nb { color: #954121 } /* Name.Builtin */ 155 | body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ 156 | body .no { color: #880000 } /* Name.Constant */ 157 | body .nd { color: #AA22FF } /* Name.Decorator */ 158 | body .ni { color: #999999; font-weight: bold } /* Name.Entity */ 159 | body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ 160 | body .nf { color: #0000FF } /* Name.Function */ 161 | body .nl { color: #A0A000 } /* Name.Label */ 162 | body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ 163 | body .nt { color: #954121; font-weight: bold } /* Name.Tag */ 164 | body .nv { color: #19469D } /* Name.Variable */ 165 | body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ 166 | body .w { color: #bbbbbb } /* Text.Whitespace */ 167 | body .mf { color: #666666 } /* Literal.Number.Float */ 168 | body .mh { color: #666666 } /* Literal.Number.Hex */ 169 | body .mi { color: #666666 } /* Literal.Number.Integer */ 170 | body .mo { color: #666666 } /* Literal.Number.Oct */ 171 | body .sb { color: #219161 } /* Literal.String.Backtick */ 172 | body .sc { color: #219161 } /* Literal.String.Char */ 173 | body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ 174 | body .s2 { color: #219161 } /* Literal.String.Double */ 175 | body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ 176 | body .sh { color: #219161 } /* Literal.String.Heredoc */ 177 | body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ 178 | body .sx { color: #954121 } /* Literal.String.Other */ 179 | body .sr { color: #BB6688 } /* Literal.String.Regex */ 180 | body .s1 { color: #219161 } /* Literal.String.Single */ 181 | body .ss { color: #19469D } /* Literal.String.Symbol */ 182 | body .bp { color: #954121 } /* Name.Builtin.Pseudo */ 183 | body .vc { color: #19469D } /* Name.Variable.Class */ 184 | body .vg { color: #19469D } /* Name.Variable.Global */ 185 | body .vi { color: #19469D } /* Name.Variable.Instance */ 186 | body .il { color: #666666 } /* Literal.Number.Integer.Long */ -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/nodewatch/lib/watch/watch.js: -------------------------------------------------------------------------------- 1 | var EventEmitter = require("events").EventEmitter, fs = require("fs"), path = require("path"); 2 | 3 | var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { 4 | for (var key in parent) { 5 | if (__hasProp.call(parent, key)) { 6 | child[key] = parent[key]; 7 | } 8 | } 9 | function ctor() { 10 | this.constructor = child; 11 | } 12 | ctor.prototype = parent.prototype; 13 | child.prototype = new ctor; 14 | child.__super__ = parent.prototype; 15 | return child; 16 | }; 17 | 18 | var WatchClass = function() { 19 | "use strict"; 20 | __extends(Watch, EventEmitter); 21 | function Watch(options) {} 22 | Watch.prototype.add = function(str_file_or_path) { 23 | return this.__handle(true, str_file_or_path); 24 | }; 25 | Watch.prototype.remove = function(str_file_or_path) { 26 | return this.__handle(false, str_file_or_path); 27 | }; 28 | Watch.prototype.onChange = function(cb) { 29 | this.on("change", cb); 30 | return this; 31 | }; 32 | Watch.prototype.clearListeners = function() { 33 | this.removeAllListeners("change"); 34 | return this; 35 | }; 36 | Watch.prototype.__handle = function(add, str_file_or_path) { 37 | if (str_file_or_path.substring(0, 1) == ".") { 38 | str_file_or_path = process.cwd() + "/" + str_file_or_path; 39 | } 40 | str_file_or_path = path.normalize(str_file_or_path); 41 | if (fs.statSync(str_file_or_path).isFile()) { 42 | return this.__file(add, str_file_or_path); 43 | } 44 | if (fs.statSync(str_file_or_path).isDirectory()) { 45 | return this.__dir(add, str_file_or_path); 46 | } 47 | }; 48 | Watch.prototype.__dir = function(add, dir) { 49 | var files = fs.readdirSync(dir); 50 | for (var i = 0; i < files.length; i++) { 51 | var full_path = dir + "/" + files[i]; 52 | if (fs.statSync(full_path).isFile()) { 53 | this.__file(add, full_path); 54 | } 55 | } 56 | return this; 57 | }; 58 | Watch.prototype.__file = function(add, file) { 59 | var self = this; 60 | if (add) { 61 | fs.watchFile(file, function(prev, curr) { 62 | if (prev.mtime.getTime() != curr.mtime.getTime()) { 63 | self.emit("change", file, prev, curr); 64 | } 65 | }); 66 | } else { 67 | fs.unwatchFile(file); 68 | } 69 | return self; 70 | }; 71 | return Watch; 72 | }(); 73 | 74 | module.exports = new WatchClass; -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/nodewatch/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "nodewatch", 3 | "description" : "Simple utility to watch file changes. A file change is a file whom's mtime is changed", 4 | "version" : "0.0.4", 5 | "homepage": "http://jorritd.github.com/node-watch/", 6 | "author" : "Jorrit Duin (https://github.com/jorritd)", 7 | "repository" : { 8 | "type" : "git", 9 | "url" : "git://github.com/jorritd/node-watch.git" 10 | }, 11 | "main" : "./lib/watch/watch", 12 | "directories" : { 13 | "lib" : "./lib/watch" 14 | }, 15 | "dependencies":{}, 16 | "devDependencies":["jake","docco","jasmine-node","uglify-js","nodewatch"], 17 | "bundleDependencies":[], 18 | "engines" : { "node" : ">=0.4.0" }, 19 | "licenses" : [ { "type" : "AS IS" } ] 20 | } -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/simple-logger/.npmignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *git 3 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/simple-logger/README.md: -------------------------------------------------------------------------------- 1 | ### Install: 2 | npm install simple-logger 3 | 4 | ### Usage: 5 | var log = require('simple-logger') 6 | 7 | // Warn 8 | log.warn('hello!'); 9 | 10 | // Change log level (info, warn, error) (default is warn) 11 | log.log_level = 'warn'; 12 | 13 | ### Fun Facts: 14 | Log multiple objects in one call! 15 | 16 | log.warn('hello', [1,2,3]); 17 | May 15:22:33 - WARN: hello 1,2,3 18 | 19 | Objects are auto-inspected 20 | 21 | log.warn({foo: 'bar', duck: 'pie'}); 22 | 27 May 15:22:53 - WARN: { foo: 'bar', duck: 'pie' } 23 | 24 | ### Neato: 25 | ![Screenshot of colorful logger output](http://andrewray.me/stuff/log-colors.png) 26 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/simple-logger/index.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'), 2 | logLevels = ['silent', 'error', 'warn', 'info', 'debug'], 3 | logger = module.exports, 4 | // Shell color escape codes 5 | escr ="", 6 | reset = escr+'[0m', 7 | // Color array matches logLevels array, starting from 'error' 8 | colors = [escr+'[31m', escr+'[33m', escr+'[34m']; 9 | 10 | // ECMAScript getter and setter syntax 11 | logger.__defineGetter__('log_level', function(){ 12 | return logLevels[this.selfLogLevel]; 13 | }); 14 | 15 | logger.__defineSetter__('log_level', function(arg){ 16 | this.selfLogLevel = logLevels.indexOf(arg); 17 | var em = function() {}; 18 | 19 | // Create a funciton for each level except silent 20 | for(var x=1, l=logLevels.length; x= x ? function(y){return function() { 22 | var args = Array.prototype.slice.call(arguments), l = args.length; 23 | while(l--) { 24 | if(args[l] && typeof args[l] == 'object' && args[l].toString() == '[object Object]') { 25 | args[l] = sys.inspect(args[l]); 26 | } 27 | } 28 | sys.log.call(this, (this.color ? (colors[y-1] || '') + logLevels[y].toUpperCase() + reset : 29 | logLevels[y].toUpperCase())+': '+args.join(' ')); 30 | };}(x) : em; 31 | } 32 | }); 33 | 34 | // Default to colorful warn 35 | logger.log_level = 'warn'; 36 | logger.color = true; 37 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/simple-logger/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "simple-logger", 3 | "author": "Andrew Ray", 4 | "description": "A simple logging package to colorize logging standard output", 5 | "version": "0.0.2", 6 | "homepage": "http://andrewray.me", 7 | "engines" : {"node" : ">=0.4.0"}, 8 | "main" : "index.js", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/DelvarWorld/Simple-Node-Logger" 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/underscore/.npmignore: -------------------------------------------------------------------------------- 1 | test/ 2 | Rakefile 3 | docs/ -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/underscore/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Jeremy Ashkenas, DocumentCloud 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/underscore/README: -------------------------------------------------------------------------------- 1 | __ 2 | /\ \ __ 3 | __ __ ___ \_\ \ __ _ __ ____ ___ ___ _ __ __ /\_\ ____ 4 | /\ \/\ \ /' _ `\ /'_ \ /'__`\/\ __\/ ,__\ / ___\ / __`\/\ __\/'__`\ \/\ \ /',__\ 5 | \ \ \_\ \/\ \/\ \/\ \ \ \/\ __/\ \ \//\__, `\/\ \__//\ \ \ \ \ \//\ __/ __ \ \ \/\__, `\ 6 | \ \____/\ \_\ \_\ \___,_\ \____\\ \_\\/\____/\ \____\ \____/\ \_\\ \____\/\_\ _\ \ \/\____/ 7 | \/___/ \/_/\/_/\/__,_ /\/____/ \/_/ \/___/ \/____/\/___/ \/_/ \/____/\/_//\ \_\ \/___/ 8 | \ \____/ 9 | \/___/ 10 | 11 | Underscore is a utility-belt library for JavaScript that provides 12 | support for the usual functional suspects (each, map, reduce, filter...) 13 | without extending any core JavaScript objects. 14 | 15 | For Docs, License, Tests, and pre-packed downloads, see: 16 | http://documentcloud.github.com/underscore/ 17 | 18 | Many thanks to our contributors: 19 | https://github.com/documentcloud/underscore/contributors 20 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/underscore/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./underscore'); 2 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/underscore/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "underscore", 3 | "description" : "JavaScript's functional programming helper library.", 4 | "homepage" : "http://documentcloud.github.com/underscore/", 5 | "keywords" : ["util", "functional", "server", "client", "browser"], 6 | "author" : "Jeremy Ashkenas ", 7 | "contributors" : [], 8 | "dependencies" : [], 9 | "repository" : {"type": "git", "url": "git://github.com/documentcloud/underscore.git"}, 10 | "main" : "underscore.js", 11 | "version" : "1.1.7" 12 | } 13 | -------------------------------------------------------------------------------- /tests/node_modules/nodeinterval/node_modules/underscore/underscore-min.js: -------------------------------------------------------------------------------- 1 | // Underscore.js 1.1.7 2 | // (c) 2011 Jeremy Ashkenas, DocumentCloud Inc. 3 | // Underscore is freely distributable under the MIT license. 4 | // Portions of Underscore are inspired or borrowed from Prototype, 5 | // Oliver Steele's Functional, and John Resig's Micro-Templating. 6 | // For all details and documentation: 7 | // http://documentcloud.github.com/underscore 8 | (function(){var p=this,C=p._,m={},i=Array.prototype,n=Object.prototype,f=i.slice,D=i.unshift,E=n.toString,l=n.hasOwnProperty,s=i.forEach,t=i.map,u=i.reduce,v=i.reduceRight,w=i.filter,x=i.every,y=i.some,o=i.indexOf,z=i.lastIndexOf;n=Array.isArray;var F=Object.keys,q=Function.prototype.bind,b=function(a){return new j(a)};typeof module!=="undefined"&&module.exports?(module.exports=b,b._=b):p._=b;b.VERSION="1.1.7";var h=b.each=b.forEach=function(a,c,b){if(a!=null)if(s&&a.forEach===s)a.forEach(c,b);else if(a.length=== 9 | +a.length)for(var e=0,k=a.length;e=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a, 13 | c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);var e={computed:Infinity};h(a,function(a,b,f){b=c?c.call(d,a,b,f):a;bd?1:0}),"value")};b.groupBy=function(a,b){var d={};h(a,function(a,f){var g=b(a,f);(d[g]||(d[g]=[])).push(a)});return d};b.sortedIndex=function(a,c,d){d|| 14 | (d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a,c){return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=f.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};b.after= 20 | function(a,b){return function(){if(--a<1)return b.apply(this,arguments)}};b.keys=F||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var b=[],d;for(d in a)l.call(a,d)&&(b[b.length]=d);return b};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){h(f.call(arguments,1),function(b){for(var d in b)b[d]!==void 0&&(a[d]=b[d])});return a};b.defaults=function(a){h(f.call(arguments, 21 | 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,c){if(a===c)return!0;var d=typeof a;if(d!=typeof c)return!1;if(a==c)return!0;if(!a&&c||a&&!c)return!1;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual)return a.isEqual(c);if(c.isEqual)return c.isEqual(a);if(b.isDate(a)&&b.isDate(c))return a.getTime()===c.getTime();if(b.isNaN(a)&&b.isNaN(c))return!1; 22 | if(b.isRegExp(a)&&b.isRegExp(c))return a.source===c.source&&a.global===c.global&&a.ignoreCase===c.ignoreCase&&a.multiline===c.multiline;if(d!=="object")return!1;if(a.length&&a.length!==c.length)return!1;d=b.keys(a);var e=b.keys(c);if(d.length!=e.length)return!1;for(var f in a)if(!(f in c)||!b.isEqual(a[f],c[f]))return!1;return!0};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(l.call(a,c))return!1;return!0};b.isElement=function(a){return!!(a&&a.nodeType== 23 | 1)};b.isArray=n||function(a){return E.call(a)==="[object Array]"};b.isObject=function(a){return a===Object(a)};b.isArguments=function(a){return!(!a||!l.call(a,"callee"))};b.isFunction=function(a){return!(!a||!a.constructor||!a.call||!a.apply)};b.isString=function(a){return!!(a===""||a&&a.charCodeAt&&a.substr)};b.isNumber=function(a){return!!(a===0||a&&a.toExponential&&a.toFixed)};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===!0||a===!1};b.isDate=function(a){return!(!a||!a.getTimezoneOffset|| 24 | !a.setUTCFullYear)};b.isRegExp=function(a){return!(!a||!a.test||!a.exec||!(a.ignoreCase||a.ignoreCase===!1))};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.noConflict=function(){p._=C;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e/g,interpolate:/<%=([\s\S]+?)%>/g}; 25 | b.template=function(a,c){var d=b.templateSettings;d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.interpolate,function(a,b){return"',"+b.replace(/\\'/g,"'")+",'"}).replace(d.evaluate||null,function(a,b){return"');"+b.replace(/\\'/g,"'").replace(/[\r\n\t]/g," ")+"__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');";d=new Function("obj",d);return c?d(c):d}; 26 | var j=function(a){this._wrapped=a};b.prototype=j.prototype;var r=function(a,c){return c?b(a).chain():a},H=function(a,c){j.prototype[a]=function(){var a=f.call(arguments);D.call(a,this._wrapped);return r(c.apply(b,a),this._chain)}};b.mixin(b);h(["pop","push","reverse","shift","sort","splice","unshift"],function(a){var b=i[a];j.prototype[a]=function(){b.apply(this._wrapped,arguments);return r(this._wrapped,this._chain)}});h(["concat","join","slice"],function(a){var b=i[a];j.prototype[a]=function(){return r(b.apply(this._wrapped, 27 | arguments),this._chain)}});j.prototype.chain=function(){this._chain=!0;return this};j.prototype.value=function(){return this._wrapped}})(); 28 | -------------------------------------------------------------------------------- /tests/node_modules/vows/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /tests/node_modules/vows/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 cloudhead 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /tests/node_modules/vows/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Run all tests 3 | # 4 | test: 5 | @@bin/vows test/* 6 | 7 | .PHONY: test install 8 | -------------------------------------------------------------------------------- /tests/node_modules/vows/README.md: -------------------------------------------------------------------------------- 1 | Vows 2 | ==== 3 | 4 | > Asynchronous BDD & continuous integration for node.js 5 | 6 | #### # 7 | 8 | introduction 9 | ------------ 10 | There are two reasons why we might want asynchronous testing. The first, and obvious reason is that node.js is asynchronous, and therefore our tests need to be. The second reason is to make test suites which target I/O libraries run much faster. 11 | 12 | _Vows_ is an experiment in making this possible, while adding a minimum of overhead. 13 | 14 | synopsis 15 | -------- 16 | 17 | var vows = require('vows'), 18 | assert = require('assert'); 19 | 20 | vows.describe('Deep Thought').addBatch({ 21 | 'An instance of DeepThought': { 22 | topic: new DeepThought, 23 | 24 | 'should know the answer to the ultimate question of life': function (deepThought) { 25 | assert.equal (deepThought.question('what is the answer to the universe?'), 42); 26 | } 27 | } 28 | }); 29 | 30 | installation 31 | ------------ 32 | 33 | $ npm install vows 34 | 35 | documentation 36 | ------------- 37 | 38 | Head over to 39 | 40 | -------------------------------------------------------------------------------- /tests/node_modules/vows/bin/vows: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | var path = require('path'), 4 | fs = require('fs'), 5 | util = require('util'), 6 | events = require('events'); 7 | 8 | // 9 | // Attempt to load Coffee-Script. If it's not available, continue on our 10 | // merry way, if it is available, set it up so we can include `*.coffee` 11 | // scripts and start searching for them. 12 | // 13 | var fileExt, specFileExt; 14 | 15 | try { 16 | var coffee = require('coffee-script'); 17 | if (require.extensions) { 18 | require.extensions['.coffee'] = function (module, filename) { 19 | var content = coffee.compile(fs.readFileSync(filename, 'utf8')); 20 | return module._compile(content, filename); 21 | }; 22 | } else { 23 | require.registerExtension('.coffee', function (content) { return coffee.compile(content) }); 24 | } 25 | fileExt = /\.(js|coffee)$/; 26 | specFileExt = /[.-](test|spec)\.(js|coffee)$/; 27 | } catch (_) { 28 | fileExt = /\.js$/; 29 | specFileExt = /[.-](test|spec)\.js$/; 30 | } 31 | 32 | var inspect = require('eyes').inspector({ 33 | stream: null, 34 | styles: { string: 'grey', regexp: 'grey' } 35 | }); 36 | 37 | var vows = require('../lib/vows'); 38 | var cutils = require('../lib/vows/console'); 39 | var stylize = require('../lib/vows/console').stylize; 40 | var _reporter = require('../lib/vows/reporters/dot-matrix'), reporter = { 41 | name: _reporter.name 42 | }; 43 | var _coverage; 44 | 45 | var help = [ 46 | "usage: vows [FILE, ...] [options]", 47 | "", 48 | "options:", 49 | " -v, --verbose Enable verbose output", 50 | " -w, --watch Watch mode", 51 | " -s, --silent Don't report", 52 | " -i, --isolate Run each test in it's own vows process", 53 | " -m PATTERN Only run tests matching the PATTERN string", 54 | " -r PATTERN Only run tests matching the PATTERN regexp", 55 | " --json Use JSON reporter", 56 | " --spec Use Spec reporter", 57 | " --dot-matrix Use Dot-Matrix reporter", 58 | " --xunit Use xUnit reporter", 59 | " --cover-plain Print plain coverage map if detected", 60 | " --cover-html Write coverage map to \"coverage.html\"", 61 | " --cover-json Write unified coverage map to \"coverage.json\"", 62 | //" --no-color Don't use terminal colors", 63 | " --version Show version", 64 | " -h, --help You're staring at it" 65 | ].join('\n'); 66 | 67 | var options = { 68 | reporter: reporter, 69 | matcher: /.*/, 70 | watch: false, 71 | coverage: false, 72 | isolate: false 73 | }; 74 | 75 | var files = []; 76 | 77 | // Get rid of process runner 78 | // ('node' in most cases) 79 | var arg, args = [], argv = process.argv.slice(2); 80 | 81 | // Current directory index, 82 | // and path of test folder. 83 | var root, testFolder; 84 | 85 | // 86 | // Parse command-line parameters 87 | // 88 | while (arg = argv.shift()) { 89 | if (arg === __filename) { continue } 90 | 91 | if (arg[0] !== '-') { 92 | args.push(arg); 93 | } else { 94 | arg = arg.match(/^--?(.+)/)[1]; 95 | 96 | if (arg[0] === 'r') { 97 | options.matcher = new(RegExp)(argv.shift()); 98 | } else if (arg[0] === 'm') { 99 | options.matcher = (function (str) { // Create an escaped RegExp 100 | var specials = '. * + ? | ( ) [ ] { } \\ ^ ? ! = : $'.split(' ').join('|\\'), 101 | regex = new(RegExp)('(\\' + specials + ')', 'g'); 102 | return new(RegExp)(str.replace(regex, '\\$1')); 103 | })(argv.shift()); 104 | } else if (arg in options) { 105 | options[arg] = true; 106 | } else { 107 | switch (arg) { 108 | case 'json': 109 | _reporter = require('../lib/vows/reporters/json'); 110 | break; 111 | case 'spec': 112 | _reporter = require('../lib/vows/reporters/spec'); 113 | break; 114 | case 'dot-matrix': 115 | _reporter = require('../lib/vows/reporters/dot-matrix'); 116 | break; 117 | case 'silent': 118 | case 's': 119 | _reporter = require('../lib/vows/reporters/silent'); 120 | break; 121 | case 'xunit': 122 | _reporter = require('../lib/vows/reporters/xunit'); 123 | break; 124 | case 'cover-plain': 125 | options.coverage = true; 126 | _coverage = require('../lib/vows/coverage/report-plain'); 127 | break; 128 | case 'cover-html': 129 | options.coverage = true; 130 | _coverage = require('../lib/vows/coverage/report-html'); 131 | break; 132 | case 'cover-json': 133 | options.coverage = true; 134 | _coverage = require('../lib/vows/coverage/report-json'); 135 | break; 136 | case 'verbose': 137 | case 'v': 138 | options.verbose = true; 139 | break; 140 | case 'watch': 141 | case 'w': 142 | options.watch = true; 143 | break; 144 | case 'supress-stdout': 145 | options.supressStdout = true; 146 | break; 147 | case 'isolate': 148 | case 'i': 149 | options.isolate = true; 150 | break; 151 | case 'no-color': 152 | options.nocolor = true; 153 | break; 154 | case 'no-error': 155 | options.error = false; 156 | break; 157 | case 'version': 158 | console.log('vows ' + vows.version); 159 | process.exit(0); 160 | case 'help': 161 | case 'h': 162 | console.log(help); 163 | process.exit(0); 164 | break; 165 | } 166 | } 167 | } 168 | } 169 | 170 | if (options.supressStdout) { 171 | _reporter.setStream && _reporter.setStream(process.stdout); 172 | process.stdout = fs.createWriteStream('/dev/null'); 173 | } 174 | 175 | if (options.watch) { 176 | options.reporter = reporter = require('../lib/vows/reporters/watch'); 177 | } 178 | 179 | msg('bin', 'argv', args); 180 | msg('bin', 'options', { reporter: options.reporter.name, matcher: options.matcher }); 181 | 182 | if (args.length === 0 || options.watch) { 183 | msg('bin', 'discovering', 'folder structure'); 184 | root = fs.readdirSync('.'); 185 | 186 | if (root.indexOf('test') !== -1) { 187 | testFolder = 'test'; 188 | } else if (root.indexOf('spec') !== -1) { 189 | testFolder = 'spec'; 190 | } else { 191 | abort("runner", "couldn't find test folder"); 192 | } 193 | msg('bin', 'discovered', "./" + testFolder); 194 | 195 | if (args.length === 0) { 196 | args = paths(testFolder).filter(function (f) { 197 | return new(RegExp)('-' + testFolder + '.(js|coffee)$').test(f); 198 | }); 199 | 200 | if (options.watch) { 201 | args = args.concat(paths('lib'), 202 | paths('src')); 203 | } 204 | } 205 | } 206 | 207 | if (! options.watch) { 208 | reporter.report = function (data, filename) { 209 | switch (data[0]) { 210 | case 'subject': 211 | case 'vow': 212 | case 'context': 213 | case 'error': 214 | _reporter.report(data, filename); 215 | break; 216 | case 'end': 217 | (options.verbose || _reporter.name === 'json') && 218 | _reporter.report(data); 219 | break; 220 | case 'finish': 221 | options.verbose ? 222 | _reporter.print('\n') 223 | : 224 | _reporter.print(' '); 225 | break; 226 | } 227 | }; 228 | reporter.reset = function () { _reporter.reset && _reporter.reset() }; 229 | reporter.print = _reporter.print; 230 | 231 | files = args.map(function (a) { 232 | return (!a.match(/^\//)) 233 | ? path.join(process.cwd(), a.replace(fileExt, '')) 234 | : a.replace(fileExt, ''); 235 | }); 236 | 237 | runSuites(importSuites(files), function (results) { 238 | var status = results.errored ? 2 : (results.broken ? 1 : 0); 239 | 240 | !options.verbose && _reporter.print('\n'); 241 | msg('runner', 'finish'); 242 | _reporter.report(['finish', results], { 243 | write: function (str) { 244 | util.print(str.replace(/^\n\n/, '\n')); 245 | } 246 | }); 247 | try { 248 | if (options.coverage === true && _$jscoverage !== undefined) { 249 | _coverage.report(_$jscoverage); 250 | } 251 | } catch (err) { 252 | // ignore the undefined jscoverage 253 | } 254 | if (process.stdout.write('')) { // Check if stdout is drained 255 | process.exit(status); 256 | } else { 257 | process.stdout.on('drain', function () { 258 | process.exit(status); 259 | }); 260 | } 261 | }); 262 | } else { 263 | // 264 | // Watch mode 265 | // 266 | (function () { 267 | var pendulum = [ 268 | '. ', '.. ', '... ', ' ...', 269 | ' ..', ' .', ' .', ' ..', 270 | '... ', '.. ', '. ' 271 | ]; 272 | var strobe = ['.', ' ']; 273 | var status, 274 | cue, 275 | current = 0, 276 | running = 0, 277 | lastRun, 278 | colors = ['32m', '33m', '31m'], 279 | timer = setInterval(tick, 100); 280 | 281 | process.on('uncaughtException', cleanup); 282 | process.on('exit', cleanup); 283 | process.on('SIGINT', function () { 284 | process.exit(0); 285 | }); 286 | process.on('SIGQUIT', function () { 287 | changed(); 288 | }); 289 | 290 | cursorHide(); 291 | 292 | // Run every 100ms 293 | function tick() { 294 | if (running && (cue !== strobe)) { 295 | cue = strobe, current = 0; 296 | } else if (!running && (cue !== pendulum)) { 297 | cue = pendulum, current = 0; 298 | } 299 | 300 | eraseLine(); 301 | lastRun && !running && esc(colors[status.errored ? 2 : (status.broken ? 1 : 0)]); 302 | print(cue[current]); 303 | 304 | if (current == cue.length - 1) { current = -1 } 305 | 306 | current ++; 307 | esc('39m'); 308 | cursorRestore(); 309 | } 310 | 311 | // 312 | // Utility functions 313 | // 314 | function print(str) { util.print(str) } 315 | function esc(str) { print("\x1b[" + str) } 316 | function eraseLine() { esc("0K") } 317 | function cursorRestore() { esc("0G") } 318 | function cursorHide() { esc("?25l") } 319 | function cursorShow() { esc("?25h") } 320 | function cleanup() { eraseLine(), cursorShow(), clearInterval(timer), print('\n') } 321 | 322 | // 323 | // Called when a file has been modified. 324 | // Run the matching tests and change the status. 325 | // 326 | function changed(file) { 327 | status = { honored: 0, broken: 0, errored: 0, pending: 0 }; 328 | 329 | msg('watcher', 'detected change in', file); 330 | 331 | file = (specFileExt.test(file) ? path.join(testFolder, file) 332 | : path.join(testFolder, file + '-' + testFolder)); 333 | 334 | try { 335 | fs.statSync(file); 336 | } catch (e) { 337 | msg('watcher', 'no equivalence found, running all tests.'); 338 | file = null; 339 | } 340 | 341 | var files = (specFileExt.test(file) ? [file] : paths(testFolder)).map(function (p) { 342 | return path.join(process.cwd(), p); 343 | }).map(function (p) { 344 | var cache = require.main.moduleCache || require.cache; 345 | if (cache[p]) { delete(cache[p]) } 346 | return p; 347 | }).map(function (p) { 348 | return p.replace(fileExt, ''); 349 | }); 350 | 351 | running ++; 352 | 353 | runSuites(importSuites(files), function (results) { 354 | delete(results.time); 355 | print(cutils.result(results).join('') + '\n\n'); 356 | lastRun = new(Date); 357 | status = results; 358 | running --; 359 | }); 360 | } 361 | 362 | msg('watcher', 'watching', args); 363 | 364 | // 365 | // Watch all relevant files, 366 | // and call `changed()` on change. 367 | // 368 | args.forEach(function (p) { 369 | fs.watchFile(p, function (current, previous) { 370 | if (new(Date)(current.mtime).valueOf() === 371 | new(Date)(previous.mtime).valueOf()) { return } 372 | else { 373 | changed(p); 374 | } 375 | }); 376 | }); 377 | })(); 378 | } 379 | 380 | function runSuites(suites, callback) { 381 | var results = { 382 | honored: 0, 383 | broken: 0, 384 | errored: 0, 385 | pending: 0, 386 | total: 0, 387 | time: 0 388 | }; 389 | reporter.reset(); 390 | 391 | (function run(suites, callback) { 392 | var suite = suites.shift(); 393 | if (suite) { 394 | msg('runner', "running", suite.subject + ' ', options.watch ? false : true); 395 | suite.run(options, function (result) { 396 | Object.keys(result).forEach(function (k) { 397 | results[k] += result[k]; 398 | }); 399 | run(suites, callback); 400 | }); 401 | } else { 402 | callback(results); 403 | } 404 | })(suites, callback); 405 | } 406 | 407 | function importSuites(files) { 408 | msg(options.watcher ? 'watcher' : 'runner', 'loading', files); 409 | 410 | var spawn = require('child_process').spawn; 411 | 412 | function cwdname(f) { 413 | return f.replace(process.cwd() + '/', '') + '.js'; 414 | } 415 | 416 | function wrapSpawn(f) { 417 | f = cwdname(f); 418 | return function (options, callback) { 419 | var args = [process.argv[1], '--json', '--supress-stdout', f], 420 | p = spawn(process.argv[0], args), 421 | result; 422 | 423 | p.on('exit', function (code) { 424 | callback( 425 | !result ? 426 | {errored: 1, total: 1} 427 | : 428 | result 429 | ); 430 | }); 431 | 432 | var buffer = []; 433 | p.stdout.on('data', function (data) { 434 | data = data.toString().split(/\n/g); 435 | if (data.length == 1) { 436 | buffer.push(data[0]); 437 | } else { 438 | data[0] = buffer.concat(data[0]).join(''); 439 | buffer = [data.pop()]; 440 | 441 | data.forEach(function (data) { 442 | if (data) { 443 | data = JSON.parse(data); 444 | if (data && data[0] === 'finish') { 445 | result = data[1]; 446 | } else { 447 | reporter.report(data); 448 | } 449 | } 450 | }); 451 | } 452 | }); 453 | 454 | p.stderr.pipe(process.stderr); 455 | } 456 | } 457 | 458 | return files.reduce(options.isolate ? function (suites, f) { 459 | return suites.concat({ 460 | run: wrapSpawn(f) 461 | }); 462 | } : function (suites, f) { 463 | var obj = require(f); 464 | return suites.concat(Object.keys(obj).map(function (s) { 465 | obj[s]._filename = cwdname(f); 466 | return obj[s]; 467 | })); 468 | }, []) 469 | } 470 | 471 | // 472 | // Recursively traverse a hierarchy, returning 473 | // a list of all relevant .js files. 474 | // 475 | function paths(dir) { 476 | var paths = []; 477 | 478 | try { fs.statSync(dir) } 479 | catch (e) { return [] } 480 | 481 | (function traverse(dir, stack) { 482 | stack.push(dir); 483 | fs.readdirSync(stack.join('/')).forEach(function (file) { 484 | var path = stack.concat([file]).join('/'), 485 | stat = fs.statSync(path); 486 | 487 | if (file[0] == '.' || file === 'vendor') { 488 | return; 489 | } else if (stat.isFile() && fileExt.test(file)) { 490 | paths.push(path); 491 | } else if (stat.isDirectory()) { 492 | traverse(file, stack); 493 | } 494 | }); 495 | stack.pop(); 496 | })(dir || '.', []); 497 | 498 | return paths; 499 | } 500 | 501 | function msg(cmd, subject, str, p) { 502 | if (options.verbose) { 503 | util[p ? 'print' : 'puts']( stylize('vows ', 'green') 504 | + stylize(cmd, 'bold') 505 | + ' ' + subject + ' ' 506 | + (str ? (typeof(str) === 'string' ? str : inspect(str)) : '') 507 | ); 508 | } 509 | } 510 | 511 | function abort(cmd, str) { 512 | console.log(stylize('vows ', 'red') + stylize(cmd, 'bold') + ' ' + str); 513 | console.log(stylize('vows ', 'red') + stylize(cmd, 'bold') + ' exiting'); 514 | process.exit(-1); 515 | } 516 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/assert/error.js: -------------------------------------------------------------------------------- 1 | var stylize = require('../vows/console').stylize; 2 | var inspect = require('../vows/console').inspect; 3 | 4 | require('assert').AssertionError.prototype.toString = function () { 5 | var that = this, 6 | source = this.stack.match(/([a-zA-Z0-9._-]+\.js)(:\d+):\d+/); 7 | 8 | function parse(str) { 9 | return str.replace(/{actual}/g, inspect(that.actual)). 10 | replace(/{operator}/g, stylize(that.operator, 'bold')). 11 | replace(/{expected}/g, (that.expected instanceof Function) 12 | ? that.expected.name 13 | : inspect(that.expected)); 14 | } 15 | 16 | if (this.message) { 17 | return stylize(parse(this.message), 'yellow') + 18 | stylize(' // ' + source[1] + source[2], 'grey'); 19 | } else { 20 | return stylize([ 21 | this.expected, 22 | this.operator, 23 | this.actual 24 | ].join(' '), 'yellow'); 25 | } 26 | }; 27 | 28 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/assert/macros.js: -------------------------------------------------------------------------------- 1 | var assert = require('assert'), 2 | utils = require('./utils'); 3 | 4 | var messages = { 5 | 'equal' : "expected {expected},\n\tgot\t {actual} ({operator})", 6 | 'notEqual' : "didn't expect {actual} ({operator})" 7 | }; 8 | messages['strictEqual'] = messages['deepEqual'] = messages['equal']; 9 | messages['notStrictEqual'] = messages['notDeepEqual'] = messages['notEqual']; 10 | 11 | for (var key in messages) { 12 | assert[key] = (function (key, callback) { 13 | return function (actual, expected, message) { 14 | callback(actual, expected, message || messages[key]); 15 | }; 16 | })(key, assert[key]); 17 | } 18 | 19 | assert.ok = (function (callback) { 20 | return function (actual, message) { 21 | callback(actual, message || "expected expression to evaluate to {expected}, but was {actual}"); 22 | }; 23 | })(assert.ok); 24 | 25 | assert.match = function (actual, expected, message) { 26 | if (! expected.test(actual)) { 27 | assert.fail(actual, expected, message || "expected {actual} to match {expected}", "match", assert.match); 28 | } 29 | }; 30 | assert.matches = assert.match; 31 | 32 | assert.isTrue = function (actual, message) { 33 | if (actual !== true) { 34 | assert.fail(actual, true, message || "expected {expected}, got {actual}", "===", assert.isTrue); 35 | } 36 | }; 37 | assert.isFalse = function (actual, message) { 38 | if (actual !== false) { 39 | assert.fail(actual, false, message || "expected {expected}, got {actual}", "===", assert.isFalse); 40 | } 41 | }; 42 | assert.isZero = function (actual, message) { 43 | if (actual !== 0) { 44 | assert.fail(actual, 0, message || "expected {expected}, got {actual}", "===", assert.isZero); 45 | } 46 | }; 47 | assert.isNotZero = function (actual, message) { 48 | if (actual === 0) { 49 | assert.fail(actual, 0, message || "expected non-zero value, got {actual}", "===", assert.isNotZero); 50 | } 51 | }; 52 | 53 | assert.greater = function (actual, expected, message) { 54 | if (actual <= expected) { 55 | assert.fail(actual, expected, message || "expected {actual} to be greater than {expected}", ">", assert.greater); 56 | } 57 | }; 58 | assert.lesser = function (actual, expected, message) { 59 | if (actual >= expected) { 60 | assert.fail(actual, expected, message || "expected {actual} to be lesser than {expected}", "<", assert.lesser); 61 | } 62 | }; 63 | 64 | assert.inDelta = function (actual, expected, delta, message) { 65 | var lower = expected - delta; 66 | var upper = expected + delta; 67 | if (actual < lower || actual > upper) { 68 | assert.fail(actual, expected, message || "expected {actual} to be in within *" + delta.toString() + "* of {expected}", null, assert.inDelta); 69 | } 70 | }; 71 | 72 | // 73 | // Inclusion 74 | // 75 | assert.include = function (actual, expected, message) { 76 | if ((function (obj) { 77 | if (isArray(obj) || isString(obj)) { 78 | return obj.indexOf(expected) === -1; 79 | } else if (isObject(actual)) { 80 | return ! obj.hasOwnProperty(expected); 81 | } 82 | return false; 83 | })(actual)) { 84 | assert.fail(actual, expected, message || "expected {actual} to include {expected}", "include", assert.include); 85 | } 86 | }; 87 | assert.includes = assert.include; 88 | 89 | assert.deepInclude = function (actual, expected, message) { 90 | if (!isArray(actual)) { 91 | return assert.include(actual, expected, message); 92 | } 93 | if (!actual.some(function (item) { return utils.deepEqual(item, expected) })) { 94 | assert.fail(actual, expected, message || "expected {actual} to include {expected}", "include", assert.deepInclude); 95 | } 96 | }; 97 | assert.deepIncludes = assert.deepInclude; 98 | 99 | // 100 | // Length 101 | // 102 | assert.isEmpty = function (actual, message) { 103 | if ((isObject(actual) && Object.keys(actual).length > 0) || actual.length > 0) { 104 | assert.fail(actual, 0, message || "expected {actual} to be empty", "length", assert.isEmpty); 105 | } 106 | }; 107 | assert.isNotEmpty = function (actual, message) { 108 | if ((isObject(actual) && Object.keys(actual).length === 0) || actual.length === 0) { 109 | assert.fail(actual, 0, message || "expected {actual} to be not empty", "length", assert.isNotEmpty); 110 | } 111 | }; 112 | 113 | assert.length = function (actual, expected, message) { 114 | if (actual.length !== expected) { 115 | assert.fail(actual, expected, message || "expected {actual} to have {expected} element(s)", "length", assert.length); 116 | } 117 | }; 118 | 119 | // 120 | // Type 121 | // 122 | assert.isArray = function (actual, message) { 123 | assertTypeOf(actual, 'array', message || "expected {actual} to be an Array", assert.isArray); 124 | }; 125 | assert.isObject = function (actual, message) { 126 | assertTypeOf(actual, 'object', message || "expected {actual} to be an Object", assert.isObject); 127 | }; 128 | assert.isNumber = function (actual, message) { 129 | if (isNaN(actual)) { 130 | assert.fail(actual, 'number', message || "expected {actual} to be of type {expected}", "isNaN", assert.isNumber); 131 | } else { 132 | assertTypeOf(actual, 'number', message || "expected {actual} to be a Number", assert.isNumber); 133 | } 134 | }; 135 | assert.isBoolean = function (actual, message) { 136 | if (actual !== true && actual !== false) { 137 | assert.fail(actual, 'boolean', message || "expected {actual} to be a Boolean", "===", assert.isBoolean); 138 | } 139 | }; 140 | assert.isNaN = function (actual, message) { 141 | if (actual === actual) { 142 | assert.fail(actual, 'NaN', message || "expected {actual} to be NaN", "===", assert.isNaN); 143 | } 144 | }; 145 | assert.isNull = function (actual, message) { 146 | if (actual !== null) { 147 | assert.fail(actual, null, message || "expected {expected}, got {actual}", "===", assert.isNull); 148 | } 149 | }; 150 | assert.isNotNull = function (actual, message) { 151 | if (actual === null) { 152 | assert.fail(actual, null, message || "expected non-null value, got {actual}", "===", assert.isNotNull); 153 | } 154 | }; 155 | assert.isUndefined = function (actual, message) { 156 | if (actual !== undefined) { 157 | assert.fail(actual, undefined, message || "expected {actual} to be {expected}", "===", assert.isUndefined); 158 | } 159 | }; 160 | assert.isDefined = function (actual, message) { 161 | if(actual === undefined) { 162 | assert.fail(actual, 0, message || "expected {actual} to be defined", "===", assert.isDefined); 163 | } 164 | }; 165 | assert.isString = function (actual, message) { 166 | assertTypeOf(actual, 'string', message || "expected {actual} to be a String", assert.isString); 167 | }; 168 | assert.isFunction = function (actual, message) { 169 | assertTypeOf(actual, 'function', message || "expected {actual} to be a Function", assert.isFunction); 170 | }; 171 | assert.typeOf = function (actual, expected, message) { 172 | assertTypeOf(actual, expected, message, assert.typeOf); 173 | }; 174 | assert.instanceOf = function (actual, expected, message) { 175 | if (! (actual instanceof expected)) { 176 | assert.fail(actual, expected, message || "expected {actual} to be an instance of {expected}", "instanceof", assert.instanceOf); 177 | } 178 | }; 179 | 180 | // 181 | // Utility functions 182 | // 183 | 184 | function assertTypeOf(actual, expected, message, caller) { 185 | if (typeOf(actual) !== expected) { 186 | assert.fail(actual, expected, message || "expected {actual} to be of type {expected}", "typeOf", caller); 187 | } 188 | }; 189 | 190 | function isArray (obj) { 191 | return Array.isArray(obj); 192 | } 193 | 194 | function isString (obj) { 195 | return typeof(obj) === 'string' || obj instanceof String; 196 | } 197 | 198 | function isObject (obj) { 199 | return typeof(obj) === 'object' && obj && !isArray(obj); 200 | } 201 | 202 | // A better `typeof` 203 | function typeOf(value) { 204 | var s = typeof(value), 205 | types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; 206 | 207 | if (s === 'object' || s === 'function') { 208 | if (value) { 209 | types.forEach(function (t) { 210 | if (value instanceof t) { s = t.name.toLowerCase() } 211 | }); 212 | } else { s = 'null' } 213 | } 214 | return s; 215 | } 216 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/assert/utils.js: -------------------------------------------------------------------------------- 1 | 2 | // Taken from node/lib/assert.js 3 | exports.deepEqual = function (actual, expected) { 4 | if (actual === expected) { 5 | return true; 6 | 7 | } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { 8 | if (actual.length != expected.length) return false; 9 | 10 | for (var i = 0; i < actual.length; i++) { 11 | if (actual[i] !== expected[i]) return false; 12 | } 13 | return true; 14 | 15 | } else if (actual instanceof Date && expected instanceof Date) { 16 | return actual.getTime() === expected.getTime(); 17 | 18 | } else if (typeof actual != 'object' && typeof expected != 'object') { 19 | return actual == expected; 20 | 21 | } else { 22 | return objEquiv(actual, expected); 23 | } 24 | } 25 | 26 | // Taken from node/lib/assert.js 27 | exports.notDeepEqual = function (actual, expected, message) { 28 | if (exports.deepEqual(actual, expected)) { 29 | fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); 30 | } 31 | } 32 | 33 | // Taken from node/lib/assert.js 34 | function isUndefinedOrNull(value) { 35 | return value === null || value === undefined; 36 | } 37 | 38 | // Taken from node/lib/assert.js 39 | function isArguments(object) { 40 | return Object.prototype.toString.call(object) == '[object Arguments]'; 41 | } 42 | 43 | // Taken from node/lib/assert.js 44 | function objEquiv(a, b) { 45 | if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) 46 | return false; 47 | if (a.prototype !== b.prototype) return false; 48 | if (isArguments(a)) { 49 | if (!isArguments(b)) { 50 | return false; 51 | } 52 | a = pSlice.call(a); 53 | b = pSlice.call(b); 54 | return exports.deepEqual(a, b); 55 | } 56 | try { 57 | var ka = Object.keys(a), 58 | kb = Object.keys(b), 59 | key, i; 60 | } catch (e) { 61 | return false; 62 | } 63 | if (ka.length != kb.length) 64 | return false; 65 | ka.sort(); 66 | kb.sort(); 67 | for (i = ka.length - 1; i >= 0; i--) { 68 | if (ka[i] != kb[i]) 69 | return false; 70 | } 71 | for (i = ka.length - 1; i >= 0; i--) { 72 | key = ka[i]; 73 | if (!exports.deepEqual(a[key], b[key])) return false; 74 | } 75 | return true; 76 | } 77 | 78 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows.js: -------------------------------------------------------------------------------- 1 | // 2 | // Vows.js - asynchronous event-based BDD for node.js 3 | // 4 | // usage: 5 | // 6 | // var vows = require('vows'); 7 | // 8 | // vows.describe('Deep Thought').addBatch({ 9 | // "An instance of DeepThought": { 10 | // topic: new DeepThought, 11 | // 12 | // "should know the answer to the ultimate question of life": function (deepThought) { 13 | // assert.equal (deepThought.question('what is the answer to the universe?'), 42); 14 | // } 15 | // } 16 | // }).run(); 17 | // 18 | var sys = require('sys'), 19 | path = require('path'), 20 | events = require('events'), 21 | vows = exports; 22 | 23 | // Options 24 | vows.options = { 25 | Emitter: events.EventEmitter, 26 | reporter: require('./vows/reporters/dot-matrix'), 27 | matcher: /.*/, 28 | error: true // Handle "error" event 29 | }; 30 | 31 | vows.__defineGetter__('reporter', function () { 32 | return vows.options.reporter; 33 | }); 34 | 35 | var stylize = require('./vows/console').stylize; 36 | var console = require('./vows/console'); 37 | 38 | vows.inspect = require('./vows/console').inspect; 39 | vows.prepare = require('./vows/extras').prepare; 40 | vows.tryEnd = require('./vows/suite').tryEnd; 41 | 42 | // 43 | // Assertion Macros & Extensions 44 | // 45 | require('./assert/error'); 46 | require('./assert/macros'); 47 | 48 | // 49 | // Suite constructor 50 | // 51 | var Suite = require('./vows/suite').Suite; 52 | 53 | // 54 | // This function gets added to events.EventEmitter.prototype, by default. 55 | // It's essentially a wrapper around `on`, which adds all the specification 56 | // goodness. 57 | // 58 | function addVow(vow) { 59 | var batch = vow.batch; 60 | 61 | batch.total ++; 62 | batch.vows.push(vow); 63 | 64 | return this.on("success", function () { 65 | var args = Array.prototype.slice.call(arguments); 66 | // If the callback is expecting two or more arguments, 67 | // pass the error as the first (null) and the result after. 68 | if (vow.callback.length >= 2 && batch.suite.options.error) { 69 | args.unshift(null); 70 | } 71 | runTest(args, this.ctx); 72 | vows.tryEnd(batch); 73 | 74 | }).on("error", function (err) { 75 | if (vow.callback.length >= 2 || !batch.suite.options.error) { 76 | runTest(arguments, this.ctx); 77 | } else { 78 | output('errored', { type: 'promise', error: err.stack || err.message || JSON.stringify(err) }); 79 | } 80 | vows.tryEnd(batch); 81 | }); 82 | 83 | function runTest(args, ctx) { 84 | var topic, status; 85 | 86 | if (vow.callback instanceof String) { 87 | return output('pending'); 88 | } 89 | 90 | // Run the test, and try to catch `AssertionError`s and other exceptions; 91 | // increment counters accordingly. 92 | try { 93 | vow.callback.apply(ctx === global || !ctx ? vow.binding : ctx, args); 94 | output('honored'); 95 | } catch (e) { 96 | if (e.name && e.name.match(/AssertionError/)) { 97 | output('broken', e.toString()); 98 | } else { 99 | output('errored', e.stack || e.message || e); 100 | } 101 | } 102 | } 103 | 104 | function output(status, exception) { 105 | batch[status] ++; 106 | vow.status = status; 107 | 108 | if (vow.context && batch.lastContext !== vow.context) { 109 | batch.lastContext = vow.context; 110 | batch.suite.report(['context', vow.context]); 111 | } 112 | batch.suite.report(['vow', { 113 | title: vow.description, 114 | context: vow.context, 115 | status: status, 116 | exception: exception || null 117 | }]); 118 | } 119 | }; 120 | 121 | // 122 | // On exit, check that all promises have been fired. 123 | // If not, report an error message. 124 | // 125 | process.on('exit', function () { 126 | var results = { honored: 0, broken: 0, errored: 0, pending: 0, total: 0 }, failure; 127 | 128 | vows.suites.forEach(function (s) { 129 | if ((s.results.total > 0) && (s.results.time === null)) { 130 | s.reporter.print('\n\n'); 131 | s.reporter.report(['error', { error: "Asynchronous Error", suite: s }]); 132 | } 133 | s.batches.forEach(function (b) { 134 | var unFired = []; 135 | 136 | b.vows.forEach(function (vow) { 137 | if (! vow.status) { 138 | if (unFired.indexOf(vow.context) === -1) { 139 | unFired.push(vow.context); 140 | } 141 | } 142 | }); 143 | 144 | if (unFired.length > 0) { sys.print('\n') } 145 | 146 | unFired.forEach(function (title) { 147 | s.reporter.report(['error', { 148 | error: "callback not fired", 149 | context: title, 150 | batch: b, 151 | suite: s 152 | }]); 153 | }); 154 | 155 | if (b.status === 'begin') { 156 | failure = true; 157 | results.errored ++; 158 | results.total ++; 159 | } 160 | Object.keys(results).forEach(function (k) { results[k] += b[k] }); 161 | }); 162 | }); 163 | if (failure) { 164 | sys.puts(console.result(results)); 165 | } 166 | }); 167 | 168 | vows.suites = []; 169 | 170 | // 171 | // Create a new test suite 172 | // 173 | vows.describe = function (subject) { 174 | var suite = new(Suite)(subject); 175 | 176 | this.options.Emitter.prototype.addVow = addVow; 177 | this.suites.push(suite); 178 | 179 | // 180 | // Add any additional arguments as batches if they're present 181 | // 182 | if (arguments.length > 1) { 183 | for (var i = 1, l = arguments.length; i < l; ++i) { 184 | suite.addBatch(arguments[i]); 185 | } 186 | } 187 | 188 | return suite; 189 | }; 190 | 191 | 192 | vows.version = require('fs').readFileSync(path.join(__dirname, '..', 'package.json')) 193 | .toString().match(/"version"\s*:\s*"([\d.]+)"/)[1]; 194 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/console.js: -------------------------------------------------------------------------------- 1 | var eyes = require('eyes').inspector({ stream: null, styles: false }); 2 | 3 | // Stylize a string 4 | this.stylize = function stylize(str, style) { 5 | var styles = { 6 | 'bold' : [1, 22], 7 | 'italic' : [3, 23], 8 | 'underline' : [4, 24], 9 | 'cyan' : [96, 39], 10 | 'yellow' : [33, 39], 11 | 'green' : [32, 39], 12 | 'red' : [31, 39], 13 | 'grey' : [90, 39], 14 | 'green-hi' : [92, 32], 15 | }; 16 | return '\033[' + styles[style][0] + 'm' + str + 17 | '\033[' + styles[style][1] + 'm'; 18 | }; 19 | 20 | var $ = this.$ = function (str) { 21 | str = new(String)(str); 22 | 23 | ['bold', 'grey', 'yellow', 'red', 'green', 'white', 'cyan', 'italic'].forEach(function (style) { 24 | Object.defineProperty(str, style, { 25 | get: function () { 26 | return exports.$(exports.stylize(this, style)); 27 | } 28 | }); 29 | }); 30 | return str; 31 | }; 32 | 33 | this.puts = function (options) { 34 | var stylize = exports.stylize; 35 | options.stream || (options.stream = process.stdout); 36 | options.tail = options.tail || ''; 37 | 38 | return function (args) { 39 | args = Array.prototype.slice.call(arguments); 40 | if (!options.raw) { 41 | args = args.map(function (a) { 42 | return a.replace(/`([^`]+)`/g, function (_, capture) { return stylize(capture, 'italic') }) 43 | .replace(/\*([^*]+)\*/g, function (_, capture) { return stylize(capture, 'bold') }); 44 | }); 45 | } 46 | return options.stream.write(args.join('\n') + options.tail); 47 | }; 48 | }; 49 | 50 | this.result = function (event) { 51 | var result = [], buffer = [], time = '', header; 52 | var complete = event.honored + event.pending + event.errored + event.broken; 53 | var status = (event.errored && 'errored') || (event.broken && 'broken') || 54 | (event.honored && 'honored') || (event.pending && 'pending'); 55 | 56 | if (event.total === 0) { 57 | return [$("Could not find any tests to run.").bold.red]; 58 | } 59 | 60 | event.honored && result.push($(event.honored).bold + " honored"); 61 | event.broken && result.push($(event.broken).bold + " broken"); 62 | event.errored && result.push($(event.errored).bold + " errored"); 63 | event.pending && result.push($(event.pending).bold + " pending"); 64 | 65 | if (complete < event.total) { 66 | result.push($(event.total - complete).bold + " dropped"); 67 | } 68 | 69 | result = result.join(' ∙ '); 70 | 71 | header = { 72 | honored: '✓ ' + $('OK').bold.green, 73 | broken: '✗ ' + $('Broken').bold.yellow, 74 | errored: '✗ ' + $('Errored').bold.red, 75 | pending: '- ' + $('Pending').bold.cyan 76 | }[status] + ' » '; 77 | 78 | if (typeof(event.time) === 'number') { 79 | time = ' (' + event.time.toFixed(3) + 's)'; 80 | time = this.stylize(time, 'grey'); 81 | } 82 | buffer.push(header + result + time + '\n'); 83 | 84 | return buffer; 85 | }; 86 | 87 | this.inspect = function inspect(val) { 88 | return '\033[1m' + eyes(val) + '\033[22m'; 89 | }; 90 | 91 | this.error = function (obj) { 92 | var string = '✗ ' + $('Errored ').red + '» '; 93 | string += $(obj.error).red.bold + '\n'; 94 | string += (obj.context ? ' in ' + $(obj.context).red + '\n': ''); 95 | string += ' in ' + $(obj.suite.subject).red + '\n'; 96 | string += ' in ' + $(obj.suite._filename).red; 97 | 98 | return string; 99 | }; 100 | 101 | this.contextText = function (event) { 102 | return ' ' + event; 103 | }; 104 | 105 | this.vowText = function (event) { 106 | var buffer = []; 107 | 108 | buffer.push(' ' + { 109 | honored: ' ✓ ', 110 | broken: ' ✗ ', 111 | errored: ' ✗ ', 112 | pending: ' - ' 113 | }[event.status] + this.stylize(event.title, ({ 114 | honored: 'green', 115 | broken: 'yellow', 116 | errored: 'red', 117 | pending: 'cyan' 118 | })[event.status])); 119 | 120 | if (event.status === 'broken') { 121 | buffer.push(' » ' + event.exception); 122 | } else if (event.status === 'errored') { 123 | if (event.exception.type === 'promise') { 124 | buffer.push(' » ' + this.stylize("An unexpected error was caught: " + 125 | this.stylize(event.exception.error, 'bold'), 'red')); 126 | } else { 127 | buffer.push(' ' + this.stylize(event.exception, 'red')); 128 | } 129 | } 130 | return buffer.join('\n'); 131 | }; 132 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/context.js: -------------------------------------------------------------------------------- 1 | 2 | this.Context = function (vow, ctx, env) { 3 | var that = this; 4 | 5 | this.tests = vow.callback; 6 | this.topics = (ctx.topics || []).slice(0); 7 | this.emitter = null; 8 | this.env = env || {}; 9 | this.env.context = this; 10 | 11 | this.env.callback = function (/* arguments */) { 12 | var ctx = this; 13 | var args = Array.prototype.slice.call(arguments); 14 | 15 | var emit = (function (args) { 16 | // 17 | // Convert callback-style results into events. 18 | // 19 | if (vow.batch.suite.options.error) { 20 | return function () { 21 | var e = args.shift(); 22 | that.emitter.ctx = ctx; 23 | // We handle a special case, where the first argument is a 24 | // boolean, in which case we treat it as a result, and not 25 | // an error. This is useful for `path.exists` and other 26 | // functions like it, which only pass a single boolean 27 | // parameter instead of the more common (error, result) pair. 28 | if (typeof(e) === 'boolean' && args.length === 0) { 29 | that.emitter.emit.call(that.emitter, 'success', e); 30 | } else { 31 | if (e) { that.emitter.emit.apply(that.emitter, ['error', e].concat(args)) } 32 | else { that.emitter.emit.apply(that.emitter, ['success'].concat(args)) } 33 | } 34 | }; 35 | } else { 36 | return function () { 37 | that.emitter.ctx = ctx; 38 | that.emitter.emit.apply(that.emitter, ['success'].concat(args)); 39 | }; 40 | } 41 | })(args.slice(0)); 42 | // If `this.callback` is called synchronously, 43 | // the emitter will not have been set yet, 44 | // so we defer the emition, that way it'll behave 45 | // asynchronously. 46 | if (that.emitter) { emit() } 47 | else { process.nextTick(emit) } 48 | }; 49 | this.name = vow.description; 50 | this.title = [ 51 | ctx.title || '', 52 | vow.description || '' 53 | ].join(/^[#.:]/.test(vow.description) ? '' : ' ').trim(); 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/coverage/file.js: -------------------------------------------------------------------------------- 1 | 2 | exports.coverage = function (filename, data) { 3 | var ret = { 4 | filename: filename, 5 | coverage: 0, 6 | hits: 0, 7 | misses: 0, 8 | sloc : 0 9 | }; 10 | 11 | var source = data.source; 12 | ret.source = source.map(function (line, num) { 13 | num++; 14 | 15 | if (data[num] === 0) { 16 | ret.misses++; 17 | ret.sloc++; 18 | } else if (data[num] !== undefined) { 19 | ret.hits++; 20 | ret.sloc++; 21 | } 22 | 23 | return { line: line, coverage: (data[num] === undefined ? '' : data[num]) }; 24 | }); 25 | 26 | ret.coverage = (ret.hits / ret.sloc) * 100; 27 | 28 | return ret; 29 | }; -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/coverage/fragments/coverage-foot.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/coverage/fragments/coverage-head.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 50 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/coverage/report-html.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'), 2 | fs = require('fs'), 3 | file = require('./file'); 4 | 5 | this.name = 'coverage-report-html'; 6 | 7 | function getCoverageClass( data ) { 8 | var fullCoverage= (data.coverage == 100); 9 | var okCoverage= (!fullCoverage && data.coverage >=60); 10 | var coverageClass= ''; 11 | if( fullCoverage ) coverageClass= 'fullCoverage'; 12 | else if( okCoverage) coverageClass= 'okCoverage'; 13 | else coverageClass= 'poorCoverage'; 14 | return coverageClass; 15 | } 16 | this.report = function (coverageMap) { 17 | var out, head, foot; 18 | 19 | try { 20 | out = fs.openSync("coverage.html", "w"); 21 | head = fs.readFileSync(__dirname + "/fragments/coverage-head.html", "utf8"); 22 | foot = fs.readFileSync(__dirname + "/fragments/coverage-foot.html", "utf8"); 23 | } catch (error) { 24 | sys.print("Error: Unable to write to file coverage.html\n"); 25 | return; 26 | } 27 | 28 | fs.writeSync(out, head); 29 | 30 | for (var filename in coverageMap) { 31 | if (coverageMap.hasOwnProperty(filename)) { 32 | var data = file.coverage(filename, coverageMap[filename]); 33 | var coverageClass= getCoverageClass( data ); 34 | fs.writeSync(out, "

" + filename + "

\n"); 35 | fs.writeSync(out, '' + "[ hits: " + data.hits); 36 | fs.writeSync(out, ", misses: " + data.misses + ", sloc: " + data.sloc); 37 | fs.writeSync(out, ", coverage: " + data.coverage.toFixed(2) + "% ]" + " [+]\n"); 38 | fs.writeSync(out, "\n"); 48 | fs.writeSync(out, "
\n"); 49 | } 50 | } 51 | 52 | fs.writeSync(out, foot); 53 | fs.close(out); 54 | }; -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/coverage/report-json.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'), 2 | fs = require('fs'), 3 | file = require('./file'); 4 | 5 | this.name = 'coverage-report-json'; 6 | 7 | this.report = function (coverageMap) { 8 | var output = { 9 | meta: { 10 | "generator": "vowsjs", 11 | "generated": new Date().toString(), 12 | "instrumentation": "node-jscoverage", 13 | "file-version": "1.0" 14 | }, 15 | files: [ ], 16 | coverage: [ ] 17 | }; 18 | 19 | 20 | for (var filename in coverageMap) { 21 | if (coverageMap.hasOwnProperty(filename)) { 22 | var data = file.coverage(filename, coverageMap[filename]); 23 | 24 | var coverage = { 25 | file: filename, 26 | coverage: data.coverage.toFixed(2), 27 | hits: data.hits, 28 | misses: data.misses, 29 | sloc: data.sloc, 30 | source: { } 31 | }; 32 | 33 | for (var i = 0; i < data.source.length; i++) { 34 | coverage.source[i + 1] = { 35 | line: data.source[i].line, 36 | coverage: data.source[i].coverage 37 | }; 38 | } 39 | 40 | output.coverage.push(coverage); 41 | 42 | output.files.push(filename); 43 | } 44 | } 45 | 46 | try { 47 | out = fs.openSync("coverage.json", "w"); 48 | fs.writeSync(out, JSON.stringify(output)); 49 | fs.close(out); 50 | } catch (error) { 51 | sys.print("Error: Unable to write to file coverage.json\n"); 52 | return; 53 | } 54 | }; -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/coverage/report-plain.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'), 2 | file = require('./file'); 3 | 4 | this.name = 'coverage-report-plain'; 5 | 6 | function lpad(str, width) { 7 | str = String(str); 8 | var n = width - str.length; 9 | 10 | if (n < 1) { 11 | return str; 12 | } 13 | 14 | while (n--) { 15 | str = ' ' + str; 16 | } 17 | 18 | return str; 19 | } 20 | 21 | 22 | this.report = function (coverageMap) { 23 | for (var filename in coverageMap) { 24 | if (coverageMap.hasOwnProperty(filename)) { 25 | var data = file.coverage(filename, coverageMap[filename]); 26 | 27 | sys.print(filename + ":\n"); 28 | sys.print("[ hits: " + data.hits + ", misses: " + data.misses); 29 | sys.print(", sloc: " + data.sloc + ", coverage: " + data.coverage.toFixed(2) + "% ]\n"); 30 | 31 | for (var i = 0; i < data.source.length; i++) { 32 | sys.print(lpad(data.source[i].coverage, 5) + " | " + data.source[i].line + "\n"); 33 | } 34 | 35 | sys.print("\n"); 36 | } 37 | } 38 | }; -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/extras.js: -------------------------------------------------------------------------------- 1 | var events = require('events'); 2 | // 3 | // Wrap a Node.js style async function into an EventEmmitter 4 | // 5 | this.prepare = function (obj, targets) { 6 | targets.forEach(function (target) { 7 | if (target in obj) { 8 | obj[target] = (function (fun) { 9 | return function () { 10 | var args = Array.prototype.slice.call(arguments); 11 | var ee = new(events.EventEmitter); 12 | 13 | args.push(function (err /* [, data] */) { 14 | var args = Array.prototype.slice.call(arguments, 1); 15 | 16 | if (err) { ee.emit.apply(ee, ['error', err].concat(args)) } 17 | else { ee.emit.apply(ee, ['success'].concat(args)) } 18 | }); 19 | fun.apply(obj, args); 20 | 21 | return ee; 22 | }; 23 | })(obj[target]); 24 | } 25 | }); 26 | return obj; 27 | }; 28 | 29 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/reporters/dot-matrix.js: -------------------------------------------------------------------------------- 1 | var options = { tail: '' }, 2 | console = require('../../vows/console'), 3 | stylize = console.stylize, 4 | puts = console.puts(options); 5 | // 6 | // Console reporter 7 | // 8 | var messages = [], lastContext; 9 | 10 | this.name = 'dot-matrix'; 11 | this.setStream = function (s) { 12 | options.stream = s; 13 | }; 14 | 15 | this.reset = function () { 16 | messages = []; 17 | lastContext = null; 18 | }; 19 | this.report = function (data) { 20 | var event = data[1]; 21 | 22 | switch (data[0]) { 23 | case 'subject': 24 | // messages.push(stylize(event, 'underline') + '\n'); 25 | break; 26 | case 'context': 27 | break; 28 | case 'vow': 29 | if (event.status === 'honored') { 30 | puts(stylize('·', 'green')); 31 | } else if (event.status === 'pending') { 32 | puts(stylize('-', 'cyan')); 33 | } else { 34 | if (lastContext !== event.context) { 35 | lastContext = event.context; 36 | messages.push(' ' + event.context); 37 | } 38 | if (event.status === 'broken') { 39 | puts(stylize('✗', 'yellow')); 40 | messages.push(console.vowText(event)); 41 | } else if (event.status === 'errored') { 42 | puts(stylize('✗', 'red')); 43 | messages.push(console.vowText(event)); 44 | } 45 | messages.push(''); 46 | } 47 | break; 48 | case 'end': 49 | puts(' '); 50 | break; 51 | case 'finish': 52 | if (messages.length) { 53 | puts('\n\n' + messages.join('\n')); 54 | } else { 55 | puts(''); 56 | } 57 | puts(console.result(event).join('\n')); 58 | break; 59 | case 'error': 60 | puts(console.error(event)); 61 | break; 62 | } 63 | }; 64 | 65 | this.print = function (str) { 66 | puts(str); 67 | }; 68 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/reporters/json.js: -------------------------------------------------------------------------------- 1 | var options = { tail: '\n', raw: true }; 2 | var console = require('../../vows/console'); 3 | var puts = console.puts(options); 4 | 5 | // 6 | // Console JSON reporter 7 | // 8 | this.name = 'json'; 9 | this.setStream = function (s) { 10 | options.stream = s; 11 | }; 12 | this.report = function (obj) { 13 | puts(JSON.stringify(obj)); 14 | }; 15 | 16 | this.print = function (str) {}; 17 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/reporters/silent.js: -------------------------------------------------------------------------------- 1 | // 2 | // Silent reporter - "Shhh" 3 | // 4 | this.name = 'silent'; 5 | this.reset = function () {}; 6 | this.report = function () {}; 7 | this.print = function () {}; 8 | 9 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/reporters/spec.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | 3 | var options = { tail: '\n' }; 4 | var console = require('../../vows/console'); 5 | var stylize = console.stylize, 6 | puts = console.puts(options); 7 | // 8 | // Console reporter 9 | // 10 | 11 | this.name = 'spec'; 12 | this.setStream = function (s) { 13 | options.stream = s; 14 | }; 15 | this.report = function (data) { 16 | var event = data[1]; 17 | 18 | buffer = []; 19 | 20 | switch (data[0]) { 21 | case 'subject': 22 | puts('\n♢ ' + stylize(event, 'bold') + '\n'); 23 | break; 24 | case 'context': 25 | puts(console.contextText(event)); 26 | break; 27 | case 'vow': 28 | puts(console.vowText(event)); 29 | break; 30 | case 'end': 31 | sys.print('\n'); 32 | break; 33 | case 'finish': 34 | puts(console.result(event).join('\n')); 35 | break; 36 | case 'error': 37 | puts(console.error(event)); 38 | break; 39 | } 40 | }; 41 | 42 | this.print = function (str) { 43 | sys.print(str); 44 | }; 45 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/reporters/watch.js: -------------------------------------------------------------------------------- 1 | var sys = require('sys'); 2 | 3 | var options = {}; 4 | var console = require('../../vows/console'); 5 | var spec = require('../../vows/reporters/spec'); 6 | var stylize = console.stylize, 7 | puts = console.puts(options); 8 | // 9 | // Console reporter 10 | // 11 | var lastContext; 12 | 13 | this.name = 'watch'; 14 | this.setStream = function (s) { 15 | options.stream = s; 16 | }; 17 | this.reset = function () { 18 | lastContext = null; 19 | }; 20 | this.report = function (data) { 21 | var event = data[1]; 22 | 23 | switch (data[0]) { 24 | case 'vow': 25 | if (['honored', 'pending'].indexOf(event.status) === -1) { 26 | if (lastContext !== event.context) { 27 | lastContext = event.context; 28 | puts(console.contextText(event.context)); 29 | } 30 | puts(console.vowText(event)); 31 | puts(''); 32 | } 33 | break; 34 | case 'error': 35 | puts(console.error(event)); 36 | break; 37 | } 38 | }; 39 | this.print = function (str) {}; 40 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/reporters/xunit.js: -------------------------------------------------------------------------------- 1 | // xunit outoput for vows, so we can run things under hudson 2 | // 3 | // The translation to xunit is simple. Most likely more tags/attributes can be 4 | // added, see: http://ant.1045680.n5.nabble.com/schema-for-junit-xml-output-td1375274.html 5 | // 6 | 7 | var puts = require('util').puts; 8 | 9 | var buffer = [], 10 | curSubject = null; 11 | 12 | function xmlEnc(value) { 13 | return !value ? value : String(value).replace(/&/g, "&") 14 | .replace(/>/g, ">") 15 | .replace(/'; 43 | } 44 | 45 | function cdata(data) { 46 | return ''; 47 | } 48 | 49 | this.name = 'xunit'; 50 | this.report = function (data) { 51 | var event = data[1]; 52 | 53 | switch (data[0]) { 54 | case 'subject': 55 | curSubject = event; 56 | break; 57 | case 'context': 58 | break; 59 | case 'vow': 60 | switch (event.status) { 61 | case 'honored': 62 | buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, true)); 63 | break; 64 | case 'broken': 65 | var err = tag('error', {type: 'vows.event.broken', message: 'Broken test'}, false, cdata(event.exception)); 66 | buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, false, err)); 67 | break; 68 | case 'errored': 69 | var skip = tag('skipped', {type: 'vows.event.errored', message: 'Errored test'}, false, cdata(event.exception)); 70 | buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, false, skip)); 71 | break; 72 | case 'pending': 73 | // nop 74 | break; 75 | } 76 | break; 77 | case 'end': 78 | buffer.push(end('testcase')); 79 | break; 80 | case 'finish': 81 | buffer.unshift(tag('testsuite', {name: 'Vows test', tests: event.total, timestamp: (new Date()).toUTCString(), errors: event.errored, failures: event.broken, skip: event.pending, time: event.time})); 82 | buffer.push(end('testsuite')); 83 | puts(buffer.join('\n')); 84 | break; 85 | case 'error': 86 | break; 87 | } 88 | }; 89 | 90 | this.print = function (str) { }; 91 | -------------------------------------------------------------------------------- /tests/node_modules/vows/lib/vows/suite.js: -------------------------------------------------------------------------------- 1 | var events = require('events'), 2 | path = require('path'); 3 | 4 | var vows = require('../vows'); 5 | var Context = require('../vows/context').Context; 6 | 7 | this.Suite = function (subject) { 8 | this.subject = subject; 9 | this.matcher = /.*/; 10 | this.reporter = require('./reporters/dot-matrix'); 11 | this.batches = []; 12 | this.options = { error: true }; 13 | this.reset(); 14 | }; 15 | 16 | this.Suite.prototype = new(function () { 17 | this.reset = function () { 18 | this.results = { 19 | honored: 0, 20 | broken: 0, 21 | errored: 0, 22 | pending: 0, 23 | total: 0, 24 | time: null 25 | }; 26 | this.batches.forEach(function (b) { 27 | b.lastContext = null; 28 | b.remaining = b._remaining; 29 | b.honored = b.broken = b.errored = b.total = b.pending = 0; 30 | b.vows.forEach(function (vow) { vow.status = null }); 31 | b.teardowns = []; 32 | }); 33 | }; 34 | 35 | this.addBatch = function (tests) { 36 | this.batches.push({ 37 | tests: tests, 38 | suite: this, 39 | vows: [], 40 | remaining: 0, 41 | _remaining: 0, 42 | honored: 0, 43 | broken: 0, 44 | errored: 0, 45 | pending: 0, 46 | total: 0, 47 | teardowns: [] 48 | }); 49 | return this; 50 | }; 51 | this.addVows = this.addBatch; 52 | 53 | this.parseBatch = function (batch, matcher) { 54 | var tests = batch.tests; 55 | 56 | if ('topic' in tests) { 57 | throw new(Error)("missing top-level context."); 58 | } 59 | // Count the number of vows/promises expected to fire, 60 | // so we know when the tests are over. 61 | // We match the keys against `matcher`, to decide 62 | // whether or not they should be included in the test. 63 | // Any key, including assertion function keys can be matched. 64 | // If a child matches, then the n parent topics must not be skipped. 65 | (function count(tests, _match) { 66 | var match = false; 67 | 68 | var keys = Object.keys(tests).filter(function (k) { 69 | return k !== 'topic' && k !== 'teardown'; 70 | }); 71 | 72 | for (var i = 0, key; i < keys.length; i++) { 73 | key = keys[i]; 74 | 75 | // If the parent node, or this one matches. 76 | match = _match || matcher.test(key); 77 | 78 | if (typeof(tests[key]) === 'object') { 79 | match = count(tests[key], match); 80 | } else { 81 | if (typeof(tests[key]) === 'string') { 82 | tests[key] = new(String)(tests[key]); 83 | } 84 | if (! match) { 85 | tests[key]._skip = true; 86 | } 87 | } 88 | } 89 | 90 | // If any of the children matched, 91 | // don't skip this node. 92 | for (var i = 0; i < keys.length; i++) { 93 | if (! tests[keys[i]]._skip) { match = true } 94 | } 95 | 96 | if (match) { batch.remaining ++ } 97 | else { tests._skip = true } 98 | 99 | return match; 100 | })(tests, false); 101 | 102 | batch._remaining = batch.remaining; 103 | }; 104 | 105 | this.runBatch = function (batch) { 106 | var topic, 107 | tests = batch.tests, 108 | promise = batch.promise = new(events.EventEmitter); 109 | 110 | var that = this; 111 | 112 | batch.status = 'begin'; 113 | 114 | // The test runner, it calls itself recursively, passing the 115 | // previous context to the inner contexts. This is so the `topic` 116 | // functions have access to all the previous context topics in their 117 | // arguments list. 118 | // It is defined and invoked at the same time. 119 | // If it encounters a `topic` function, it waits for the returned 120 | // promise to emit (the topic), at which point it runs the functions under it, 121 | // passing the topic as an argument. 122 | (function run(ctx, lastTopic) { 123 | var old = false; 124 | topic = ctx.tests.topic; 125 | 126 | if (typeof(topic) === 'function') { 127 | // Run the topic, passing the previous context topics 128 | topic = topic.apply(ctx.env, ctx.topics); 129 | 130 | if (typeof(topic) === 'undefined') { ctx._callback = true } 131 | } 132 | 133 | // If this context has a topic, store it in `lastTopic`, 134 | // if not, use the last topic, passed down by a parent 135 | // context. 136 | if (typeof(topic) !== 'undefined' || ctx._callback) { 137 | lastTopic = topic; 138 | } else { 139 | old = true; 140 | topic = lastTopic; 141 | } 142 | 143 | // If the topic doesn't return an event emitter (such as a promise), 144 | // we create it ourselves, and emit the value on the next tick. 145 | if (! (topic && topic.constructor === events.EventEmitter)) { 146 | ctx.emitter = new(events.EventEmitter); 147 | 148 | if (! ctx._callback) { 149 | process.nextTick(function (val) { 150 | return function () { ctx.emitter.emit("success", val) }; 151 | }(topic)); 152 | } 153 | topic = ctx.emitter; 154 | } 155 | 156 | topic.on('success', function (val) { 157 | // Once the topic fires, add the return value 158 | // to the beginning of the topics list, so it 159 | // becomes the first argument for the next topic. 160 | // If we're using the parent topic, no need to 161 | // prepend it to the topics list, or we'll get 162 | // duplicates. 163 | if (! old) Array.prototype.unshift.apply(ctx.topics, arguments); 164 | }); 165 | if (topic.setMaxListeners) { topic.setMaxListeners(Infinity) } 166 | 167 | // Now run the tests, or sub-contexts 168 | Object.keys(ctx.tests).filter(function (k) { 169 | return ctx.tests[k] && k !== 'topic' && 170 | k !== 'teardown' && !ctx.tests[k]._skip; 171 | }).forEach(function (item) { 172 | // Create a new evaluation context, 173 | // inheriting from the parent one. 174 | var env = Object.create(ctx.env); 175 | env.suite = that; 176 | 177 | // Holds the current test or context 178 | var vow = Object.create({ 179 | callback: ctx.tests[item], 180 | context: ctx.title, 181 | description: item, 182 | binding: ctx.env, 183 | status: null, 184 | batch: batch 185 | }); 186 | 187 | // If we encounter a function, add it to the callbacks 188 | // of the `topic` function, so it'll get called once the 189 | // topic fires. 190 | // If we encounter an object literal, we recurse, sending it 191 | // our current context. 192 | if ((typeof(vow.callback) === 'function') || (vow.callback instanceof String)) { 193 | topic.addVow(vow); 194 | } else if (typeof(vow.callback) === 'object') { 195 | // If there's a setup stage, we have to wait for it to fire, 196 | // before calling the inner context. Else, just run the inner context 197 | // synchronously. 198 | if (topic) { 199 | topic.on("success", function (ctx) { 200 | return function (val) { 201 | return run(new(Context)(vow, ctx, env), lastTopic); 202 | }; 203 | }(ctx)); 204 | } else { 205 | run(new(Context)(vow, ctx, env), lastTopic); 206 | } 207 | } 208 | }); 209 | // Teardown 210 | if (ctx.tests.teardown) { 211 | batch.teardowns.push(ctx); 212 | } 213 | if (! ctx.tests._skip) { 214 | batch.remaining --; 215 | } 216 | // Check if we're done running the tests 217 | exports.tryEnd(batch); 218 | // This is our initial, empty context 219 | })(new(Context)({ callback: tests, context: null, description: null }, {})); 220 | return promise; 221 | }; 222 | 223 | this.report = function () { 224 | return this.reporter.report.apply(this.reporter, arguments); 225 | }; 226 | 227 | this.run = function (options, callback) { 228 | var that = this, start; 229 | 230 | options = options || {}; 231 | 232 | for (var k in options) { this.options[k] = options[k] } 233 | 234 | this.matcher = this.options.matcher || this.matcher; 235 | this.reporter = this.options.reporter || this.reporter; 236 | 237 | this.batches.forEach(function (batch) { 238 | that.parseBatch(batch, that.matcher); 239 | }); 240 | 241 | this.reset(); 242 | 243 | start = new(Date); 244 | 245 | if (this.batches.filter(function (b) { return b.remaining > 0 }).length) { 246 | this.report(['subject', this.subject]); 247 | } 248 | 249 | return (function run(batches) { 250 | var batch = batches.shift(); 251 | 252 | if (batch) { 253 | // If the batch has no vows to run, 254 | // go to the next one. 255 | if (batch.remaining === 0) { 256 | run(batches); 257 | } else { 258 | that.runBatch(batch).on('end', function () { 259 | run(batches); 260 | }); 261 | } 262 | } else { 263 | that.results.time = (new(Date) - start) / 1000; 264 | that.report(['finish', that.results]); 265 | 266 | if (callback) { callback(that.results) } 267 | 268 | if (that.results.honored + that.results.pending === that.results.total) { 269 | return 0; 270 | } else { 271 | return 1; 272 | } 273 | } 274 | })(this.batches.slice(0)); 275 | }; 276 | 277 | this.runParallel = function () {}; 278 | 279 | this.export = function (module, options) { 280 | for (var k in (options || {})) { this.options[k] = options[k] } 281 | 282 | if (require.main === module) { 283 | return this.run(); 284 | } else { 285 | return module.exports[this.subject] = this; 286 | } 287 | }; 288 | this.exportTo = function (module, options) { // Alias, for JSLint 289 | return this.export(module, options); 290 | }; 291 | }); 292 | 293 | // 294 | // Checks if all the tests in the batch have been run, 295 | // and triggers the next batch (if any), by emitting the 'end' event. 296 | // 297 | this.tryEnd = function (batch) { 298 | var result, style, time; 299 | 300 | if (batch.honored + batch.broken + batch.errored + batch.pending === batch.total && 301 | batch.remaining === 0) { 302 | 303 | Object.keys(batch).forEach(function (k) { 304 | (k in batch.suite.results) && (batch.suite.results[k] += batch[k]); 305 | }); 306 | 307 | // Run teardowns 308 | if (batch.teardowns) { 309 | for (var i = batch.teardowns.length - 1, ctx; i >= 0; i--) { 310 | ctx = batch.teardowns[i]; 311 | ctx.tests.teardown.apply(ctx.env, ctx.topics); 312 | } 313 | } 314 | 315 | batch.status = 'end'; 316 | batch.suite.report(['end']); 317 | batch.promise.emit('end', batch.honored, batch.broken, batch.errored, batch.pending); 318 | } 319 | }; 320 | -------------------------------------------------------------------------------- /tests/node_modules/vows/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "vows", 3 | "description" : "Asynchronous BDD & continuous integration for node.js", 4 | "url" : "http://vowsjs.org", 5 | "keywords" : ["testing", "spec", "test", "BDD"], 6 | "author" : "Alexis Sellier ", 7 | "contributors" : [{ "name": "Charlie Robbins", "email": "charlie.robbins@gmail.com" }], 8 | "dependencies" : {"eyes": ">=0.1.6"}, 9 | "main" : "./lib/vows", 10 | "bin" : { "vows": "./bin/vows" }, 11 | "directories" : { "test": "./test", "bin": "./bin" }, 12 | "version" : "0.5.11", 13 | "engines" : {"node": ">=0.2.6"} 14 | } 15 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/assert-test.js: -------------------------------------------------------------------------------- 1 | var vows = require('../lib/vows'); 2 | var assert = require('assert'); 3 | 4 | vows.describe('vows/assert').addBatch({ 5 | "The Assertion module": { 6 | topic: require('assert'), 7 | 8 | "`equal`": function (assert) { 9 | assert.equal("hello world", "hello world"); 10 | assert.equal(1, true); 11 | }, 12 | "`match`": function (assert) { 13 | assert.match("hello world", /^[a-z]+ [a-z]+$/); 14 | }, 15 | "`length`": function (assert) { 16 | assert.length("hello world", 11); 17 | assert.length([1, 2, 3], 3); 18 | }, 19 | "`isDefined`": function (assert) { 20 | assert.isDefined(null); 21 | assertError(assert.isDefined, undefined); 22 | }, 23 | "`include`": function (assert) { 24 | assert.include("hello world", "world"); 25 | assert.include([0, 42, 0], 42); 26 | assert.include({goo:true}, 'goo'); 27 | }, 28 | "`deepInclude`": function (assert) { 29 | assert.deepInclude([{a:'b'},{c:'d'}], {a:'b'}); 30 | assert.deepInclude("hello world", "world"); 31 | assert.deepInclude({goo:true}, 'goo'); 32 | }, 33 | "`typeOf`": function (assert) { 34 | assert.typeOf('goo', 'string'); 35 | assert.typeOf(42, 'number'); 36 | assert.typeOf([], 'array'); 37 | assert.typeOf({}, 'object'); 38 | assert.typeOf(false, 'boolean'); 39 | }, 40 | "`instanceOf`": function (assert) { 41 | assert.instanceOf([], Array); 42 | assert.instanceOf(function () {}, Function); 43 | }, 44 | "`isArray`": function (assert) { 45 | assert.isArray([]); 46 | assertError(assert.isArray, {}); 47 | }, 48 | "`isString`": function (assert) { 49 | assert.isString(""); 50 | }, 51 | "`isObject`": function (assert) { 52 | assert.isObject({}); 53 | assertError(assert.isObject, []); 54 | }, 55 | "`isNumber`": function (assert) { 56 | assert.isNumber(0); 57 | }, 58 | "`isBoolean`": function (assert){ 59 | assert.isBoolean(true); 60 | assert.isBoolean(false); 61 | assertError(assert.isBoolean, 0); 62 | }, 63 | "`isNan`": function (assert) { 64 | assert.isNaN(0/0); 65 | }, 66 | "`isTrue`": function (assert) { 67 | assert.isTrue(true); 68 | assertError(assert.isTrue, 1); 69 | }, 70 | "`isFalse`": function (assert) { 71 | assert.isFalse(false); 72 | assertError(assert.isFalse, 0); 73 | }, 74 | "`isZero`": function (assert) { 75 | assert.isZero(0); 76 | assertError(assert.isZero, null); 77 | }, 78 | "`isNotZero`": function (assert) { 79 | assert.isNotZero(1); 80 | }, 81 | "`isUndefined`": function (assert) { 82 | assert.isUndefined(undefined); 83 | assertError(assert.isUndefined, null); 84 | }, 85 | "`isDefined`": function (assert) { 86 | assert.isDefined(null); 87 | assertError(assert.isDefined, undefined); 88 | }, 89 | "`isNull`": function (assert) { 90 | assert.isNull(null); 91 | assertError(assert.isNull, 0); 92 | assertError(assert.isNull, undefined); 93 | }, 94 | "`isNotNull`": function (assert) { 95 | assert.isNotNull(0); 96 | }, 97 | "`greater` and `lesser`": function (assert) { 98 | assert.greater(5, 4); 99 | assert.lesser(4, 5); 100 | }, 101 | "`inDelta`": function (assert) { 102 | assert.inDelta(42, 40, 5); 103 | assert.inDelta(42, 40, 2); 104 | assert.inDelta(42, 42, 0); 105 | assert.inDelta(3.1, 3.0, 0.2); 106 | assertError(assert.inDelta, [42, 40, 1]); 107 | }, 108 | "`isEmpty`": function (assert) { 109 | assert.isEmpty({}); 110 | assert.isEmpty([]); 111 | assert.isEmpty(""); 112 | }, 113 | "`isNotEmpty`": function (assert) { 114 | assert.isNotEmpty({goo:true}); 115 | assert.isNotEmpty([1]); 116 | assert.isNotEmpty(" "); 117 | assertError(assert.isNotEmpty, {}); 118 | assertError(assert.isNotEmpty, []); 119 | assertError(assert.isNotEmpty, ""); 120 | } 121 | } 122 | }).export(module); 123 | 124 | function assertError(assertion, args, fail) { 125 | if (!Array.isArray(args)) { args = [args]; } 126 | try { 127 | assertion.apply(null, args); 128 | fail = true; 129 | } catch (e) {/* Success */} 130 | 131 | fail && assert.fail(args.join(' '), assert.AssertionError, 132 | "expected an AssertionError for {actual}", 133 | "assertError", assertError); 134 | } 135 | 136 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/fixtures/isolate/failing.js: -------------------------------------------------------------------------------- 1 | var vows = require('../../../lib/vows'), 2 | assert = require('assert'); 3 | 4 | var obvious; 5 | vows.describe('failing').addBatch({ 6 | 'Obvious test': obvious = { 7 | topic: function () { 8 | this.callback(null, false); 9 | }, 10 | 'should work': function (result) { 11 | assert.ok(result); 12 | } 13 | // but it won't 14 | }, 15 | 'Obvious test #2': obvious, 16 | 'Obvious test #3': obvious, 17 | 'Obvious test #4': obvious 18 | }).export(module); 19 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/fixtures/isolate/log.js: -------------------------------------------------------------------------------- 1 | var vows = require('../../../lib/vows'), 2 | assert = require('assert'); 3 | 4 | var obvious; 5 | vows.describe('stderr').addBatch({ 6 | 'Obvious test': obvious = { 7 | topic: function () { 8 | this.callback(null, true); 9 | }, 10 | 'should work': function (result) { 11 | console.log('oh no!'); 12 | assert.ok(result); 13 | } 14 | }, 15 | 'Obvious test #2': obvious, 16 | 'Obvious test #3': obvious, 17 | 'Obvious test #4': obvious 18 | }).export(module); 19 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/fixtures/isolate/passing.js: -------------------------------------------------------------------------------- 1 | var vows = require('../../../lib/vows'), 2 | assert = require('assert'); 3 | 4 | var obvious; 5 | vows.describe('passing').addBatch({ 6 | 'Obvious test': obvious = { 7 | topic: function () { 8 | this.callback(null, true); 9 | }, 10 | 'should work': function (result) { 11 | assert.ok(result); 12 | } 13 | }, 14 | 'Obvious test #2': obvious, 15 | 'Obvious test #3': obvious, 16 | 'Obvious test #4': obvious 17 | }).export(module); 18 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/fixtures/isolate/stderr.js: -------------------------------------------------------------------------------- 1 | var vows = require('../../../lib/vows'), 2 | assert = require('assert'); 3 | 4 | var obvious; 5 | vows.describe('stderr').addBatch({ 6 | 'Obvious test': obvious = { 7 | topic: function () { 8 | this.callback(null, true); 9 | }, 10 | 'should work': function (result) { 11 | console.error('oh no!'); 12 | assert.ok(result); 13 | } 14 | }, 15 | 'Obvious test #2': obvious, 16 | 'Obvious test #3': obvious, 17 | 'Obvious test #4': obvious 18 | }).export(module); 19 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/isolate-test.js: -------------------------------------------------------------------------------- 1 | var vows = require('../lib/vows'), 2 | assert = require('assert'), 3 | path = require('path'), 4 | exec = require('child_process').exec; 5 | 6 | function generateTopic(args, file) { 7 | return function () { 8 | var cmd = './bin/vows' + ' -i ' + (args || '') + 9 | ' ./test/fixtures/isolate/' + file, 10 | options = {cwd: path.resolve(__dirname + '/../')}, 11 | callback = this.callback; 12 | 13 | exec(cmd, options, function (err, stdout, stderr) { 14 | callback(null, { 15 | err: err, 16 | stdout: stdout, 17 | stderr: stderr 18 | }); 19 | }); 20 | } 21 | }; 22 | 23 | function assertExecOk(r) { 24 | assert.isNull(r.err); 25 | } 26 | 27 | function assertExecNotOk(r) { 28 | assert.isNotNull(r.err); 29 | } 30 | 31 | function parseResults(stdout) { 32 | return stdout.split(/\n/g).map(function (s) { 33 | if (!s) return; 34 | return JSON.parse(s); 35 | }).filter(function (s) {return s}); 36 | } 37 | 38 | function assertResultTypePresent(results, type) { 39 | assert.ok(results.some(function (result) { 40 | return result[0] == type; 41 | })); 42 | } 43 | 44 | function assertResultsFinish(results, expected) { 45 | var finish = results[results.length - 1]; 46 | assert.equal(finish[0], 'finish'); 47 | 48 | finish = finish[1]; 49 | 50 | Object.keys(expected).forEach(function (key) { 51 | assert.equal(finish[key], expected[key]); 52 | }); 53 | } 54 | 55 | vows.describe('vows/isolate').addBatch({ 56 | 'Running vows with -i flag for test/fixtures/isolate/': { 57 | 'passing.js': { 58 | 'with default reporter': { 59 | topic: generateTopic(null, 'passing.js'), 60 | 'should be ok': assertExecOk 61 | }, 62 | 'with json reporter': { 63 | topic: generateTopic('--json', 'passing.js'), 64 | 'should be ok': assertExecOk, 65 | 'should have correct output': function (r) { 66 | var results = parseResults(r.stdout) 67 | 68 | assertResultTypePresent(results, 'subject'); 69 | assertResultTypePresent(results, 'end'); 70 | 71 | assertResultsFinish(results, { 72 | total: 4, 73 | honored: 4 74 | }); 75 | } 76 | } 77 | }, 78 | 'failing.js': { 79 | 'with json reporter': { 80 | topic: generateTopic('--json', 'failing.js'), 81 | 'should be not ok': assertExecNotOk, 82 | 'should have correct output though': function (r) { 83 | var results = parseResults(r.stdout); 84 | 85 | assertResultsFinish(results, { 86 | total: 4, 87 | broken: 4 88 | }); 89 | } 90 | } 91 | }, 92 | 'stderr.js': { 93 | 'with json reporter': { 94 | topic: generateTopic('--json', 'stderr.js'), 95 | 'should be ok': assertExecOk, 96 | 'should have stderr': function (r) { 97 | assert.equal(r.stderr, 98 | ['oh no!', 'oh no!', 'oh no!', 'oh no!', ''].join('\n')); 99 | }, 100 | 'should have correct output': function (r) { 101 | var results= parseResults(r.stdout); 102 | 103 | assertResultsFinish(results, { 104 | total: 4, 105 | honored: 4 106 | }); 107 | } 108 | } 109 | }, 110 | 'log.js': { 111 | 'with json reporter': { 112 | topic: generateTopic('--json', 'log.js'), 113 | 'should be ok': assertExecOk, 114 | 'should have correct output': function (r) { 115 | var results= parseResults(r.stdout); 116 | 117 | assertResultsFinish(results, { 118 | total: 4, 119 | honored: 4 120 | }); 121 | } 122 | } 123 | }, 124 | 'all tests (*)': { 125 | 'with json reporter': { 126 | topic: generateTopic('--json', '*'), 127 | 'should be not ok': assertExecNotOk, 128 | 'should have correct output': function (r) { 129 | var results= parseResults(r.stdout); 130 | 131 | assertResultsFinish(results, { 132 | total: 16, 133 | broken: 4, 134 | honored: 12 135 | }); 136 | } 137 | } 138 | } 139 | } 140 | }).export(module); 141 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/testInherit.js: -------------------------------------------------------------------------------- 1 | /* 2 | * instanceof is a more complete check then .constructor === 3 | * 4 | * It works when using node's built-in util.inherits function 5 | * and it also honors a class's entire ancestry 6 | * 7 | * Here I am only testing the change to vows in suite.js at line 147 to change 8 | * the check from .constructor === to instanceof. These tests should demonstrate 9 | * that this change should work both cases. For completness I also check 10 | * the case when EventEmitter is an ancestor, not the parent Class. 11 | * 12 | */ 13 | var EventEmitter = process.EventEmitter, 14 | util = require('util'), 15 | vows = require('vows'), 16 | assert = require('assert'); 17 | 18 | vows.describe('EventEmitters as a return value from a topic').addBatch({ 19 | 'returning an EventEmitter' : { 20 | topic : function () { 21 | //Make an event emitter 22 | var tmp = new EventEmitter(); 23 | //set it to emit success in a bit 24 | setTimeout(function () { 25 | //pass a value to make sure this all works 26 | tmp.emit('success', 'I work'); 27 | }, 10); 28 | 29 | return tmp; 30 | }, 31 | 'will catch what I pass to success' : function (ret) { 32 | assert.strictEqual(ret, 'I work'); 33 | } 34 | }, 35 | 'returning a class that uses util.inherit to inherit from EventEmitter' : { 36 | topic : function () { 37 | //Make a class that will util.inherit from EventEmitter 38 | var Class = function () { 39 | EventEmitter.call(this); 40 | }, 41 | tmp; 42 | 43 | //inherit from EventEmitter 44 | util.inherits(Class, EventEmitter); 45 | //Get a new one 46 | tmp = new Class(); 47 | //set it to emit success in a bit 48 | setTimeout(function () { 49 | //pass a value to make sure this all works 50 | tmp.emit('success', 'I work'); 51 | }, 10); 52 | 53 | return tmp; 54 | }, 55 | 'will catch what I pass to success' : function (ret) { 56 | assert.strictEqual(ret, 'I work'); 57 | } 58 | }, 59 | 'returning a class that uses Class.prototype = new EventEmitter()' : { 60 | topic : function () { 61 | //Make a class that will inherit from EventEmitter 62 | var Class = function () {}, tmp; 63 | //inherit 64 | Class.prototype = new EventEmitter(); 65 | //Get a new one 66 | tmp = new Class(); 67 | //set it to emit success in a bit 68 | setTimeout(function () { 69 | //pass a value to make sure this all works 70 | tmp.emit('success', 'I work'); 71 | }, 10); 72 | 73 | return tmp; 74 | }, 75 | 'will catch what I pass to success' : function (ret) { 76 | assert.strictEqual(ret, 'I work'); 77 | } 78 | }, 79 | 'returning a class that uses util.inherit to inherit from a class that inherits from EventEmitter ' : { 80 | topic : function () { 81 | //Class1 inherits from EventEmitter 82 | var Class1 = function () { 83 | var self = this; 84 | EventEmitter.call(self); 85 | }, 86 | //Class2 inherits from Class1 87 | Class2 = function () { 88 | Class1.call(this); 89 | }, tmp; 90 | //Inherit 91 | util.inherits(Class1, EventEmitter); 92 | util.inherits(Class2, Class1); 93 | //Get a new one 94 | tmp = new Class2(); 95 | //set it to emit success in a bit 96 | setTimeout(function () { 97 | //pass a value to make sure this all works 98 | tmp.emit('success', 'I work'); 99 | },10); 100 | 101 | return tmp; 102 | }, 103 | 'will catch what I pass to success' : function (ret) { 104 | assert.strictEqual(ret, 'I work'); 105 | } 106 | }, 107 | 'returning a class that uses Class2.prototype = new Class1() and Class1.prototype = new EventEmitter()' : { 108 | topic : function () { 109 | //Class1 will inherit from EventEmitter 110 | var Class1 = function () {}, 111 | //Class2 will inherit from Class1 112 | Class2 = function () {}, tmp; 113 | //Inherit 114 | Class1.prototype = new EventEmitter(); 115 | Class2.prototype = new Class1(); 116 | //Get a new one 117 | tmp = new Class2(); 118 | //seit it to emit success in a bit 119 | setTimeout(function () { 120 | //pass a value to make sure this all works 121 | tmp.emit('success', 'I work'); 122 | },10); 123 | 124 | return tmp; 125 | }, 126 | 'will catch what I pass to success' : function (ret) { 127 | assert.strictEqual(ret, 'I work'); 128 | } 129 | } 130 | }).export(module); 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /tests/node_modules/vows/test/vows-error-test.js: -------------------------------------------------------------------------------- 1 | var path = require('path'), 2 | events = require('events'), 3 | assert = require('assert'), 4 | fs = require('fs'), 5 | vows = require('../lib/vows'); 6 | 7 | function doSomethingAsync(callback) { 8 | var err = null; 9 | var testValue = 'a'; 10 | 11 | process.nextTick(function() { 12 | callback(err, testValue); 13 | }); 14 | } 15 | 16 | function doSomethingAsyncWithError(callback) { 17 | var err = true; 18 | var testValue = 'a'; 19 | 20 | process.nextTick(function() { 21 | callback(err, testValue); 22 | }); 23 | } 24 | 25 | 26 | vows.describe('vows/error').addBatch({ 27 | 'Generate success response to async function': { 28 | topic: function() { 29 | doSomethingAsync(this.callback) 30 | }, 31 | 'Validate success': function(err, testValue) { 32 | assert.ok(!err); 33 | }, 34 | 'Validate testValue': function(err, testValue) { 35 | assert.equal(testValue, 'a'); 36 | } 37 | }, 38 | 39 | 'Generate error response to async function': { 40 | topic: function() { 41 | doSomethingAsyncWithError(this.callback) 42 | }, 43 | 'Validate error': function(err, testValue) { 44 | assert.ok(err); 45 | }, 46 | 'Validate testValue': function(err, testValue) { 47 | // This assertion fails. It shouldn't. 48 | assert.equal(testValue, 'a'); 49 | } 50 | } 51 | }).export(module) -------------------------------------------------------------------------------- /tests/node_modules/vows/test/vows-test.js: -------------------------------------------------------------------------------- 1 | var path = require('path'), 2 | events = require('events'), 3 | assert = require('assert'), 4 | fs = require('fs'), 5 | vows = require('../lib/vows'); 6 | 7 | var api = vows.prepare({ 8 | get: function (id, callback) { 9 | process.nextTick(function () { callback(null, id) }); 10 | }, 11 | version: function () { return '1.0' } 12 | }, ['get']); 13 | 14 | var promiser = function (val) { 15 | return function () { 16 | var promise = new(events.EventEmitter); 17 | process.nextTick(function () { promise.emit('success', val) }); 18 | return promise; 19 | } 20 | }; 21 | 22 | vows.describe("Vows").addBatch({ 23 | "A context": { 24 | topic: promiser("hello world"), 25 | 26 | "with a nested context": { 27 | topic: function (parent) { 28 | this.state = 42; 29 | return promiser(parent)(); 30 | }, 31 | "has access to the environment": function () { 32 | assert.equal(this.state, 42); 33 | }, 34 | "and a sub nested context": { 35 | topic: function () { 36 | return this.state; 37 | }, 38 | "has access to the parent environment": function (r) { 39 | assert.equal(r, 42); 40 | assert.equal(this.state, 42); 41 | }, 42 | "has access to the parent context object": function (r) { 43 | assert.ok(Array.isArray(this.context.topics)); 44 | assert.include(this.context.topics, "hello world"); 45 | } 46 | } 47 | } 48 | }, 49 | "A nested context": { 50 | topic: promiser(1), 51 | 52 | ".": { 53 | topic: function (a) { return promiser(2)() }, 54 | 55 | ".": { 56 | topic: function (b, a) { return promiser(3)() }, 57 | 58 | ".": { 59 | topic: function (c, b, a) { return promiser([4, c, b, a])() }, 60 | 61 | "should have access to the parent topics": function (topics) { 62 | assert.equal(topics.join(), [4, 3, 2, 1].join()); 63 | } 64 | }, 65 | 66 | "from": { 67 | topic: function (c, b, a) { return promiser([4, c, b, a])() }, 68 | 69 | "the parent topics": function(topics) { 70 | assert.equal(topics.join(), [4, 3, 2, 1].join()); 71 | } 72 | } 73 | } 74 | } 75 | }, 76 | "Nested contexts with callback-style async": { 77 | topic: function () { 78 | fs.stat(__dirname + '/vows-test.js', this.callback); 79 | }, 80 | 'after a successful `fs.stat`': { 81 | topic: function (stat) { 82 | fs.open(__dirname + '/vows-test.js', "r", stat.mode, this.callback); 83 | }, 84 | 'after a successful `fs.open`': { 85 | topic: function (fd, stat) { 86 | fs.read(fd, stat.size, 0, "utf8", this.callback); 87 | }, 88 | 'after a successful `fs.read`': function (data) { 89 | assert.match (data, /after a successful `fs.read`/); 90 | } 91 | } 92 | } 93 | }, 94 | "A nested context with no topics": { 95 | topic: 45, 96 | ".": { 97 | ".": { 98 | "should pass the value down": function (topic) { 99 | assert.equal(topic, 45); 100 | } 101 | } 102 | } 103 | }, 104 | "A Nested context with topic gaps": { 105 | topic: 45, 106 | ".": { 107 | ".": { 108 | topic: 101, 109 | ".": { 110 | ".": { 111 | topic: function (prev, prev2) { 112 | return this.context.topics.slice(0); 113 | }, 114 | "should pass the topics down": function (topics) { 115 | assert.length(topics, 2); 116 | assert.equal(topics[0], 101); 117 | assert.equal(topics[1], 45); 118 | } 119 | } 120 | } 121 | } 122 | } 123 | }, 124 | "A non-promise return value": { 125 | topic: function () { return 1 }, 126 | "should be converted to a promise": function (val) { 127 | assert.equal(val, 1); 128 | } 129 | }, 130 | "A 'prepared' interface": { 131 | "with a wrapped function": { 132 | topic: function () { return api.get(42) }, 133 | "should work as expected": function (val) { 134 | assert.equal(val, 42); 135 | } 136 | }, 137 | "with a non-wrapped function": { 138 | topic: function () { return api.version() }, 139 | "should work as expected": function (val) { 140 | assert.equal(val, '1.0'); 141 | } 142 | } 143 | }, 144 | "A non-function topic": { 145 | topic: 45, 146 | 147 | "should work as expected": function (topic) { 148 | assert.equal(topic, 45); 149 | } 150 | }, 151 | "A non-function topic with a falsy value": { 152 | topic: 0, 153 | 154 | "should work as expected": function (topic) { 155 | assert.equal(topic, 0); 156 | } 157 | }, 158 | "A topic returning a function": { 159 | topic: function () { 160 | return function () { return 42 }; 161 | }, 162 | 163 | "should work as expected": function (topic) { 164 | assert.isFunction(topic); 165 | assert.equal(topic(), 42); 166 | }, 167 | "in a sub-context": { 168 | "should work as expected": function (topic) { 169 | assert.isFunction(topic); 170 | assert.equal(topic(), 42); 171 | }, 172 | } 173 | }, 174 | "A topic emitting an error": { 175 | topic: function () { 176 | var promise = new(events.EventEmitter); 177 | process.nextTick(function () { 178 | promise.emit("error", 404); 179 | }); 180 | return promise; 181 | }, 182 | "shouldn't raise an exception if the test expects it": function (e, res) { 183 | assert.equal(e, 404); 184 | assert.ok(! res); 185 | } 186 | }, 187 | "A topic not emitting an error": { 188 | topic: function () { 189 | var promise = new(events.EventEmitter); 190 | process.nextTick(function () { 191 | promise.emit("success", true); 192 | }); 193 | return promise; 194 | }, 195 | "should pass `null` as first argument, if the test is expecting an error": function (e, res) { 196 | assert.strictEqual(e, null); 197 | assert.equal(res, true); 198 | }, 199 | "should pass the result as first argument if the test isn't expecting an error": function (res) { 200 | assert.equal(res, true); 201 | } 202 | }, 203 | "A topic with callback-style async": { 204 | "when successful": { 205 | topic: function () { 206 | var that = this; 207 | process.nextTick(function () { 208 | that.callback(null, "OK"); 209 | }); 210 | }, 211 | "should work like an event-emitter": function (res) { 212 | assert.equal(res, "OK"); 213 | }, 214 | "should assign `null` to the error argument": function (e, res) { 215 | assert.strictEqual(e, null); 216 | assert.equal(res, "OK"); 217 | } 218 | }, 219 | "when unsuccessful": { 220 | topic: function () { 221 | function async(callback) { 222 | process.nextTick(function () { 223 | callback("ERROR"); 224 | }); 225 | } 226 | async(this.callback); 227 | }, 228 | "should have a non-null error value": function (e, res) { 229 | assert.equal(e, "ERROR"); 230 | }, 231 | "should work like an event-emitter": function (e, res) { 232 | assert.equal(res, undefined); 233 | } 234 | }, 235 | "using this.callback synchronously": { 236 | topic: function () { 237 | this.callback(null, 'hello'); 238 | }, 239 | "should work the same as returning a value": function (res) { 240 | assert.equal(res, 'hello'); 241 | } 242 | }, 243 | "using this.callback with a user context": { 244 | topic: function () { 245 | this.callback.call({ boo: true }, null, 'hello'); 246 | }, 247 | "should give access to the user context": function (res) { 248 | assert.isTrue(this.boo); 249 | } 250 | }, 251 | "passing this.callback to a function": { 252 | topic: function () { 253 | this.boo = true; 254 | var async = function (callback) { 255 | callback(null); 256 | }; 257 | async(this.callback); 258 | }, 259 | "should give access to the topic context": function () { 260 | assert.isTrue(this.boo); 261 | } 262 | }, 263 | "with multiple arguments": { 264 | topic: function () { 265 | this.callback(null, 1, 2, 3); 266 | }, 267 | "should pass them to the vow": function (e, a, b, c) { 268 | assert.strictEqual(e, null); 269 | assert.strictEqual(a, 1); 270 | assert.strictEqual(b, 2); 271 | assert.strictEqual(c, 3); 272 | }, 273 | "and a sub-topic": { 274 | topic: function (a, b, c) { 275 | return [a, b, c]; 276 | }, 277 | "should receive them too": function (val) { 278 | assert.deepEqual(val, [1, 2, 3]); 279 | } 280 | } 281 | } 282 | } 283 | }).addBatch({ 284 | "A Sibling context": { 285 | "'A', with `this.foo = true`": { 286 | topic: function () { 287 | this.foo = true; 288 | return this; 289 | }, 290 | "should have `this.foo` set to true": function (res) { 291 | assert.equal(res.foo, true); 292 | } 293 | }, 294 | "'B', with nothing set": { 295 | topic: function () { 296 | return this; 297 | }, 298 | "shouldn't have access to `this.foo`": function (e, res) { 299 | assert.isUndefined(res.foo); 300 | } 301 | } 302 | } 303 | }).addBatch({ 304 | "A 2nd batch": { 305 | topic: function () { 306 | var p = new(events.EventEmitter); 307 | setTimeout(function () { 308 | p.emit("success"); 309 | }, 100); 310 | return p; 311 | }, 312 | "should run after the first": function () {} 313 | } 314 | }).addBatch({ 315 | "A 3rd batch": { 316 | topic: true, "should run last": function () {} 317 | } 318 | }).addBatch({}).export(module); 319 | 320 | vows.describe("Vows with a single batch", { 321 | "This is a batch that's added as the optional parameter to describe()": { 322 | topic: true, 323 | "And a vow": function () {} 324 | } 325 | }).export(module); 326 | 327 | vows.describe("Vows with multiple batches added as optional parameters", { 328 | "First batch": { 329 | topic: true, 330 | "should be run first": function () {} 331 | } 332 | }, { 333 | "Second batch": { 334 | topic: true, 335 | "should be run second": function () {} 336 | } 337 | }).export(module); 338 | 339 | vows.describe("Vows with teardowns").addBatch({ 340 | "A context": { 341 | topic: function () { 342 | return { flag: true }; 343 | }, 344 | "And a vow": function (topic) { 345 | assert.isTrue(topic.flag); 346 | }, 347 | "And another vow": function (topic) { 348 | assert.isTrue(topic.flag); 349 | }, 350 | "And a final vow": function (topic) { 351 | assert.isTrue(topic.flag); 352 | }, 353 | 'subcontext': { 354 | 'nested': function (_, topic) { 355 | assert.isTrue(topic.flag); 356 | } 357 | }, 358 | teardown: function (topic) { 359 | topic.flag = false; 360 | }, 361 | "with a subcontext" : { 362 | topic: function (topic) { 363 | var that = this; 364 | process.nextTick(function () { 365 | that.callback(null, topic); 366 | }); 367 | }, 368 | "Waits for the subcontext before teardown" : function(topic) { 369 | assert.isTrue(topic.flag); 370 | } 371 | } 372 | } 373 | }).export(module); 374 | 375 | -------------------------------------------------------------------------------- /tests/run-tests.js: -------------------------------------------------------------------------------- 1 | // Test engine. 2 | var vows = require('vows'), 3 | assert = require('assert'), 4 | watch = require('nodewatch'), 5 | fs = require('fs'); 6 | 7 | // Test package. 8 | var NodeInterval = require('nodeinterval'); 9 | 10 | // NodeInterval init commands. 11 | var watchFolder = 'src/templates/', 12 | inputFile = 'src/index.html', 13 | replacementString = '@templates@', 14 | outputFile = 'assets/index.html'; 15 | 16 | // Test variables: 17 | var randomString = 'Hi there id="bob" ' +(+ new Date), 18 | testFile1 = watchFolder + 'template01.tmpl', 19 | testFile2 = watchFolder + 'dir_level_2/dir_level_3/template09.tmpl'; 20 | 21 | 22 | function fileExists(path){ 23 | try{ 24 | fs.lstatSync(outputFile); 25 | }catch(e){ 26 | return false; 27 | } 28 | return true; 29 | } 30 | 31 | function init(){ 32 | // Delete outputFile to start clean tests. 33 | if (fileExists(outputFile)){ 34 | fs.unlinkSync(outputFile); 35 | } 36 | 37 | // Create a NI instance. 38 | ni = new NodeInterval.Watcher({ 39 | watchFolder: watchFolder, 40 | inputFile: inputFile, 41 | outputFile: outputFile 42 | }).startWatch(); 43 | 44 | vows.describe('All tests').addBatch({ 45 | 'Verifying new ni object': { 46 | topic: function(){ 47 | return ni; 48 | }, 49 | 'Assert that we are listening to all files, in all sub dirs, and ignoring .dot files..': function(topic){ 50 | assert.length(topic.watchFiles, 10); 51 | }, 52 | 'Assert that passed options are stored in ni.options': function(topic){ 53 | assert.isObject(topic.options); 54 | }, 55 | 'Assert that default options extend passed in options': function(topic){ 56 | assert.equal(topic.options.replacementString, '@templates@'); 57 | } 58 | }, 59 | 60 | 'Output file has content': { 61 | topic: function(){ 62 | if (fileExists(outputFile)){ 63 | return fs.readFileSync(outputFile, 'utf8'); 64 | } 65 | return false; 66 | }, 67 | 'Assert output file is updated on start and created if doesn\'t exist.': function(topic){ 68 | assert.isTrue(topic.length > 0); 69 | } 70 | }, 71 | 72 | 'Editing a file': { 73 | topic: function(){ 74 | var that = this; 75 | console.log('making file edit...'); 76 | fs.writeFileSync(watchFolder + 'template01.tmpl', randomString, 'utf8'); 77 | // Wait a few secs and check that ni updated the file. 78 | setTimeout(function(){ 79 | that.callback(); 80 | } ,8000); 81 | }, 82 | 'Assert concatinated output file has new changes.': function(topic){ 83 | console.log('checking change...'); 84 | var topic = fs.readFileSync(outputFile, 'utf8') 85 | assert.isTrue(!!topic.match(randomString)); 86 | 87 | // Revert change 88 | console.log('Tests done. Reverting changes...'); 89 | fs.writeFileSync(watchFolder + 'template01.tmpl', '', 'utf8'); 90 | ni.stopWatch(); 91 | } 92 | } 93 | }).run(); 94 | } 95 | 96 | console.log('Starting test...'); 97 | init(); -------------------------------------------------------------------------------- /tests/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | NodInterval Test page 5 | 6 | 7 |

Test Test page

8 |

My templates below

9 | @templates@ 10 |

My templates above

11 | 12 | 13 | -------------------------------------------------------------------------------- /tests/src/templates/.bob: -------------------------------------------------------------------------------- 1 | This file should be ignored! -------------------------------------------------------------------------------- /tests/src/templates/dir_level_2/.doggies/file1: -------------------------------------------------------------------------------- 1 | This should also be ignored! -------------------------------------------------------------------------------- /tests/src/templates/dir_level_2/dir_level_3/template09.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/src/templates/dir_level_2/template07.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/src/templates/dir_level_2/template08.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/src/templates/template01.tmpl: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/src/templates/template02.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/src/templates/template03.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/src/templates/template04.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/src/templates/template05.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /tests/src/templates/template06.tmpl: -------------------------------------------------------------------------------- 1 | 4 | 5 | --------------------------------------------------------------------------------