pax_global_header00006660000000000000000000000064135514315030014512gustar00rootroot0000000000000052 comment=cbd4b9f670bcd0085f311005e5da436354607a68 vows-0.8.3/000077500000000000000000000000001355143150300125205ustar00rootroot00000000000000vows-0.8.3/.gitignore000066400000000000000000000001141355143150300145040ustar00rootroot00000000000000node_modules .idea .nul .hgignore .hgsubstate .hg .hgsub test/npm-debug.log vows-0.8.3/.travis.yml000066400000000000000000000001441355143150300146300ustar00rootroot00000000000000language: node_js before_install: - "npm i -g npm@1.4.28" node_js: - "0.8" - "0.10" - "0.11"vows-0.8.3/CHANGELOG.md000066400000000000000000001030601355143150300143310ustar00rootroot00000000000000v0.8.3 / Tue, 15 Oct 2019 ======================== * Update `diff` dependency to fix regexp denial-of-service vulnerability (`Trott`) v0.8.0 / Tue, 4 Nov 2014 ======================== * [775db8f] [dist] Version bump. 0.8.0 (`indexzero`) * [623b375] [dist] Update dependencies to latest. (`indexzero`) * [bf8e6aa] [dist] Update contributors on README and package.json. (`indexzero`) * [f113849] [doc] Added TravisCI build status. (`indexzero`) * [f9f37df] sh instead of js (`Ionică Bizău`) * [8db36b9] Code highlight (`Ionică Bizău`) * [43e917c] Regenerated package.json (`Ionică Bizău`) * [a7764ad] Add tests on context and sub context, synchronous and asynchronous (`Romain`) * [03a04db] [fix] Support backwards compatibility for Object reporters in #190. (`indexzero`) * [f120d45] Ability to programmatically specify reporter (`Ilya Shaisultanov`) * [a9a02d0] Merge pull request #297 from snoble/master (`Charlie Robbins`) * [7939c94] [test] fix .travis.yml file needs quote, remove 0.9, add 0.11 (`Swaagie`) * [dfdc074] Merge pull request #304 from eventualbuddha/patch-1 (`Martijn Swaagman`) * [a5acef5] Typo fix. (`Brian Donovan`) * [aa8cd5e] Merge pull request #263 from adamstallard/master (`Jerry Sievert`) * [1e8fa11] Make coffeescript register itself if it has a register function. (`Steven H. Noble`) * [253ca34] Merge pull request #283 from gabeio/patch-1 (`Maciej Małecki`) * [42f23c3] refactor: remove line that was made redundant after the last merge from upstream (`adamstallard`) * [ef5e76b] ignore hg files (`adamstallard`) * [e6bcc64] update vows package (`adamstallard`) * [45e9fdf] Moved tag master to changeset 45104b15b3a8 (from changeset 45e0b0d31984) (`adamstallard`) * [ecac185] Moved tag default/master to changeset 45104b15b3a8 (from changeset 5797560897ea) (`adamstallard`) * [ce6c2c6] update vows package (`adamstallard`) * [383acd6] Merge (`adamstallard`) * [c8c2ff0] Backed out changeset: be18031783bf (`adamstallard`) * [e86bddd] Backed out changeset: 19f9533f9bae (`adamstallard`) * [f031545] Added tag default for changeset 162f542dd244 (`adamstallard`) * [eaaf51a] Moved tag master to changeset 45e0b0d31984 (from changeset be18031783bf) (`adamstallard`) * [7595734] Moved tag default/master to changeset 45e0b0d31984 (from changeset 5797560897ea) (`adamstallard`) * [d6e2872] Added tag master for changeset be18031783bf (`adamstallard`) * [e1d3d16] remove accidental commit (`adamstallard`) * [ae4a214] Merge from Upstream (`adamstallard`) * [2d77a7a] update vows package (`adamstallard`) * [1ed1b8c] Added repository field to package.json (`Gabe De`) * [d1d02e0] [test] Test on recent versions of node (`Maciej Małecki`) * [bc4c239] [fix] Do not use `util.{print,puts}` (`Maciej Małecki`) * [a23a1c9] continue to run subtopics even if a parent topic has an error in it (fixes #231) (`adamstallard`) * [fb0ec87] Merge pull request #267 from coltrane/glob (`Charlie Robbins`) * [eb66421] Set the return value to 'undefined' on an unexpected error (since we always use a callback); improve comments (`adamstallard`) * [8e4c8b8] use node-glob instead of wildcard for better pattern support (`J. Lee Coltrane`) * [d6604c3] Don't print out extra blank lines in the spec reporter when end of suite fires. (`adamstallard`) * [e10dc94] Make the xunit reporter follow the established pattern of using the vows console module and allowing for overriding the stream. (`adamstallard`) * [98470cb] revert accidental inclusion of print statement (`adamstallard`) * [4acd17e] Check that tests report errors like they should (`adamstallard`) * [50a13b5] Handle errors correctly based on suite.options.error and the number of parameters expected by the vow: When suite.options.error is set to false or a vow expects two or more parameters, get the error as the first argument and don't report it; When suite.options.error is set to true and a vow expects zero or one parameters, report the error and do not run the vow. (`adamstallard`) * [26e5941] fix typo in comment (`adamstallard`) * [a7843f4] [dist doc] Remove unnecessary Makefile and document that tests should be run with `npm test`. Fixes #241 (`indexzero`) * [458eb3e] diff colors were reversed (`Andrew Petersen`) * [154b6cd] Add a not include assertion (`Fred Cox`) * [4a9dc5d] added nopstream to mimic writing to /dev/null on windows (`Dale Stammen`) * [5d087fc] added nullstream.js to mock /dev/null on windows (`Dale Stammen`) * [92868a9] support for windows drives other than c: (`Dale Stammen`) * [f7d09c5] node can't write to nul. reserved filename in windows. changed to .nul. updated .gitignore (`Dale Stammen`) * [4c53be1] fix for issue 248. file starts with a c (`Dale Stammen`) v0.7.0 / Fri, 16 Nov 2012 ========================= * [c683d88] [dist] Bump version to 0.7.0 (`Maciej Małecki`) * [8776492] use nul for windows equivalent of /dev/null. Added nul to .gitignore (`Dale Stammen`) * [48683fb] fixed path handling for wildcards and test module loading with require (`Dale Stammen`) * [5085b39] remove console.log statementsif present from start of results (`Dale Stammen`) * [7f8d511] remove os.EOL for strerr test. Only removed first result if not json (`Dale Stammen`) * [aace8dd] skip over non json results (`Dale Stammen`) * [b5438a1] remove --supress-stdout only on win32 (`Dale Stammen`) * [d419819] remove windows specific reposne in stdout (`Dale Stammen`) * [8ceef77] removed --supress-stdout from spawn. check for C: in file paths (`Dale Stammen`) * [cfe7888] removed console.log (`Dale Stammen`) * [70865cc] added wildcard * support to files (`Dale Stammen`) * [e85197b] use process.execPath and not ./bin/vows in for cmd in call to exec(). Fix for windows (`Dale Stammen`) * [cde6d9b] added ignore .idea (`Dale Stammen`) * [304643f] use process.execPath not ./bin/vows. This is consistent with how exec works in vows and works on windows. Use os.EOL to check oh no string so it works on platforms that use \r\n (`Dale Stammen`) * [d728652] added cross-platform fixes to support windows (`Dale Stammen`) * [f412e4a] [fix] Fix crashes on node v0.9.3 (`Maciej Małecki`) * [808a773] Merge pull request #202 from Filirom1/master (`Alexis Sellier`) * [d073b06] Do not catch ReferenceError (`Romain`) v0.6.4 / Thu, 23 Aug 2012 ========================= * [e797515] [dist] Bump version to 0.6.4 (`Maciej Małecki`) * [8dea08d] [dist] Fix `package.json` (`Maciej Małecki`) * [fb123cc] fix console require (`Jerry Sievert`) * [e5a000b] Merge remote-tracking branch 'execjosh/tap-reporter' into v0.6.4 (`Jerry Sievert`) * [bcb82f1] merge in mocha style html coverage reports (`Jerry Sievert`) * [0779766] merged in diff support (`Jerry Sievert`) * [bfdd005] Merge pull request #220 from trevnorris/master (`Maciej Małecki`) * [5564dd5] Merge remote-tracking branch 'cloudhead/master' (`Trevor Norris`) * [bfb4bf5] Use plus/minus unicode in error msg (`Trevor Norris`) * [1e6eb0f] Epsilon check fix (`Trevor Norris`) * [3c0dc3b] Add IEEE float epsilon check (`Trevor Norris`) * [bfb8998] Add Mocha credit. (`Reid Burke`) * [cbd6123] Add Mocha-style multi-line string diffs. (`Reid Burke`) * [aa51288] Add to the HTML coverage report. (`Reid Burke`) * [f7afb1b] Better style for directory names in coverage menu. (`Reid Burke`) * [526f036] Use Mocha's style for HTML coverage report. (`Reid Burke`) * [93dbc61] Summarize coverage data for HTML report. (`Reid Burke`) * [abb0d5a] Implement TAP reporter (`execjosh`) v0.6.3 / Wed, 27 Jun 2012 ========================= * [f0d2ecc] [dist] Bump version to 0.6.3 (`Maciej Małecki`) * [674830d] [bin] Make isolate mode work in node >= 0.7 (`Maciej Małecki`) * [075b0eb] [minor] `Math.floor` instead of `Math.ceil` (`Maciej Małecki`) * [796ac5d] [bin] Add `--shuffle` option (`Maciej Małecki`) * [4347cdd] [fix] Fix unsafe object iterations (`Maciej Małecki`) * [a785630] Allow camelCase test filename (`Romain`) * [03f60dd] Add `assert.lengthOf` on objects (`Romain`) * [38817c1] Exit code should be 1 if asynchronous errors occurs (`Olivier Bazoud`) * [3e60864] [refactor] Don't touch `require.extensions` (`Maciej Małecki`) v0.6.2 / Fri, 24 Feb 2012 ========================= * [6aa9673] [dist] Version 0.6.2 (`Maciej Małecki`) * [6b803ab] [bin] Use `process.execPath` instead of `process.argv[0]` (`Maciej Małecki`) * [1d06e90] [api] Write XML coverage report to `coverage.xml` (`Maciej Małecki`) * [e0fb4dc] Merge pull request #161 from cliffano/master (`Maciej Małecki`) * [9dd9b9e] [bin] Skip dotfiles before `fs.stat()`ing them (`Nathan Hunzaker`) * [4342fe9] [ui] Add support for `\n` in context names (`jmreidy`) * [bbc8e55] [api] Make `assert.include` fail when given unknown type (`Maciej Małecki`) * [fe37eec] [test] Add `.travis.yml` for testing on Travis CI (`Maciej Małecki`) * [b2ca904] Add coverage report in xml format. (`Cliffano Subagio`) v0.6.1 / Mon, 26 Dec 2011 ========================= * [c84e55c] [dist] Version 0.6.1 (`Maciej Małecki`) * [239df60] [test] Test if exception thrown in the topic gets passed down (`Bernardo Heynemann`) * [6f84e3b] [api fix] When topic `throw`s, treat exception as a return value (`Maciej Małecki`) * [a480a5f] Merge pull request #160 from seebees/nested_context_with_callback (`Charlie Robbins`) * [30a9d94] Merge pull request #168 from johnnywengluu/master (`Maciej Małecki`) * [722d4d8] Documentation bug fix: Rename *length* to *lengthOf* in a test. (`Johnny Weng Luu`) * [08b0650] [reporters/json] fix async error reporting (`Fedor Indutny`) * [fbf7f69] [fix] Fix leaking `self` (`Maciej Małecki`) * [9853e64] Async topic is passed to vows with topic-less subcontext (`seebees`) v0.6.0 / Fri, 25 Nov 2011 ========================= * [82d5541] [dist] Version bump. 0.6.0 (`indexzero`) * [3943fec] event order for 'on' (`seebees`) * [d9fe353] [minor] Update style from previous commit (`indexzero`) * [e92c1e4] Added --no-color option to suppress terminal colors (`Alexander Shtuchkin`) * [8788a52] [v0.6 fix] Properly inspect errors (`Maciej Małecki`) * [6760a2e] [merge] Manual merge of #135 since the fork no longer exists. Fixes #135 (`indexzero`) * [ddd9588] When an uncaught exception is caught in watch mode, print it in the console and continue watch. (`Julien Guimont`) * [ddf3cf4] [merge] add support for coffee files when printing out errors. Fixes #140 (`indexzero`) * [1448de2] When called outside the vows context where `this.stack` && `source` are undefined it will now no longer crash and burn (`Raynos`) * [c92aabc] Expose console so we can re-use it in custom reporters. (`Raynos`) * [c67786f] [merge] Manual merge of #95 since the fork no longer exists. Fixes #95 (`indexzero`) * [81482b1] Fixed indentation and some missing semicolons requested in #82 (`Ryan Olds`) * [f39a4e2] Add support for asynchronous teardowns. (`Daniel Brockman`) * [a44ee69] Edited README.md via GitHub (`Jerry Sievert`) * [a781c45] events other then success (`seebees`) * [d081d49] Buffer not needed and leaking a global. (`Nicolas Morel`) * [482d09c] adding a filter to the watch logic, so that only test files are run (`jmreidy`) * [f77e4bd] fixing regular expression for specFileExt to use an OR (`jmreidy`) * [e7fbdb4] test require should refer to lib/vows, not system vows (`jmreidy`) * [907d308] Adding vows support for underscores, in addition to dashes, in spec or test names (`jmreidy`) v0.5.13 / Wed, 2 Nov 2011 ========================= * [a5912ba] [dist] Version bump. 0.5.13 (`indexzero`) * [0894d94] Merge pull request #146 from mmalecki/fix-output (`Charlie Robbins`) * [7290532] [fix] Fix failed assertions output (`Maciej Małecki`) v0.5.12 / Sat, 22 Oct 2011 ========================== * [ef4a803] [dist] Version bump. 0.5.12 (`indexzero`) * [58f44f0] [dist] Add test script for `npm test` (`indexzero`) * [bd14209] [fix minor] Remove unnecessary argument in `exec` callback (`Maciej Małecki`) * [00509bd] [test] Test `--supress-stdout` flag (`Maciej Małecki`) * [8ce12a5] [test] Add fixtures for supress-stdout test (`Maciej Małecki`) * [50052f5] [test v0.6] Make `assert-test.js` v0.6-compatible (`Maciej Małecki`) * [fde1216] [refactor minor] Use `JSON.parse` when getting version (`Maciej Małecki`) * [cc76162] [refactor minor] Remove unused variables in `vows.addVow.runTest` (`Maciej Małecki`) * [006476f] [v0.6] Handle stdout suppressing correctly (`Maciej Małecki`) * [87462e6] [api] Rename `assert.length` to `assert.lengthOf` (`Maciej Małecki`) * [fd44e08] [fix v0.6] No `error.stack` for nextTick errors (`Maciej Małecki`) * [eac4362] [refactor v0.6] Remove/replace `sys` usages (`Maciej Małecki`) * [485698d] (doc) add 'authors' section to README (`Alexis Sellier`) v0.5.11 / Sat, 20 Aug 2011 ========================== * [3843409] (dist) Version bump. 0.5.11 (`indexzero`) * [954386c] (test) Added tests for error pass thru (`indexzero`) * [0108f1f] Allow arguments to flow through to callbacks in error conditions. (`Ben Taber`) * [3b9acac] add unified coverage maps, and fix issue when using coverage without instrumentation (`Jerry Sievert`) * [3a2f697] add unified coverage maps, and fix issue when using coverage without instrumentation (`Jerry Sievert`) * [5b2ae84] (fix) Check topic.constructor to reverse regression introduced by instanceof check (`indexzero`) * [c7f9e3c] added assert.isNotEmpty and assert.isDefined (`nekaab`) v0.5.10 / Fri, 12 Aug 2011 ========================== * [484b5f4] [fix] Update references to `stylize` after refactor (`indexzero`) * [f18b45c] (minor) Move .vowsText and .contextText out of reporters/spec into vows/console (`indexzero`) * [a813268] (fix) Remove unecessary reference to spec in reporters/dot-matrix.js. Fixes #117 (`indexzero`) * [0d8c406] [fix] Dont always append a tailing `\n` to all test output (`indexzero`) * [67b7ce7] (minor) Update package.json (`indexzero`) * [33aeb64] (dist) Version bump. 0.5.10 (`indexzero`) * [889b748] [bin test] Added additional teardown test. Update bin/vows to support absolute path. #83 (`indexzero`) * [c8ee815] [style] respect cloudhead's style (`Fedor Indutny`) * [dcf5021] [isolate] fixed test fixtures naming (`Fedor Indutny`) * [9be20ef] [isolate] allow reporters to output raw data (`Fedor Indutny`) * [5c40a46] [isolate] tests (`Fedor Indutny`) * [26fc3f7] [isolate] supress-stdout option and true stream usage in reporters (`Fedor Indutny`) * [d53c429] [isolate] exec => spawn, stream suite output, fix command line arguments to child process (`Fedor Indutny`) * [c2a1d60] [isolate] collect results (`Fedor Indutny`) * [b275024] [isolate] implement runner (`Fedor Indutny`) * [3543c0e] [isolate] added command line option (`Fedor Indutny`) * [76565ef] Merge pull request #102 from seebees/master (`Alexis Sellier`) * [661b34f] Merge pull request #107 from ciaranj/provide_collapsable_coverage_boxes (`Alexis Sellier`) * [63a15e7] Provide some very rudimentary CSS & JS to collapse the 'covered' source by default and use colours to draw your eye to the areas that need tackling (`ciaranj`) * [96a17a2] use instanceof to check if the return value from a topic is an EventEmitter (`seebees`) * [3e98285] Test for change (`seebees`) v0.5.9 / Fri, 22 Jul 2011 ========================= * [e80e96d] (dist) version bump (`cloudhead`) * [76e9175] add /bin folder to package.json (`cloudhead`) * [d597378] fix assert.inDelta global vars (`cloudhead`) * [9418795] remove `require.paths` dependency (`cloudhead`) * [13a52f4] Merge pull request #101 from JerrySievert/master (`Alexis Sellier`) * [3d400b8] adds coverage map functionality (`Jerry Sievert`) * [bc868fa] (new) added assert.inDelta (`mynyml`) * [5b770a4] Merge pull request #93 from joshkehn/master (`Alexis Sellier`) * [db608e2] NaN !== Boolean (`Joshua Kehn`) * [4144271] Implemented isBoolean and tests to match (`Joshua Kehn`) * [3802967] Merged pull request #78 from mynyml/master. (`Alexis Sellier`) * [342dbae] added assert.deepInclude (`mynyml`) * [27f683a] added assert.deepInclude (`mynyml`) v0.5.8 / Sat, 12 Mar 2011 ========================= * [7c9b21d] (dist) version bump (`Alexis Sellier`) * [72b9299] (style) ws (`Alexis Sellier`) * [381c0a3] Fixed CoffeeScript support on Node 0.3+ (`Janne Hietamäki`) * [697ada4] (minor test) cleanup (`Alexis Sellier`) * [3291d77] fix vow context when global (`Alexis Sellier`) v0.5.7 / Sun, 20 Feb 2011 ========================= * [f700eed] (dist) version bump (`Alexis Sellier`) * [7b20446] support for this.callback.call({}, ...) (`Alexis Sellier`) * [7874f54] improve async error report (`Alexis Sellier`) * [332b522] include test filename in some error reports (`Alexis Sellier`) * [1ddf5b1] (api) support for /.test.js$/ filenames (`Alexis Sellier`) * [93da10b] (minor) cleanup (`cloudhead`) * [402e309] Fixed watch mode. (`Matteo Collina`) v0.5.6 / Mon, 31 Jan 2011 ========================= * [0b54a98] (dist) revert to node 0.2.6, version bump to 0.5.6 (`cloudhead`) * [430021f] merge improved teardown support (`cloudhead`) * [f1ff2c1] preserve 0.2.6 compatibility (`cloudhead`) * [d6ba141] added simple xunit support, so vows can be used together with Hudson (`Anders Thøgersen`) * [d88924d] (dist) update package.json to include node version (`cloudhead`) * [a00c89d] Updated teardown to execute after subcontexts complete (`Jeremiah Wuenschel`) v0.5.4 / Sat, 29 Jan 2011 ========================= * [c2633dc] (dist) version bump (`cloudhead`) * [4361e42] use 'on' instead of 'addListener' (`cloudhead`) * [eb4d50d] support '.' in filenames (`cloudhead`) * [3030206] (test) test for multiple arguments in callbacks (`cloudhead`) * [1c18b66] remove listeners warning on topics (`cloudhead`) * [8fb1a56] support for multiple arguments passed to sub-topics (`cloudhead`) * [398443d] (minor) aliased export to exportTo (`cloudhead`) * [3b1545a] (bin) update for node 0.2.5 (`cloudhead`) * [f0f823d] (bin) fix auto-discover mode (`cloudhead`) v0.5.3 / Wed, 29 Dec 2010 ========================= * [3d12553] (dist) version bump (`cloudhead`) * [936e18a] fix some error messages (`cloudhead`) * [64760fe] (bin) fix exit status (`cloudhead`) v0.5.2 / Wed, 13 Oct 2010 ========================= * [349437b] (dist) version bump (`cloudhead`) * [61c01d9] tell user if no tests were run. (`cloudhead`) * [50077aa] Pass suite reference to batches (`Yurii Rashkovskii`) * [213d6cd] Made a change that eliminates the following bug (see http://github.com/cloudhead/vows/issues#issue/16): Sometimes you want to test an object that inherits from EventEmitter. In this case, if you return said testable object as the topic, then the code hangs if the EventEmitter subclass instance that I'm testing doesn't emit "success" or "error." (`bnoguchi`) v0.5.1 / Tue, 24 Aug 2010 ========================= * [679e8a6] (dist) version bump (`cloudhead`) * [c3ad80d] (new) basic teardown support (`cloudhead`) v0.5.0 / Tue, 10 Aug 2010 ========================= * [7cdf94f] (dist) version bump, update package.json (`cloudhead`) * [e8cf93e] (minor) naming/style changes (`cloudhead`) * [db57e70] Add ability to circumvent `addBatch` (`Travis Swicegood`) * [36c5c47] Add ability to run .coffee files (`Travis Swicegood`) * [df1e61b] Merge branch 'master' of github.com:cloudhead/vows (`cloudhead`) * [ccf6ec0] (doc) fix link (`Alexis Sellier`) v0.4.6 / Thu, 1 Jul 2010 ======================== * [d78e098] (dist) version bump (`cloudhead`) * [a6c51c4] better assert.isNaN check (`cloudhead`) * [2b7398e] ability to pass suite options to export method (`cloudhead`) * [4fc9097] (new) --no-error (`cloudhead`) * [f2eb7b2] more refactoring in addVow (`cloudhead`) * [cca54cf] refactor counter updates (`cloudhead`) * [c98bcc4] (doc) fix README (`Alexis Sellier`) * [726b82f] updated README for site (`cloudhead`) v0.4.5 / Mon, 28 Jun 2010 ========================= * [ed576d7] (dist) version bump (`cloudhead`) * [5cdc2ba] (api) watch mode can take arguments, fixed a couple edge cases (`cloudhead`) v0.4.4 / Sun, 27 Jun 2010 ========================= * [9ea324f] (dist) version bump (`cloudhead`) * [e0ffeea] fix --version (`cloudhead`) * [afd3aab] handle edge case in this.callback, where a single boolean is returned (`cloudhead`) * [30e6688] don't exit until stdout is drained (`cloudhead`) * [d1b71d8] (test) add an empty batch to make sure it works (`cloudhead`) * [92aafed] improved error message when callback returns uncaught error (`cloudhead`) * [93aeaa3] result of this.callback is passed down to nested topics (`cloudhead`) * [ae16916] fixed a bug with falsy topics (`cloudhead`) v0.4.3 / Thu, 24 Jun 2010 ========================= * [335a8ee] (dist) version bump (`cloudhead`) * [7875366] return an appropriate exit code from bin/vows, depending on success of the tests. (`cloudhead`) * [4e1da2f] allow this.callback to be used more flexibly (`cloudhead`) v0.4.2 / Wed, 23 Jun 2010 ========================= * [3d83502] (dist) version bump (`cloudhead`) * [b94c047] fixed watch mode in OS X Terminal (`cloudhead`) * [a532f17] rename context.name => context.description, and make context.name be the last level only (`cloudhead`) * [cd4a763] remove throw/doesNotThrow message customization, cause it's fucked (`cloudhead`) * [6298227] (minor) fixed grammar in assertion message (`cloudhead`) v0.4.1 / Thu, 17 Jun 2010 ========================= * [a2f11f0] (dist) version bump (`cloudhead`) * [df248d4] include subject in error message (`cloudhead`) * [cf3f4e2] use suite's reporter for errors (`cloudhead`) * [833a2a0] console.result prints 'dropped' vows (`cloudhead`) * [3d1217a] detect un-fired vows on exit, and report error (`cloudhead`) * [e1d1ea5] track vows and vow statuses in batches (`cloudhead`) * [8917efe] fix indentation in assert.equal error message (`cloudhead`) * [31c46cf] (dist) fix Makefile (`cloudhead`) * [8ac48b9] rename some internal functions for consistency (`cloudhead`) * [0acf40e] update --help command (`cloudhead`) * [3f3cc66] silent reporter (`cloudhead`) * [692cb71] try to handle async errors more intelligently (`cloudhead`) * [7ed9f65] (api) '-m' and '-r' now require a space between pattern (`cloudhead`) * [82f6e5e] (new) added more options to bin (`cloudhead`) * [75ff4ab] (api) addVows => addBatch (`cloudhead`) * [a7f9f30] (test) improve test descriptions (`cloudhead`) * [e53338c] (api) don't add space between context descriptions in some cases (`cloudhead`) * [1593768] (test) remove other-test.js (`cloudhead`) * [f2ff9b5] (test) move assert module tests to its own file (`cloudhead`) * [5f415df] output function name in AssertionError, if {expected} is a function (`cloudhead`) v0.4.0 / Tue, 15 Jun 2010 ========================= * [0b32f54] (dist) version bump to 0.4.0 (`cloudhead`) * [3e0fb87] improve subject appearance in spec.js (`cloudhead`) * [29161c7] make sure we only output on exit, if there's a failure (`cloudhead`) * [98418c7] set batch.status to 'end' when ended (`cloudhead`) * [5a3362f] catch silent async failures on exit (`cloudhead`) * [6546552] don't try to exist when tests complete (`cloudhead`) * [7edb97a] reset pending vows in Suite#reset (`cloudhead`) * [6baca02] nicer output. refactor of formatters (`cloudhead`) v0.3.5 / Sun, 13 Jun 2010 ========================= * [4a1a65a] (dist) version bump (`cloudhead`) * [f10884d] improved assertion error messages. added tests (`cloudhead`) * [72eecd7] (new) added new assertions (`cloudhead`) * [1e90188] set styles to false for inspector (`cloudhead`) * [47c2d1f] (new) support multiple test suites per file (`cloudhead`) * [bb9a5af] abort() function to exit with an error (`cloudhead`) * [90e0bae] (api) watch mode is activated with -w (`cloudhead`) * [1cdfd1c] don't output contexts for pending vows in watch mode (`cloudhead`) * [3416f44] fix spec reporter + pending vow (`cloudhead`) * [4b92fa4] (new api) '-m' matches a string, changes -R to -r (`cloudhead`) v0.3.4 / Wed, 9 Jun 2010 ======================== * [25abf72] (dist) version bump (`cloudhead`) * [8052146] fix/improve the cleanup on exit (`cloudhead`) * [df83078] print a different cue when running tests in watch mode (`cloudhead`) * [c533efa] fix context reporting for dot-matrix (`cloudhead`) * [3e67750] remove deprecated 'brief' option (`cloudhead`) * [11a1edd] (new) tests can be 'pending' (`cloudhead`) * [062450c] handle this.callback called synchronously (`cloudhead`) v0.3.3 / Tue, 8 Jun 2010 ======================== * [311df5f] (dist) version bump (`cloudhead`) * [55a7a92] print contexts in dot-matrix & watch output (`cloudhead`) * [06b5563] (doc) updated README (`cloudhead`) v0.3.2 / Mon, 7 Jun 2010 ======================== * [4079f57] (dist) version bump (`cloudhead`) * [cca5d46] move inspect() to vows/console (`cloudhead`) v0.3.1 / Mon, 7 Jun 2010 ======================== * [fe7ae18] (dist) version bump (`cloudhead`) * [a0dacb7] Set default for `options` in run(). (`cloudhead`) * [e27bdfc] round time output (`cloudhead`) v0.3.0 / Sat, 5 Jun 2010 ======================== * [868cd9f] ability to print messages without a nl (`cloudhead`) * [b851ffe] only the spec reporter prints subjects (`cloudhead`) * [d5b0d34] pattern matching is operational (`cloudhead`) * [09e31cf] better remaining vow detection and handling (`cloudhead`) * [b3985d8] we don't support vows as functions anymore (`cloudhead`) * [a2e15a2] better vow counting (`cloudhead`) * [7beb71d] parse vows at run-time, so we can apply a matcher (`cloudhead`) * [247015b] use options in run() or default to Suite (`cloudhead`) * [ee77415] Suite-level matcher/reporter (`cloudhead`) * [aae87c2] no more global module state (`cloudhead`) * [f825f7f] tidy up the requires in bin/vows (`cloudhead`) * [b9d856e] (dist) lib is lib/vows (`cloudhead`) * [2f9bb00] (dist) added bin to package.json (`cloudhead`) * [575d1a5] updated Makefile to use test runner (`cloudhead`) * [7d93078] (dist) version bump (`cloudhead`) * [c3afbbc] revised vows.js header (`cloudhead`) * [ec867b6] output fixes (`cloudhead`) * [1f2abe5] (new) watch reporter (`cloudhead`) * [b9882a5] add print() function to reporters (`cloudhead`) * [151b76c] fuck the buffer (`cloudhead`) * [1ab43bd] report subject on run() (`cloudhead`) * [88b5ade] complete rewrite of bin/vows (`cloudhead`) * [af04a10] exported Suites also run automatically when file is run directly (`cloudhead`) * [244cd01] reset Suite before running it, instead of after, so we don't upset the exit check (`cloudhead`) * [7ce4579] another test, just to test runner (`cloudhead`) * [0e3b661] ability to export batch/suite (`cloudhead`) * [073e875] ability to reset batch/suite (`cloudhead`) * [bd8a4f8] refactor reporters, share more. (`cloudhead`) * [8cd49ba] 'reporter' option instead of boolean flags. Also pass subject to Suite. (`cloudhead`) * [e2d1951] bye bye addVow (`cloudhead`) * [e5855a2] fix dot-matrix reporter not reporting errors (`cloudhead`) * [6fe14ec] suite.js init (`cloudhead`) * [b9c0329] Complete re-architecturing of vows. (`cloudhead`) * [4adab80] dot-matrix is the default reporter (`cloudhead`) * [e16cadf] (dist) cleanup Makefile (`cloudhead`) * [7200208] moved vows.prepare to extras.js (`cloudhead`) * [14278d0] cleaned up project structure a little (`cloudhead`) * [fb7d8a9] extracted console utils out of spec/dot-matrix reporters (`cloudhead`) * [ba8c46e] (new) dot-matrix reporter (`cloudhead`) v0.2.5 / Mon, 24 May 2010 ========================= * [0a53b70] (dist) version bump (`cloudhead`) * [ce73ecd] Cleaned up the inner loop a little (`cloudhead`) * [9fa313c] Fix incorrect binding in test functions. (`cloudhead`) v0.2.4 / Sun, 23 May 2010 ========================= * [b10a30a] (dist) version bump (`cloudhead`) * [2f231b1] (doc) updated README with assertion macros (`cloudhead`) * [179f854] (new) assert.instanceOf assert.isUndefined (`cloudhead`) * [87afe4c] don't complain about return value in topic if old (`cloudhead`) v0.2.3 / Sat, 22 May 2010 ========================= * [f867791] (dist) version bump (`cloudhead`) * [cb9e66e] (new) added assert.isNull, and made isObject more robust (`cloudhead`) * [cf459bc] fixed inspector doing weird shit. (`cloudhead`) v0.2.2 / Sat, 22 May 2010 ========================= * [5df28a5] (dist) version bump (`cloudhead`) * [c741f7b] (minor doc) typo in README (`cloudhead`) * [8092bb3] throw error when this.callback with a return value (`cloudhead`) * [70cf79e] (minor) standardized error messages (`cloudhead`) * [a214eb8] (new) Support for callback-style async testing (`cloudhead`) * [c600238] (doc) new install instructions (`cloudhead`) * [473e215] (dist) fixed dependencies (`cloudhead`) * [0083f0a] (dist) version bump (`cloudhead`) * [94a58be] (dist) updated paths and package.json (`cloudhead`) * [03a4171] (new) test for NaN, and added assert.isNaN (`cloudhead`) * [3f4bbec] throw Error if missing top-level context (`cloudhead`) * [9294ed8] Merge branch 'master' of github.com:cloudhead/vows (`cloudhead`) * [748e1ee] added 'install' task (`cloudhead`) * [babc2e6] version bump to 0.2.0 (`cloudhead`) v0.2.0 / Mon, 17 May 2010 ========================= * [fba631c] (minor) renamed statusText to status (`cloudhead`) * [bf80bec] time can equal 0, check more reliably (`cloudhead`) * [98c70ad] make console reporter a little more powerful (`cloudhead`) * [1606341] use json reporter if --json is passed (`cloudhead`) * [8a1d447] overhaul of continuous testing functionality, to use json backend (`cloudhead`) * [cc041ee] fix JSON reporter (`cloudhead`) * [24e6516] Merge branch 'master' of github.com:cloudhead/vows (`cloudhead`) * [a604161] renamed 'printer' -> 'reporter' (`cloudhead`) * [dc9a746] Decouple the reporting system. (`cloudhead`) * [aba0f57] updated SS (`Alexis Sellier`) * [1882f19] (fix) topics getting added multiple times (`cloudhead`) * [f59fb55] version bump (`cloudhead`) v0.1.4 / Sun, 16 May 2010 ========================= * [f887206] (fix) output the subjects without need for nextTick (`cloudhead`) * [1cb886c] (fix) count vows properly, by skipping 'topic' keys (`cloudhead`) * [6454351] fixed bug with function returning topics (`cloudhead`) * [053d7de] (test) topics returning functions (`cloudhead`) * [28f23ca] make sure result doesn't precede title (`cloudhead`) * [219ea81] fix lastTopic not being set properly (`cloudhead`) * [0cefa91] version bump (`cloudhead`) v0.1.3 / Wed, 12 May 2010 ========================= * [e97b946] pass emitted errors if test is expecting it (`cloudhead`) * [d79b6d5] fixed assert.include on objects (`cloudhead`) * [e43aa0e] added assert.length & assert.isFunction (`cloudhead`) * [99eb7de] improved emitter code in describe() (`cloudhead`) * [8a4f76d] vows.describe is the default now (`cloudhead`) v0.1.2 / Tue, 11 May 2010 ========================= * [06290ee] updated readme/comments to new API (`cloudhead`) * [fee2e78] version bump (`cloudhead`) * [15648b1] 'end' takes some parameters (`cloudhead`) * [a54c076] when passing a function, there is no promise, also print an nl (`cloudhead`) * [4fc5b9c] only count vows if passing an object to addVows() (`cloudhead`) * [0dd8387] tests. (`cloudhead`) * [cb3ab7e] don't require a topic at all (`cloudhead`) * [57fa14b] use 'end' as a completion event for test-suites (`cloudhead`) * [68e147d] pass the test-suite promises to tryFinish() (`cloudhead`) * [bfa2a26] keep track of the number of test suites (`cloudhead`) * [8e55f78] merge (`cloudhead`) * [f394e79] test for chained vows (`cloudhead`) * [b7a65c0] vow counting is sync. emit success when local remaining == 0 (`cloudhead`) * [b95d282] API change, ability to run serial test suites (`cloudhead`) * [fa51949] allow nested contexts with no topics (`cloudhead`) * [0b891d6] topic/subject ref fix (`cloudhead`) * [6e49a11] write an error if an EventEmitter hasn't fired (`cloudhead`) * [06485b8] added spinning wheel (`cloudhead`) * [8260e38] updated READMe (`cloudhead`) * [8a03c2a] 'setup' is now called 'topic' (`cloudhead`) * [a7b5857] allow non-function subjects (`cloudhead`) * [11d2e8f] added isEmpty and typeOf assertion macros (`cloudhead`) v0.1.1 / Sun, 2 May 2010 ======================== * [abadd5d] updated eyes (`cloudhead`) * [1198d46] evaluate everything within an 'environment', which is passed down (`cloudhead`) * [531d4bf] refactored escape code printing (`cloudhead`) * [c1167bd] package.json (`cloudhead`) * [d15c538] rename makefile to Makefile (`cloudhead`) * [333a7f2] attempt to detect the name of the test folder (`cloudhead`) * [3cfd5a5] explicitly return vows.promise from test runner (`cloudhead`) * [b78539e] allow access to Context object, from tests (`cloudhead`) * [1348def] describe is an alias of tell (`cloudhead`) * [ba08ca3] use typeof instead of instanceof (`cloudhead`) v0.1.0 / Sat, 1 May 2010 ======================== * [547d478] forgot to remove some test code (`cloudhead`) * [5bba9c3] default value for matcher (`cloudhead`) * [1a64009] bin/vows, autotesting utility (`cloudhead`) * [051bb40] formatting (`cloudhead`) * [3db9c6a] the matcher is an option now. -R'match string' (`cloudhead`) * [d4d7e3e] the --brief option. Also fixed various buffering problems (`cloudhead`) * [6d6c950] changed spacing in test output (`cloudhead`) * [8b2afda] don't use a Vow object, just use Object.create() (`cloudhead`) * [70ef3a6] whitespace (`cloudhead`) * [1d14683] Buffer test output, return EventEmitter. (`cloudhead`) * [f6d27ac] Merge branch 'master' of github.com:cloudhead/vows.js (`cloudhead`) * [50f76f8] other repos should be submodules (`Matt Lyon`) * [1b02c0a] bugfix: only add setup vals to context once (`Matt Lyon`) ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/LICENSE����������������������������������������������������������������������������������0000664�0000000�0000000�00000002035�13551431503�0013525�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������Copyright (c) 2009 cloudhead Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/README.md��������������������������������������������������������������������������������0000664�0000000�0000000�00000004363�13551431503�0014005�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������# vows [![Build Status](https://api.travis-ci.org/flatiron/vows.svg)](http://travis-ci.org/flatiron/vows) > Asynchronous BDD & continuous integration for node.js #### <http://vowsjs.org> # introduction ------------ 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. _Vows_ is an experiment in making this possible, while adding a minimum of overhead. synopsis -------- ```js var vows = require('vows'), assert = require('assert'); vows.describe('Deep Thought').addBatch({ 'An instance of DeepThought': { topic: new DeepThought, 'should know the answer to the ultimate question of life': function (deepThought) { assert.equal (deepThought.question('what is the answer to the universe?'), 42); } } }); ``` coverage reporting ------------------ Code coverage reporting is available if _instrumented_ code is detected. Currently only _instrumentation_ via [node-jscoverage](https://github.com/visionmedia/node-jscoverage) is supported. When _instrumented_ code is detected and coverage reporting is enabled using any of the `--cover-plain`, `--cover-html`, or `--cover-json` options a code coverage map is generated. ### downloading and installing [node-jscoverage](https://github.com/visionmedia/node-jscoverage) [node-jscoverage](https://github.com/visionmedia/node-jscoverage) is a binary package that needs to be compiled from source: ```sh $ git clone https://github.com/visionmedia/node-jscoverage.git $ cd node-jscoverage/ $ ./configure checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes [...] $ make && sudo make install ``` ### instrumenting with jscoverage ```sh $ jscoverage myfile.js myfile-instrumented.js ``` installation ------------ ```sh $ npm install vows ``` documentation ------------- Head over to <http://vowsjs.org> run tests ------------- ```sh $ npm test ``` authors ------- [Alexis Sellier](https://github.com/cloudhead), [Charlie Robbins](https://github.com/indexzero), [Jerry Sievert](https://github.com/jerrysievert) *...and many others* �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/bin/�������������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13551431503�0013270�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/bin/vows���������������������������������������������������������������������������������0000775�0000000�0000000�00000050324�13551431503�0014220�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������#!/usr/bin/env node var path = require('path'), fs = require('fs'), util = require('util'), glob = require('glob'), NopStream = require('../lib/utils/nopstream').NopStream, events = require('events'); // // Attempt to load Coffee-Script. If it's not available, continue on our // merry way, if it is available, start searching for `*.coffee` scripts too. // var fileExt, specFileExt; try { var coffee = require('coffee-script'); if(coffee.register) coffee.register(); fileExt = /\.(js|coffee)$/; specFileExt = /[.(-|_)]((t|T)est|(s|S)pec)\.(js|coffee)$/; } catch (_) { fileExt = /\.js$/; specFileExt = /[.(-|_)]((t|T)est|(s|S)pec)\.js$/; } var inspect = require('eyes').inspector({ stream: null, styles: { string: 'grey', regexp: 'grey' } }); var vows = require('../lib/vows'); var cutils = require('../lib/vows/console'); var stylize = require('../lib/vows/console').stylize; var _reporter = require('../lib/vows/reporters/dot-matrix'), reporter = { name: _reporter.name }; var _coverage; var nodeMinorVersion = parseInt(process.version.split('.')[1], 10); var help = [ "usage: vows [FILE, ...] [options]", "", "options:", " -v, --verbose Enable verbose output", " -w, --watch Watch mode", " -s, --silent Don't report", " -i, --isolate Run each test in its own vows process", " -m PATTERN Only run tests matching the PATTERN string", " -r PATTERN Only run tests matching the PATTERN regexp", " --json Use JSON reporter", " --spec Use Spec reporter", " --tap Use TAP reporter", " --dot-matrix Use Dot-Matrix reporter", " --xunit Use xUnit reporter", " --cover-plain Print plain coverage map if detected", " --cover-html Write coverage map to \"coverage.html\"", " --cover-json Write unified coverage map to \"coverage.json\"", " --cover-xml Write coverage map to \"coverage.xml\" in Emma xml", " --no-color Don't use terminal colors", " --version Show version", " -h, --help You're staring at it" ].join('\n'); var options = { reporter: reporter, matcher: /.*/, watch: false, coverage: false, isolate: false, shuffle: false, nocolor: !process.stdout.isTTY }; var files = []; var wildcardFiles = []; // Get rid of process runner // ('node' in most cases) var arg, args = [], argv = process.argv.slice(2); // Current directory index, // and path of test folder. var root, testFolder; // // Parse command-line parameters // while (arg = argv.shift()) { if (arg === __filename) { continue } if (arg[0] !== '-') { args.push(arg); } else { arg = arg.match(/^--?(.+)/)[1]; if (arg[0] === 'r') { options.matcher = new(RegExp)(argv.shift()); } else if (arg[0] === 'm') { options.matcher = (function (str) { // Create an escaped RegExp var specials = '. * + ? | ( ) [ ] { } \\ ^ ? ! = : $'.split(' ').join('|\\'), regex = new(RegExp)('(\\' + specials + ')', 'g'); return new(RegExp)(str.replace(regex, '\\$1')); })(argv.shift()); } else if (arg in options) { options[arg] = true; } else { switch (arg) { case 'json': _reporter = require('../lib/vows/reporters/json'); break; case 'spec': _reporter = require('../lib/vows/reporters/spec'); break; case 'tap': _reporter = require('../lib/vows/reporters/tap'); break; case 'dot-matrix': _reporter = require('../lib/vows/reporters/dot-matrix'); break; case 'silent': case 's': _reporter = require('../lib/vows/reporters/silent'); break; case 'xunit': _reporter = require('../lib/vows/reporters/xunit'); break; case 'cover-plain': options.coverage = true; _coverage = require('../lib/vows/coverage/report-plain'); break; case 'cover-html': options.coverage = true; _coverage = require('../lib/vows/coverage/report-html'); break; case 'cover-json': options.coverage = true; _coverage = require('../lib/vows/coverage/report-json'); break; case 'cover-xml': options.coverage = true; _coverage = require('../lib/vows/coverage/report-xml'); break; case 'verbose': case 'v': options.verbose = true; break; case 'watch': case 'w': options.watch = true; break; case 'supress-stdout': options.supressStdout = true; break; case 'shuffle': options.shuffle = true; break; case 'isolate': case 'i': options.isolate = true; break; case 'no-color': options.nocolor = true; break; case 'color': options.nocolor = false; break; case 'no-error': options.error = false; break; case 'version': console.log('vows ' + vows.version); process.exit(0); case 'help': case 'h': console.log(help); process.exit(0); break; } } } } if (options.nocolor) { cutils.nocolor = true; inspect = require('eyes').inspector({ stream: null, styles: false }); } if (options.supressStdout) { _reporter.setStream && _reporter.setStream(process.stdout); var devNullStream = null; if(process.platform === 'win32'){ devNullStream = new NopStream (); } else { devNullStream = fs.createWriteStream('/dev/null'); } process.__defineGetter__('stdout', function () { return devNullStream; }); } if (options.watch) { options.reporter = reporter = require('../lib/vows/reporters/watch'); } msg('bin', 'argv', args); msg('bin', 'options', { reporter: options.reporter.name, matcher: options.matcher }); if (args.length === 0 || options.watch) { msg('bin', 'discovering', 'folder structure'); root = fs.readdirSync('.'); if (root.indexOf('test') !== -1) { testFolder = 'test'; } else if (root.indexOf('spec') !== -1) { testFolder = 'spec'; } else { abort("runner", "couldn't find test folder"); } msg('bin', 'discovered', "./" + testFolder); if (args.length === 0) { args = paths(testFolder).filter(function (f) { return specFileExt.test(f); }); if (options.watch) { args = args.concat(paths('lib'), paths('src')); } } } if (! options.watch) { reporter.report = function (data, filename) { switch (data[0]) { case 'subject': case 'vow': case 'context': case 'error': _reporter.report(data, filename); break; case 'end': (options.verbose || _reporter.name === 'json') && _reporter.report(data); break; case 'finish': options.verbose ? _reporter.print('\n') : _reporter.print(' '); break; } }; reporter.reset = function () { _reporter.reset && _reporter.reset() }; reporter.print = _reporter.print; // add full path if necessary files = args.map(function (a) { if(process.platform === 'win32') { // check if path starts with a valid windows drive name return (!a.match(/^[a-z]:/i))? path.join(process.cwd(), a) : a; } else { // check if path starts at root return (!a.match(/^\//))? path.join(process.cwd(), a) : a; } }); // preprocess the list of files for any wildcards. win32 does not handle wildcards before calling vows // any paths not containing wildcards are simple returned by wildcard() files.forEach(function(a) { wildcardFiles = wildcardFiles.concat(glob.sync(a)); }); // now set up the file list for vows including all the wildcard files files = wildcardFiles.map(function (a) { return a.replace(fileExt, ''); }); if (options.shuffle) { var source = files.slice(0); files.length = 0; while (source.length) { files.push(source.splice(Math.floor(Math.random() * source.length), 1)[0]); } } runSuites(importSuites(files), function (results) { var status = results.errored ? 2 : (results.broken ? 1 : 0); !options.verbose && _reporter.print('\n'); msg('runner', 'finish'); _reporter.report(['finish', results], { write: function (str) { process.stdout.write(str.replace(/^\n\n/, '\n')); } }); try { if (options.coverage === true && _$jscoverage !== undefined) { _coverage.report(_$jscoverage); } } catch (err) { // ignore the undefined jscoverage } process.on('exit', function (code) { if (code === 0) { process.exit(status); } }); }); } else { // // Watch mode // (function () { var pendulum = [ '. ', '.. ', '... ', ' ...', ' ..', ' .', ' .', ' ..', '... ', '.. ', '. ' ]; var strobe = ['.', ' ']; var status, cue, current = 0, running = 0, lastRun, colors = ['32m', '33m', '31m'], timer = setInterval(tick, 100); process.on('uncaughtException', exception); process.on('exit', cleanup); process.on('SIGINT', function () { process.exit(0); }); process.on('SIGQUIT', function () { changed(); }); cursorHide(); // Run every 100ms function tick() { if (running && (cue !== strobe)) { cue = strobe, current = 0; } else if (!running && (cue !== pendulum)) { cue = pendulum, current = 0; } eraseLine(); lastRun && !running && esc(colors[status.errored ? 2 : (status.broken ? 1 : 0)]); print(cue[current]); if (current == cue.length - 1) { current = -1 } current ++; esc('39m'); cursorRestore(); } // // Utility functions // function print(str) { process.stdout.write(str) } function esc(str) { print("\x1b[" + str) } function eraseLine() { esc("0K") } function cursorRestore() { esc("0G") } function cursorHide() { esc("?25l") } function cursorShow() { esc("?25h") } function cleanup() { eraseLine(), cursorShow(), clearInterval(timer), print('\n') } function exception(err) { print(err.stack || err.message || JSON.stringify(err)), running = 0} // // Get a matching test for a given file // function getMatchingTest(file, join) { join || (join = '-'); var testFile; if (specFileExt.test(file)) { testFile = path.join(testFolder, file); } else { var root, extension; _s = file.split('.'), root = _s[0], extension = _s[1]; testFile = path.join(testFolder, root + join + testFolder + "." + extension); } try { fs.statSync(testFile); } catch (e) { if (join == '-') { return getMatchingTest(file, '_'); } else { msg('watcher', 'no equivalence found, running all tests.'); testFile = null; } } return testFile; } // // Called when a file has been modified. // Run the matching tests and change the status. // function changed(file) { status = { honored: 0, broken: 0, errored: 0, pending: 0 }; msg('watcher', 'detected change in', file); file = getMatchingTest(file); var files = (specFileExt.test(file) ? [file] : paths(testFolder)).map(function (p) { return path.join(process.cwd(), p); }).filter(function (p) { return specFileExt.test(p); }).map(function (p) { var cache = require.main.moduleCache || require.cache; if (cache[p]) { delete(cache[p]) } return p; }).map(function (p) { return p.replace(fileExt, ''); }); running ++; runSuites(importSuites(files), function (results) { delete(results.time); print(cutils.result(results).join('') + '\n\n'); lastRun = new(Date); status = results; running --; }); } msg('watcher', 'watching', args); // // Watch all relevant files, // and call `changed()` on change. // args.forEach(function (p) { fs.watchFile(p, function (current, previous) { if (new(Date)(current.mtime).valueOf() === new(Date)(previous.mtime).valueOf()) { return } else { changed(p); } }); }); })(); } function runSuites(suites, callback) { var results = { honored: 0, broken: 0, errored: 0, pending: 0, total: 0, time: 0 }; reporter.reset(); (function run(suites, callback) { var suite = suites.shift(); if (suite) { msg('runner', "running", suite.subject + ' ', options.watch ? false : true); suite.run(options, function (result) { Object.keys(result).forEach(function (k) { results[k] += result[k]; }); run(suites, callback); }); } else { callback(results); } })(suites, callback); } function importSuites(files) { msg(options.watcher ? 'watcher' : 'runner', 'loading', files); var spawn = require('child_process').spawn; function cwdname(f) { return f.replace(process.cwd() + '/', '') + '.js'; } function wrapSpawn(f) { f = cwdname(f); return function (options, callback) { var args = [process.argv[1], '--json', f], result; // --supress-stdout stops the stream too early on win32 if(process.platform !== 'win32') { args.push( '--supress-stdout'); } var p = spawn(process.execPath, args); // // AvianFlu, you broke the API! OH NOEZ. // Anyway. // Since node 0.7.something, semantics of child process events // changed - `exit` event is emitted when child process exits // and `close` event is emitted when child's streams stdio streams // are closed. `exit` event is emitted before `close` event, and // since we use child's stdio streams, we shouldn't rely on `exit` // event. // p.on(nodeMinorVersion >= 7 ? 'close' : 'exit', function (code) { callback( !result ? {errored: 1, total: 1} : result ); }); var buffer = []; p.stdout.on('data', function (data) { data = data.toString().split(/\n/g); if (data.length == 1) { buffer.push(data[0]); } else { data[0] = buffer.concat(data[0]).join(''); buffer = [data.pop()]; data.forEach(function (data) { if (data && data !== 'undefined') { try { data = JSON.parse(data); // on win32 we may get back console.log strings which break JSON.parse if (data && data[0] === 'finish') { result = data[1]; } else { reporter.report(data); } } catch(e) { } } }); } }); p.stderr.pipe(process.stderr); } } return files.reduce(options.isolate ? function (suites, f) { return suites.concat({ run: wrapSpawn(f) }); } : function (suites, f) { //f = path.join(process.cwd(), path.relative(process.cwd(),f)); var obj = require(f); return suites.concat( Object.keys(obj) .filter(function(s) { return s !== '_$jscoverage'; }) .map(function (s) { try { obj[s]._filename = cwdname(f); } catch (e) { if (e instanceof TypeError && typeof(obj[s]) === 'undefined') { abort("runner", "Caught a TypeError while trying to import " + "suites: a suite is undefined." + "Check your exports; are you doing something like " + "exports.suite = vows.describe('foo')." + "addBatch({}).run()? If so, remove '.run()'"); } else { throw e; } } return obj[s]; }) ); }, []) } // // Recursively traverse a hierarchy, returning // a list of all relevant .js files. // function paths(dir) { var paths = []; try { fs.statSync(dir) } catch (e) { return [] } (function traverse(dir, stack) { stack.push(dir); var dirPath = stack.join('/'); fs.readdirSync(stack.join('/')).forEach(function (file) { // // Skip dotfiles and `vendor` directory before `fs.stat()`ing them. // Not doing so causes race conditions with Emacs buffer files // (`.#filename.js`). // if (file[0] == '.' || file === 'vendor') { return; } var path = stack.concat([file]).join('/'), stat = fs.statSync(path); if (stat.isFile() && fileExt.test(file)) { paths.push(path); } else if (stat.isDirectory()) { traverse(file, stack); } }); stack.pop(); })(dir || '.', []); return paths; } function msg(cmd, subject, str, p) { if (options.verbose) { var func = p ? process.stdout.write.bind(process.stdout) : console.log; func( stylize('vows ', 'green') + stylize(cmd, 'bold') + ' ' + subject + ' ' + (str ? (typeof(str) === 'string' ? str : inspect(str)) : '') ); } } function abort(cmd, str) { console.log(stylize('vows ', 'red') + stylize(cmd, 'bold') + ' ' + str); console.log(stylize('vows ', 'red') + stylize(cmd, 'bold') + ' exiting'); process.exit(-1); } ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/�������������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13551431503�0013266�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/assert/������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13551431503�0014567�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/assert/error.js����������������������������������������������������������������������0000664�0000000�0000000�00000011174�13551431503�0016262�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/** This software contains code adapted from Mocha (https://github.com/visionmedia/mocha) by TJ Holowaychuk and is used herein under the following MIT license: Copyright (c) 2011-2012 TJ Holowaychuk <tj@vision-media.ca> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var stylize = require('../vows/console').stylize; var inspect = require('../vows/console').inspect; var diff = require('diff'); /** * Pad the given `str` to `len`. * * @param {String} str * @param {String} len * @return {String} * @api private */ function pad(str, len) { str = String(str); return Array(len - str.length + 1).join(' ') + str; } /** * Color lines for `str`, using the color `name`. * * @param {String} name * @param {String} str * @return {String} * @api private */ function styleLines(str, name) { return str.split('\n').map(function(str){ return stylize(str, name); }).join('\n'); } /** * Return a character diff for `err`. * * @param {Error} err * @return {String} * @api private */ function errorDiff(err, type) { return diff['diff' + type](err.expected, err.actual).map(function(str){ if (/^(\n+)$/.test(str.value)) str.value = Array(++RegExp.$1.length).join('<newline>'); if (str.added) return styleLines(str.value, 'green'); if (str.removed) return styleLines(str.value, 'red'); return str.value; }).join(''); } function extractPathFromStack(stack) { var regex = /\((.*?[a-zA-Z0-9._-]+\.(?:js|coffee))(:\d+):\d+\)/; return stack.match(regex); } /* Do not override .toString() when this.stack is used, otherwise this will end in an endless recursive call... See issue https://github.com/cloudhead/vows/issues/278#issuecomment-22837493 */ require('assert').AssertionError.prototype.toStringEx = function () { var that = this, source; if (this.stack) { source = extractPathFromStack(this.stack); } function parse(str) { var actual = that.actual, expected = that.expected, msg, len; if ( 'string' === typeof actual && 'string' === typeof expected ) { len = Math.max(actual.length, expected.length); if (len < 20) msg = errorDiff(that, 'Chars'); else msg = errorDiff(that, 'Words'); // linenos var lines = msg.split('\n'); if (lines.length > 4) { var width = String(lines.length).length; msg = lines.map(function(str, i){ return pad(++i, width) + ' |' + ' ' + str; }).join('\n'); } // legend msg = '\n' + stylize('actual', 'green') + ' ' + stylize('expected', 'red') + '\n\n' + msg + '\n'; // indent msg = msg.replace(/^/gm, ' '); return msg; } actual = inspect(actual, {showHidden: actual instanceof Error}); if (expected instanceof Function) { expected = expected.name; } else { expected = inspect(expected, {showHidden: actual instanceof Error}); } return str.replace(/{actual}/g, actual). replace(/{operator}/g, stylize(that.operator, 'bold')). replace(/{expected}/g, expected); } if (this.message) { var msg = stylize(parse(this.message), 'yellow'); if (source) { msg += stylize(' // ' + source[1] + source[2], 'grey'); } return msg; } else { return stylize([ this.expected, this.operator, this.actual ].join(' '), 'yellow'); } }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/assert/macros.js���������������������������������������������������������������������0000664�0000000�0000000�00000024152�13551431503�0016415�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������var assert = require('assert'), utils = require('./utils'); var messages = { 'equal' : "expected {expected},\n\tgot\t {actual} ({operator})", 'notEqual' : "didn't expect {actual} ({operator})" }; messages['strictEqual'] = messages['deepEqual'] = messages['equal']; messages['notStrictEqual'] = messages['notDeepEqual'] = messages['notEqual']; for (var key in messages) { assert[key] = (function (key, callback) { return function (actual, expected, message) { callback(actual, expected, message || messages[key]); }; })(key, assert[key]); } assert.epsilon = function (eps, actual, expected, message) { assertMissingArguments(arguments, assert.epsilon); if (isNaN(eps)) { assert.fail(actual, expected, message || "cannot compare {actual} with {expected} \u00B1 NaN"); } else if (isNaN(actual) || Math.abs(actual - expected) > eps) { assert.fail(actual, expected, message || "expected {expected} \u00B1"+ eps +", but was {actual}"); } }; assert.ok = (function (callback) { assertMissingArguments(arguments, assert.ok); return function (actual, message) { callback(actual, message || "expected expression to evaluate to {expected}, but was {actual}"); }; })(assert.ok); assert.match = function (actual, expected, message) { assertMissingArguments(arguments, assert.match); if (! expected.test(actual)) { assert.fail(actual, expected, message || "expected {actual} to match {expected}", "match", assert.match); } }; assert.matches = assert.match; assert.isTrue = function (actual, message) { assertMissingArguments(arguments, assert.isTrue); if (actual !== true) { assert.fail(actual, true, message || "expected {expected}, got {actual}", "===", assert.isTrue); } }; assert.isFalse = function (actual, message) { assertMissingArguments(arguments, assert.isFalse); if (actual !== false) { assert.fail(actual, false, message || "expected {expected}, got {actual}", "===", assert.isFalse); } }; assert.isZero = function (actual, message) { assertMissingArguments(arguments, assert.isZero); if (actual !== 0) { assert.fail(actual, 0, message || "expected {expected}, got {actual}", "===", assert.isZero); } }; assert.isNotZero = function (actual, message) { assertMissingArguments(arguments, assert.isNotZero); if (actual === 0) { assert.fail(actual, 0, message || "expected non-zero value, got {actual}", "===", assert.isNotZero); } }; assert.greater = function (actual, expected, message) { assertMissingArguments(arguments, assert.greater); if (actual <= expected) { assert.fail(actual, expected, message || "expected {actual} to be greater than {expected}", ">", assert.greater); } }; assert.lesser = function (actual, expected, message) { assertMissingArguments(arguments, assert.lesser); if (actual >= expected) { assert.fail(actual, expected, message || "expected {actual} to be lesser than {expected}", "<", assert.lesser); } }; assert.inDelta = function (actual, expected, delta, message) { assertMissingArguments(arguments, assert.inDelta); var lower = expected - delta; var upper = expected + delta; if (actual != +actual || actual < lower || actual > upper) { assert.fail(actual, expected, message || "expected {actual} to be in within *" + delta.toString() + "* of {expected}", null, assert.inDelta); } }; // // Inclusion // assert.include = function (actual, expected, message) { assertMissingArguments(arguments, assert.include); if ((function (obj) { if (isArray(obj) || isString(obj)) { return obj.indexOf(expected) === -1; } else if (isObject(actual)) { return ! obj.hasOwnProperty(expected); } return true; })(actual)) { assert.fail(actual, expected, message || "expected {actual} to include {expected}", "include", assert.include); } }; assert.includes = assert.include; assert.notInclude = function (actual, expected, message) { assertMissingArguments(arguments, assert.notInclude); if ((function (obj) { if (isArray(obj) || isString(obj)) { return obj.indexOf(expected) !== -1; } else if (isObject(actual)) { return obj.hasOwnProperty(expected); } return true; })(actual)) { assert.fail(actual, expected, message || "expected {actual} not to include {expected}", "include", assert.notInclude); } }; assert.notIncludes = assert.notInclude; assert.deepInclude = function (actual, expected, message) { assertMissingArguments(arguments, assert.deepInclude); if (!isArray(actual)) { return assert.include(actual, expected, message); } if (!actual.some(function (item) { return utils.deepEqual(item, expected) })) { assert.fail(actual, expected, message || "expected {actual} to include {expected}", "include", assert.deepInclude); } }; assert.deepIncludes = assert.deepInclude; // // Length // assert.isEmpty = function (actual, message) { assertMissingArguments(arguments, assert.isEmpty); if ((isObject(actual) && Object.keys(actual).length > 0) || actual.length > 0) { assert.fail(actual, 0, message || "expected {actual} to be empty", "length", assert.isEmpty); } }; assert.isNotEmpty = function (actual, message) { assertMissingArguments(arguments, assert.isNotEmpty); if ((isObject(actual) && Object.keys(actual).length === 0) || actual.length === 0) { assert.fail(actual, 0, message || "expected {actual} to be not empty", "length", assert.isNotEmpty); } }; assert.lengthOf = function (actual, expected, message) { assertMissingArguments(arguments, assert.lengthOf); var len = isObject(actual) ? Object.keys(actual).length : actual.length; if (len !== expected) { assert.fail(actual, expected, message || "expected {actual} to have {expected} element(s)", "length", assert.length); } }; // // Type // assert.isArray = function (actual, message) { assertMissingArguments(arguments, assert.isArray); assertTypeOf(actual, 'array', message || "expected {actual} to be an Array", assert.isArray); }; assert.isObject = function (actual, message) { assertMissingArguments(arguments, assert.isObject); assertTypeOf(actual, 'object', message || "expected {actual} to be an Object", assert.isObject); }; assert.isNumber = function (actual, message) { assertMissingArguments(arguments, assert.isNumber); if (isNaN(actual)) { assert.fail(actual, 'number', message || "expected {actual} to be of type {expected}", "isNaN", assert.isNumber); } else { assertTypeOf(actual, 'number', message || "expected {actual} to be a Number", assert.isNumber); } }; assert.isBoolean = function (actual, message) { assertMissingArguments(arguments, assert.isBoolean); if (actual !== true && actual !== false) { assert.fail(actual, 'boolean', message || "expected {actual} to be a Boolean", "===", assert.isBoolean); } }; assert.isNaN = function (actual, message) { assertMissingArguments(arguments, assert.isNaN); if (actual === actual) { assert.fail(actual, 'NaN', message || "expected {actual} to be NaN", "===", assert.isNaN); } }; assert.isNull = function (actual, message) { assertMissingArguments(arguments, assert.isNull); if (actual !== null) { assert.fail(actual, null, message || "expected {expected}, got {actual}", "===", assert.isNull); } }; assert.isNotNull = function (actual, message) { assertMissingArguments(arguments, assert.isNotNull); if (actual === null) { assert.fail(actual, null, message || "expected non-null value, got {actual}", "===", assert.isNotNull); } }; assert.isUndefined = function (actual, message) { assertMissingArguments(arguments, assert.isUndefined); if (actual !== undefined) { assert.fail(actual, undefined, message || "expected {actual} to be {expected}", "===", assert.isUndefined); } }; assert.isDefined = function (actual, message) { assertMissingArguments(arguments, assert.isDefined); if(actual === undefined) { assert.fail(actual, 0, message || "expected {actual} to be defined", "===", assert.isDefined); } }; assert.isString = function (actual, message) { assertMissingArguments(arguments, assert.isString); assertTypeOf(actual, 'string', message || "expected {actual} to be a String", assert.isString); }; assert.isFunction = function (actual, message) { assertMissingArguments(arguments, assert.isFunction); assertTypeOf(actual, 'function', message || "expected {actual} to be a Function", assert.isFunction); }; assert.typeOf = function (actual, expected, message) { assertMissingArguments(arguments, assert.typeOf); assertTypeOf(actual, expected, message, assert.typeOf); }; assert.instanceOf = function (actual, expected, message) { assertMissingArguments(arguments, assert.instanceof); if (! (actual instanceof expected)) { assert.fail(actual, expected, message || "expected {actual} to be an instance of {expected}", "instanceof", assert.instanceOf); } }; // // Utility functions // function assertMissingArguments(args, caller) { if (args.length === 0) { assert.fail("", "", "expected number of arguments to be greater than zero", "", caller); } } function assertTypeOf(actual, expected, message, caller) { if (typeOf(actual) !== expected) { assert.fail(actual, expected, message || "expected {actual} to be of type {expected}", "typeOf", caller); } } function isArray (obj) { return Array.isArray(obj); } function isString (obj) { return typeof(obj) === 'string' || obj instanceof String; } function isObject (obj) { return typeof(obj) === 'object' && obj && !isArray(obj); } // A better `typeof` function typeOf(value) { var s = typeof(value), types = [Object, Array, String, RegExp, Number, Function, Boolean, Date]; if (s === 'object' || s === 'function') { if (value) { types.forEach(function (t) { if (value instanceof t) { s = t.name.toLowerCase() } }); } else { s = 'null' } } return s; } ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/assert/utils.js����������������������������������������������������������������������0000664�0000000�0000000�00000003561�13551431503�0016272�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ // Taken from node/lib/assert.js exports.deepEqual = function (actual, expected) { if (actual === expected) { return true; } else if (Buffer.isBuffer(actual) && Buffer.isBuffer(expected)) { if (actual.length != expected.length) return false; for (var i = 0; i < actual.length; i++) { if (actual[i] !== expected[i]) return false; } return true; } else if (actual instanceof Date && expected instanceof Date) { return actual.getTime() === expected.getTime(); } else if (typeof actual != 'object' && typeof expected != 'object') { return actual == expected; } else { return objEquiv(actual, expected); } } // Taken from node/lib/assert.js exports.notDeepEqual = function (actual, expected, message) { if (exports.deepEqual(actual, expected)) { fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); } } // Taken from node/lib/assert.js function isUndefinedOrNull(value) { return value === null || value === undefined; } // Taken from node/lib/assert.js function isArguments(object) { return Object.prototype.toString.call(object) == '[object Arguments]'; } // Taken from node/lib/assert.js function objEquiv(a, b) { if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) return false; if (a.prototype !== b.prototype) return false; if (isArguments(a)) { if (!isArguments(b)) { return false; } a = pSlice.call(a); b = pSlice.call(b); return exports.deepEqual(a, b); } try { var ka = Object.keys(a), kb = Object.keys(b), key, i; } catch (e) { return false; } if (ka.length != kb.length) return false; ka.sort(); kb.sort(); for (i = ka.length - 1; i >= 0; i--) { if (ka[i] != kb[i]) return false; } for (i = ka.length - 1; i >= 0; i--) { key = ka[i]; if (!exports.deepEqual(a[key], b[key])) return false; } return true; } �����������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/utils/�������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13551431503�0014426�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/utils/nopstream.js�������������������������������������������������������������������0000664�0000000�0000000�00000001374�13551431503�0017001�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// NopStream // a writeable stream to mimic writing to /dev/null on windows // from https://gist.github.com/3221453 // Set both readable and writable in constructor. var NopStream = exports.NopStream = function () { this.readable = true; this.writable = true; }; // Inherit from base stream class. require('util').inherits(NopStream , require('stream')); // Extract args to `write` and emit as `data` event. NopStream .prototype.write = function () { args = Array.prototype.slice.call(arguments, 0); this.emit.apply(this, ['data'].concat(args)) }; // Extract args to `end` and emit as `end` event. NopStream .prototype.end = function () { args = Array.prototype.slice.call(arguments, 0); this.emit.apply(this, ['end'].concat(args)) };��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows.js������������������������������������������������������������������������������0000664�0000000�0000000�00000017673�13551431503�0014640�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// // Vows.js - asynchronous event-based BDD for node.js // // usage: // // var vows = require('vows'); // // vows.describe('Deep Thought').addBatch({ // "An instance of DeepThought": { // topic: new DeepThought, // // "should know the answer to the ultimate question of life": function (deepThought) { // assert.equal (deepThought.question('what is the answer to the universe?'), 42); // } // } // }).run(); // var path = require('path'), events = require('events'), util = require('util'), vows = exports; // Options vows.options = { Emitter: events.EventEmitter, reporter: require('./vows/reporters/dot-matrix'), matcher: /.*/, error: true // Handle "error" event }; vows.__defineGetter__('reporter', function () { return vows.options.reporter; }); var stylize = require('./vows/console').stylize; var console = vows.console = require('./vows/console'); vows.inspect = require('./vows/console').inspect; vows.prepare = require('./vows/extras').prepare; vows.tryEnd = require('./vows/suite').tryEnd; // // Assertion Macros & Extensions // require('./assert/error'); require('./assert/macros'); // // Suite constructor // var Suite = require('./vows/suite').Suite; // // This function gets added to events.EventEmitter.prototype, by default. // It's essentially a wrapper around `on`, which adds all the specification // goodness. // function addVow(vow) { var batch = vow.batch, event = vow.binding.context.event || 'success', self = this; batch.total ++; batch.vows.push(vow); // always set a listener on the event this.on(event, function () { if(vow.caughtError) return; var args = Array.prototype.slice.call(arguments); // If the vow is a sub-event then we know it is an // emitted event. So I don't muck with the arguments // However the legacy behavior: // If the callback is expecting two or more arguments, // pass the error as the first (null) and the result after. if (!(this.ctx && this.ctx.isEvent) && vow.callback.length >= 2 && batch.suite.options.error) { args.unshift(null); } runTest(args, this.ctx); vows.tryEnd(batch); }); if (event !== 'error') { this.on("error", function (err) { vow.caughtError = true; if (vow.callback.length >= 2 || !batch.suite.options.error) { runTest(arguments, this.ctx); } else { output('errored', { type: 'emitter', error: err.stack || err.message || JSON.stringify(err) }); } vows.tryEnd(batch); }); } // in case an event fired before we could listen if (this._vowsEmitedEvents && this._vowsEmitedEvents.hasOwnProperty(event)) { // make sure no one is messing with me if (Array.isArray(this._vowsEmitedEvents[event])) { // I don't think I need to optimize for one event, // I think it is more important to make sure I check the vow n times self._vowsEmitedEvents[event].forEach(function(args) { runTest(args, self.ctx); }); } else { // initial conditions problem throw new Error('_vowsEmitedEvents[' + event + '] is not an Array') } vows.tryEnd(batch); } return this; function runTest(args, ctx) { if (vow.callback instanceof String) { return output('pending'); } if (vow.binding.context.isEvent && vow.binding.context.after) { var after = vow.binding.context.after; // only need to check order. I won't get here if the after event // has never been emitted if (self._vowsEmitedEventsOrder.indexOf(after) > self._vowsEmitedEventsOrder.indexOf(event)) { output('broken', event + ' emitted before ' + after); return; } } // Run the test, and try to catch `AssertionError`s and other exceptions; // increment counters accordingly. try { vow.callback.apply(ctx === global || !ctx ? vow.binding : ctx, args); output('honored'); } catch (e) { if (e.name && e.name.match(/AssertionError/)) { output('broken', e.toStringEx().replace(/\`/g, '`')); } else { output('errored', e.stack || e.message || e); } } } function output(status, exception) { batch[status] ++; vow.status = status; if (vow.context && batch.lastContext !== vow.context) { batch.lastContext = vow.context; batch.suite.report(['context', vow.context]); } batch.suite.report(['vow', { title: vow.description, context: vow.context, status: status, exception: exception || null }]); } }; // // On exit, check that all emitters have been fired. // If not, report an error message. // process.on('exit', function () { var results = { honored: 0, broken: 0, errored: 0, pending: 0, total: 0 }, failure; vows.suites.forEach(function (s) { if ((s.results.total > 0) && (s.results.time === null)) { s.reporter.print('\n\n'); s.reporter.report(['error', { error: "Asynchronous Error", suite: s }]); } s.batches.forEach(function (b) { var unFired = []; b.vows.forEach(function (vow) { if (! vow.status) { if (unFired.indexOf(vow.context) === -1) { unFired.push(vow.context); } } }); if (unFired.length > 0) { util.print('\n'); } unFired.forEach(function (title) { s.reporter.report(['error', { error: "callback not fired", context: title, batch: b, suite: s }]); }); if (b.status === 'begin') { failure = true; results.errored ++; results.total ++; } Object.keys(results).forEach(function (k) { results[k] += b[k] }); }); }); if (failure) { util.puts(console.result(results)); process.exit(1); } }); vows.suites = []; // We need the old emit function so we can hook it // and do magic to deal with events that have fired var oldEmit = vows.options.Emitter.prototype.emit; // // Create a new test suite // vows.describe = function (subject) { var suite = new(Suite)(subject); this.options.Emitter.prototype.addVow = addVow; // just in case someone emit's before I get to it this.options.Emitter.prototype.emit = function (event) { this._vowsEmitedEvents = this._vowsEmitedEvents || {}; this._vowsEmitedEventsOrder = this._vowsEmitedEventsOrder || []; // slice off the event var args = Array.prototype.slice.call(arguments, 1); // if multiple events are fired, add or push if (this._vowsEmitedEvents.hasOwnProperty(event)) { this._vowsEmitedEvents[event].push(args); } else { this._vowsEmitedEvents[event] = [args]; } // push the event onto a stack so I have an order this._vowsEmitedEventsOrder.push(event); return oldEmit.apply(this, arguments); } this.suites.push(suite); // // Add any additional arguments as batches if they're present // if (arguments.length > 1) { for (var i = 1, l = arguments.length; i < l; ++i) { suite.addBatch(arguments[i]); } } return suite; }; vows.version = JSON.parse(require('fs') .readFileSync(path.join(__dirname, '..', 'package.json'))) .version ���������������������������������������������������������������������vows-0.8.3/lib/vows/��������������������������������������������������������������������������������0000775�0000000�0000000�00000000000�13551431503�0014264�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows/console.js����������������������������������������������������������������������0000664�0000000�0000000�00000010602�13551431503�0016263�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������var eyes = require('eyes').inspector({ stream: null, styles: false }); // Stylize a string this.stylize = function stylize(str, style) { if (module.exports.nocolor) { return str; } var styles = { 'bold' : [1, 22], 'italic' : [3, 23], 'underline' : [4, 24], 'cyan' : [96, 39], 'yellow' : [33, 39], 'green' : [32, 39], 'red' : [31, 39], 'grey' : [90, 39], 'green-hi' : [92, 32], }; return '\033[' + styles[style][0] + 'm' + str + '\033[' + styles[style][1] + 'm'; }; var $ = this.$ = function (str) { str = new(String)(str); ['bold', 'grey', 'yellow', 'red', 'green', 'white', 'cyan', 'italic'].forEach(function (style) { Object.defineProperty(str, style, { get: function () { return exports.$(exports.stylize(this, style)); } }); }); return str; }; this.puts = function (options) { var stylize = exports.stylize; options.stream || (options.stream = process.stdout); options.tail = options.tail || ''; return function (args) { args = Array.prototype.slice.call(arguments); if (!options.raw) { args = args.map(function (a) { return a.replace(/`([^`]+)`/g, function (_, capture) { return stylize(capture, 'italic') }) .replace(/\*([^*]+)\*/g, function (_, capture) { return stylize(capture, 'bold') }) .replace(/\n/g, function (_, capture) { return ' \n ' } ); }); } return options.stream.write(args.join('\n') + options.tail); }; }; this.log = this.puts({}); this.result = function (event) { var result = [], buffer = [], time = '', header; var complete = event.honored + event.pending + event.errored + event.broken; var status = (event.errored && 'errored') || (event.broken && 'broken') || (event.honored && 'honored') || (event.pending && 'pending'); if (event.total === 0) { return [$("Could not find any tests to run.").bold.red]; } event.honored && result.push($(event.honored).bold + " honored"); event.broken && result.push($(event.broken).bold + " broken"); event.errored && result.push($(event.errored).bold + " errored"); event.pending && result.push($(event.pending).bold + " pending"); if (complete < event.total) { result.push($(event.total - complete).bold + " dropped"); } result = result.join(' ∙ '); header = { honored: '✓ ' + $('OK').bold.green, broken: '✗ ' + $('Broken').bold.yellow, errored: '✗ ' + $('Errored').bold.red, pending: '- ' + $('Pending').bold.cyan }[status] + ' » '; if (typeof(event.time) === 'number') { time = ' (' + event.time.toFixed(3) + 's)'; time = this.stylize(time, 'grey'); } buffer.push(header + result + time + '\n'); return buffer; }; this.inspect = function inspect(val) { if (module.exports.nocolor) { return eyes(val); } return '\033[1m' + eyes(val) + '\033[22m'; }; this.error = function (obj) { var string = '✗ ' + $('Errored ').red + '» '; string += $(obj.error).red.bold + '\n'; string += (obj.context ? ' in ' + $(obj.context).red + '\n': ''); string += ' in ' + $(obj.suite.subject).red + '\n'; string += ' in ' + $(obj.suite._filename).red; return string; }; this.contextText = function (event) { return ' ' + event; }; this.vowText = function (event) { var buffer = []; buffer.push(' ' + { honored: ' ✓ ', broken: ' ✗ ', errored: ' ✗ ', pending: ' - ' }[event.status] + this.stylize(event.title, ({ honored: 'green', broken: 'yellow', errored: 'red', pending: 'cyan' })[event.status])); if (event.status === 'broken') { buffer.push(' » ' + event.exception); } else if (event.status === 'errored') { if (event.exception.type === 'emitter') { buffer.push(' » ' + this.stylize("An unexpected error was caught: " + this.stylize(event.exception.error, 'bold'), 'red')); } else { buffer.push(' ' + this.stylize(event.exception, 'red')); } } return buffer.join('\n'); }; ������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows/context.js����������������������������������������������������������������������0000664�0000000�0000000�00000005276�13551431503�0016320�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ this.Context = function (vow, ctx, env) { var that = this; this.tests = vow.callback; this.topics = (ctx.topics || []).slice(0); this.emitter = null; this.env = env || {}; this.env.context = this; this.env.callback = function (/* arguments */) { var ctx = this; var args = Array.prototype.slice.call(arguments); var emit = (function (args) { // // Convert callback-style results into events. // if (vow.batch.suite.options.error) { return function () { var e = args.shift(); that.emitter.ctx = ctx; // We handle a special case, where the first argument is a // boolean, in which case we treat it as a result, and not // an error. This is useful for `path.exists` and other // functions like it, which only pass a single boolean // parameter instead of the more common (error, result) pair. if (typeof(e) === 'boolean' && args.length === 0) { that.emitter.emit.call(that.emitter, 'success', e); } else { if (e) { that.emitter.emit.apply(that.emitter, ['error', e].concat(args)) } else { that.emitter.emit.apply(that.emitter, ['success'].concat(args)) } } }; } else { return function () { that.emitter.ctx = ctx; that.emitter.emit.apply(that.emitter, ['success'].concat(args)); }; } })(args.slice(0)); // If `this.callback` is called synchronously, // the emitter will not have been set yet, // so we defer the emition, that way it'll behave // asynchronously. if (that.emitter) { emit() } else { process.nextTick(emit) } }; this.name = vow.description; // events is an alias for on if (this.name === 'events') { this.name = vow.description = 'on'; } // if this is a sub-event context AND it's context was an event, // then I must enforce event order. // this will not do a good job of handling pin-pong events if (this.name === 'on' && ctx.isEvent) { this.after = ctx.name; } if (ctx.name === 'on') { this.isEvent = true; this.event = this.name; this.after = ctx.after; } else { this.isEvent = false; this.event = 'success'; } this.title = [ ctx.title || '', vow.description || '' ].join(/^[#.:]/.test(vow.description) ? '' : ' ').trim(); }; ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows/coverage/�����������������������������������������������������������������������0000775�0000000�0000000�00000000000�13551431503�0016057�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows/coverage/file.js����������������������������������������������������������������0000664�0000000�0000000�00000001207�13551431503�0017334�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������ exports.coverage = function (filename, data) { var ret = { filename: filename, coverage: 0, hits: 0, misses: 0, sloc : 0 }; var source = data.source; ret.source = source.map(function (line, num) { num++; if (data[num] === 0) { ret.misses++; ret.sloc++; } else if (data[num] !== undefined) { ret.hits++; ret.sloc++; } return { line: line, coverage: (data[num] === undefined ? '' : data[num]) }; }); ret.coverage = (ret.hits / ret.sloc) * 100; return ret; };�����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows/coverage/fragments/�������������������������������������������������������������0000775�0000000�0000000�00000000000�13551431503�0020045�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows/coverage/fragments/coverage-foot.html�������������������������������������������0000664�0000000�0000000�00000000027�13551431503�0023472�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������</div> </body> </html> ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������vows-0.8.3/lib/vows/coverage/fragments/coverage-head.html�������������������������������������������0000664�0000000�0000000�00000040121�13551431503�0023423�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html> <html> <head> <title>Coverage
vows-0.8.3/lib/vows/coverage/report-html.js000066400000000000000000000117221355143150300206750ustar00rootroot00000000000000/** This software contains code adapted from Mocha (https://github.com/visionmedia/mocha) by TJ Holowaychuk and is used herein under the following MIT license: Copyright (c) 20011-2012 TJ Holowaychuk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var util = require('util'), path = require('path'), fs = require('fs'), file = require('./file'); this.name = 'coverage-report-html'; function getCoverageClass( data ) { var highCoverage= (data.coverage >= 80); var okCoverage= (!highCoverage && data.coverage >=60); var coverageClass= ''; if( highCoverage ) coverageClass= 'high'; else if( okCoverage) coverageClass= 'medium'; else coverageClass= 'low'; return coverageClass; } this.report = function (coverageMap) { var out, head, foot, files = [], summary = { hits: 0, misses: 0, sloc: 0 }; try { out = fs.openSync("coverage.html", "w"); head = fs.readFileSync(__dirname + "/fragments/coverage-head.html", "utf8"); foot = fs.readFileSync(__dirname + "/fragments/coverage-foot.html", "utf8"); } catch (error) { console.log("Error: Unable to write to file coverage.html"); return; } fs.writeSync(out, head); for (var filename in coverageMap) { if (coverageMap.hasOwnProperty(filename)) { var data = file.coverage(filename, coverageMap[filename]); data.filename = filename; files.push(data); summary.hits += data.hits; summary.misses += data.misses; summary.sloc += data.sloc; } } summary.coverage = ((summary.hits / summary.sloc) * 100).toFixed(1); fs.writeSync(out, '

Coverage

'); fs.writeSync(out, '
' + '
' + summary.hits + '
' + summary.misses + '
' + summary.sloc + '
' + summary.coverage.toFixed(1) + "%
"); files.forEach(function (data) { var coverageClass = getCoverageClass(data); fs.writeSync(out, '
'); fs.writeSync(out, '

' + data.filename + '

\n'); fs.writeSync(out, '
' + '
' + data.hits + '
' + data.misses + '
' + data.sloc + '
' + data.coverage.toFixed(1) + "%
"); fs.writeSync(out, ''); for (var i = 0, l = data.source.length; i < l; i++) { var line = data.source[i], klass = (line.coverage === 0 ? 'miss' : 'hit'); fs.writeSync(out, ''); } fs.writeSync(out, "
LineHitsSource
' + i + '' + line.coverage + '' + line.line + '
\n"); fs.writeSync(out, "
\n"); }); fs.writeSync(out, foot); fs.close(out); }; vows-0.8.3/lib/vows/coverage/report-json.js000066400000000000000000000027451355143150300207070ustar00rootroot00000000000000var util = require('util'), fs = require('fs'), file = require('./file'); this.name = 'coverage-report-json'; this.report = function (coverageMap) { var output = { meta: { "generator": "vowsjs", "generated": new Date().toString(), "instrumentation": "node-jscoverage", "file-version": "1.0" }, files: [ ], coverage: [ ] }; for (var filename in coverageMap) { if (coverageMap.hasOwnProperty(filename)) { var data = file.coverage(filename, coverageMap[filename]); var coverage = { file: filename, coverage: data.coverage.toFixed(2), hits: data.hits, misses: data.misses, sloc: data.sloc, source: { } }; for (var i = 0; i < data.source.length; i++) { coverage.source[i + 1] = { line: data.source[i].line, coverage: data.source[i].coverage }; } output.coverage.push(coverage); output.files.push(filename); } } try { out = fs.openSync("coverage.json", "w"); fs.writeSync(out, JSON.stringify(output)); fs.close(out); } catch (error) { console.log("Error: Unable to write to file coverage.json"); return; } }; vows-0.8.3/lib/vows/coverage/report-plain.js000066400000000000000000000017111355143150300210310ustar00rootroot00000000000000var util = require('util'), file = require('./file'); this.name = 'coverage-report-plain'; function lpad(str, width) { str = String(str); var n = width - str.length; if (n < 1) { return str; } while (n--) { str = ' ' + str; } return str; } this.report = function (coverageMap) { for (var filename in coverageMap) { if (coverageMap.hasOwnProperty(filename)) { var data = file.coverage(filename, coverageMap[filename]); console.log(filename + ":"); process.stdout.write("[ hits: " + data.hits + ", misses: " + data.misses); console.log(", sloc: " + data.sloc + ", coverage: " + data.coverage.toFixed(2) + "% ]"); for (var i = 0; i < data.source.length; i++) { console.log(lpad(data.source[i].coverage, 5) + " | " + data.source[i].line); } console.log(); } } }; vows-0.8.3/lib/vows/coverage/report-xml.js000066400000000000000000000054371355143150300205370ustar00rootroot00000000000000var fs = require('fs'), file = require('./file'); this.name = 'coverage-report-xml'; this.report = function (coverageMap) { var all = { xml: '', packages: 0, files: 0, lines: 0, hits: 0 }, data = {}; // group data by path for (var filename in coverageMap) { if (coverageMap.hasOwnProperty(filename)) { var pkg = (filename.indexOf('/') > 0) ? filename.substr(0, filename.lastIndexOf('/')) : filename; if (!data[pkg]) { data[pkg] = {}; } data[pkg][ (filename.indexOf('/')) ? filename.substr(filename.lastIndexOf('/') + 1, filename.length) : filename ] = file.coverage(filename, coverageMap[filename]); } } // generate groups xml-fragment for (var pkg in data) { if (data.hasOwnProperty(pkg)) { var pkgStat = { xml: '', files: 0, lines: 0, hits: 0 }; all.xml += '\t\n'; for (var filename in data[pkg]) { if (data[pkg].hasOwnProperty(filename)) { pkgStat.files += 1; pkgStat.lines += data[pkg][filename].sloc; pkgStat.hits += data[pkg][filename].hits; pkgStat.xml += '\t\t\n' + '\t\t\t\n' + '\t\t\n'; } } all.packages += 1; all.files += pkgStat.files; all.lines += pkgStat.lines; all.hits += pkgStat.hits; all.xml += '\t\t\n' + pkgStat.xml + '\t\n'; } } all.xml = '\n' + '\n\n' + '\t\n' + '\t\n' + '\t\n' + '\t\n' + '\t\n' + '\n\n' + '\n' + '\t\n' + all.xml + '\n\n\n'; fs.writeFileSync('coverage.xml', all.xml); }; vows-0.8.3/lib/vows/extras.js000066400000000000000000000016101355143150300161260ustar00rootroot00000000000000var events = require('events'); // // Wrap a Node.js style async function into an EventEmitter // this.prepare = function (obj, targets) { targets.forEach(function (target) { if (target in obj) { obj[target] = (function (fun) { return function () { var args = Array.prototype.slice.call(arguments); var ee = new(events.EventEmitter); args.push(function (err /* [, data] */) { var args = Array.prototype.slice.call(arguments, 1); if (err) { ee.emit.apply(ee, ['error', err].concat(args)) } else { ee.emit.apply(ee, ['success'].concat(args)) } }); fun.apply(obj, args); return ee; }; })(obj[target]); } }); return obj; }; vows-0.8.3/lib/vows/reporters/000077500000000000000000000000001355143150300163115ustar00rootroot00000000000000vows-0.8.3/lib/vows/reporters/dot-matrix.js000066400000000000000000000034721355143150300207450ustar00rootroot00000000000000var options = { tail: '' }, console = require('../../vows/console'), stylize = console.stylize, puts = console.puts(options); // // Console reporter // var messages = [], lastContext; this.name = 'dot-matrix'; this.setStream = function (s) { options.stream = s; }; this.reset = function () { messages = []; lastContext = null; }; this.report = function (data) { var event = data[1]; switch (data[0]) { case 'subject': // messages.push(stylize(event, 'underline') + '\n'); break; case 'context': break; case 'vow': if (event.status === 'honored') { puts(stylize('·', 'green')); } else if (event.status === 'pending') { puts(stylize('-', 'cyan')); } else { if (lastContext !== event.context) { lastContext = event.context; messages.push(' ' + event.context); } if (event.status === 'broken') { puts(stylize('✗', 'yellow')); messages.push(console.vowText(event)); } else if (event.status === 'errored') { puts(stylize('✗', 'red')); messages.push(console.vowText(event)); } messages.push(''); } break; case 'end': puts(' '); break; case 'finish': if (messages.length) { puts('\n\n' + messages.join('\n')); } else { puts(''); } puts(console.result(event).join('\n')); break; case 'error': puts(console.error(event)); break; } }; this.print = function (str) { puts(str); }; vows-0.8.3/lib/vows/reporters/json.js000066400000000000000000000013231355143150300176170ustar00rootroot00000000000000var options = { tail: '\n', raw: true }; var console = require('../../vows/console'); var puts = console.puts(options); // // Console JSON reporter // this.name = 'json'; this.setStream = function (s) { options.stream = s; }; function removeCircularSuite(obj, suite) { var result = {}; if (typeof obj !== 'object' || obj === null) return obj; Object.keys(obj).forEach(function(key) { if (obj[key] === suite) { result[key] = {}; } else { result[key] = removeCircularSuite(obj[key], suite || obj.suite); } }); return result; }; this.report = function (obj) { puts(JSON.stringify(removeCircularSuite(obj))); }; this.print = function (str) {}; vows-0.8.3/lib/vows/reporters/silent.js000066400000000000000000000003021355143150300201400ustar00rootroot00000000000000// // Silent reporter - "Shhh" // this.name = 'silent'; this.setStream = function () {}; this.reset = function () {}; this.report = function () {}; this.print = function () {}; vows-0.8.3/lib/vows/reporters/spec.js000066400000000000000000000016631355143150300176070ustar00rootroot00000000000000var util = require('util'); var options = { tail: '\n' }; var console = require('../../vows/console'); var stylize = console.stylize, puts = console.puts(options); // // Console reporter // this.name = 'spec'; this.setStream = function (s) { options.stream = s; }; this.report = function (data) { var event = data[1]; switch (data[0]) { case 'subject': puts('\n♢ ' + stylize(event, 'bold') + '\n'); break; case 'context': puts(console.contextText(event)); break; case 'vow': puts(console.vowText(event)); break; case 'end': this.print('\n'); break; case 'finish': puts(console.result(event).join('\n')); break; case 'error': puts(console.error(event)); break; } }; this.print = function (str) { process.stdout.write(str); }; vows-0.8.3/lib/vows/reporters/tap.js000066400000000000000000000047011355143150300174350ustar00rootroot00000000000000var options = { tail: "\n" }; var console = require("../console"); var stylize = console.stylize; var puts = console.puts(options); // // TAP Reporter // this.name = "tap"; this.setStream = function setStream(s) { options.stream = s; }; var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; var TapInterface = (function() { function TapInterface() { this.genOutput_ = __bind(this.genOutput_, this); this.testCount = __bind(this.testCount, this); this.bailOut = __bind(this.bailOut, this); this.skip = __bind(this.skip, this); this.notOk = __bind(this.notOk, this); this.ok = __bind(this.ok, this); this.count_ = 0; } TapInterface.prototype.ok = function(description) { return this.genOutput_("ok", ++this.count_, "- " + description); }; TapInterface.prototype.notOk = function(description) { return this.genOutput_("not ok", ++this.count_, "- " + description); }; TapInterface.prototype.skip = function(description) { return this.genOutput_("ok", ++this.count_, "# SKIP " + description); }; TapInterface.prototype.bailOut = function(reason) { return "Bail out!" + (reason !== null ? " " + reason : ""); }; TapInterface.prototype.testCount = function() { return "1.." + this.count_; }; TapInterface.prototype.genOutput_ = function(status, testNumber, description) { return "" + status + " " + testNumber + " " + description; }; return TapInterface; })(); var tap = new TapInterface(); this.report = function report(data) { var type = data[0]; var event = data[1]; switch (type) { case "subject": puts("# " + stylize(event, "bold")); break; case "context": puts("# " + event); break; case "vow": switch (event.status) { case "honored": puts(tap.ok(event.title)); break; case "pending": puts(tap.skip(event.title)); break; case "broken": puts(tap.notOk(event.title + "\n# " + event.exception)); break; case "errored": puts(tap.notOk(event.title)); puts(tap.bailOut(event.exception)); break; } break; case "end": puts("\n"); break; case "finish": puts(tap.testCount()); break; case "error": puts("#> Errored"); puts("# " + JSON.stringify(data)); break; } }; this.print = function print(str) { require("util").print(str); }; vows-0.8.3/lib/vows/reporters/watch.js000066400000000000000000000016501355143150300177570ustar00rootroot00000000000000var options = {}; var console = require('../../vows/console'); var spec = require('../../vows/reporters/spec'); var stylize = console.stylize, puts = console.puts(options); // // Console reporter // var lastContext; this.name = 'watch'; this.setStream = function (s) { options.stream = s; }; this.reset = function () { lastContext = null; }; this.report = function (data) { var event = data[1]; switch (data[0]) { case 'vow': if (['honored', 'pending'].indexOf(event.status) === -1) { if (lastContext !== event.context) { lastContext = event.context; puts(console.contextText(event.context)); } puts(console.vowText(event)); puts(''); } break; case 'error': puts(console.error(event)); break; } }; this.print = function (str) {}; vows-0.8.3/lib/vows/reporters/xunit.js000066400000000000000000000057061355143150300200260ustar00rootroot00000000000000// xunit outoput for vows, so we can run things under hudson // // The translation to xunit is simple. Most likely more tags/attributes can be // added, see: http://ant.1045680.n5.nabble.com/schema-for-junit-xml-output-td1375274.html // var options = { tail: '\n', raw: true }; var console = require('../../vows/console'); var puts = console.puts(options); var buffer = [], curSubject = null; function xmlEnc(value) { return !value ? value : String(value).replace(/&/g, "&") .replace(/>/g, ">") .replace(/'; } function cdata(data) { return ''; } this.name = 'xunit'; this.setStream = function (s) { options.stream = s; }; this.report = function (data) { var event = data[1]; switch (data[0]) { case 'subject': curSubject = event; break; case 'context': break; case 'vow': switch (event.status) { case 'honored': buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, true)); break; case 'broken': var err = tag('error', {type: 'vows.event.broken', message: 'Broken test'}, false, cdata(event.exception)); buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, false, err)); break; case 'errored': var skip = tag('skipped', {type: 'vows.event.errored', message: 'Errored test'}, false, cdata(event.exception)); buffer.push(tag('testcase', {classname: curSubject, name: event.context + ': ' + event.title}, false, skip)); break; case 'pending': // nop break; } break; case 'end': buffer.push(end('testcase')); break; case 'finish': 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})); buffer.push(end('testsuite')); puts(buffer.join('\n')); break; case 'error': break; } }; this.print = function (str) { }; vows-0.8.3/lib/vows/suite.js000066400000000000000000000333771355143150300157700ustar00rootroot00000000000000var events = require('events'), path = require('path'); var vows = require('../vows'); var Context = require('../vows/context').Context; this.Suite = function (subject) { this.subject = subject; this.matcher = /.*/; this.reporter = require('./reporters/dot-matrix'); this.batches = []; this.options = { error: true }; this.reset(); }; this.Suite.prototype = new(function () { this.reset = function () { this.results = { honored: 0, broken: 0, errored: 0, pending: 0, total: 0, time: null }; this.batches.forEach(function (b) { b.lastContext = null; b.remaining = b._remaining; b.honored = b.broken = b.errored = b.total = b.pending = 0; b.vows.forEach(function (vow) { vow.status = null }); b.teardowns = []; }); }; this.addBatch = function (tests) { this.batches.push({ tests: tests, suite: this, vows: [], remaining: 0, _remaining: 0, honored: 0, broken: 0, errored: 0, pending: 0, total: 0, teardowns: [] }); return this; }; this.addVows = this.addBatch; this.parseBatch = function (batch, matcher) { var tests = batch.tests; if ('topic' in tests) { throw new(Error)("missing top-level context."); } // Count the number of vows/emitters expected to fire, // so we know when the tests are over. // We match the keys against `matcher`, to decide // whether or not they should be included in the test. // Any key, including assertion function keys can be matched. // If a child matches, then the n parent topics must not be skipped. (function count(tests, _match) { var match = false; var keys = Object.keys(tests).filter(function (k) { return k !== 'topic' && k !== 'teardown'; }); for (var i = 0, key; i < keys.length; i++) { key = keys[i]; // If the parent node, or this one matches. match = _match || matcher.test(key); if (typeof(tests[key]) === 'object') { match = count(tests[key], match); } else { if (typeof(tests[key]) === 'string') { tests[key] = new(String)(tests[key]); } if (! match) { tests[key]._skip = true; } } } // If any of the children matched, // don't skip this node. for (var i = 0; i < keys.length; i++) { if (! tests[keys[i]]._skip) { match = true } } if (match) { batch.remaining ++ } else { tests._skip = true } return match; })(tests, false); batch._remaining = batch.remaining; }; this.runBatch = function (batch) { var topic, tests = batch.tests, emitter = batch.emitter = new(events.EventEmitter); var that = this; batch.status = 'begin'; // The test runner, it calls itself recursively, passing the // previous context to the inner contexts. This is so the `topic` // functions have access to all the previous context topics in their // arguments list. // It is defined and invoked at the same time. // If it encounters a `topic` function, it waits for the returned // emitter to emit (the topic), at which point it runs the functions under it, // passing the topic as an argument. (function run(ctx, lastTopic) { var old = false; topic = ctx.tests.topic; if (typeof(topic) === 'function') { if (ctx.isEvent || ctx.name === 'on') { throw new Error('Event context cannot contain a topic'); } // Run the topic, passing the previous context topics try { topic = topic.apply(ctx.env, ctx.topics); } // If an unexpected error occurs in the topic, set the return // value to 'undefined' and call back with the error catch (ex) { ctx.env.callback(ex); topic = undefined; } if (typeof(topic) === 'undefined') { ctx._callback = true } } // If this context has a topic, store it in `lastTopic`, // if not, use the last topic, passed down by a parent // context. if (typeof(topic) !== 'undefined' || ctx._callback) { lastTopic = topic; } else { old = true; topic = lastTopic; } // If the topic doesn't return an event emitter (such as an EventEmitter), // we create it ourselves, and emit the value on the next tick. if (! (topic && topic.constructor === events.EventEmitter)) { // If the context is a traditional vow, then a topic can ONLY // be an EventEmitter. However if the context is a sub-event // then the topic may be an instanceof EventEmitter if (!ctx.isEvent || (ctx.isEvent && !(topic instanceof events.EventEmitter))) { ctx.emitter = new(events.EventEmitter); if (! ctx._callback) { process.nextTick(function (val) { return function () { ctx.emitter.emit("success", val) }; }(topic)); } // if I have a callback, push the new topic back up to // lastTopic if (ctx._callback) { lastTopic = topic = ctx.emitter; } else { topic = ctx.emitter; } } } topic.on(ctx.event, function (val) { // Once the topic fires, add the return value // to the beginning of the topics list, so it // becomes the first argument for the next topic. // If we're using the parent topic, no need to // prepend it to the topics list, or we'll get // duplicates. if (!old || ctx.isEvent) { Array.prototype.unshift.apply(ctx.topics, arguments) }; }); if (topic.setMaxListeners) { topic.setMaxListeners(Infinity) } // Now run the tests, or sub-contexts Object.keys(ctx.tests).filter(function (k) { return ctx.tests[k] && k !== 'topic' && k !== 'teardown' && !ctx.tests[k]._skip; }).forEach(function (item) { // Create a new evaluation context, // inheriting from the parent one. var env = Object.create(ctx.env); env.suite = that; // Holds the current test or context var vow = Object.create({ callback: ctx.tests[item], context: ctx.title, description: item, binding: ctx.env, status: null, batch: batch }); // If we encounter a function, add it to the callbacks // of the `topic` function, so it'll get called once the // topic fires. // If we encounter an object literal, we recurse, sending it // our current context. if ((typeof(vow.callback) === 'function') || (vow.callback instanceof String)) { topic.addVow(vow); } else if (typeof(vow.callback) === 'object') { // If there's a setup stage, we have to wait for it to fire, // before calling the inner context. // If the event has already fired, the context is 'on' or // there is no setup stage, just run the inner context // synchronously. if (topic && ctx.name !== 'on' && (!topic._vowsEmitedEvents || !topic._vowsEmitedEvents.hasOwnProperty(ctx.event))) { var runInnerContext = function(ctx){ return function(val){ return run(new (Context)(vow, ctx, env), lastTopic); }; }(ctx); topic.on(ctx.event, runInnerContext); // Run an inner context if the outer context fails, too. topic.on('error', runInnerContext); } else { run(new (Context)(vow, ctx, env), lastTopic); } } }); // Teardown if (ctx.tests.teardown) { batch.teardowns.push(ctx); } if (! ctx.tests._skip) { batch.remaining --; } // Check if we're done running the tests exports.tryEnd(batch); // This is our initial, empty context })(new(Context)({ callback: tests, context: null, description: null }, {})); return emitter; }; this.report = function () { return this.reporter.report.apply(this.reporter, arguments); }; this.run = function (options, callback) { var that = this, start; options = options || {}; Object.keys(options).forEach(function (k) { that.options[k] = options[k]; }); this.matcher = this.options.matcher || this.matcher; if (options.reporter) { try { this.reporter = typeof options.reporter === 'string' ? require('./reporters/' + options.reporter) : options.reporter; } catch (e) { console.log('Reporter was not found, defaulting to dot-matrix.'); } } this.batches.forEach(function (batch) { that.parseBatch(batch, that.matcher); }); this.reset(); start = new(Date); if (this.batches.filter(function (b) { return b.remaining > 0 }).length) { this.report(['subject', this.subject]); } return (function run(batches) { var batch = batches.shift(); if (batch) { // If the batch has no vows to run, // go to the next one. if (batch.remaining === 0) { run(batches); } else { that.runBatch(batch).on('end', function () { run(batches); }); } } else { that.results.time = (new(Date) - start) / 1000; that.report(['finish', that.results]); if (callback) { callback(that.results) } if (that.results.honored + that.results.pending === that.results.total) { return 0; } else { return 1; } } })(this.batches.slice(0)); }; this.runParallel = function () {}; this.export = function (module, options) { var that = this; Object.keys(options || {}).forEach(function (k) { that.options[k] = options[k]; }); if (require.main === module) { return this.run(); } else { return module.exports[this.subject] = this; } }; this.exportTo = function (module, options) { // Alias, for JSLint return this.export(module, options); }; }); // // Checks if all the tests in the batch have been run, // and triggers the next batch (if any), by emitting the 'end' event. // this.tryEnd = function (batch) { var result, style, time; if (batch.honored + batch.broken + batch.errored + batch.pending === batch.total && batch.remaining === 0) { Object.keys(batch).forEach(function (k) { (k in batch.suite.results) && (batch.suite.results[k] += batch[k]); }); if (batch.teardowns) { for (var i = batch.teardowns.length - 1, ctx; i >= 0; i--) { runTeardown(batch.teardowns[i]); } maybeFinish(); } function runTeardown(teardown) { var env = Object.create(teardown.env); Object.defineProperty(env, "callback", { get: function () { teardown.awaitingCallback = true; return function () { teardown.awaitingCallback = false; maybeFinish(); }; } }); teardown.tests.teardown.apply(env, teardown.topics); } function maybeFinish() { var pending = batch.teardowns.filter(function (teardown) { return teardown.awaitingCallback; }); if (pending.length === 0) { finish(); } } function finish() { batch.status = 'end'; batch.suite.report(['end']); batch.emitter.emit('end', batch.honored, batch.broken, batch.errored, batch.pending); } } }; vows-0.8.3/package.json000066400000000000000000000015651355143150300150150ustar00rootroot00000000000000{ "name": "vows", "version": "0.8.3", "description": "Asynchronous BDD & continuous integration for node.js", "url": "http://vowsjs.org", "keywords": [ "testing", "spec", "test", "BDD" ], "author": "Alexis Sellier ", "contributors": [ "Charlie Robbins ", "Jerry Sievert " ], "dependencies": { "diff": "^4.0.1", "eyes": "~0.1.6", "glob": "^7.1.2" }, "main": "./lib/vows", "repository": { "type": "git", "url": "https://github.com/cloudhead/vows.git" }, "bin": { "vows": "./bin/vows" }, "directories": { "test": "test" }, "scripts": { "test": "node ./bin/vows --spec" }, "bugs": { "url": "https://github.com/cloudhead/vows/issues" }, "homepage": "https://github.com/cloudhead/vows", "license": "MIT" } vows-0.8.3/test/000077500000000000000000000000001355143150300134775ustar00rootroot00000000000000vows-0.8.3/test/VowsCamelCaseTest.js000066400000000000000000000004651355143150300173760ustar00rootroot00000000000000var vows = require('../lib/vows'), assert = require('assert'); vows.describe("Vows test file with camel case").addBatch({ "The test file": { topic: function () { return { flag: true }; }, "is run": function (topic) { assert.isTrue(topic.flag); } } }).export(module); vows-0.8.3/test/assert-test.js000066400000000000000000000151471355143150300163230ustar00rootroot00000000000000var vows = require('../lib/vows'); var assert = require('assert'); vows.describe('vows/assert').addBatch({ "The Assertion module": { "`equal`": function () { assert.equal("hello world", "hello world"); assert.equal(1, true); }, "`epsilon`": function() { assertNoArguments(assert.epsilon); assert.epsilon(1e-5, 0.1+0.2, 0.3); assert.throws(function() { assert.epsilon(1e-5, NaN, 0.3); }); assert.throws(function() { assert.epsilon(NaN, 1.0, 1.0); }); }, "`match`": function () { assertNoArguments(assert.match); assert.match("hello world", /^[a-z]+ [a-z]+$/); }, "`lengthOf`": function () { assertNoArguments(assert.lengthOf); assert.lengthOf("hello world", 11); assert.lengthOf([1, 2, 3], 3); assert.lengthOf({goo: true, gies: false}, 2); }, "`isDefined`": function () { assertNoArguments(assert.isDefined); assert.isDefined(null); assertError(assert.isDefined, undefined); }, "`include`": function () { assertNoArguments(assert.include); assert.include("hello world", "world"); assert.include([0, 42, 0], 42); assert.include({goo:true}, 'goo'); }, "`deepInclude`": function () { assertNoArguments(assert.deepInclude); assert.deepInclude([{a:'b'},{c:'d'}], {a:'b'}); assert.deepInclude("hello world", "world"); assert.deepInclude({goo:true}, 'goo'); }, "`typeOf`": function () { assertNoArguments(assert.typeOf); assert.typeOf('goo', 'string'); assert.typeOf(42, 'number'); assert.typeOf([], 'array'); assert.typeOf({}, 'object'); assert.typeOf(false, 'boolean'); }, "`instanceOf`": function () { assertNoArguments(assert.instanceOf); assert.instanceOf([], Array); assert.instanceOf(function () {}, Function); }, "`isArray`": function () { assertNoArguments(assert.isArray); assert.isArray([]); assertError(assert.isArray, {}); }, "`isString`": function () { assertNoArguments(assert.isString); assert.isString(""); }, "`isObject`": function () { assertNoArguments(assert.isObject); assert.isObject({}); assertError(assert.isObject, []); }, "`isNumber`": function () { assertNoArguments(assert.isNumber); assert.isNumber(0); }, "`isBoolean`": function (){ assertNoArguments(assert.isBoolean); assert.isBoolean(true); assert.isBoolean(false); assertError(assert.isBoolean, 0); }, "`isNan`": function () { assertNoArguments(assert.isNaN); assert.isNaN(0/0); }, "`isTrue`": function () { assertNoArguments(assert.isTrue); assert.isTrue(true); assertError(assert.isTrue, 1); }, "`isFalse`": function () { assertNoArguments(assert.isFalse); assert.isFalse(false); assertError(assert.isFalse, 0); }, "`isZero`": function () { assertNoArguments(assert.isZero); assert.isZero(0); assertError(assert.isZero, null); }, "`isNotZero`": function () { assertNoArguments(assert.isNotZero); assert.isNotZero(1); }, "`isUndefined`": function () { assertNoArguments(assert.isUndefined); assert.isUndefined(undefined); assertError(assert.isUndefined, null); }, "`isNull`": function () { assertNoArguments(assert.isNull); assert.isNull(null); assertError(assert.isNull, 0); assertError(assert.isNull, undefined); }, "`isNotNull`": function () { assertNoArguments(assert.isNotNull); assert.isNotNull(0); }, "`greater` and `lesser`": function () { assertNoArguments(assert.greater); assertNoArguments(assert.lesser); assert.greater(5, 4); assert.lesser(4, 5); }, "`inDelta`": function () { assertNoArguments(assert.inDelta); assert.inDelta(42, 40, 5); assert.inDelta(42, 40, 2); assert.inDelta(42, 42, 0); assert.inDelta(3.1, 3.0, 0.2); assertError(assert.inDelta, [42, 40, 1]); }, "`isEmpty`": function () { assertNoArguments(assert.isEmpty); assert.isEmpty({}); assert.isEmpty([]); assert.isEmpty(""); }, "`isNotEmpty`": function () { assertNoArguments(assert.isNotEmpty); assert.isNotEmpty({goo:true}); assert.isNotEmpty([1]); assert.isNotEmpty(" "); assertError(assert.isNotEmpty, {}); assertError(assert.isNotEmpty, []); assertError(assert.isNotEmpty, ""); }, "`notIncludes`": function () { assert.notIncludes([1, 2, 3], 4); assert.notIncludes({"red": 1, "blue": 2}, "green"); } }, 'An AssertionError': { topic: function generateAssertionError() { try { assert.isFalse(true); } catch (e) { return e.toStringEx(); } }, 'should have full path in stack trace': function(topic) { var regexp = new RegExp("// " + __filename + ":\\d+"); assert.isTrue(regexp.test(topic)); } }, }).export(module); function assertError(assertion, args, fail) { if (!Array.isArray(args)) { args = [args]; } try { assertion.apply(null, args); fail = true; } catch (e) {/* Success */} if (fail) { assert.fail( args.join(' '), assert.AssertionError, "expected an AssertionError for {actual}", "assertError", assertError ); } } function assertNoArguments(assertion) { var fail; try { assertion.apply(null, []); fail = true; } catch (e) {/* Success */} if (fail) { assert.fail( "", assert.AssertionError, "expected an AssertionError for missing argument(s)", "assertError", assertError ); } } vows-0.8.3/test/c-test.js000066400000000000000000000004631355143150300152370ustar00rootroot00000000000000var vows = require('../lib/vows'), assert = require('assert'); vows.describe("Vows test file starts with c").addBatch({ "The test file": { topic: function () { return { flag: true }; }, "is run": function (topic) { assert.isTrue(topic.flag); } } }).export(module); vows-0.8.3/test/experimental/000077500000000000000000000000001355143150300161745ustar00rootroot00000000000000vows-0.8.3/test/experimental/gh-325.js000066400000000000000000000011031355143150300174320ustar00rootroot00000000000000var vows = require('./'), assert = require('assert'); vows.describe('basic-formulation').addBatch({ "An invocation with no query string": { topic: function() { request.get("http://localhost:8080/something", this.callback); }, "does not fail": function(error, response, body) { assert.notEqual(true, error); }, "receives a response": { "with status 200": function(error, response, body) { assert.equal(200, response.statusCode); } } } }).export(module);vows-0.8.3/test/fixtures/000077500000000000000000000000001355143150300153505ustar00rootroot00000000000000vows-0.8.3/test/fixtures/isolate/000077500000000000000000000000001355143150300170105ustar00rootroot00000000000000vows-0.8.3/test/fixtures/isolate/failing.js000066400000000000000000000006461355143150300207650ustar00rootroot00000000000000var vows = require('../../../lib/vows'), assert = require('assert'); var obvious; vows.describe('failing').addBatch({ 'Obvious test': obvious = { topic: function () { this.callback(null, false); }, 'should work': function (result) { assert.ok(result); } // but it won't }, 'Obvious test #2': obvious, 'Obvious test #3': obvious, 'Obvious test #4': obvious }).export(module); vows-0.8.3/test/fixtures/isolate/log.js000066400000000000000000000006551355143150300201350ustar00rootroot00000000000000var vows = require('../../../lib/vows'), assert = require('assert'); var obvious; vows.describe('stderr').addBatch({ 'Obvious test': obvious = { topic: function () { this.callback(null, true); }, 'should work': function (result) { console.log('oh no!'); assert.ok(result); } }, 'Obvious test #2': obvious, 'Obvious test #3': obvious, 'Obvious test #4': obvious }).export(module); vows-0.8.3/test/fixtures/isolate/passing.js000066400000000000000000000006211355143150300210110ustar00rootroot00000000000000var vows = require('../../../lib/vows'), assert = require('assert'); var obvious; vows.describe('passing').addBatch({ 'Obvious test': obvious = { topic: function () { this.callback(null, true); }, 'should work': function (result) { assert.ok(result); } }, 'Obvious test #2': obvious, 'Obvious test #3': obvious, 'Obvious test #4': obvious }).export(module); vows-0.8.3/test/fixtures/isolate/stderr.js000066400000000000000000000006571355143150300206610ustar00rootroot00000000000000var vows = require('../../../lib/vows'), assert = require('assert'); var obvious; vows.describe('stderr').addBatch({ 'Obvious test': obvious = { topic: function () { this.callback(null, true); }, 'should work': function (result) { console.error('oh no!'); assert.ok(result); } }, 'Obvious test #2': obvious, 'Obvious test #3': obvious, 'Obvious test #4': obvious }).export(module); vows-0.8.3/test/fixtures/supress-stdout/000077500000000000000000000000001355143150300203745ustar00rootroot00000000000000vows-0.8.3/test/fixtures/supress-stdout/output.js000066400000000000000000000005231355143150300222720ustar00rootroot00000000000000var vows = require('../../../lib/vows'), assert = require('assert'); vows.describe('output').addBatch({ 'outputting': { topic: function () { console.log('goo'); this.callback(null, true); }, 'should work': function (result) { console.log('goo'); assert.ok(result); } }, }).export(module); vows-0.8.3/test/isolate-test.js000066400000000000000000000100151355143150300164470ustar00rootroot00000000000000var vows = require('../lib/vows'), assert = require('assert'), path = require('path'), os = require('os'), exec = require('child_process').exec; function generateTopic(args, file) { return function () { var cmd = '"' + process.execPath + '"' + ' ./bin/vows' + ' -i ' + (args || '') + ' ./test/fixtures/isolate/' + file, options = {cwd: path.resolve(__dirname + '/../')}, callback = this.callback; exec(cmd, options, function (err, stdout, stderr) { callback(null, { err: err, stdout: stdout, stderr: stderr }); }); } } function assertExecOk(r) { assert.isNull(r.err); } function assertExecNotOk(r) { assert.isNotNull(r.err); } function parseResults(stdout) { var results = stdout.split('\n'); // win32 may console.log data which need to filter out invalid JSON at start of results //TODO: do we need to filter out any console.log data as we are expecting only valid json // any console.log used for dedugging may break parseResults if(process.platform === 'win32') { while(results.length > 0 && results[0].charAt(0) !== '{') { results.shift(); } } return results.map(function (s) { if (!s) return; return JSON.parse(s); }).filter(function (s) {return s}); } function assertResultTypePresent(results, type) { assert.ok(results.some(function (result) { return result[0] == type; })); } function assertResultsFinish(results, expected) { var finish = results[results.length - 1]; assert.equal(finish[0], 'finish'); finish = finish[1]; Object.keys(expected).forEach(function (key) { assert.equal(finish[key], expected[key]); }); } vows.describe('vows/isolate').addBatch({ 'Running vows with -i flag for test/fixtures/isolate/': { 'passing.js': { 'with default reporter': { topic: generateTopic(null, 'passing.js'), 'should be ok': assertExecOk }, 'with json reporter': { topic: generateTopic('--json', 'passing.js'), 'should be ok': assertExecOk, 'should have correct output': function (r) { var results = parseResults(r.stdout) assertResultTypePresent(results, 'subject'); assertResultTypePresent(results, 'end'); assertResultsFinish(results, { total: 4, honored: 4 }); } } }, 'failing.js': { 'with json reporter': { topic: generateTopic('--json', 'failing.js'), 'should be not ok': assertExecNotOk, 'should have correct output though': function (r) { var results = parseResults(r.stdout); assertResultsFinish(results, { total: 4, broken: 4 }); } } }, 'stderr.js': { 'with json reporter': { topic: generateTopic('--json', 'stderr.js'), 'should be ok': assertExecOk, 'should have stderr': function (r) { assert.equal(r.stderr, ['oh no!', 'oh no!', 'oh no!', 'oh no!', ''].join('\n')); }, 'should have correct output': function (r) { var results= parseResults(r.stdout); assertResultsFinish(results, { total: 4, honored: 4 }); } } }, 'log.js': { 'with json reporter': { topic: generateTopic('--json', 'log.js'), 'should be ok': assertExecOk, 'should have correct output': function (r) { var results= parseResults(r.stdout); assertResultsFinish(results, { total: 4, honored: 4 }); } } }, 'all tests (*)': { 'with json reporter': { topic: generateTopic('--json', '*'), 'should be not ok': assertExecNotOk, 'should have correct output': function (r) { var results= parseResults(r.stdout); assertResultsFinish(results, { total: 16, broken: 4, honored: 12 }); } } } } }).export(module); vows-0.8.3/test/reporters/000077500000000000000000000000001355143150300155245ustar00rootroot00000000000000vows-0.8.3/test/reporters/reporters-test.js000066400000000000000000000012361355143150300210660ustar00rootroot00000000000000var fs = require('fs'); var path = require('path'); var vows = require('../../lib/vows'); var assert = require('assert'); var reporterPath = path.join(__dirname, '..', '..', 'lib', 'vows', 'reporters') var reporters = fs.readdirSync(reporterPath).reduce(function (acc, name) { acc[name] = require(path.join(reporterPath, name)); return acc; }, {}) vows.describe('vows/reporters').addBatch( Object.keys(reporters).reduce(function (acc, name) { acc[name] = { topic: reporters[name], 'should have the setStream() method': function (reporter) { assert.isFunction(reporter.setStream); } }; return acc; }, {}) ).export(module);vows-0.8.3/test/supress-stdout-test.js000066400000000000000000000030161355143150300200360ustar00rootroot00000000000000var assert = require('assert'), path = require('path'), vows = require('../lib/vows'), exec = require('child_process').exec; function generateTopic(supress) { return function () { var cmd = '"' + process.execPath + '"' + ' ./bin/vows ' + (supress ? '--supress-stdout ' : '') + './test/fixtures/supress-stdout/output.js', options = {cwd: path.resolve(__dirname + '/../')}, callback = this.callback; exec(cmd, options, function (err, stdout) { callback(null, {err: err, stdout: stdout}); }); }; } vows.describe('vows/supress-stdout').addBatch({ 'Running vows for test/fixtures/supress-stdout/output.js': { 'with --supress-stdout flag': { topic: generateTopic(true), 'should be ok': function (result) { assert.isNull(result.err); }, 'should not contain output from stdout': function (result) { assert.equal(result.stdout.toString().indexOf('goo'), -1); // console.log output? // nope, just Chuck Testa! } }, 'without --supress-stdout flag': { topic: generateTopic(), 'should be ok': function (result) { assert.isNull(result.err); }, 'should contain output from stdout': function (result) { assert.notEqual(result.stdout.toString().indexOf('goo'), -1); } } } }).export(module); vows-0.8.3/test/vows-error-test.js000066400000000000000000000075641355143150300171530ustar00rootroot00000000000000var path = require('path'), events = require('events'), assert = require('assert'), fs = require('fs'), vows = require('../lib/vows'), silent = require('../lib/vows/reporters/silent'); function doSomethingAsync(callback) { var err = null; var testValue = 'a'; process.nextTick(function() { callback(err, testValue); }); } function doSomethingAsyncWithError(callback) { var err = true; var testValue = 'a'; process.nextTick(function() { callback(err, testValue); }); } vows.describe('vows/error').addBatch({ 'Generate success response to async function': { topic: function() { doSomethingAsync(this.callback) }, 'Validate success': function(err, testValue) { assert.ok(!err); }, 'Validate testValue': function(err, testValue) { assert.equal(testValue, 'a'); } }, 'Generate error response to async function': { topic: function() { doSomethingAsyncWithError(this.callback) }, 'Validate error': function(err, testValue) { assert.ok(err); }, 'Validate testValue': function(err, testValue) { // This assertion fails. It shouldn't. assert.equal(testValue, 'a'); } } }).export(module) vows.describe('Error Handling').addBatch({ "A topic with a function that errors": { topic: function() { throw("Something wrong here"); }, "should return an error to a vow with two parameters": function(e, data) { assert.equal(e, "Something wrong here"); } }, "A topic with a built-in error": { topic: function() { bad.bad; }, "should return an error to a vow with two parameters": function(e, data) { assert(e instanceof Error, "Return value " + e + " wasn't an Error."); } }, "The previous two topics run in their own suite," : { "connected to two vows expecting one argument each" : { topic: function(){ vows.describe().addBatch({ "A topic with a function that errors": { topic: function() { throw("Something wrong here"); }, "should record the error in the test results" : function(data) { assert.ok(!data); } //» An unexpected error was caught: "Something wrong here" }, "A topic with a built-in error": { topic: function() { bad.bad; }, "should record the error in the test results" : function(data) { assert.ok(!data); } //» An unexpected error was caught: ReferenceError: bad is not defined } }).run({reporter : silent}, this.callback); }, "should have an errored count of two" : function(results, unused) { assert.equal(results.errored, 2); }, "should have a total count of two" : function(results, unused) { assert.equal(results.total, 2); }, "should have an honored count of zero" : function(results, unused){ assert.equal(results.honored, 0); } } }, "A topic with an error in it" : { topic : function(){ throw('awesome'); }, "should error" : function(error, result){ assert.equal(error, 'awesome'); }, "containing a subtopic" : { topic : function(){ return 52; }, "should reach a vow in the subtopic" : function(){ } } } }).export(module); vows-0.8.3/test/vows-test.js000066400000000000000000000527561355143150300160270ustar00rootroot00000000000000var path = require('path'), events = require('events'), assert = require('assert'), fs = require('fs'), vows = require('../lib/vows'); var api = vows.prepare({ get: function (id, callback) { process.nextTick(function () { callback(null, id) }); }, version: function () { return '1.0' } }, ['get']); var emitNextTick = function (val) { return function () { var emitter = new(events.EventEmitter); process.nextTick(function () { emitter.emit('success', val) }); return emitter; } }; vows.describe("Vows").addBatch({ "A context": { topic: emitNextTick("hello world"), "with a nested context": { topic: function (parent) { this.state = 42; return emitNextTick(parent)(); }, "has access to the environment": function () { assert.equal(this.state, 42); }, "and a sub nested context": { topic: function () { return this.state; }, "has access to the parent environment": function (r) { assert.equal(r, 42); assert.equal(this.state, 42); }, "has access to the parent context object": function (r) { assert.ok(Array.isArray(this.context.topics)); assert.include(this.context.topics, "hello world"); } } } }, "A nested context": { topic: emitNextTick(1), ".": { topic: function (a) { return emitNextTick(2)() }, ".": { topic: function (b, a) { return emitNextTick(3)() }, ".": { topic: function (c, b, a) { return emitNextTick([4, c, b, a])() }, "should have access to the parent topics": function (topics) { assert.equal(topics.join(), [4, 3, 2, 1].join()); } }, "from": { topic: function (c, b, a) { return emitNextTick([4, c, b, a])() }, "the parent topics": function(topics) { assert.equal(topics.join(), [4, 3, 2, 1].join()); } } } } }, "Nested contexts with callback-style async": { topic: function () { fs.stat(__dirname + '/vows-test.js', this.callback); }, 'after a successful `fs.stat`': { topic: function (stat) { fs.open(__dirname + '/vows-test.js', "r", stat.mode, this.callback); }, 'after a successful `fs.open`': { topic: function (fd, stat) { var buf = new Buffer(stat.size); fs.read(fd, buf, 0, stat.size, null, this.callback); }, 'after a successful `fs.read`': function (err, bytesRead, buf) { assert.ifError(err); assert.isNumber(bytesRead); assert.isObject(buf); assert.instanceOf(buf, Buffer); var data = buf.toString('utf8'); assert.match (data, /after a successful `fs.read`/); } } } }, "A nested context with no topics": { topic: 45, ".": { ".": { "should pass the value down": function (topic) { assert.equal(topic, 45); } } } }, "A Nested context with topic gaps": { topic: 45, ".": { ".": { topic: 101, ".": { ".": { topic: function (prev, prev2) { return this.context.topics.slice(0); }, "should pass the topics down": function (topics) { assert.lengthOf(topics, 2); assert.equal(topics[0], 101); assert.equal(topics[1], 45); } } } } } }, "A non-EventEmitter return value": { topic: function () { return 1 }, "should be converted to a vow": function (val) { assert.equal(val, 1); } }, "A 'prepared' interface": { "with a wrapped function": { topic: function () { return api.get(42) }, "should work as expected": function (val) { assert.equal(val, 42); } }, "with a non-wrapped function": { topic: function () { return api.version() }, "should work as expected": function (val) { assert.equal(val, '1.0'); } } }, "A non-function topic": { topic: 45, "should work as expected": function (topic) { assert.equal(topic, 45); } }, "A non-function topic with a falsy value": { topic: 0, "should work as expected": function (topic) { assert.equal(topic, 0); } }, "A topic returning a function": { topic: function () { return function () { return 42 }; }, "should work as expected": function (topic) { assert.isFunction(topic); assert.equal(topic(), 42); }, "in a sub-context": { "should work as expected": function (topic) { assert.isFunction(topic); assert.equal(topic(), 42); } } }, "A topic emitting an error": { topic: function () { var emitter = new(events.EventEmitter); process.nextTick(function () { emitter.emit("error", 404); }); return emitter; }, "shouldn't raise an exception if the test expects it": function (e, res) { assert.equal(e, 404); assert.ok(! res); } }, "A topic not emitting an error": { topic: function () { var emitter = new(events.EventEmitter); process.nextTick(function () { emitter.emit("success", true); }); return emitter; }, "should pass `null` as first argument, if the test is expecting an error": function (e, res) { assert.strictEqual(e, null); assert.equal(res, true); }, "should pass the result as first argument if the test isn't expecting an error": function (res) { assert.equal(res, true); } }, "A topic with callback-style async": { "when successful": { topic: function () { var that = this; process.nextTick(function () { that.callback(null, "OK"); }); }, "should work like an event-emitter": function (res) { assert.equal(res, "OK"); }, "should assign `null` to the error argument": function (e, res) { assert.strictEqual(e, null); assert.equal(res, "OK"); } }, "when unsuccessful": { topic: function () { function async(callback) { process.nextTick(function () { callback("ERROR"); }); } async(this.callback); }, "should have a non-null error value": function (e, res) { assert.equal(e, "ERROR"); }, "should work like an event-emitter": function (e, res) { assert.equal(res, undefined); } }, "using this.callback synchronously": { topic: function () { this.callback(null, 'hello'); }, "should work the same as returning a value": function (res) { assert.equal(res, 'hello'); } }, "using this.callback with a user context": { topic: function () { this.callback.call({ boo: true }, null, 'hello'); }, "should give access to the user context": function (res) { assert.isTrue(this.boo); } }, "passing this.callback to a function": { topic: function () { this.boo = true; var async = function (callback) { callback(null); }; async(this.callback); }, "should give access to the topic context": function () { assert.isTrue(this.boo); } }, "with multiple arguments": { topic: function () { this.callback(null, 1, 2, 3); }, "should pass them to the vow": function (e, a, b, c) { assert.strictEqual(e, null); assert.strictEqual(a, 1); assert.strictEqual(b, 2); assert.strictEqual(c, 3); }, "and a sub-topic": { topic: function (a, b, c) { return [a, b, c]; }, "should receive them too": function (val) { assert.deepEqual(val, [1, 2, 3]); } } } } }).addBatch({ "A Sibling context": { "'A', with `this.foo = true`": { topic: function () { this.foo = true; return this; }, "should have `this.foo` set to true": function (res) { assert.equal(res.foo, true); } }, "'B', with `this.bar = true`": { topic: function () { this.bar = true; return 42; }, "should pass the result": function (res) { assert.equal(res, 42); }, "should have `this.bar` set to true": function () { assert.equal(this.bar, true); }, 'with a sub context': { topic: function(){ this.barSubContext = { sub: true } return 42; }, "should have `this.bar` set to true": function (res) { assert.equal(this.bar, true); }, "should have `this.barSubContext`": function (res) { assert.deepEqual(this.barSubContext, { sub: true }); }, 'with gaps': { '.': { '.': { '.': { topic: 12, '.': { '.': { topic: function(){ this.barSubContext.subsub = true; return 42; }, "should have `this.bar` set to true": function (res) { assert.equal(this.bar, true); }, 'should have `this.barSubContext`': function(){ assert.deepEqual(this.barSubContext, { sub: true, subsub: true }); } } } } } } } } }, "'C', with nothing set": { topic: function () { return this; }, "shouldn't have access to `this.foo`": function (res) { assert.isUndefined(res.foo); assert.isUndefined(this.foo); }, "shouldn't have access to `this.bar`": function (res) { assert.isUndefined(res.bar); assert.isUndefined(this.bar); }, "shouldn't have access to `this.barSubContext`": function (res) { assert.isUndefined(res.barSubContext); assert.isUndefined(this.barSubContext); } } }, "Sibling context asynchronous": { "'A', with `this.foo = true`": { topic: function () { this.foo = true; var self = this; process.nextTick(function(){ self.callback(null, self); }) }, "should have `this.foo` set to true": function (res) { assert.equal(res.foo, true); } }, "'B', with `this.bar = true`": { topic: function () { this.bar = true; var self = this; process.nextTick(function(){ self.callback(null, 42); }) }, "should pass the result": function (res) { assert.equal(res, 42); }, "should have `this.bar` set to true": function (res) { assert.equal(this.bar, true); }, 'with a sub context': { topic: function(){ this.barSubContext = { sub: true }; var self = this; process.nextTick(function(){ self.callback(null, 42); }) }, "should have `this.foo` set to true": function (res) { assert.equal(this.bar, true); }, "should have `this.fooSubContext`": function (res) { assert.deepEqual(this.barSubContext, { sub: true }); }, 'with gaps': { '.': { '.': { '.': { topic: 12, '.': { '.': { topic: function(){ this.barSubContext.subsub = true; var self = this; process.nextTick(function(){ self.callback(null, 42); }) }, "should have `this.bar` set to true": function (res) { assert.equal(this.bar, true); }, 'should have `this.barSubContext': function(){ assert.deepEqual(this.barSubContext, { sub: true, subsub: true }); } } } } } } } } }, "'C', with nothing set": { topic: function () { var self = this; process.nextTick(function(){ self.callback(null, self); }) }, "shouldn't have access to `this.foo`": function (e, res) { assert.isUndefined(res.foo); }, "shouldn't have access to `this.bar`": function (e, res) { assert.isUndefined(res.bar); }, "shouldn't have access to `this.barSubContext`": function (e, res) { assert.isUndefined(res.barSubContext); } } } }).addBatch({ "A 2nd batch": { topic: function () { var p = new(events.EventEmitter); setTimeout(function () { p.emit("success"); }, 100); return p; }, "should run after the first": function () {} } }).addBatch({ "A 3rd batch": { topic: true, "should run last": function () {} } }).addBatch({}).export(module); vows.describe("Vows with a single batch", { "This is a batch that's added as the optional parameter to describe()": { topic: true, "And a vow": function () {} } }).export(module); vows.describe("Vows with multiple batches added as optional parameters", { "First batch": { topic: true, "should be run first": function () {} } }, { "Second batch": { topic: true, "should be run second": function () {} } }).export(module); vows.describe("Vows with teardowns").addBatch({ "A context": { topic: function () { return { flag: true }; }, "And a vow": function (topic) { assert.isTrue(topic.flag); }, "And another vow": function (topic) { assert.isTrue(topic.flag); }, "And a final vow": function (topic) { assert.isTrue(topic.flag); }, 'subcontext': { 'nested': function (_, topic) { assert.isTrue(topic.flag); } }, teardown: function (topic) { topic.flag = false; }, "with a subcontext" : { topic: function (topic) { var that = this; process.nextTick(function () { that.callback(null, topic); }); }, "Waits for the subcontext before teardown" : function(topic) { assert.isTrue(topic.flag); } } } }).export(module); vows.describe("Vows with sub events").addBatch({ "A context with sub-events": { topic: function () { var topic = new(events.EventEmitter); topic.emit('before', 'before'); process.nextTick(function () { topic.emit('request', 'request_data'); }); process.nextTick(function () { topic.emit('end', 'end_data'); }); process.nextTick(function () { topic.emit('nested', 'empty_nest'); }); process.nextTick(function () { topic.emit('success', 'legacey_data'); }); return topic; }, on: { "before": { "will catch events emited before the topic returns" : function (ret) { assert.strictEqual(ret, 'before'); } }, "request": { "will catch request": function (ret) { assert.strictEqual(ret, 'request_data'); }, on: { on: { "end": { "will require that 'end' is emitted after 'request'": function (ret) { assert.strictEqual(ret, 'end_data'); // TODO need a test that fails to prove this works } } } } }, on: { on: { "nested": { "will catch nested, even if it is in empty nested 'on'": function (ret) { assert.strictEqual(ret, 'empty_nest') } } } } }, "will catch the legacy success event": function (err, ret) { assert.strictEqual(ret, 'legacey_data'); } }, "Sub-events emitted by children of EventEmitter": { topic: function() { var MyEmitter = function () { events.EventEmitter.call(this); }; require('util').inherits(MyEmitter, events.EventEmitter); var topic = new(MyEmitter); process.nextTick(function () { topic.emit('success', 'Legacy Does not Catch'); }); return topic; }, "will return the emitter for traditional vows" : function (err, ret) { assert.ok(ret instanceof events.EventEmitter); }, // events is an alias for on events: { "success" : { "will catch the event" : function (ret) { assert.strictEqual(ret, 'Legacy Does not Catch'); }, "will change events to on in the title" : function() { assert.strictEqual(this.context.title, 'Sub-events emitted by children of EventEmitter on success'); } } } } }).export(module); var tornDown = false vows.describe("Vows with asynchonous teardowns").addBatch({ "Context with long-running teardown": { "is run first": function () {}, teardown: function () { var callback = this.callback; setTimeout(function () { tornDown = true; callback(); }, 100); } } }).addBatch({ "The next batch": { "is not run until the teardown is complete": function () { assert.ok(tornDown); } } }).export(module); vows.describe('Async topic is passed to vows with topic-less subcontext').addBatch({ 'Async 42': { topic: function () { var callback = this.callback; process.nextTick(function () { callback(null, 42); }); }, 'equals 42': function (topic) { assert.equal(topic, 42); }, 'has the property that': { 'it is equal to 42': function (topic) { // <-- This vow fails, topic is undefined!? assert.equal(topic, 42); } }, 'plus 1': { topic: function (parentTopic) { return parentTopic + 1; }, 'equals 43': function (topic) { assert.equal(topic, 43); } } } })['export'](module); vows-0.8.3/test/vows_underscore_test.js000066400000000000000000000004651355143150300203300ustar00rootroot00000000000000var vows = require('../lib/vows'), assert = require('assert'); vows.describe("Vows test file with underscore").addBatch({ "The test file": { topic: function () { return { flag: true }; }, "is run": function (topic) { assert.isTrue(topic.flag); } } }).export(module);