From 7d6f552f36e70fd34f991cc1cc682cd72a9c449f Mon Sep 17 00:00:00 2001 From: Guller Yuri Date: Thu, 25 Feb 2016 11:53:31 +0200 Subject: [PATCH] initial commit --- .gitignore | 6 + git_trigger_sandbox.txt | 3 + integration-tests/pom.xml | 56 + .../devops/demoapp/ConfigurationService.java | 78 + .../hp/devops/demoapp/RestServletTest.java | 88 + mocha/node_modules/expect.js/.npmignore | 3 + mocha/node_modules/expect.js/History.md | 54 + mocha/node_modules/expect.js/README.md | 263 +++ mocha/node_modules/expect.js/index.js | 1284 +++++++++++++ mocha/node_modules/expect.js/package.json | 38 + mocha/node_modules/nconf/.npmignore | 10 + mocha/node_modules/nconf/.travis.yml | 12 + mocha/node_modules/nconf/CHANGELOG.md | 248 +++ mocha/node_modules/nconf/LICENSE | 19 + mocha/node_modules/nconf/README.md | 279 +++ mocha/node_modules/nconf/docs/docco.css | 194 ++ mocha/node_modules/nconf/docs/nconf.html | 20 + .../node_modules/nconf/docs/nconf/common.html | 85 + .../nconf/docs/nconf/formats.html | 22 + .../nconf/docs/nconf/provider.html | 378 ++++ .../node_modules/nconf/docs/nconf/stores.html | 19 + .../nconf/docs/nconf/stores/file.html | 170 ++ .../nconf/docs/nconf/stores/memory.html | 143 ++ .../nconf/docs/nconf/stores/system.html | 98 + mocha/node_modules/nconf/lib/nconf.js | 40 + mocha/node_modules/nconf/lib/nconf/common.js | 123 ++ mocha/node_modules/nconf/lib/nconf/formats.js | 28 + .../node_modules/nconf/lib/nconf/provider.js | 568 ++++++ .../nconf/lib/nconf/stores/argv.js | 69 + .../nconf/lib/nconf/stores/env.js | 82 + .../nconf/lib/nconf/stores/file.js | 237 +++ .../nconf/lib/nconf/stores/literal.js | 29 + .../nconf/lib/nconf/stores/memory.js | 225 +++ .../nconf/node_modules/async/.travis.yml | 3 + .../nconf/node_modules/async/LICENSE | 19 + .../nconf/node_modules/async/README.md | 1646 +++++++++++++++++ .../nconf/node_modules/async/component.json | 11 + .../nconf/node_modules/async/lib/async.js | 1123 +++++++++++ .../nconf/node_modules/async/package.json | 60 + .../node_modules/ini/.npm-completion.tmp | 0 .../nconf/node_modules/ini/.npmignore | 1 + .../nconf/node_modules/ini/LICENSE | 15 + .../nconf/node_modules/ini/README.md | 102 + .../nconf/node_modules/ini/ini.js | 190 ++ .../nconf/node_modules/ini/package.json | 53 + .../nconf/node_modules/ini/test/bar.js | 23 + .../node_modules/ini/test/fixtures/foo.ini | 63 + .../nconf/node_modules/ini/test/foo.js | 105 ++ .../nconf/node_modules/optimist/.travis.yml | 4 + .../nconf/node_modules/optimist/LICENSE | 21 + .../node_modules/optimist/example/bool.js | 10 + .../optimist/example/boolean_double.js | 7 + .../optimist/example/boolean_single.js | 7 + .../optimist/example/default_hash.js | 8 + .../optimist/example/default_singles.js | 7 + .../node_modules/optimist/example/divide.js | 8 + .../optimist/example/line_count.js | 20 + .../optimist/example/line_count_options.js | 29 + .../optimist/example/line_count_wrap.js | 29 + .../node_modules/optimist/example/nonopt.js | 4 + .../node_modules/optimist/example/reflect.js | 2 + .../node_modules/optimist/example/short.js | 3 + .../node_modules/optimist/example/string.js | 11 + .../optimist/example/usage-options.js | 19 + .../node_modules/optimist/example/xup.js | 10 + .../nconf/node_modules/optimist/index.js | 343 ++++ .../node_modules/minimist/.travis.yml | 4 + .../optimist/node_modules/minimist/LICENSE | 18 + .../node_modules/minimist/example/parse.js | 2 + .../optimist/node_modules/minimist/index.js | 187 ++ .../node_modules/minimist/package.json | 67 + .../node_modules/minimist/readme.markdown | 73 + .../node_modules/minimist/test/bool.js | 119 ++ .../node_modules/minimist/test/dash.js | 24 + .../minimist/test/default_bool.js | 20 + .../node_modules/minimist/test/dotted.js | 22 + .../node_modules/minimist/test/long.js | 31 + .../node_modules/minimist/test/num.js | 36 + .../node_modules/minimist/test/parse.js | 197 ++ .../minimist/test/parse_modified.js | 9 + .../node_modules/minimist/test/short.js | 67 + .../node_modules/minimist/test/whitespace.js | 8 + .../optimist/node_modules/wordwrap/.npmignore | 1 + .../node_modules/wordwrap/README.markdown | 70 + .../node_modules/wordwrap/example/center.js | 10 + .../node_modules/wordwrap/example/meat.js | 3 + .../optimist/node_modules/wordwrap/index.js | 76 + .../node_modules/wordwrap/package.json | 61 + .../node_modules/wordwrap/test/break.js | 30 + .../node_modules/wordwrap/test/idleness.txt | 63 + .../node_modules/wordwrap/test/wrap.js | 31 + .../nconf/node_modules/optimist/package.json | 64 + .../node_modules/optimist/readme.markdown | 513 +++++ .../nconf/node_modules/optimist/test/_.js | 71 + .../node_modules/optimist/test/_/argv.js | 2 + .../nconf/node_modules/optimist/test/_/bin.js | 3 + .../nconf/node_modules/optimist/test/dash.js | 31 + .../nconf/node_modules/optimist/test/parse.js | 446 +++++ .../optimist/test/parse_modified.js | 14 + .../nconf/node_modules/optimist/test/short.js | 16 + .../nconf/node_modules/optimist/test/usage.js | 292 +++ .../node_modules/optimist/test/whitespace.js | 8 + mocha/node_modules/nconf/package.json | 68 + mocha/node_modules/nconf/test/common-test.js | 32 + .../node_modules/nconf/test/complete-test.js | 126 ++ .../node_modules/nconf/test/fixtures/bom.json | 19 + .../nconf/test/fixtures/complete.json | 19 + .../node_modules/nconf/test/fixtures/data.js | 30 + .../nconf/test/fixtures/hierarchy/global.json | 5 + .../test/fixtures/hierarchy/hierarchical.json | 3 + .../nconf/test/fixtures/hierarchy/user.json | 4 + .../nconf/test/fixtures/malformed.json | 3 + .../nconf/test/fixtures/merge/file1.json | 19 + .../nconf/test/fixtures/merge/file2.json | 10 + .../nconf/test/fixtures/no-bom.json | 19 + .../nconf/test/fixtures/scripts/nconf-argv.js | 10 + .../fixtures/scripts/nconf-change-argv.js | 16 + .../nconf/test/fixtures/scripts/nconf-env.js | 10 + .../scripts/nconf-hierarchical-file-argv.js | 17 + .../scripts/nconf-hierarchical-load-merge.js | 18 + .../scripts/nconf-hierarchical-load-save.js | 32 + .../test/fixtures/scripts/nconf-nested-env.js | 11 + .../test/fixtures/scripts/provider-argv.js | 12 + .../test/fixtures/scripts/provider-env.js | 12 + mocha/node_modules/nconf/test/helpers.js | 68 + .../node_modules/nconf/test/hierarchy-test.js | 113 ++ .../nconf/test/mocks/mock-store.js | 38 + mocha/node_modules/nconf/test/nconf-test.js | 132 ++ .../nconf/test/provider-save-test.js | 39 + .../node_modules/nconf/test/provider-test.js | 170 ++ .../nconf/test/stores/argv-test.js | 22 + .../nconf/test/stores/env-test.js | 24 + .../nconf/test/stores/file-store-test.js | 226 +++ .../nconf/test/stores/literal-test.js | 31 + .../nconf/test/stores/memory-store-test.js | 125 ++ mocha/node_modules/nconf/usage.js | 50 + mocha/test/test1.js | 27 + mocha/test/test2.js | 20 + mvn | 0 paths.txt | 1 + pom.xml | 67 + ui-tests-testng/pom.xml | 105 ++ .../devops/demoapp/tests/ui/TestSuiteA.java | 120 ++ .../devops/demoapp/tests/ui/TestSuiteB.java | 118 ++ ui-tests-testng/src/test/resources/testng.xml | 23 + ui-tests/pom.xml | 96 + .../devops/demoapp/tests/ui/SpecialTests.java | 11 + .../com/hp/devops/demoapp/tests/ui/TestA.java | 116 ++ .../com/hp/devops/demoapp/tests/ui/TestB.java | 112 ++ .../com/hp/devops/demoapp/tests/ui/TestC.java | 118 ++ .../tests/ui/generated/placeholder.txt | 0 .../tests/ui/testGenerator/TestCreator.java | 182 ++ webapp/pom.xml | 103 ++ .../main/java/com/hp/devops/demoapp/Band.java | 49 + .../java/com/hp/devops/demoapp/Calcs.java | 28 + .../com/hp/devops/demoapp/DataManager.java | 121 ++ .../com/hp/devops/demoapp/RestServlet.java | 93 + .../java/com/hp/devops/demoapp/Utils.java | 29 + webapp/src/main/webapp/WEB-INF/fdb/bands.json | 37 + webapp/src/main/webapp/WEB-INF/web.xml | 16 + webapp/src/main/webapp/css/app.css | 120 ++ .../main/webapp/css/fonts/HPSimplified.ttf | Bin 0 -> 111764 bytes .../webapp/css/fonts/HPSimplified_BdIt.ttf | Bin 0 -> 129916 bytes .../main/webapp/css/fonts/HPSimplified_It.ttf | Bin 0 -> 125884 bytes .../main/webapp/css/fonts/HPSimplified_Lt.ttf | Bin 0 -> 142740 bytes .../webapp/css/fonts/HPSimplified_LtIt.ttf | Bin 0 -> 138356 bytes .../main/webapp/css/fonts/HPSimplified_Rg.ttf | Bin 0 -> 122412 bytes webapp/src/main/webapp/images/logo_dt.png | Bin 0 -> 52431 bytes webapp/src/main/webapp/images/logo_qsr.png | Bin 0 -> 7075 bytes webapp/src/main/webapp/images/logo_rush.png | Bin 0 -> 5430 bytes webapp/src/main/webapp/images/logo_sx.png | Bin 0 -> 6228 bytes webapp/src/main/webapp/images/logo_tool.png | Bin 0 -> 23056 bytes webapp/src/main/webapp/index.html | 31 + webapp/src/main/webapp/index.jsp | 5 + webapp/src/main/webapp/js/main.js | 104 ++ webapp/src/main/webapp/teepoc.html | 597 ++++++ webapp/src/main/webapp/testlist.html | 212 +++ .../java/com/hp/devops/demoapp/BandTest.java | 78 + .../java/com/hp/devops/demoapp/CalcsTest.java | 62 + .../hp/devops/demoapp/DataManagerTest.java | 72 + .../java/com/hp/devops/demoapp/UtilsTest.java | 76 + 181 files changed, 16098 insertions(+) create mode 100644 .gitignore create mode 100644 git_trigger_sandbox.txt create mode 100644 integration-tests/pom.xml create mode 100644 integration-tests/src/test/java/com/hp/devops/demoapp/ConfigurationService.java create mode 100644 integration-tests/src/test/java/com/hp/devops/demoapp/RestServletTest.java create mode 100644 mocha/node_modules/expect.js/.npmignore create mode 100644 mocha/node_modules/expect.js/History.md create mode 100644 mocha/node_modules/expect.js/README.md create mode 100644 mocha/node_modules/expect.js/index.js create mode 100644 mocha/node_modules/expect.js/package.json create mode 100644 mocha/node_modules/nconf/.npmignore create mode 100644 mocha/node_modules/nconf/.travis.yml create mode 100644 mocha/node_modules/nconf/CHANGELOG.md create mode 100644 mocha/node_modules/nconf/LICENSE create mode 100644 mocha/node_modules/nconf/README.md create mode 100644 mocha/node_modules/nconf/docs/docco.css create mode 100644 mocha/node_modules/nconf/docs/nconf.html create mode 100644 mocha/node_modules/nconf/docs/nconf/common.html create mode 100644 mocha/node_modules/nconf/docs/nconf/formats.html create mode 100644 mocha/node_modules/nconf/docs/nconf/provider.html create mode 100644 mocha/node_modules/nconf/docs/nconf/stores.html create mode 100644 mocha/node_modules/nconf/docs/nconf/stores/file.html create mode 100644 mocha/node_modules/nconf/docs/nconf/stores/memory.html create mode 100644 mocha/node_modules/nconf/docs/nconf/stores/system.html create mode 100644 mocha/node_modules/nconf/lib/nconf.js create mode 100644 mocha/node_modules/nconf/lib/nconf/common.js create mode 100644 mocha/node_modules/nconf/lib/nconf/formats.js create mode 100644 mocha/node_modules/nconf/lib/nconf/provider.js create mode 100644 mocha/node_modules/nconf/lib/nconf/stores/argv.js create mode 100644 mocha/node_modules/nconf/lib/nconf/stores/env.js create mode 100644 mocha/node_modules/nconf/lib/nconf/stores/file.js create mode 100644 mocha/node_modules/nconf/lib/nconf/stores/literal.js create mode 100644 mocha/node_modules/nconf/lib/nconf/stores/memory.js create mode 100644 mocha/node_modules/nconf/node_modules/async/.travis.yml create mode 100644 mocha/node_modules/nconf/node_modules/async/LICENSE create mode 100644 mocha/node_modules/nconf/node_modules/async/README.md create mode 100644 mocha/node_modules/nconf/node_modules/async/component.json create mode 100644 mocha/node_modules/nconf/node_modules/async/lib/async.js create mode 100644 mocha/node_modules/nconf/node_modules/async/package.json create mode 100644 mocha/node_modules/nconf/node_modules/ini/.npm-completion.tmp create mode 100644 mocha/node_modules/nconf/node_modules/ini/.npmignore create mode 100644 mocha/node_modules/nconf/node_modules/ini/LICENSE create mode 100644 mocha/node_modules/nconf/node_modules/ini/README.md create mode 100644 mocha/node_modules/nconf/node_modules/ini/ini.js create mode 100644 mocha/node_modules/nconf/node_modules/ini/package.json create mode 100644 mocha/node_modules/nconf/node_modules/ini/test/bar.js create mode 100644 mocha/node_modules/nconf/node_modules/ini/test/fixtures/foo.ini create mode 100644 mocha/node_modules/nconf/node_modules/ini/test/foo.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/.travis.yml create mode 100644 mocha/node_modules/nconf/node_modules/optimist/LICENSE create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/bool.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/boolean_double.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/boolean_single.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/default_hash.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/default_singles.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/divide.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/line_count.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/line_count_options.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/line_count_wrap.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/nonopt.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/reflect.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/short.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/string.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/usage-options.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/example/xup.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/index.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/.travis.yml create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/LICENSE create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/example/parse.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/index.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/package.json create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/readme.markdown create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/bool.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/dash.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/default_bool.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/dotted.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/long.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/num.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/parse.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/parse_modified.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/short.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/minimist/test/whitespace.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/.npmignore create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/README.markdown create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/example/center.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/example/meat.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/index.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/package.json create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/test/break.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/test/idleness.txt create mode 100644 mocha/node_modules/nconf/node_modules/optimist/node_modules/wordwrap/test/wrap.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/package.json create mode 100644 mocha/node_modules/nconf/node_modules/optimist/readme.markdown create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/_.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/_/argv.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/_/bin.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/dash.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/parse.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/parse_modified.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/short.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/usage.js create mode 100644 mocha/node_modules/nconf/node_modules/optimist/test/whitespace.js create mode 100644 mocha/node_modules/nconf/package.json create mode 100644 mocha/node_modules/nconf/test/common-test.js create mode 100644 mocha/node_modules/nconf/test/complete-test.js create mode 100644 mocha/node_modules/nconf/test/fixtures/bom.json create mode 100644 mocha/node_modules/nconf/test/fixtures/complete.json create mode 100644 mocha/node_modules/nconf/test/fixtures/data.js create mode 100644 mocha/node_modules/nconf/test/fixtures/hierarchy/global.json create mode 100644 mocha/node_modules/nconf/test/fixtures/hierarchy/hierarchical.json create mode 100644 mocha/node_modules/nconf/test/fixtures/hierarchy/user.json create mode 100644 mocha/node_modules/nconf/test/fixtures/malformed.json create mode 100644 mocha/node_modules/nconf/test/fixtures/merge/file1.json create mode 100644 mocha/node_modules/nconf/test/fixtures/merge/file2.json create mode 100644 mocha/node_modules/nconf/test/fixtures/no-bom.json create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/nconf-argv.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/nconf-change-argv.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/nconf-env.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/nconf-hierarchical-file-argv.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/nconf-hierarchical-load-merge.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/nconf-hierarchical-load-save.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/nconf-nested-env.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/provider-argv.js create mode 100644 mocha/node_modules/nconf/test/fixtures/scripts/provider-env.js create mode 100644 mocha/node_modules/nconf/test/helpers.js create mode 100644 mocha/node_modules/nconf/test/hierarchy-test.js create mode 100644 mocha/node_modules/nconf/test/mocks/mock-store.js create mode 100644 mocha/node_modules/nconf/test/nconf-test.js create mode 100644 mocha/node_modules/nconf/test/provider-save-test.js create mode 100644 mocha/node_modules/nconf/test/provider-test.js create mode 100644 mocha/node_modules/nconf/test/stores/argv-test.js create mode 100644 mocha/node_modules/nconf/test/stores/env-test.js create mode 100644 mocha/node_modules/nconf/test/stores/file-store-test.js create mode 100644 mocha/node_modules/nconf/test/stores/literal-test.js create mode 100644 mocha/node_modules/nconf/test/stores/memory-store-test.js create mode 100644 mocha/node_modules/nconf/usage.js create mode 100644 mocha/test/test1.js create mode 100644 mocha/test/test2.js create mode 100644 mvn create mode 100644 paths.txt create mode 100644 pom.xml create mode 100644 ui-tests-testng/pom.xml create mode 100644 ui-tests-testng/src/test/java/com/hp/devops/demoapp/tests/ui/TestSuiteA.java create mode 100644 ui-tests-testng/src/test/java/com/hp/devops/demoapp/tests/ui/TestSuiteB.java create mode 100644 ui-tests-testng/src/test/resources/testng.xml create mode 100644 ui-tests/pom.xml create mode 100644 ui-tests/src/test/java/com/hp/devops/demoapp/tests/ui/SpecialTests.java create mode 100644 ui-tests/src/test/java/com/hp/devops/demoapp/tests/ui/TestA.java create mode 100644 ui-tests/src/test/java/com/hp/devops/demoapp/tests/ui/TestB.java create mode 100644 ui-tests/src/test/java/com/hp/devops/demoapp/tests/ui/TestC.java create mode 100644 ui-tests/src/test/java/com/hp/devops/demoapp/tests/ui/generated/placeholder.txt create mode 100644 ui-tests/src/test/java/com/hp/devops/demoapp/tests/ui/testGenerator/TestCreator.java create mode 100644 webapp/pom.xml create mode 100644 webapp/src/main/java/com/hp/devops/demoapp/Band.java create mode 100644 webapp/src/main/java/com/hp/devops/demoapp/Calcs.java create mode 100644 webapp/src/main/java/com/hp/devops/demoapp/DataManager.java create mode 100644 webapp/src/main/java/com/hp/devops/demoapp/RestServlet.java create mode 100644 webapp/src/main/java/com/hp/devops/demoapp/Utils.java create mode 100644 webapp/src/main/webapp/WEB-INF/fdb/bands.json create mode 100644 webapp/src/main/webapp/WEB-INF/web.xml create mode 100644 webapp/src/main/webapp/css/app.css create mode 100644 webapp/src/main/webapp/css/fonts/HPSimplified.ttf create mode 100644 webapp/src/main/webapp/css/fonts/HPSimplified_BdIt.ttf create mode 100644 webapp/src/main/webapp/css/fonts/HPSimplified_It.ttf create mode 100644 webapp/src/main/webapp/css/fonts/HPSimplified_Lt.ttf create mode 100644 webapp/src/main/webapp/css/fonts/HPSimplified_LtIt.ttf create mode 100644 webapp/src/main/webapp/css/fonts/HPSimplified_Rg.ttf create mode 100644 webapp/src/main/webapp/images/logo_dt.png create mode 100644 webapp/src/main/webapp/images/logo_qsr.png create mode 100644 webapp/src/main/webapp/images/logo_rush.png create mode 100644 webapp/src/main/webapp/images/logo_sx.png create mode 100644 webapp/src/main/webapp/images/logo_tool.png create mode 100644 webapp/src/main/webapp/index.html create mode 100644 webapp/src/main/webapp/index.jsp create mode 100644 webapp/src/main/webapp/js/main.js create mode 100644 webapp/src/main/webapp/teepoc.html create mode 100644 webapp/src/main/webapp/testlist.html create mode 100644 webapp/src/test/java/com/hp/devops/demoapp/BandTest.java create mode 100644 webapp/src/test/java/com/hp/devops/demoapp/CalcsTest.java create mode 100644 webapp/src/test/java/com/hp/devops/demoapp/DataManagerTest.java create mode 100644 webapp/src/test/java/com/hp/devops/demoapp/UtilsTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..07eb114 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +/.idea/** +**/*.iml +**/target/* +*.log +*.bak +.idea diff --git a/git_trigger_sandbox.txt b/git_trigger_sandbox.txt new file mode 100644 index 0000000..a886d16 --- /dev/null +++ b/git_trigger_sandbox.txt @@ -0,0 +1,3 @@ +some text +more text +3rd line \ No newline at end of file diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml new file mode 100644 index 0000000..83474bf --- /dev/null +++ b/integration-tests/pom.xml @@ -0,0 +1,56 @@ + + + app-all + discover-demo-app + 1.0-SNAPSHOT + + 4.0.0 + integration-tests + jar + integration-tests Maven Webapp + http://maven.apache.org + + + junit + junit + 4.11 + test + + + com.jayway.restassured + rest-assured + 2.4.0 + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12.4 + + true + + + + integration-tests + + + + runTests + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.12.4 + + false + + + + + + + diff --git a/integration-tests/src/test/java/com/hp/devops/demoapp/ConfigurationService.java b/integration-tests/src/test/java/com/hp/devops/demoapp/ConfigurationService.java new file mode 100644 index 0000000..accbe06 --- /dev/null +++ b/integration-tests/src/test/java/com/hp/devops/demoapp/ConfigurationService.java @@ -0,0 +1,78 @@ +package com.hp.devops.demoapp; + +import javax.annotation.PostConstruct; + +/** + * User: belozovs + * Date: 11/25/14 + * Description + */ +public class ConfigurationService { + + private static ConfigurationService instance = new ConfigurationService(); + + private String protocol = "http"; + private String hostName = "localhost"; + private int port = 9999; + private String basePath = "/api"; + private String proxyHost = ""; //rhvwebcachevip.bastion.europe.hp.com + private int proxyPort = 0; //8080 + + private ConfigurationService(){ + + } + public static ConfigurationService getInstance(){ + if(System.getProperty("hostname")!=null){ + instance.hostName = System.getProperty("hostname"); + } + if(System.getProperty("port")!=null){ + instance.port = Integer.parseInt(System.getProperty("port")); + } + if(System.getProperty("protocol")!=null){ + instance.protocol = System.getProperty("protocol"); + } + if(System.getProperty("basepath")!=null){ + instance.basePath = System.getProperty("basepath"); + } + if(System.getProperty("proxyhost")!=null){ + instance.proxyHost =System.getProperty("proxyhost"); + } + if(System.getProperty("proxyport")!=null){ + instance.proxyPort =Integer.parseInt(System.getProperty("proxyport")); + } + System.out.println("Starting the test for " + instance.protocol + "://" + instance.hostName + ":" + instance.port + instance.basePath); + if(!instance.proxyHost.isEmpty()){ + System.out.println("The tests will run via proxy: " + instance.proxyHost + ":" + instance.proxyPort); + } + + return instance; + } + + public String getProtocol() { + return protocol; + } + + public String getHostName() { + return hostName; + } + + public int getPort() { + return port; + } + + public String getBasePath() { + return basePath; + } + + public String getProxyHost() { + return proxyHost; + } + + public int getProxyPort() { + return proxyPort; + } + + public String getBaseUri(){ + return protocol + "://" + hostName; + } +} diff --git a/integration-tests/src/test/java/com/hp/devops/demoapp/RestServletTest.java b/integration-tests/src/test/java/com/hp/devops/demoapp/RestServletTest.java new file mode 100644 index 0000000..41e5004 --- /dev/null +++ b/integration-tests/src/test/java/com/hp/devops/demoapp/RestServletTest.java @@ -0,0 +1,88 @@ +package com.hp.devops.demoapp;/** + * Created with IntelliJ IDEA. + * User: belozovs + * Date: 11/25/14 + * Time: 4:32 PM + * To change this template use File | Settings | File Templates. + */ + +import com.jayway.restassured.RestAssured; +import com.jayway.restassured.http.ContentType; +import com.jayway.restassured.specification.RequestSpecification; +import org.junit.*; + +import java.util.HashMap; +import java.util.List; + +import static com.jayway.restassured.path.json.JsonPath.from; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.isOneOf; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +public class RestServletTest { + + private static RequestSpecification spec; + private static ConfigurationService configurationService = ConfigurationService.getInstance(); + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + RestAssured.baseURI = configurationService.getBaseUri(); + RestAssured.port = configurationService.getPort(); + RestAssured.basePath = configurationService.getBasePath(); + if (!configurationService.getProxyHost().isEmpty()) { + RestAssured.proxy(configurationService.getProxyHost(), configurationService.getProxyPort()); + } + + spec = RestAssured.given(); + System.out.println("Base URI: " + configurationService.getBaseUri()); + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + } + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void testGetBands() throws Exception { + String result = spec.log().all().expect().statusCode(isOneOf(200)).get("/bands").asString(); + List bandsList = from(result).get(""); + assertEquals("We should have 5 bands", 5, bandsList.size()); + } + + @Test + public void testReloadDb() throws Exception { + spec.log().all().expect().statusCode(200).contentType(ContentType.TEXT).body(equalTo("done")).get("/reloadDB"); + } + + @Test + public void testVoteForBand() throws Exception { + String response1 = spec.log().all().expect().statusCode(200).when().put("/band/1/vote").asString(); + List votesList1 = from(response1).get(""); + int votes1 = ((HashMap) votesList1.get(0)).get("votes"); + System.out.println("Votes1: " + votesList1.get(0)); + String response2 = spec.log().all().expect().statusCode(200).when().put("/band/1/vote").asString(); + List votesList2 = from(response2).get(""); + int votes2 = ((HashMap) votesList2.get(0)).get("votes"); + System.out.println("Votes2: " + votesList2.get(0)); + int diff = votes2 - votes1; + assertTrue("Votes should increase by 1", diff == 1); + } + + @Test + public void testMultipleVotingBlocked() throws Exception { + String cookieValue; + cookieValue = spec.log().all().expect().statusCode(isOneOf(200)).get("/bands").getCookie("hpDevopsDemoApp"); + assertTrue("cookie value should be equal 'null'", cookieValue == null); + cookieValue = spec.log().all().expect().statusCode(200).when().put("/band/1/vote").getCookie("hpDevopsDemoApp"); + assertTrue("cookie value should be equal 'true'", cookieValue.compareTo("true") == 0); + } +} diff --git a/mocha/node_modules/expect.js/.npmignore b/mocha/node_modules/expect.js/.npmignore new file mode 100644 index 0000000..26ef5d8 --- /dev/null +++ b/mocha/node_modules/expect.js/.npmignore @@ -0,0 +1,3 @@ +support +test +Makefile diff --git a/mocha/node_modules/expect.js/History.md b/mocha/node_modules/expect.js/History.md new file mode 100644 index 0000000..e03f91f --- /dev/null +++ b/mocha/node_modules/expect.js/History.md @@ -0,0 +1,54 @@ + +0.3.0 / 2014-02-20 +================== + + * renmaed to `index.js` + * added repository to package.json + * remove unused variable and merge + * simpify isDate() and remove unnecessary semicolon. + * Add .withArgs() syntax for building scenario + * eql(): fix wrong order of actual vs. expected. + * Added formatting for Error objects + * Add support for 'regexp' type and eql comparison of regular expressions. + * Better to follow the same coding style + * Use 'showDiff' flag + * Add 'actual' & 'expected' property to the thrown error + * Pass .fail() unit test + * Ignore 'script*' global leak in chrome + * Exposed object stringification function + * Use isRegExp in Assertion::throwException. Fix #25 + * Cleaned up local variables + +0.2.0 / 2012-10-19 +================== + + * fix isRegExp bug in some edge cases + * add closure to all assertion messages deferring costly inspects + until there is actually a failure + * fix `make test` for recent mochas + * add inspect() case for DOM elements + * relax failure msg null check + * add explicit failure through `expect().fail()` + * clarified all `empty` functionality in README example + * added docs for throwException fn/regexp signatures + +0.1.2 / 2012-02-04 +================== + + * Added regexp matching support for exceptions. + * Added support for throwException callback. + * Added `throwError` synonym to `throwException`. + * Added object support for `.empty`. + * Fixed `.a('object')` with nulls, and english error in error message. + * Fix bug `indexOf` (IE). [hokaccha] + * Fixed object property checking with `undefined` as value. [vovik] + +0.1.1 / 2011-12-18 +================== + + * Fixed typo + +0.1.0 / 2011-12-18 +================== + + * Initial import diff --git a/mocha/node_modules/expect.js/README.md b/mocha/node_modules/expect.js/README.md new file mode 100644 index 0000000..2683ed3 --- /dev/null +++ b/mocha/node_modules/expect.js/README.md @@ -0,0 +1,263 @@ +# Expect + +Minimalistic BDD assertion toolkit based on +[should.js](http://github.com/visionmedia/should.js) + +```js +expect(window.r).to.be(undefined); +expect({ a: 'b' }).to.eql({ a: 'b' }) +expect(5).to.be.a('number'); +expect([]).to.be.an('array'); +expect(window).not.to.be.an(Image); +``` + +## Features + +- Cross-browser: works on IE6+, Firefox, Safari, Chrome, Opera. +- Compatible with all test frameworks. +- Node.JS ready (`require('expect.js')`). +- Standalone. Single global with no prototype extensions or shims. + +## How to use + +### Node + +Install it with NPM or add it to your `package.json`: + +``` +$ npm install expect.js +``` + +Then: + +```js +var expect = require('expect.js'); +``` + +### Browser + +Expose the `expect.js` found at the top level of this repository. + +```html + +``` + +## API + +**ok**: asserts that the value is _truthy_ or not + +```js +expect(1).to.be.ok(); +expect(true).to.be.ok(); +expect({}).to.be.ok(); +expect(0).to.not.be.ok(); +``` + +**be** / **equal**: asserts `===` equality + +```js +expect(1).to.be(1) +expect(NaN).not.to.equal(NaN); +expect(1).not.to.be(true) +expect('1').to.not.be(1); +``` + +**eql**: asserts loose equality that works with objects + +```js +expect({ a: 'b' }).to.eql({ a: 'b' }); +expect(1).to.eql('1'); +``` + +**a**/**an**: asserts `typeof` with support for `array` type and `instanceof` + +```js +// typeof with optional `array` +expect(5).to.be.a('number'); +expect([]).to.be.an('array'); // works +expect([]).to.be.an('object'); // works too, since it uses `typeof` + +// constructors +expect(5).to.be.a(Number); +expect([]).to.be.an(Array); +expect(tobi).to.be.a(Ferret); +expect(person).to.be.a(Mammal); +``` + +**match**: asserts `String` regular expression match + +```js +expect(program.version).to.match(/[0-9]+\.[0-9]+\.[0-9]+/); +``` + +**contain**: asserts indexOf for an array or string + +```js +expect([1, 2]).to.contain(1); +expect('hello world').to.contain('world'); +``` + +**length**: asserts array `.length` + +```js +expect([]).to.have.length(0); +expect([1,2,3]).to.have.length(3); +``` + +**empty**: asserts that an array is empty or not + +```js +expect([]).to.be.empty(); +expect({}).to.be.empty(); +expect({ length: 0, duck: 'typing' }).to.be.empty(); +expect({ my: 'object' }).to.not.be.empty(); +expect([1,2,3]).to.not.be.empty(); +``` + +**property**: asserts presence of an own property (and value optionally) + +```js +expect(window).to.have.property('expect') +expect(window).to.have.property('expect', expect) +expect({a: 'b'}).to.have.property('a'); +``` + +**key**/**keys**: asserts the presence of a key. Supports the `only` modifier + +```js +expect({ a: 'b' }).to.have.key('a'); +expect({ a: 'b', c: 'd' }).to.only.have.keys('a', 'c'); +expect({ a: 'b', c: 'd' }).to.only.have.keys(['a', 'c']); +expect({ a: 'b', c: 'd' }).to.not.only.have.key('a'); +``` + +**throwException**/**throwError**: asserts that the `Function` throws or not when called + +```js +expect(fn).to.throwError(); // synonym of throwException +expect(fn).to.throwException(function (e) { // get the exception object + expect(e).to.be.a(SyntaxError); +}); +expect(fn).to.throwException(/matches the exception message/); +expect(fn2).to.not.throwException(); +``` + +**withArgs**: creates anonymous function to call fn with arguments + +```js +expect(fn).withArgs(invalid, arg).to.throwException(); +expect(fn).withArgs(valid, arg).to.not.throwException(); +``` + +**within**: asserts a number within a range + +```js +expect(1).to.be.within(0, Infinity); +``` + +**greaterThan**/**above**: asserts `>` + +```js +expect(3).to.be.above(0); +expect(5).to.be.greaterThan(3); +``` + +**lessThan**/**below**: asserts `<` + +```js +expect(0).to.be.below(3); +expect(1).to.be.lessThan(3); +``` + +**fail**: explicitly forces failure. + +```js +expect().fail() +expect().fail("Custom failure message") +``` + +## Using with a test framework + +For example, if you create a test suite with +[mocha](http://github.com/visionmedia/mocha). + +Let's say we wanted to test the following program: + +**math.js** + +```js +function add (a, b) { return a + b; }; +``` + +Our test file would look like this: + +```js +describe('test suite', function () { + it('should expose a function', function () { + expect(add).to.be.a('function'); + }); + + it('should do math', function () { + expect(add(1, 3)).to.equal(4); + }); +}); +``` + +If a certain expectation fails, an exception will be raised which gets captured +and shown/processed by the test runner. + +## Differences with should.js + +- No need for static `should` methods like `should.strictEqual`. For example, + `expect(obj).to.be(undefined)` works well. +- Some API simplifications / changes. +- API changes related to browser compatibility. + +## Running tests + +Clone the repository and install the developer dependencies: + +``` +git clone git://github.com/LearnBoost/expect.js.git expect +cd expect && npm install +``` + +### Node + +`make test` + +### Browser + +`make test-browser` + +and point your browser(s) to `http://localhost:3000/test/` + +## Credits + +(The MIT License) + +Copyright (c) 2011 Guillermo Rauch <guillermo@learnboost.com> + +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. + +### 3rd-party + +Heavily borrows from [should.js](http://github.com/visionmedia/should.js) by TJ +Holowaychuck - MIT. diff --git a/mocha/node_modules/expect.js/index.js b/mocha/node_modules/expect.js/index.js new file mode 100644 index 0000000..b1e921d --- /dev/null +++ b/mocha/node_modules/expect.js/index.js @@ -0,0 +1,1284 @@ +(function (global, module) { + + var exports = module.exports; + + /** + * Exports. + */ + + module.exports = expect; + expect.Assertion = Assertion; + + /** + * Exports version. + */ + + expect.version = '0.3.1'; + + /** + * Possible assertion flags. + */ + + var flags = { + not: ['to', 'be', 'have', 'include', 'only'] + , to: ['be', 'have', 'include', 'only', 'not'] + , only: ['have'] + , have: ['own'] + , be: ['an'] + }; + + function expect (obj) { + return new Assertion(obj); + } + + /** + * Constructor + * + * @api private + */ + + function Assertion (obj, flag, parent) { + this.obj = obj; + this.flags = {}; + + if (undefined != parent) { + this.flags[flag] = true; + + for (var i in parent.flags) { + if (parent.flags.hasOwnProperty(i)) { + this.flags[i] = true; + } + } + } + + var $flags = flag ? flags[flag] : keys(flags) + , self = this; + + if ($flags) { + for (var i = 0, l = $flags.length; i < l; i++) { + // avoid recursion + if (this.flags[$flags[i]]) continue; + + var name = $flags[i] + , assertion = new Assertion(this.obj, name, this) + + if ('function' == typeof Assertion.prototype[name]) { + // clone the function, make sure we dont touch the prot reference + var old = this[name]; + this[name] = function () { + return old.apply(self, arguments); + }; + + for (var fn in Assertion.prototype) { + if (Assertion.prototype.hasOwnProperty(fn) && fn != name) { + this[name][fn] = bind(assertion[fn], assertion); + } + } + } else { + this[name] = assertion; + } + } + } + } + + /** + * Performs an assertion + * + * @api private + */ + + Assertion.prototype.assert = function (truth, msg, error, expected) { + var msg = this.flags.not ? error : msg + , ok = this.flags.not ? !truth : truth + , err; + + if (!ok) { + err = new Error(msg.call(this)); + if (arguments.length > 3) { + err.actual = this.obj; + err.expected = expected; + err.showDiff = true; + } + throw err; + } + + this.and = new Assertion(this.obj); + }; + + /** + * Check if the value is truthy + * + * @api public + */ + + Assertion.prototype.ok = function () { + this.assert( + !!this.obj + , function(){ return 'expected ' + i(this.obj) + ' to be truthy' } + , function(){ return 'expected ' + i(this.obj) + ' to be falsy' }); + }; + + /** + * Creates an anonymous function which calls fn with arguments. + * + * @api public + */ + + Assertion.prototype.withArgs = function() { + expect(this.obj).to.be.a('function'); + var fn = this.obj; + var args = Array.prototype.slice.call(arguments); + return expect(function() { fn.apply(null, args); }); + }; + + /** + * Assert that the function throws. + * + * @param {Function|RegExp} callback, or regexp to match error string against + * @api public + */ + + Assertion.prototype.throwError = + Assertion.prototype.throwException = function (fn) { + expect(this.obj).to.be.a('function'); + + var thrown = false + , not = this.flags.not; + + try { + this.obj(); + } catch (e) { + if (isRegExp(fn)) { + var subject = 'string' == typeof e ? e : e.message; + if (not) { + expect(subject).to.not.match(fn); + } else { + expect(subject).to.match(fn); + } + } else if ('function' == typeof fn) { + fn(e); + } + thrown = true; + } + + if (isRegExp(fn) && not) { + // in the presence of a matcher, ensure the `not` only applies to + // the matching. + this.flags.not = false; + } + + var name = this.obj.name || 'fn'; + this.assert( + thrown + , function(){ return 'expected ' + name + ' to throw an exception' } + , function(){ return 'expected ' + name + ' not to throw an exception' }); + }; + + /** + * Checks if the array is empty. + * + * @api public + */ + + Assertion.prototype.empty = function () { + var expectation; + + if ('object' == typeof this.obj && null !== this.obj && !isArray(this.obj)) { + if ('number' == typeof this.obj.length) { + expectation = !this.obj.length; + } else { + expectation = !keys(this.obj).length; + } + } else { + if ('string' != typeof this.obj) { + expect(this.obj).to.be.an('object'); + } + + expect(this.obj).to.have.property('length'); + expectation = !this.obj.length; + } + + this.assert( + expectation + , function(){ return 'expected ' + i(this.obj) + ' to be empty' } + , function(){ return 'expected ' + i(this.obj) + ' to not be empty' }); + return this; + }; + + /** + * Checks if the obj exactly equals another. + * + * @api public + */ + + Assertion.prototype.be = + Assertion.prototype.equal = function (obj) { + this.assert( + obj === this.obj + , function(){ return 'expected ' + i(this.obj) + ' to equal ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to not equal ' + i(obj) }); + return this; + }; + + /** + * Checks if the obj sortof equals another. + * + * @api public + */ + + Assertion.prototype.eql = function (obj) { + this.assert( + expect.eql(this.obj, obj) + , function(){ return 'expected ' + i(this.obj) + ' to sort of equal ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to sort of not equal ' + i(obj) } + , obj); + return this; + }; + + /** + * Assert within start to finish (inclusive). + * + * @param {Number} start + * @param {Number} finish + * @api public + */ + + Assertion.prototype.within = function (start, finish) { + var range = start + '..' + finish; + this.assert( + this.obj >= start && this.obj <= finish + , function(){ return 'expected ' + i(this.obj) + ' to be within ' + range } + , function(){ return 'expected ' + i(this.obj) + ' to not be within ' + range }); + return this; + }; + + /** + * Assert typeof / instance of + * + * @api public + */ + + Assertion.prototype.a = + Assertion.prototype.an = function (type) { + if ('string' == typeof type) { + // proper english in error msg + var n = /^[aeiou]/.test(type) ? 'n' : ''; + + // typeof with support for 'array' + this.assert( + 'array' == type ? isArray(this.obj) : + 'regexp' == type ? isRegExp(this.obj) : + 'object' == type + ? 'object' == typeof this.obj && null !== this.obj + : type == typeof this.obj + , function(){ return 'expected ' + i(this.obj) + ' to be a' + n + ' ' + type } + , function(){ return 'expected ' + i(this.obj) + ' not to be a' + n + ' ' + type }); + } else { + // instanceof + var name = type.name || 'supplied constructor'; + this.assert( + this.obj instanceof type + , function(){ return 'expected ' + i(this.obj) + ' to be an instance of ' + name } + , function(){ return 'expected ' + i(this.obj) + ' not to be an instance of ' + name }); + } + + return this; + }; + + /** + * Assert numeric value above _n_. + * + * @param {Number} n + * @api public + */ + + Assertion.prototype.greaterThan = + Assertion.prototype.above = function (n) { + this.assert( + this.obj > n + , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n } + , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n }); + return this; + }; + + /** + * Assert numeric value below _n_. + * + * @param {Number} n + * @api public + */ + + Assertion.prototype.lessThan = + Assertion.prototype.below = function (n) { + this.assert( + this.obj < n + , function(){ return 'expected ' + i(this.obj) + ' to be below ' + n } + , function(){ return 'expected ' + i(this.obj) + ' to be above ' + n }); + return this; + }; + + /** + * Assert string value matches _regexp_. + * + * @param {RegExp} regexp + * @api public + */ + + Assertion.prototype.match = function (regexp) { + this.assert( + regexp.exec(this.obj) + , function(){ return 'expected ' + i(this.obj) + ' to match ' + regexp } + , function(){ return 'expected ' + i(this.obj) + ' not to match ' + regexp }); + return this; + }; + + /** + * Assert property "length" exists and has value of _n_. + * + * @param {Number} n + * @api public + */ + + Assertion.prototype.length = function (n) { + expect(this.obj).to.have.property('length'); + var len = this.obj.length; + this.assert( + n == len + , function(){ return 'expected ' + i(this.obj) + ' to have a length of ' + n + ' but got ' + len } + , function(){ return 'expected ' + i(this.obj) + ' to not have a length of ' + len }); + return this; + }; + + /** + * Assert property _name_ exists, with optional _val_. + * + * @param {String} name + * @param {Mixed} val + * @api public + */ + + Assertion.prototype.property = function (name, val) { + if (this.flags.own) { + this.assert( + Object.prototype.hasOwnProperty.call(this.obj, name) + , function(){ return 'expected ' + i(this.obj) + ' to have own property ' + i(name) } + , function(){ return 'expected ' + i(this.obj) + ' to not have own property ' + i(name) }); + return this; + } + + if (this.flags.not && undefined !== val) { + if (undefined === this.obj[name]) { + throw new Error(i(this.obj) + ' has no property ' + i(name)); + } + } else { + var hasProp; + try { + hasProp = name in this.obj + } catch (e) { + hasProp = undefined !== this.obj[name] + } + + this.assert( + hasProp + , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name) } + , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name) }); + } + + if (undefined !== val) { + this.assert( + val === this.obj[name] + , function(){ return 'expected ' + i(this.obj) + ' to have a property ' + i(name) + + ' of ' + i(val) + ', but got ' + i(this.obj[name]) } + , function(){ return 'expected ' + i(this.obj) + ' to not have a property ' + i(name) + + ' of ' + i(val) }); + } + + this.obj = this.obj[name]; + return this; + }; + + /** + * Assert that the array contains _obj_ or string contains _obj_. + * + * @param {Mixed} obj|string + * @api public + */ + + Assertion.prototype.string = + Assertion.prototype.contain = function (obj) { + if ('string' == typeof this.obj) { + this.assert( + ~this.obj.indexOf(obj) + , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) }); + } else { + this.assert( + ~indexOf(this.obj, obj) + , function(){ return 'expected ' + i(this.obj) + ' to contain ' + i(obj) } + , function(){ return 'expected ' + i(this.obj) + ' to not contain ' + i(obj) }); + } + return this; + }; + + /** + * Assert exact keys or inclusion of keys by using + * the `.own` modifier. + * + * @param {Array|String ...} keys + * @api public + */ + + Assertion.prototype.key = + Assertion.prototype.keys = function ($keys) { + var str + , ok = true; + + $keys = isArray($keys) + ? $keys + : Array.prototype.slice.call(arguments); + + if (!$keys.length) throw new Error('keys required'); + + var actual = keys(this.obj) + , len = $keys.length; + + // Inclusion + ok = every($keys, function (key) { + return ~indexOf(actual, key); + }); + + // Strict + if (!this.flags.not && this.flags.only) { + ok = ok && $keys.length == actual.length; + } + + // Key string + if (len > 1) { + $keys = map($keys, function (key) { + return i(key); + }); + var last = $keys.pop(); + str = $keys.join(', ') + ', and ' + last; + } else { + str = i($keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (!this.flags.only ? 'include ' : 'only have ') + str; + + // Assertion + this.assert( + ok + , function(){ return 'expected ' + i(this.obj) + ' to ' + str } + , function(){ return 'expected ' + i(this.obj) + ' to not ' + str }); + + return this; + }; + + /** + * Assert a failure. + * + * @param {String ...} custom message + * @api public + */ + Assertion.prototype.fail = function (msg) { + var error = function() { return msg || "explicit failure"; } + this.assert(false, error, error); + return this; + }; + + /** + * Function bind implementation. + */ + + function bind (fn, scope) { + return function () { + return fn.apply(scope, arguments); + } + } + + /** + * Array every compatibility + * + * @see bit.ly/5Fq1N2 + * @api public + */ + + function every (arr, fn, thisObj) { + var scope = thisObj || global; + for (var i = 0, j = arr.length; i < j; ++i) { + if (!fn.call(scope, arr[i], i, arr)) { + return false; + } + } + return true; + } + + /** + * Array indexOf compatibility. + * + * @see bit.ly/a5Dxa2 + * @api public + */ + + function indexOf (arr, o, i) { + if (Array.prototype.indexOf) { + return Array.prototype.indexOf.call(arr, o, i); + } + + if (arr.length === undefined) { + return -1; + } + + for (var j = arr.length, i = i < 0 ? i + j < 0 ? 0 : i + j : i || 0 + ; i < j && arr[i] !== o; i++); + + return j <= i ? -1 : i; + } + + // https://gist.github.com/1044128/ + var getOuterHTML = function(element) { + if ('outerHTML' in element) return element.outerHTML; + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + var xmlSerializer = new XMLSerializer(); + var html; + if (document.xmlVersion) { + return xmlSerializer.serializeToString(element); + } else { + container.appendChild(element.cloneNode(false)); + html = container.innerHTML.replace('><', '>' + element.innerHTML + '<'); + container.innerHTML = ''; + return html; + } + }; + + // Returns true if object is a DOM element. + var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } + }; + + /** + * Inspects an object. + * + * @see taken from node.js `util` module (copyright Joyent, MIT license) + * @api private + */ + + function i (obj, showHidden, depth) { + var seen = []; + + function stylize (str) { + return str; + } + + function format (value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value !== exports && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + return value.inspect(recurseTimes); + } + + // Primitive types cannot have properties + switch (typeof value) { + case 'undefined': + return stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + json.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return stylize(simple, 'string'); + + case 'number': + return stylize('' + value, 'number'); + + case 'boolean': + return stylize('' + value, 'boolean'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return stylize('null', 'null'); + } + + if (isDOMElement(value)) { + return getOuterHTML(value); + } + + // Look up the keys of the object. + var visible_keys = keys(value); + var $keys = showHidden ? Object.getOwnPropertyNames(value) : visible_keys; + + // Functions without properties can be shortcutted. + if (typeof value === 'function' && $keys.length === 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + var name = value.name ? ': ' + value.name : ''; + return stylize('[Function' + name + ']', 'special'); + } + } + + // Dates without properties can be shortcutted + if (isDate(value) && $keys.length === 0) { + return stylize(value.toUTCString(), 'date'); + } + + // Error objects can be shortcutted + if (value instanceof Error) { + return stylize("["+value.toString()+"]", 'Error'); + } + + var base, type, braces; + // Determine the object type + if (isArray(value)) { + type = 'Array'; + braces = ['[', ']']; + } else { + type = 'Object'; + braces = ['{', '}']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + var n = value.name ? ': ' + value.name : ''; + base = (isRegExp(value)) ? ' ' + value : ' [Function' + n + ']'; + } else { + base = ''; + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + value.toUTCString(); + } + + if ($keys.length === 0) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return stylize('' + value, 'regexp'); + } else { + return stylize('[Object]', 'special'); + } + } + + seen.push(value); + + var output = map($keys, function (key) { + var name, str; + if (value.__lookupGetter__) { + if (value.__lookupGetter__(key)) { + if (value.__lookupSetter__(key)) { + str = stylize('[Getter/Setter]', 'special'); + } else { + str = stylize('[Getter]', 'special'); + } + } else { + if (value.__lookupSetter__(key)) { + str = stylize('[Setter]', 'special'); + } + } + } + if (indexOf(visible_keys, key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (indexOf(seen, value[key]) < 0) { + if (recurseTimes === null) { + str = format(value[key]); + } else { + str = format(value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (isArray(value)) { + str = map(str.split('\n'), function (line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + map(str.split('\n'), function (line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (type === 'Array' && key.match(/^\d+$/)) { + return str; + } + name = json.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = stylize(name, 'string'); + } + } + + return name + ': ' + str; + }); + + seen.pop(); + + var numLinesEst = 0; + var length = reduce(output, function (prev, cur) { + numLinesEst++; + if (indexOf(cur, '\n') >= 0) numLinesEst++; + return prev + cur.length + 1; + }, 0); + + if (length > 50) { + output = braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + + } else { + output = braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + return output; + } + return format(obj, (typeof depth === 'undefined' ? 2 : depth)); + } + + expect.stringify = i; + + function isArray (ar) { + return Object.prototype.toString.call(ar) === '[object Array]'; + } + + function isRegExp(re) { + var s; + try { + s = '' + re; + } catch (e) { + return false; + } + + return re instanceof RegExp || // easy case + // duck-type for context-switching evalcx case + typeof(re) === 'function' && + re.constructor.name === 'RegExp' && + re.compile && + re.test && + re.exec && + s.match(/^\/.*\/[gim]{0,3}$/); + } + + function isDate(d) { + return d instanceof Date; + } + + function keys (obj) { + if (Object.keys) { + return Object.keys(obj); + } + + var keys = []; + + for (var i in obj) { + if (Object.prototype.hasOwnProperty.call(obj, i)) { + keys.push(i); + } + } + + return keys; + } + + function map (arr, mapper, that) { + if (Array.prototype.map) { + return Array.prototype.map.call(arr, mapper, that); + } + + var other= new Array(arr.length); + + for (var i= 0, n = arr.length; i= 2) { + var rv = arguments[1]; + } else { + do { + if (i in this) { + rv = this[i++]; + break; + } + + // if array contains no values, no initial value to return + if (++i >= len) + throw new TypeError(); + } while (true); + } + + for (; i < len; i++) { + if (i in this) + rv = fun.call(null, rv, this[i], i, this); + } + + return rv; + } + + /** + * Asserts deep equality + * + * @see taken from node.js `assert` module (copyright Joyent, MIT license) + * @api private + */ + + expect.eql = function eql(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + } else if ('undefined' != typeof Buffer + && 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; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (actual instanceof Date && expected instanceof Date) { + return actual.getTime() === expected.getTime(); + + // 7.3. Other pairs that do not both pass typeof value == "object", + // equivalence is determined by ==. + } else if (typeof actual != 'object' && typeof expected != 'object') { + return actual == expected; + // If both are regular expression use the special `regExpEquiv` method + // to determine equivalence. + } else if (isRegExp(actual) && isRegExp(expected)) { + return regExpEquiv(actual, expected); + // 7.4. For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical "prototype" property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } + }; + + function isUndefinedOrNull (value) { + return value === null || value === undefined; + } + + function isArguments (object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; + } + + function regExpEquiv (a, b) { + return a.source === b.source && a.global === b.global && + a.ignoreCase === b.ignoreCase && a.multiline === b.multiline; + } + + function objEquiv (a, b) { + if (isUndefinedOrNull(a) || isUndefinedOrNull(b)) + return false; + // an identical "prototype" property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return expect.eql(a, b); + } + try{ + var ka = keys(a), + kb = keys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!expect.eql(a[key], b[key])) + return false; + } + return true; + } + + var json = (function () { + "use strict"; + + if ('object' == typeof JSON && JSON.parse && JSON.stringify) { + return { + parse: nativeJSON.parse + , stringify: nativeJSON.stringify + } + } + + var JSON = {}; + + function f(n) { + // Format integers to have at least two digits. + return n < 10 ? '0' + n : n; + } + + function date(d, key) { + return isFinite(d.valueOf()) ? + d.getUTCFullYear() + '-' + + f(d.getUTCMonth() + 1) + '-' + + f(d.getUTCDate()) + 'T' + + f(d.getUTCHours()) + ':' + + f(d.getUTCMinutes()) + ':' + + f(d.getUTCSeconds()) + 'Z' : null; + } + + var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, + gap, + indent, + meta = { // table of character substitutions + '\b': '\\b', + '\t': '\\t', + '\n': '\\n', + '\f': '\\f', + '\r': '\\r', + '"' : '\\"', + '\\': '\\\\' + }, + rep; + + + function quote(string) { + + // If the string contains no control characters, no quote characters, and no + // backslash characters, then we can safely slap some quotes around it. + // Otherwise we must also replace the offending characters with safe escape + // sequences. + + escapable.lastIndex = 0; + return escapable.test(string) ? '"' + string.replace(escapable, function (a) { + var c = meta[a]; + return typeof c === 'string' ? c : + '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }) + '"' : '"' + string + '"'; + } + + + function str(key, holder) { + + // Produce a string from holder[key]. + + var i, // The loop counter. + k, // The member key. + v, // The member value. + length, + mind = gap, + partial, + value = holder[key]; + + // If the value has a toJSON method, call it to obtain a replacement value. + + if (value instanceof Date) { + value = date(key); + } + + // If we were called with a replacer function, then call the replacer to + // obtain a replacement value. + + if (typeof rep === 'function') { + value = rep.call(holder, key, value); + } + + // What happens next depends on the value's type. + + switch (typeof value) { + case 'string': + return quote(value); + + case 'number': + + // JSON numbers must be finite. Encode non-finite numbers as null. + + return isFinite(value) ? String(value) : 'null'; + + case 'boolean': + case 'null': + + // If the value is a boolean or null, convert it to a string. Note: + // typeof null does not produce 'null'. The case is included here in + // the remote chance that this gets fixed someday. + + return String(value); + + // If the type is 'object', we might be dealing with an object or an array or + // null. + + case 'object': + + // Due to a specification blunder in ECMAScript, typeof null is 'object', + // so watch out for that case. + + if (!value) { + return 'null'; + } + + // Make an array to hold the partial results of stringifying this object value. + + gap += indent; + partial = []; + + // Is the value an array? + + if (Object.prototype.toString.apply(value) === '[object Array]') { + + // The value is an array. Stringify every element. Use null as a placeholder + // for non-JSON values. + + length = value.length; + for (i = 0; i < length; i += 1) { + partial[i] = str(i, value) || 'null'; + } + + // Join all of the elements together, separated with commas, and wrap them in + // brackets. + + v = partial.length === 0 ? '[]' : gap ? + '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : + '[' + partial.join(',') + ']'; + gap = mind; + return v; + } + + // If the replacer is an array, use it to select the members to be stringified. + + if (rep && typeof rep === 'object') { + length = rep.length; + for (i = 0; i < length; i += 1) { + if (typeof rep[i] === 'string') { + k = rep[i]; + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } else { + + // Otherwise, iterate through all of the keys in the object. + + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = str(k, value); + if (v) { + partial.push(quote(k) + (gap ? ': ' : ':') + v); + } + } + } + } + + // Join all of the member texts together, separated with commas, + // and wrap them in braces. + + v = partial.length === 0 ? '{}' : gap ? + '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : + '{' + partial.join(',') + '}'; + gap = mind; + return v; + } + } + + // If the JSON object does not yet have a stringify method, give it one. + + JSON.stringify = function (value, replacer, space) { + + // The stringify method takes a value and an optional replacer, and an optional + // space parameter, and returns a JSON text. The replacer can be a function + // that can replace values, or an array of strings that will select the keys. + // A default replacer method can be provided. Use of the space parameter can + // produce text that is more easily readable. + + var i; + gap = ''; + indent = ''; + + // If the space parameter is a number, make an indent string containing that + // many spaces. + + if (typeof space === 'number') { + for (i = 0; i < space; i += 1) { + indent += ' '; + } + + // If the space parameter is a string, it will be used as the indent string. + + } else if (typeof space === 'string') { + indent = space; + } + + // If there is a replacer, it must be a function or an array. + // Otherwise, throw an error. + + rep = replacer; + if (replacer && typeof replacer !== 'function' && + (typeof replacer !== 'object' || + typeof replacer.length !== 'number')) { + throw new Error('JSON.stringify'); + } + + // Make a fake root object containing our value under the key of ''. + // Return the result of stringifying the value. + + return str('', {'': value}); + }; + + // If the JSON object does not yet have a parse method, give it one. + + JSON.parse = function (text, reviver) { + // The parse method takes a text and an optional reviver function, and returns + // a JavaScript value if the text is a valid JSON text. + + var j; + + function walk(holder, key) { + + // The walk method is used to recursively walk the resulting structure so + // that modifications can be made. + + var k, v, value = holder[key]; + if (value && typeof value === 'object') { + for (k in value) { + if (Object.prototype.hasOwnProperty.call(value, k)) { + v = walk(value, k); + if (v !== undefined) { + value[k] = v; + } else { + delete value[k]; + } + } + } + } + return reviver.call(holder, key, value); + } + + + // Parsing happens in four stages. In the first stage, we replace certain + // Unicode characters with escape sequences. JavaScript handles many characters + // incorrectly, either silently deleting them, or treating them as line endings. + + text = String(text); + cx.lastIndex = 0; + if (cx.test(text)) { + text = text.replace(cx, function (a) { + return '\\u' + + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); + }); + } + + // In the second stage, we run the text against regular expressions that look + // for non-JSON patterns. We are especially concerned with '()' and 'new' + // because they can cause invocation, and '=' because it can cause mutation. + // But just to be safe, we want to reject all unexpected forms. + + // We split the second stage into 4 regexp operations in order to work around + // crippling inefficiencies in IE's and Safari's regexp engines. First we + // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we + // replace all simple value tokens with ']' characters. Third, we delete all + // open brackets that follow a colon or comma or that begin the text. Finally, + // we look to see that the remaining characters are only whitespace or ']' or + // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. + + if (/^[\],:{}\s]*$/ + .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@') + .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') + .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { + + // In the third stage we use the eval function to compile the text into a + // JavaScript structure. The '{' operator is subject to a syntactic ambiguity + // in JavaScript: it can begin a block or an object literal. We wrap the text + // in parens to eliminate the ambiguity. + + j = eval('(' + text + ')'); + + // In the optional fourth stage, we recursively walk the new structure, passing + // each name/value pair to a reviver function for possible transformation. + + return typeof reviver === 'function' ? + walk({'': j}, '') : j; + } + + // If the text is not JSON parseable, then a SyntaxError is thrown. + + throw new SyntaxError('JSON.parse'); + }; + + return JSON; + })(); + + if ('undefined' != typeof window) { + window.expect = module.exports; + } + +})( + this + , 'undefined' != typeof module ? module : {exports: {}} +); diff --git a/mocha/node_modules/expect.js/package.json b/mocha/node_modules/expect.js/package.json new file mode 100644 index 0000000..b5205d0 --- /dev/null +++ b/mocha/node_modules/expect.js/package.json @@ -0,0 +1,38 @@ +{ + "name": "expect.js", + "version": "0.3.1", + "description": "BDD style assertions for node and the browser.", + "repository": { + "type": "git", + "url": "git://github.com/LearnBoost/expect.js.git" + }, + "devDependencies": { + "mocha": "*", + "serve": "*" + }, + "bugs": { + "url": "https://github.com/LearnBoost/expect.js/issues" + }, + "homepage": "https://github.com/LearnBoost/expect.js", + "_id": "expect.js@0.3.1", + "dist": { + "shasum": "b0a59a0d2eff5437544ebf0ceaa6015841d09b5b", + "tarball": "http://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz" + }, + "_from": "expect.js@", + "_npmVersion": "1.4.2", + "_npmUser": { + "name": "rauchg", + "email": "rauchg@gmail.com" + }, + "maintainers": [ + { + "name": "rauchg", + "email": "rauchg@gmail.com" + } + ], + "directories": {}, + "_shasum": "b0a59a0d2eff5437544ebf0ceaa6015841d09b5b", + "_resolved": "https://registry.npmjs.org/expect.js/-/expect.js-0.3.1.tgz", + "readme": "ERROR: No README data found!" +} diff --git a/mocha/node_modules/nconf/.npmignore b/mocha/node_modules/nconf/.npmignore new file mode 100644 index 0000000..d049acd --- /dev/null +++ b/mocha/node_modules/nconf/.npmignore @@ -0,0 +1,10 @@ +.DS_Store +config.json +test/fixtures/*.json +!test/fixtures/complete.json +!test/fixtures/malformed.json +!test/fixtures/bom.json +!test/fixtures/no-bom.json +node_modules/ +node_modules/* +npm-debug.log diff --git a/mocha/node_modules/nconf/.travis.yml b/mocha/node_modules/nconf/.travis.yml new file mode 100644 index 0000000..cfec1b0 --- /dev/null +++ b/mocha/node_modules/nconf/.travis.yml @@ -0,0 +1,12 @@ +language: node_js +before_install: + - "npm i -g npm@1.4.28" +node_js: + - 0.8 + - 0.10 + - 0.11 +notifications: + email: + - travis@nodejitsu.com + irc: "irc.freenode.org#nodejitsu" + diff --git a/mocha/node_modules/nconf/CHANGELOG.md b/mocha/node_modules/nconf/CHANGELOG.md new file mode 100644 index 0000000..1d3f7ec --- /dev/null +++ b/mocha/node_modules/nconf/CHANGELOG.md @@ -0,0 +1,248 @@ + +v0.6.7 / Thu, 20 Dec 2012 +========================= + * [d77c55d](https://github.com/flatiron/nconf/commit/d77c55d) [dist] Version bump. 0.6.7 (`indexzero`) + * [bb57c49](https://github.com/flatiron/nconf/commit/bb57c49) Prefer this fix for #65 to 6045618 (`Michael Hart`) + +v0.6.6 / Thu, 20 Dec 2012 +========================= + * [aec2b4e](https://github.com/flatiron/nconf/commit/aec2b4e) [dist] Version bump. 0.6.6 (`indexzero`) + * [6045618](https://github.com/flatiron/nconf/commit/6045618) [fix] Fix for #65 (`indexzero`) + * [0d795ec](https://github.com/flatiron/nconf/commit/0d795ec) [test] Better tests to show #65 (`indexzero`) + * [f19f0b6](https://github.com/flatiron/nconf/commit/f19f0b6) [test] Added failing test to illustrate #65 (`indexzero`) + * [bcbaf3a](https://github.com/flatiron/nconf/commit/bcbaf3a) [dist] Bump version to 0.6.5 (`Maciej Małecki`) + * [8b65e19](https://github.com/flatiron/nconf/commit/8b65e19) [test] Test on newer node versions (`Maciej Małecki`) + * [8e987b8](https://github.com/flatiron/nconf/commit/8e987b8) make it possible to use other formats than json in common.loadFiles and common.loadFilesSync (`Christian Tellnes`) + * [da39d3c](https://github.com/flatiron/nconf/commit/da39d3c) [fix] null values should merge properly instead of throwing errors (`Bradley Meck`) + * [7421836](https://github.com/flatiron/nconf/commit/7421836) [fix] heirarchy fixture file path wrong in tests (`Bradley Meck`) + * [683f789](https://github.com/flatiron/nconf/commit/683f789) [fix] #59 root get/set should work via null/undefined as key (`Bradley Meck`) + * [0f092ab](https://github.com/flatiron/nconf/commit/0f092ab) Added docs for options hash to optimist. (`Ethan Winn`) + +v0.6.4 / Tue, 10 Jul 2012 +========================= + * [7279bc1](https://github.com/flatiron/nconf/commit/7279bc1) [dist] Version bump. 0.6.4 (`indexzero`) + * [d96d254](https://github.com/flatiron/nconf/commit/d96d254) [fix] Fix regression introduced by 36e061c4bda8d79f657dc24b1dcf1937f31d7efe (`indexzero`) + * [7e8d9d6](https://github.com/flatiron/nconf/commit/7e8d9d6) [test] Added failing test for `.save()` regression introduced by @russfrank in 36e061c4bda8d79f657dc24b1dcf1937f31d7efe (`indexzero`) + * [04e2230](https://github.com/flatiron/nconf/commit/04e2230) [minor doc] Update file header in test/provider-test.js (`indexzero`) + +v0.6.3 / Tue, 10 Jul 2012 +========================= + * [c7c6b6f](https://github.com/flatiron/nconf/commit/c7c6b6f) [dist] Version bump. 0.6.3 (`indexzero`) + * [3073430](https://github.com/flatiron/nconf/commit/3073430) [api test doc] Make options to `Provider.prototype.file` take more flexible options (`indexzero`) + * [8b53c12](https://github.com/flatiron/nconf/commit/8b53c12) [minor] Use locally scoped `path` variable (`indexzero`) + +v0.6.2 / Tue, 10 Jul 2012 +========================= + * [80a7973](https://github.com/flatiron/nconf/commit/80a7973) [dist] Version bump. 0.6.2 (`indexzero`) + * [7515f66](https://github.com/flatiron/nconf/commit/7515f66) [fix] Ensure that all options are passed to `Provider.prototype.add` in `Provider.prototype.file`. Fixes #51 [doc] Update README.md and method documentation [dist] Remove vim comments (`indexzero`) + +v0.6.1 / Sun, 8 Jul 2012 +======================== + * [eeddb70](https://github.com/flatiron/nconf/commit/eeddb70) [dist] Version bump. 0.6.1 (`indexzero`) + * [9aaafc5](https://github.com/flatiron/nconf/commit/9aaafc5) Ugh, fixed whitespace (`Michael Hart`) + * [3c08fad](https://github.com/flatiron/nconf/commit/3c08fad) Changed to as it's more accurate (`Michael Hart`) + * [e15f787](https://github.com/flatiron/nconf/commit/e15f787) Updated README and allowed a simpley syntax (`Michael Hart`) + * [92d4e9e](https://github.com/flatiron/nconf/commit/92d4e9e) Added test and updated docs (`Michael Hart`) + * [8921d05](https://github.com/flatiron/nconf/commit/8921d05) Added support for nested configs via env (`Michael Hart`) + * [6cbc323](https://github.com/flatiron/nconf/commit/6cbc323) Add reset to the list of destructive commands (`Michael Hart`) + * [26d81e8](https://github.com/flatiron/nconf/commit/26d81e8) Merge objects if necessary when traversing stores on get() (`Michael Hart`) + * [83440f9](https://github.com/flatiron/nconf/commit/83440f9) fix spelling in error message (`Christian Tellnes`) + * [87b0dd0](https://github.com/flatiron/nconf/commit/87b0dd0) [minor] Use `fs.exists` when available (`Maciej Małecki`) + * [1f67d35](https://github.com/flatiron/nconf/commit/1f67d35) [dist] Fix maintainers field (`Christian Howe`) + * [6353d02](https://github.com/flatiron/nconf/commit/6353d02) api and doc change for flatiron/nconf#28 (`.file` may now take a string instead of an object) (`Jonathan Stewmon`) + * [d3e6897](https://github.com/flatiron/nconf/commit/d3e6897) Proper teardowns in `complete-test.js` (`Russell Frank`) + * [94bdb7d](https://github.com/flatiron/nconf/commit/94bdb7d) Added `complete-test.js` & fixture. (`Russell Frank`) + * [36e061c](https://github.com/flatiron/nconf/commit/36e061c) Fixes to `Provider.save()` and tests. (`Russell Frank`) + * [29eb5f9](https://github.com/flatiron/nconf/commit/29eb5f9) [minor] Fix whitespaces (`Pavan Kumar Sunkara`) + * [6ce0b7a](https://github.com/flatiron/nconf/commit/6ce0b7a) Surfacing additional JSON.stringify arguments in formats.json.stringify, and adding the json_spacing option to the File constructor. (`Jordan Harband`) + * [b369931](https://github.com/flatiron/nconf/commit/b369931) [minor] Use `fs.existsSync` when available (`Maciej Małecki`) + * [d8c4749](https://github.com/flatiron/nconf/commit/d8c4749) [test] Test on `node@0.7` (`Maciej Małecki`) + * [464af41](https://github.com/flatiron/nconf/commit/464af41) [fix test] Fix bad test assertion (`indexzero`) + +v0.5.1 / Mon, 2 Jan 2012 +======================== + * [6a6e092](https://github.com/flatiron/nconf/commit/6a6e092) [dist] Version bump. 0.5.1 (`indexzero`) + * [6242caa](https://github.com/flatiron/nconf/commit/6242caa) [api minor] Add `.loadSync()` to Memory store. Fixes #24 (`indexzero`) + * [d0a9121](https://github.com/flatiron/nconf/commit/d0a9121) [test dist] Remove unused `eyes` dependency (`indexzero`) + * [9e9e37b](https://github.com/flatiron/nconf/commit/9e9e37b) [minor] Update whitespace (`indexzero`) + * [fdb73f0](https://github.com/flatiron/nconf/commit/fdb73f0) updated tests to verify that Provider.load respects hierarchy (`Jonathan Stewmon`) + * [a216336](https://github.com/flatiron/nconf/commit/a216336) updated Provider.load to respect sources hierarchy (`Jonathan Stewmon`) + * [6b6bf85](https://github.com/flatiron/nconf/commit/6b6bf85) updated optimist to version 0.3.x (`Jonathan Stewmon`) + * [5c43d54](https://github.com/flatiron/nconf/commit/5c43d54) fixed merge issue in Provider.load by reversing store keys in getStores (`Jonathan Stewmon`) + * [2804b1f](https://github.com/flatiron/nconf/commit/2804b1f) fixed issue caused by using same name for defaults and overrides (`Jonathan Stewmon`) + * [e0e070a](https://github.com/flatiron/nconf/commit/e0e070a) [test] Test if `File.saveSync()` returns store content (`Maciej Małecki`) + * [963387c](https://github.com/flatiron/nconf/commit/963387c) [api] `File.saveSync()` should return store content (`Maciej Małecki`) + * [d5ce1ed](https://github.com/flatiron/nconf/commit/d5ce1ed) [test] Test `saveSync()` method of file store (`Maciej Małecki`) + * [cf9889e](https://github.com/flatiron/nconf/commit/cf9889e) [dist] Upgrade vows to 0.6.x (`Pavan Kumar Sunkara`) + +v0.5.0 / Thu, 24 Nov 2011 +========================= + * [62cb7fb](https://github.com/flatiron/nconf/commit/62cb7fb) [dist] Version bump. 0.5.0 (`indexzero`) + * [6c720ee](https://github.com/flatiron/nconf/commit/6c720ee) [dist] Update Copyright and Author to Nodejitsu Inc. (`indexzero`) + * [4643a14](https://github.com/flatiron/nconf/commit/4643a14) [doc] Updated README and added CHANGELOG.md (`indexzero`) + * [90b0297](https://github.com/flatiron/nconf/commit/90b0297) [test] Update tests to use optional options API (`indexzero`) + * [53d854a](https://github.com/flatiron/nconf/commit/53d854a) [api] Default to `options` if `options.store` is not available in nconf.Literal (`indexzero`) + * [b658f68](https://github.com/flatiron/nconf/commit/b658f68) [test] Add additional test coverage for hierarchical configuration (`indexzero`) + * [a9c3540](https://github.com/flatiron/nconf/commit/a9c3540) [fix test] Fix overwritten tests in file-store-test.js (`indexzero`) + * [f4f1fdf](https://github.com/flatiron/nconf/commit/f4f1fdf) [fix test] Update to respected `.sources` option correctly (`indexzero`) + * [bbcb271](https://github.com/flatiron/nconf/commit/bbcb271) [api fix] Dont eagerly create config files in `.load()` and `.loadSync()` (`indexzero`) + * [021850a](https://github.com/flatiron/nconf/commit/021850a) [test] Move around test .json files (`indexzero`) + * [0fbc9a2](https://github.com/flatiron/nconf/commit/0fbc9a2) [test] Added tests (which are now passing) for #15 (`indexzero`) + * [16a18bf](https://github.com/flatiron/nconf/commit/16a18bf) [refactor] Expose all store prototypes on `nconf.*`. Expose store instances on Provider.stores and Provider.sources (`indexzero`) + * [c3cebe7](https://github.com/flatiron/nconf/commit/c3cebe7) [refactor] Rename `.sources` to `._stores` and bring back `._sources` (`indexzero`) + * [78ce556](https://github.com/flatiron/nconf/commit/78ce556) [minor] Dont allow `.set()` calls to change values in readOnly stores: argv, env, and literal (`indexzero`) + * [1aa2f1f](https://github.com/flatiron/nconf/commit/1aa2f1f) [doc] Updated README.md (`indexzero`) + * [47a56cc](https://github.com/flatiron/nconf/commit/47a56cc) [test] Test for hierarchical argv options get() (`Sander Tolsma`) + * [c3c315d](https://github.com/flatiron/nconf/commit/c3c315d) [refactor] Refactor to make using nconf more fluent. (`indexzero`) + * [2c1ef71](https://github.com/flatiron/nconf/commit/2c1ef71) [dist] Bump to v0.4.6 (`Marak Squires`) + * [1b258bf](https://github.com/flatiron/nconf/commit/1b258bf) [fix] Fix option parsing (`Maciej Małecki`) + * [ef3222e](https://github.com/flatiron/nconf/commit/ef3222e) [dist] Make `repository` point to `flatiron/nconf` (`Maciej Małecki`) + +v0.4.5 / Sun, 20 Nov 2011 +========================= + * [f4723e9](https://github.com/flatiron/nconf/commit/f4723e9) [dist] Version bump. 0.4.5 (`indexzero`) + * [2475d06](https://github.com/flatiron/nconf/commit/2475d06) [test] Test command line arguments reparsing (`Maciej Małecki`) + * [bbc5885](https://github.com/flatiron/nconf/commit/bbc5885) [api] Reparse argv arguments on `system.loadArgv()` (`Maciej Małecki`) + * [51700ca](https://github.com/flatiron/nconf/commit/51700ca) [test minor] Use `process.argv[0]` when spawning processes (`Maciej Małecki`) + * [07f8c3e](https://github.com/flatiron/nconf/commit/07f8c3e) [doc] Add Travis build status image (`Maciej Małecki`) + * [bab96b0](https://github.com/flatiron/nconf/commit/bab96b0) [test] Add `.travis.yml` for testing on Travis CI (`Maciej Małecki`) + +v0.4.4 / Sat, 22 Oct 2011 +========================= + * [b96151e](https://github.com/flatiron/nconf/commit/b96151e) [dist] Version bump. 0.4.4 (`indexzero`) + * [d8a3020](https://github.com/flatiron/nconf/commit/d8a3020) [fix] filename --> file in a few file transport examples (`Joshua Holbrook`) + * [2e33082](https://github.com/flatiron/nconf/commit/2e33082) [api] Automatically search for a file if `options.search` is true in File store (`indexzero`) + +v0.4.3 / Sun, 25 Sep 2011 +========================= + * [86e22cb](https://github.com/flatiron/nconf/commit/86e22cb) [dist] Version bump. 0.4.3 (`indexzero`) + * [a2464d2](https://github.com/flatiron/nconf/commit/a2464d2) [api] Load sources into the default system store so they are permenantly cached (`indexzero`) + +v0.4.2 / Sun, 25 Sep 2011 +========================= + * [e243b0b](https://github.com/flatiron/nconf/commit/e243b0b) [dist] Version bump. 0.4.2 (`indexzero`) + * [d0aee0d](https://github.com/flatiron/nconf/commit/d0aee0d) [api test] Added `.sources` option for `nconf.Provider` for readonly configuration data (`indexzero`) + * [0234e17](https://github.com/flatiron/nconf/commit/0234e17) [fix] Update bad variable reference (`indexzero`) + +v0.4.1 / Mon, 19 Sep 2011 +========================= + * [d334d07](https://github.com/flatiron/nconf/commit/d334d07) [dist] Version bump. 0.4.1 (`indexzero`) + * [a490c77](https://github.com/flatiron/nconf/commit/a490c77) [fix] Match case in `require` statements (`indexzero`) + +v0.4.0 / Sun, 18 Sep 2011 +========================= + * [0addce4](https://github.com/flatiron/nconf/commit/0addce4) [dist] Version bump. 0.4.0 (`indexzero`) + * [c4c8d7b](https://github.com/flatiron/nconf/commit/c4c8d7b) [doc] Updated docco docs (`indexzero`) + * [f867e74](https://github.com/flatiron/nconf/commit/f867e74) [dist] Remove unused test fixtures (`indexzero`) + * [1ef5797](https://github.com/flatiron/nconf/commit/1ef5797) [api test] Finished API and tests for hierarchical configuration storage. (`indexzero`) + * [7ef9b11](https://github.com/flatiron/nconf/commit/7ef9b11) [doc] Minor update to library `title` (`indexzero`) + * [a063880](https://github.com/flatiron/nconf/commit/a063880) [doc] Updated usage.js and README.md for the next hierarchical syntax. (`indexzero`) + * [da2da7a](https://github.com/flatiron/nconf/commit/da2da7a) [api test breaking refactor] Significant refactor to how nconf works. Now a fully hierarchical configuration storage mechanism capable of multiple levels of stores of the same type. (`indexzero`) + * [2bda7b6](https://github.com/flatiron/nconf/commit/2bda7b6) [api] Added `nconf.stores.System` (`indexzero`) + +v0.3.1 / Mon, 29 Aug 2011 +========================= + * [54ea095](https://github.com/flatiron/nconf/commit/54ea095) [dist] Version bump. 0.3.1 (`indexzero`) + * [e631d23](https://github.com/flatiron/nconf/commit/e631d23) [fix] Lazy-load any CLI arguments from `optimist` (`indexzero`) + +v0.3.0 / Sun, 28 Aug 2011 +========================= + * [8a31728](https://github.com/flatiron/nconf/commit/8a31728) [dist] Version bump. 0.3.0 (`indexzero`) + * [2e47d02](https://github.com/flatiron/nconf/commit/2e47d02) [doc] Updated README.md (`indexzero`) + * [954b5fd](https://github.com/flatiron/nconf/commit/954b5fd) [doc] Updated docco docs (`indexzero`) + * [fb392dd](https://github.com/flatiron/nconf/commit/fb392dd) [api test] Updated test/provider-test.js and associated merge implementation (`indexzero`) + * [e8904e9](https://github.com/flatiron/nconf/commit/e8904e9) [api] Added `nconf.loadFiles()` method (`indexzero`) + * [a6533aa](https://github.com/flatiron/nconf/commit/a6533aa) [dist api test] Finished integrating features from reconf and updating associated tests (`indexzero`) + * [add8922](https://github.com/flatiron/nconf/commit/add8922) [api dist] Begin to integrate features from reconf (`indexzero`) + * [57f0742](https://github.com/flatiron/nconf/commit/57f0742) [doc] Update README.md for nconf-redis (`indexzero`) + +v0.2.0 / Fri, 8 Jul 2011 +======================== + * [b6adab2](https://github.com/flatiron/nconf/commit/b6adab2) [dist] Version bump. 0.2.0 (`indexzero`) + * [8620e6b](https://github.com/flatiron/nconf/commit/8620e6b) [api test] Remove Redis store in preparation for nconf-redis (`indexzero`) + * [49a1a6d](https://github.com/flatiron/nconf/commit/49a1a6d) [dist] Added LICENSE (MIT ftw) (`indexzero`) + +0.1.14 / Sat, 25 Jun 2011 +========================= + * [d485f5e](https://github.com/flatiron/nconf/commit/d485f5e) [dist] Version bump. 0.1.14 (`indexzero`) + * [7e4623e](https://github.com/flatiron/nconf/commit/7e4623e) [api test] Update `nconf.Provider` to create a new instance of the store if the options are different (`indexzero`) + +v0.1.13 / Fri, 24 Jun 2011 +========================== + * [1b0f347](https://github.com/flatiron/nconf/commit/1b0f347) [dist] Version bump. 0.1.13 (`indexzero`) + * [d8b5a80](https://github.com/flatiron/nconf/commit/d8b5a80) [minor] Small style updates to the File store (`indexzero`) + * [c436851](https://github.com/flatiron/nconf/commit/c436851) [refactor]: Cleaned up error handling on File.loadSync and File.load [refactor]: Using path module to determine if file exists instead of throwing error [api]: File.load and File.loadSync will now automatically create the requested JSON file path if no file is found. (`Marak Squires`) + * [6c6887a](https://github.com/flatiron/nconf/commit/6c6887a) move callback outside of try / catch (`Dominic Tarr`) + +v0.1.12 / Wed, 8 Jun 2011 +========================= + * [ae5aec6](https://github.com/flatiron/nconf/commit/ae5aec6) [dist] Version bump. 0.1.12 (`indexzero`) + * [76db254](https://github.com/flatiron/nconf/commit/76db254) [fix test] Update nconf.stores.File to respond with an error when loading malformed JSON async (`indexzero`) + +v0.1.11 / Tue, 7 Jun 2011 +========================= + * [d7495f8](https://github.com/flatiron/nconf/commit/d7495f8) [dist] Version bump. 0.1.11 (`indexzero`) + * [4c7aea9](https://github.com/flatiron/nconf/commit/4c7aea9) [doc] Update docco docs (`indexzero`) + * [f611066](https://github.com/flatiron/nconf/commit/f611066) [dist] Update to pkginfo 0.2.0 (`indexzero`) + +v0.1.10 / Sun, 5 Jun 2011 +========================= + * [be76887](https://github.com/flatiron/nconf/commit/be76887) [dist] Version bump. 0.1.10 (`indexzero`) + * [7ffbf0a](https://github.com/flatiron/nconf/commit/7ffbf0a) [doc] Regenerate docco docs (`indexzero`) + * [13f5753](https://github.com/flatiron/nconf/commit/13f5753) [minor] Update `nconf.version` to use pkginfo (`indexzero`) + * [c9e60d9](https://github.com/flatiron/nconf/commit/c9e60d9) [doc] Update code docs (`indexzero`) + * [4459ba5](https://github.com/flatiron/nconf/commit/4459ba5) [api] Added `.merge()` to stores.Memory and stores.Redis (`indexzero`) + * [a4f00be](https://github.com/flatiron/nconf/commit/a4f00be) [dist] Update package.json and .gitignore (`indexzero`) + * [8a79ef0](https://github.com/flatiron/nconf/commit/8a79ef0) test retrieving non-existent keys and drilling into non-objects (`Sami Samhuri`) + * [6acc1fc](https://github.com/flatiron/nconf/commit/6acc1fc) allow storing null in redis (`Sami Samhuri`) + * [faa8ab9](https://github.com/flatiron/nconf/commit/faa8ab9) correctly retrieve falsy values from memory (hence file) (`Sami Samhuri`) + * [bdf2fc8](https://github.com/flatiron/nconf/commit/bdf2fc8) [fix] Fixed spelling error (`avian`) + * [e7c216e](https://github.com/flatiron/nconf/commit/e7c216e) [minor] Clarified error message returned when a config file contains invalid JSON. (`avian`) + * [e26bbe2](https://github.com/flatiron/nconf/commit/e26bbe2) [doc] Updated code samples for GitHub flavored markdown with Javascript (`indexzero`) + +v0.1.9 / Mon, 16 May 2011 +========================= + * [78202ec](https://github.com/flatiron/nconf/commit/78202ec) [dist] Version bump. 0.1.9 (`indexzero`) + * [87351ca](https://github.com/flatiron/nconf/commit/87351ca) [fix] Use the memory engine by default (`indexzero`) + +v0.1.8 / Mon, 16 May 2011 +========================= + * [badbb59](https://github.com/flatiron/nconf/commit/badbb59) [dist] Version bump. 0.1.8 (`indexzero`) + * [9da37df](https://github.com/flatiron/nconf/commit/9da37df) [dist api test] Refactor pluggable nconf-level logic into nconf.Provider. Update .gitignore for npm 1.0. Update pathing in source and tests to be more `require.paths` future-proof (`indexzero`) + +v0.1.7 / Wed, 20 Apr 2011 +========================= + * [4a61560](https://github.com/flatiron/nconf/commit/4a61560) [dist] Version bump. 0.1.7 (`indexzero`) + * [3b104f2](https://github.com/flatiron/nconf/commit/3b104f2) [doc] Update docco docs (`indexzero`) + * [d65922d](https://github.com/flatiron/nconf/commit/d65922d) [api] Add `.saveSync()` and `.loadSync()` methods to File store (`indexzero`) + +v0.1.6 / Tue, 19 Apr 2011 +========================= + * [b9951b4](https://github.com/flatiron/nconf/commit/b9951b4) [dist] Version bump. 0.1.6. (`indexzero`) + * [da85594](https://github.com/flatiron/nconf/commit/da85594) [doc] Update docco docs (`indexzero`) + * [067d58a](https://github.com/flatiron/nconf/commit/067d58a) [minor test] Add tests for File store `save()`. Improve default file format to pretty print the JSON output (`indexzero`) + +v0.1.5 / Wed, 13 Apr 2011 +========================= + * [96859f9](https://github.com/flatiron/nconf/commit/96859f9) [dist] Version bump. 0.1.5 (`indexzero`) + * [d99ab32](https://github.com/flatiron/nconf/commit/d99ab32) [fix] Dont allow `async.forEach` to be called on undefined or null arrays (`indexzero`) + +v0.1.4 / Tue, 5 Apr 2011 +======================== + * [7484fdb](https://github.com/flatiron/nconf/commit/7484fdb) [dist] Version bump. 0.1.4 (`indexzero`) + * [04a59e9](https://github.com/flatiron/nconf/commit/04a59e9) [fix] Supress errors from Redis (`indexzero`) + +v0.1.3 / Tue, 5 Apr 2011 +======================== + * [9bd6e26](https://github.com/flatiron/nconf/commit/9bd6e26) [dist] Version bump. 0.1.3 (`indexzero`) + * [4094125](https://github.com/flatiron/nconf/commit/4094125) [api] Add support for Redis auth and optional callbacks. (`indexzero`) + +v0.1.2 / Sun, 3 Apr 2011 +======================== + * [81e1883](https://github.com/flatiron/nconf/commit/81e1883) [dist] Version bump. 0.1.2 (`indexzero`) + * [b850ae2](https://github.com/flatiron/nconf/commit/b850ae2) [fix] Update path to require statement in Redis store (`indexzero`) + +v0.1.1 / Sat, 2 Apr 2011 +======================== + * [6f16bc7](https://github.com/flatiron/nconf/commit/6f16bc7) [dist] Version bump. 0.1.1 (`indexzero`) + * [752bb98](https://github.com/flatiron/nconf/commit/752bb98) [api] Improve the `.use()` method. Use the memory engine by default (`indexzero`) diff --git a/mocha/node_modules/nconf/LICENSE b/mocha/node_modules/nconf/LICENSE new file mode 100644 index 0000000..14bac73 --- /dev/null +++ b/mocha/node_modules/nconf/LICENSE @@ -0,0 +1,19 @@ +Copyright (C) 2011 Charlie Robbins and the Contributors. + +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. diff --git a/mocha/node_modules/nconf/README.md b/mocha/node_modules/nconf/README.md new file mode 100644 index 0000000..c7314c1 --- /dev/null +++ b/mocha/node_modules/nconf/README.md @@ -0,0 +1,279 @@ +# nconf [![Build Status](https://secure.travis-ci.org/flatiron/nconf.png)](http://travis-ci.org/flatiron/nconf) + +Hierarchical node.js configuration with files, environment variables, command-line arguments, and atomic object merging. + +## Example +Using nconf is easy; it is designed to be a simple key-value store with support for both local and remote storage. Keys are namespaced and delimited by `:`. Lets dive right into sample usage: + +``` js + var fs = require('fs'), + nconf = require('nconf'); + + // + // Setup nconf to use (in-order): + // 1. Command-line arguments + // 2. Environment variables + // 3. A file located at 'path/to/config.json' + // + nconf.argv() + .env() + .file({ file: 'path/to/config.json' }); + + // + // Set a few variables on `nconf`. + // + nconf.set('database:host', '127.0.0.1'); + nconf.set('database:port', 5984); + + // + // Get the entire database object from nconf. This will output + // { host: '127.0.0.1', port: 5984 } + // + console.log('foo: ' + nconf.get('foo')); + console.log('NODE_ENV: ' + nconf.get('NODE_ENV')); + console.log('database: ' + nconf.get('database')); + + // + // Save the configuration object to disk + // + nconf.save(function (err) { + fs.readFile('path/to/your/config.json', function (err, data) { + console.dir(JSON.parse(data.toString())) + }); + }); +``` + +If you run the above script: + +``` bash + $ NODE_ENV=production sample.js --foo bar +``` + +The output will be: + +``` + foo: bar + NODE_ENV: production + database: { host: '127.0.0.1', port: 5984 } +``` + +## Hierarchical configuration + +Configuration management can get complicated very quickly for even trivial applications running in production. `nconf` addresses this problem by enabling you to setup a hierarchy for different sources of configuration with no defaults. **The order in which you attach these configuration sources determines their priority in the hierarchy.** Lets take a look at the options available to you + + 1. **nconf.argv(options)** Loads `process.argv` using optimist. If `options` is supplied it is passed along to optimist. + 2. **nconf.env(options)** Loads `process.env` into the hierarchy. + 3. **nconf.file(options)** Loads the configuration data at options.file into the hierarchy. + 4. **nconf.defaults(options)** Loads the data in options.store into the hierarchy. + 5. **nconf.overrides(options)** Loads the data in options.store into the hierarchy. + +A sane default for this could be: + +``` js + var nconf = require('nconf'); + + // + // 1. any overrides + // + nconf.overrides({ + 'always': 'be this value' + }); + + // + // 2. `process.env` + // 3. `process.argv` + // + nconf.env().argv(); + + // + // 4. Values in `config.json` + // + nconf.file('/path/to/config.json'); + + // + // Or with a custom name + // Note: A custom key must be supplied for hierarchy to work if multiple files are used. + // + nconf.file('custom', '/path/to/config.json'); + + // + // Or searching from a base directory. + // Note: `name` is optional. + // + nconf.file(name, { + file: 'config.json', + dir: 'search/from/here', + search: true + }); + + // + // 5. Any default values + // + nconf.defaults({ + 'if nothing else': 'use this value' + }); +``` + +## API Documentation + +The top-level of `nconf` is an instance of the `nconf.Provider` abstracts this all for you into a simple API. + +### nconf.add(name, options) +Adds a new store with the specified `name` and `options`. If `options.type` is not set, then `name` will be used instead: + +``` js + nconf.add('supplied', { type: 'literal', store: { 'some': 'config' }); + nconf.add('user', { type: 'file', file: '/path/to/userconf.json' }); + nconf.add('global', { type: 'file', file: '/path/to/globalconf.json' }); +``` + +### nconf.use(name, options) +Similar to `nconf.add`, except that it can replace an existing store if new options are provided + +``` js + // + // Load a file store onto nconf with the specified settings + // + nconf.use('file', { file: '/path/to/some/config-file.json' }); + + // + // Replace the file store with new settings + // + nconf.use('file', { file: 'path/to/a-new/config-file.json' }); +``` + +### nconf.remove(name) +Removes the store with the specified `name.` The configuration stored at that level will no longer be used for lookup(s). + +``` js + nconf.remove('file'); +``` + +## Storage Engines + +### Memory +A simple in-memory storage engine that stores a nested JSON representation of the configuration. To use this engine, just call `.use()` with the appropriate arguments. All calls to `.get()`, `.set()`, `.clear()`, `.reset()` methods are synchronous since we are only dealing with an in-memory object. + +``` js + nconf.use('memory'); +``` + +### Argv +Responsible for loading the values parsed from `process.argv` by `optimist` into the configuration hierarchy. See the [optimist option docs](https://github.com/substack/node-optimist/#optionskey-opt) for more on the option format. + +``` js + // + // Can optionally also be an object literal to pass to `optimist`. + // + nconf.argv({ + "x": { + alias: 'example', + describe: 'Example description for usage generation', + demand: true, + default: 'some-value' + } + }); +``` + +### Env +Responsible for loading the values parsed from `process.env` into the configuration hierarchy. + +``` js + // + // Can optionally also be an Array of values to limit process.env to. + // + nconf.env(['only', 'load', 'these', 'values', 'from', 'process.env']); + + // + // Can also specify a separator for nested keys (instead of the default ':') + // + nconf.env('__'); + // Get the value of the env variable 'database__host' + var dbHost = nconf.get('database:host'); + + // + // Or use all options + // + nconf.env({ + separator: '__', + match: /^whatever_matches_this_will_be_whitelisted/ + whitelist: ['database__host', 'only', 'load', 'these', 'values', 'if', 'whatever_doesnt_match_but_is_whitelisted_gets_loaded_too'] + }); + var dbHost = nconf.get('database:host'); +``` + +### Literal +Loads a given object literal into the configuration hierarchy. Both `nconf.defaults()` and `nconf.overrides()` use the Literal store. + +``` js + nconf.defaults({ + 'some': 'default value' + }); +``` + +### File +Based on the Memory store, but provides additional methods `.save()` and `.load()` which allow you to read your configuration to and from file. As with the Memory store, all method calls are synchronous with the exception of `.save()` and `.load()` which take callback functions. It is important to note that setting keys in the File engine will not be persisted to disk until a call to `.save()` is made. Note a custom key must be supplied as the first parameter for hierarchy to work if multiple files are used. + +``` js + nconf.file('path/to/your/config.json'); + // add multiple files, hierarchically. notice the unique key for each file + nconf.file('user', 'path/to/your/user.json'); + nconf.file('global', 'path/to/your/global.json'); +``` + +The file store is also extensible for multiple file formats, defaulting to `JSON`. To use a custom format, simply pass a format object to the `.use()` method. This object must have `.parse()` and `.stringify()` methods just like the native `JSON` object. + +If the file does not exist at the provided path, the store will simply be empty. + +### Redis +There is a separate Redis-based store available through [nconf-redis][0]. To install and use this store simply: + +``` bash + $ npm install nconf + $ npm install nconf-redis +``` + +Once installing both `nconf` and `nconf-redis`, you must require both modules to use the Redis store: + +``` js + var nconf = require('nconf'); + + // + // Requiring `nconf-redis` will extend the `nconf` + // module. + // + require('nconf-redis'); + + nconf.use('redis', { host: 'localhost', port: 6379, ttl: 60 * 60 * 1000 }); +``` + +## Installation + +### Installing npm (node package manager) +``` + curl http://npmjs.org/install.sh | sh +``` + +### Installing nconf +``` + [sudo] npm install nconf +``` + +## More Documentation +There is more documentation available through docco. I haven't gotten around to making a gh-pages branch so in the meantime if you clone the repository you can view the docs: + +``` + open docs/nconf.html +``` + +## Run Tests +Tests are written in vows and give complete coverage of all APIs and storage engines. + +``` bash + $ npm test +``` + +#### Author: [Charlie Robbins](http://nodejitsu.com) +#### License: MIT + +[0]: http://github.com/indexzero/nconf-redis diff --git a/mocha/node_modules/nconf/docs/docco.css b/mocha/node_modules/nconf/docs/docco.css new file mode 100644 index 0000000..bd54134 --- /dev/null +++ b/mocha/node_modules/nconf/docs/docco.css @@ -0,0 +1,194 @@ +/*--------------------- Layout and Typography ----------------------------*/ +body { + font-family: 'Palatino Linotype', 'Book Antiqua', Palatino, FreeSerif, serif; + font-size: 15px; + line-height: 22px; + color: #252519; + margin: 0; padding: 0; +} +a { + color: #261a3b; +} + a:visited { + color: #261a3b; + } +p { + margin: 0 0 15px 0; +} +h4, h5, h6 { + color: #333; + margin: 6px 0 6px 0; + font-size: 13px; +} + h2, h3 { + margin-bottom: 0; + color: #000; + } + h1 { + margin-top: 40px; + margin-bottom: 15px; + color: #000; + } +#container { + position: relative; +} +#background { + position: fixed; + top: 0; left: 525px; right: 0; bottom: 0; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + z-index: -1; +} +#jump_to, #jump_page { + background: white; + -webkit-box-shadow: 0 0 25px #777; -moz-box-shadow: 0 0 25px #777; + -webkit-border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; + font: 10px Arial; + text-transform: uppercase; + cursor: pointer; + text-align: right; +} +#jump_to, #jump_wrapper { + position: fixed; + right: 0; top: 0; + padding: 5px 10px; +} + #jump_wrapper { + padding: 0; + display: none; + } + #jump_to:hover #jump_wrapper { + display: block; + } + #jump_page { + padding: 5px 0 3px; + margin: 0 0 25px 25px; + } + #jump_page .source { + display: block; + padding: 5px 10px; + text-decoration: none; + border-top: 1px solid #eee; + } + #jump_page .source:hover { + background: #f5f5ff; + } + #jump_page .source:first-child { + } +table td { + border: 0; + outline: 0; +} + td.docs, th.docs { + max-width: 450px; + min-width: 450px; + min-height: 5px; + padding: 10px 25px 1px 50px; + overflow-x: hidden; + vertical-align: top; + text-align: left; + } + .docs pre { + margin: 15px 0 15px; + padding-left: 15px; + } + .docs p tt, .docs p code { + background: #f8f8ff; + border: 1px solid #dedede; + font-size: 12px; + padding: 0 0.2em; + } + .pilwrap { + position: relative; + } + .pilcrow { + font: 12px Arial; + text-decoration: none; + color: #454545; + position: absolute; + top: 3px; left: -20px; + padding: 1px 2px; + opacity: 0; + -webkit-transition: opacity 0.2s linear; + } + td.docs:hover .pilcrow { + opacity: 1; + } + td.code, th.code { + padding: 14px 15px 16px 25px; + width: 100%; + vertical-align: top; + background: #f5f5ff; + border-left: 1px solid #e5e5ee; + } + pre, tt, code { + font-size: 12px; line-height: 18px; + font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace; + margin: 0; padding: 0; + } + + +/*---------------------- Syntax Highlighting -----------------------------*/ +td.linenos { background-color: #f0f0f0; padding-right: 10px; } +span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; } +body .hll { background-color: #ffffcc } +body .c { color: #408080; font-style: italic } /* Comment */ +body .err { border: 1px solid #FF0000 } /* Error */ +body .k { color: #954121 } /* Keyword */ +body .o { color: #666666 } /* Operator */ +body .cm { color: #408080; font-style: italic } /* Comment.Multiline */ +body .cp { color: #BC7A00 } /* Comment.Preproc */ +body .c1 { color: #408080; font-style: italic } /* Comment.Single */ +body .cs { color: #408080; font-style: italic } /* Comment.Special */ +body .gd { color: #A00000 } /* Generic.Deleted */ +body .ge { font-style: italic } /* Generic.Emph */ +body .gr { color: #FF0000 } /* Generic.Error */ +body .gh { color: #000080; font-weight: bold } /* Generic.Heading */ +body .gi { color: #00A000 } /* Generic.Inserted */ +body .go { color: #808080 } /* Generic.Output */ +body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */ +body .gs { font-weight: bold } /* Generic.Strong */ +body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +body .gt { color: #0040D0 } /* Generic.Traceback */ +body .kc { color: #954121 } /* Keyword.Constant */ +body .kd { color: #954121; font-weight: bold } /* Keyword.Declaration */ +body .kn { color: #954121; font-weight: bold } /* Keyword.Namespace */ +body .kp { color: #954121 } /* Keyword.Pseudo */ +body .kr { color: #954121; font-weight: bold } /* Keyword.Reserved */ +body .kt { color: #B00040 } /* Keyword.Type */ +body .m { color: #666666 } /* Literal.Number */ +body .s { color: #219161 } /* Literal.String */ +body .na { color: #7D9029 } /* Name.Attribute */ +body .nb { color: #954121 } /* Name.Builtin */ +body .nc { color: #0000FF; font-weight: bold } /* Name.Class */ +body .no { color: #880000 } /* Name.Constant */ +body .nd { color: #AA22FF } /* Name.Decorator */ +body .ni { color: #999999; font-weight: bold } /* Name.Entity */ +body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */ +body .nf { color: #0000FF } /* Name.Function */ +body .nl { color: #A0A000 } /* Name.Label */ +body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */ +body .nt { color: #954121; font-weight: bold } /* Name.Tag */ +body .nv { color: #19469D } /* Name.Variable */ +body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */ +body .w { color: #bbbbbb } /* Text.Whitespace */ +body .mf { color: #666666 } /* Literal.Number.Float */ +body .mh { color: #666666 } /* Literal.Number.Hex */ +body .mi { color: #666666 } /* Literal.Number.Integer */ +body .mo { color: #666666 } /* Literal.Number.Oct */ +body .sb { color: #219161 } /* Literal.String.Backtick */ +body .sc { color: #219161 } /* Literal.String.Char */ +body .sd { color: #219161; font-style: italic } /* Literal.String.Doc */ +body .s2 { color: #219161 } /* Literal.String.Double */ +body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */ +body .sh { color: #219161 } /* Literal.String.Heredoc */ +body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */ +body .sx { color: #954121 } /* Literal.String.Other */ +body .sr { color: #BB6688 } /* Literal.String.Regex */ +body .s1 { color: #219161 } /* Literal.String.Single */ +body .ss { color: #19469D } /* Literal.String.Symbol */ +body .bp { color: #954121 } /* Name.Builtin.Pseudo */ +body .vc { color: #19469D } /* Name.Variable.Class */ +body .vg { color: #19469D } /* Name.Variable.Global */ +body .vi { color: #19469D } /* Name.Variable.Instance */ +body .il { color: #666666 } /* Literal.Number.Integer.Long */ \ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf.html b/mocha/node_modules/nconf/docs/nconf.html new file mode 100644 index 0000000..cb9a1f9 --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf.html @@ -0,0 +1,20 @@ + nconf.js

nconf.js

/*
+ * nconf.js: Top-level include for the nconf module
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+
+var fs = require('fs'),
+    async = require('async'),
+    common = require('./nconf/common'),
+    Provider = require('./nconf/provider').Provider,
+    nconf = module.exports = new Provider();

Expose the version from the package.json using pkginfo.

require('pkginfo')(module, 'version');

Expose the various components included with nconf

nconf.key           = common.key;
+nconf.path          = common.path;
+nconf.loadFiles     = common.loadFiles;
+nconf.loadFilesSync = common.loadFilesSync;
+nconf.formats       = require('./nconf/formats');
+nconf.stores        = require('./nconf/stores');
+nconf.Provider      = Provider;
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf/common.html b/mocha/node_modules/nconf/docs/nconf/common.html new file mode 100644 index 0000000..5c359ce --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf/common.html @@ -0,0 +1,85 @@ + common.js

common.js

/*
+ * utils.js: Utility functions for the nconf module.
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+ 
+var fs = require('fs'),
+    async = require('async'),
+    formats = require('./formats'),
+    Memory = require('./stores/Memory').Memory;
+
+var common = exports;

function path (key)

+ +

@key {string} The ':' delimited key to split

+ +

Returns a fully-qualified path to a nested nconf key.

common.path = function (key) {
+  return key.split(':');
+};

function key (arguments)

+ +

Returns a : joined string from the arguments.

common.key = function () {
+  return Array.prototype.slice.call(arguments).join(':');
+};

function loadFiles (files, callback)

+ +

@files {Object|Array} List of files (or settings object) to load.

+ +

@callback {function} Continuation to respond to when complete.

+ +

Loads all the data in the specified files.

common.loadFiles = function (files, callback) {
+  if (!files) {
+    return callback(null, {});
+  }
+
+  var options = Array.isArray(files) ? { files: files } : files;

Set the default JSON format if not already +specified

  options.format = options.format || formats.json;
+
+  function parseFile (file, next) {
+    fs.readFile(file, function (err, data) {
+      return !err 
+        ? next(null, options.format.parse(data.toString()))
+        : next(err);
+    });
+  }
+
+  async.map(files, parseFile, function (err, objs) {
+    return err ? callback(err) : callback(null, common.merge(objs));
+  });
+};

function loadFilesSync (files)

+ +

@files {Object|Array} List of files (or settings object) to load.

+ +

Loads all the data in the specified files synchronously.

common.loadFilesSync = function (files) {
+  if (!files) {
+    return;
+  }

Set the default JSON format if not already +specified

  var options = Array.isArray(files) ? { files: files } : files;
+  options.format = options.format || formats.json;
+
+  return common.merge(files.map(function (file) {
+    return options.format.parse(fs.readFileSync(file, 'utf8'));
+  }));
+};

function merge (objs)

+ +

@objs {Array} Array of object literals to merge

+ +

Merges the specified objs using a temporary instance +of stores.Memory.

common.merge = function (objs) {
+  var store = new Memory();
+  
+  objs.forEach(function (obj) {
+    Object.keys(obj).forEach(function (key) {
+      store.merge(key, obj[key]);
+    });
+  });
+  
+  return store.store;
+};

function capitalize (str)

+ +

@str {string} String to capitalize

+ +

Capitalizes the specified str.

common.capitalize = function (str) {
+  return str && str[0].toUpperCase() + str.slice(1);
+};
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf/formats.html b/mocha/node_modules/nconf/docs/nconf/formats.html new file mode 100644 index 0000000..a2ab2f5 --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf/formats.html @@ -0,0 +1,22 @@ + formats.js

formats.js

/*
+ * formats.js: Default formats supported by nconf
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+
+var ini = require('ini');
+
+var formats = exports;

@json

+ +

Standard JSON format which pretty prints .stringify().

formats.json = {
+  stringify: function (obj) {
+    return JSON.stringify(obj, null, 2)
+  },
+  parse: JSON.parse
+};

@ini

+ +

Standard INI format supplied from the ini module +http://en.wikipedia.org/wiki/INI_file

formats.ini = ini;
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf/provider.html b/mocha/node_modules/nconf/docs/nconf/provider.html new file mode 100644 index 0000000..66c6718 --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf/provider.html @@ -0,0 +1,378 @@ + provider.js

provider.js

/*
+ * provider.js: Abstraction providing an interface into pluggable configuration storage.
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+
+var async = require('async'),
+    common = require('./common'),
+    stores = require('./stores');

function Provider (options)

+ +

@options {Object} Options for this instance.

+ +

Constructor function for the Provider object responsible +for exposing the pluggable storage features of nconf.

var Provider = exports.Provider = function (options) {
+  var self = this;  
+  

Setup default options for working with stores, +overrides, process.env and process.argv.

  options         = options           || {};
+  this._overrides = options.overrides || null;
+  this._argv      = options.argv      || false;
+  this._env       = options.env       || false;
+  this._reserved  = Object.keys(Provider.prototype);
+  this._stores    = [];
+  

Add the default system store for working with +overrides, process.env, process.argv and +a simple in-memory objects.

  this.add('system', options);
+  
+  if (options.type) {
+    this.add(options.type, options);
+  }
+  else if (options.store) {
+    this.add(options.store.name || options.store.type, options.store);
+  }
+  else if (options.stores) {
+    Object.keys(options.stores).forEach(function (store) {
+      self.add(store.name || store.type, store);
+    });
+  }
+};

function use (name, options)

+ +

@type {string} Type of the nconf store to use.

+ +

@options {Object} Options for the store instance.

+ +

Adds (or replaces) a new store with the specified name +and options. If options.type is not set, then name +will be used instead:

+ +

provider.use('file'); + provider.use('file', { type: 'file', filename: '/path/to/userconf' })

Provider.prototype.use = function (name, options) {
+  if (name === 'system') {
+    return;
+  }
+  else if (this._reserved.indexOf(name) !== -1) {
+    throw new Error('Cannot use reserved name: ' + name);
+  }
+  
+  options  = options      || {};
+  var type = options.type || name;
+
+  function sameOptions (store) {
+    return Object.keys(options).every(function (key) {
+      return options[key] === store[key];
+    });
+  }
+  
+  var store = this[name],
+      update = store && !sameOptions(store);
+  
+  if (!store || update) {
+    if (update) {
+      this.remove(name);
+    }
+    
+    this.add(name, options);
+  }
+  
+  return this;
+};

function add (name, options)

+ +

@name {string} Name of the store to add to this instance

+ +

@options {Object} Options for the store to create

+ +

Adds a new store with the specified name and options. If options.type +is not set, then name will be used instead:

+ +

provider.add('memory'); + provider.add('userconf', { type: 'file', filename: '/path/to/userconf' })

Provider.prototype.add = function (name, options) {
+  if (this._reserved.indexOf(name) !== -1) {
+    throw new Error('Cannot use reserved name: ' + name);
+  }
+  
+  options  = options      || {};
+  var type = options.type || name;
+  
+  if (Object.keys(stores).indexOf(common.capitalize(type)) === -1) {
+    throw new Error('Cannot add store with unknown type: ' + type);
+  }
+  
+  this[name] = this.create(type, options);
+  this._stores.push(name);
+  
+  if (this[name].loadSync) {
+    this[name].loadSync();
+  }
+};

function remove (name)

+ +

@name {string} Name of the store to remove from this instance

+ +

Removes a store with the specified name from this instance. Users +are allowed to pass in a type argument (e.g. memory) as name if +this was used in the call to .add().

Provider.prototype.remove = function (name) {
+  if (this._reserved.indexOf(name) !== -1) {
+    throw new Error('Cannot use reserved name: ' + name);
+  }
+  else if (!this[name]) {
+    throw new Error('Cannot remove store that does not exist: ' + name);
+  }
+  
+  delete this[name];
+  this._stores.splice(this._stores.indexOf(name), 1);
+};

function create (type, options)

+ +

@type {string} Type of the nconf store to use.

+ +

@options {Object} Options for the store instance.

+ +

Creates a store of the specified type using the +specified options.

Provider.prototype.create = function (type, options) {
+  return new stores[common.capitalize(type.toLowerCase())](options);
+};

function get (key, callback)

+ +

@key {string} Key to retrieve for this instance.

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Retrieves the value for the specified key (if any).

Provider.prototype.get = function (key, callback) {

If there is no callback we can short-circuit into the default +logic for traversing stores.

  if (!callback) {
+    return this._execute('get', 1, key, callback);
+  }
+  

Otherwise the asynchronous, hierarchical get is +slightly more complicated because we do not need to traverse +the entire set of stores, but up until there is a defined value.

  var current = 0,
+      self = this,
+      response;
+      
+  async.whilst(function () {
+    return typeof response === 'undefined' && current < self._stores.length;
+  }, function (next) {
+    var store = self[self._stores[current]];
+    current++;
+    
+    if (store.get.length >= 2) {
+      return store.get(key, function (err, value) {
+        if (err) {
+          return next(err);
+        }
+        
+        response = value;
+        next();
+      });
+    }
+    
+    response = store.get(key);
+    next();
+  }, function (err) {
+    return err ? callback(err) : callback(null, response);
+  });
+};

function set (key, value, callback)

+ +

@key {string} Key to set in this instance

+ +

@value {literal|Object} Value for the specified key

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Sets the value for the specified key in this instance.

Provider.prototype.set = function (key, value, callback) {
+  return this._execute('set', 2, key, value, callback);
+};

function reset (callback)

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Clears all keys associated with this instance.

Provider.prototype.reset = function (callback) {
+  return this._execute('reset', 0, callback);  
+};

function clear (key, callback)

+ +

@key {string} Key to remove from this instance

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Removes the value for the specified key from this instance.

Provider.prototype.clear = function (key, callback) {
+  return this._execute('clear', 1, key, callback);
+};

function merge ([key,] value [, callback])

+ +

@key {string} Key to merge the value into

+ +

@value {literal|Object} Value to merge into the key

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Merges the properties in value into the existing object value at key.

+ +
    +
  1. If the existing value key is not an Object, it will be completely overwritten.
  2. +
  3. If key is not supplied, then the value will be merged into the root.
  4. +
Provider.prototype.merge = function () {
+  var self = this,
+      args = Array.prototype.slice.call(arguments),
+      callback = typeof args[args.length - 1] === 'function' && args.pop(),
+      value = args.pop(),
+      key = args.pop();
+      
+  function mergeProperty (prop, next) {
+    return self._execute('merge', 2, prop, value[prop], next);
+  }
+      
+  if (!key) {
+    if (Array.isArray(value) || typeof value !== 'object') {
+      return onError(new Error('Cannot merge non-Object into top-level.'), callback);
+    }
+    
+    return async.forEach(Object.keys(value), mergeProperty, callback || function () { })
+  }
+  
+  return this._execute('merge', 2, key, value, callback);
+};

function load (callback)

+ +

@callback {function} Continuation to respond to when complete.

+ +

Responds with an Object representing all keys associated in this instance.

Provider.prototype.load = function (callback) {
+  var self = this;
+  
+  function loadStoreSync(name) {
+    var store = self[name];
+    
+    if (!store.loadSync) {
+      throw new Error('nconf store ' + store.type + ' has no loadSync() method');
+    }
+    
+    return store.loadSync();
+  }
+  
+  function loadStore(name, next) {
+    var store = self[name];
+    
+    if (!store.load && !store.loadSync) {
+      return next(new Error('nconf store ' + store.type + ' has no load() method'));
+    }
+    
+    return store.loadSync
+      ? next(null, store.loadSync())
+      : store.load(next);
+  }
+  

If we don't have a callback and the current +store is capable of loading synchronously +then do so.

  if (!callback) {
+    return common.merge(this._stores.map(loadStoreSync));
+  }
+  
+  async.map(this._stores, loadStore, function (err, objs) {
+    return err ? callback(err) : callback(null, common.merge(objs));
+  });
+};

function save (value, callback)

+ +

@value {Object} Optional Config object to set for this instance

+ +

@callback {function} Continuation to respond to when complete.

+ +

Removes any existing configuration settings that may exist in this +instance and then adds all key-value pairs in value.

Provider.prototype.save = function (value, callback) {
+  if (!callback && typeof value === 'function') {
+    callback = value;
+    value = null;
+  }
+  
+  var self = this;
+  
+  function saveStoreSync(name) {
+    var store = self[name];
+    
+    if (!store.saveSync) {
+      throw new Error('nconf store ' + store.type + ' has no saveSync() method');
+    }
+    
+    return store.saveSync();
+  }
+  
+  function saveStore(name, next) {
+    var store = self[name];
+    
+    if (!store.save && !store.saveSync) {
+      return next(new Error('nconf store ' + store.type + ' has no save() method'));
+    }
+    
+    return store.saveSync
+      ? next(null, store.saveSync())
+      : store.save(next);
+  }
+  

If we don't have a callback and the current +store is capable of saving synchronously +then do so.

  if (!callback) {
+    return common.merge(this._stores.map(saveStoreSync));
+  }
+  
+  async.map(this._stores, saveStore, function (err, objs) {
+    return err ? callback(err) : callback();
+  });  
+};

@private function _execute (action, syncLength, [arguments])

+ +

@action {string} Action to execute on this.store.

+ +

@syncLength {number} Function length of the sync version.

+ +

@arguments {Array} Arguments array to apply to the action

+ +

Executes the specified action on all stores for this instance, ensuring a callback supplied +to a synchronous store function is still invoked.

Provider.prototype._execute = function (action, syncLength /* [arguments] */) {
+  var args = Array.prototype.slice.call(arguments, 2),
+      callback = typeof args[args.length - 1] === 'function' && args.pop(),
+      self = this,
+      response;
+  
+  function runAction (name, next) {
+    var store = self[name]
+    
+    return store[action].length > syncLength
+      ? store[action].apply(store, args.concat(next))
+      : next(null, store[action].apply(store, args));
+  }
+  
+  if (callback) {
+    return async.forEach(self._stores, runAction, function (err) {
+      return err ? callback(err) : callback();
+    });
+  }
+
+  this._stores.forEach(function (name) {
+    var store = self[name];
+    response = store[action].apply(store, args);
+  });
+    
+  return response;
+}

@argv {boolean}

+ +

Gets or sets a property representing overrides which supercede all +other values for this instance.

Provider.prototype.__defineSetter__('overrides', function (val) { updateSystem.call(this, 'overrides', val) });
+Provider.prototype.__defineGetter__('overrides', function () { return this._argv });

@argv {boolean}

+ +

Gets or sets a property indicating if we should wrap calls to .get +by checking optimist.argv. Can be a boolean or the pass-thru +options for optimist.

Provider.prototype.__defineSetter__('argv', function (val) { updateSystem.call(this, 'argv', val) });
+Provider.prototype.__defineGetter__('argv', function () { return this._argv });

@env {boolean}

+ +

Gets or sets a property indicating if we should wrap calls to .get +by checking process.env. Can be a boolean or an Array of +environment variables to extract.

Provider.prototype.__defineSetter__('env', function (val) { updateSystem.call(this, 'env', val) });
+Provider.prototype.__defineGetter__('env', function () { return this._env });

Throw the err if a callback is not supplied

function onError(err, callback) {
+  if (callback) {
+    return callback(err);
+  }
+  
+  throw err;
+}

Helper function for working with the +default system store for providers.

function updateSystem(prop, value) {
+  var system = this['system'];
+  
+  if (system[prop] === value) {
+    return;
+  }
+  
+  value = value || false;
+  this['_' + prop] = value;
+  system[prop] = value;
+  system.loadSync();
+}
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf/stores.html b/mocha/node_modules/nconf/docs/nconf/stores.html new file mode 100644 index 0000000..d799966 --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf/stores.html @@ -0,0 +1,19 @@ + stores.js

stores.js

/*
+ * stores.js: Top-level include for all nconf stores
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+ 
+var fs = require('fs'),
+    common = require('./common'),
+    stores = exports;

Setup all stores as lazy-loaded getters.

fs.readdirSync(__dirname + '/stores').forEach(function (file) {
+  var store = file.replace('.js', ''),
+      name  = common.capitalize(store);
+      
+  stores.__defineGetter__(name, function () {
+    return require('./stores/' + store)[name];
+  });
+});
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf/stores/file.html b/mocha/node_modules/nconf/docs/nconf/stores/file.html new file mode 100644 index 0000000..7a00765 --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf/stores/file.html @@ -0,0 +1,170 @@ + file.js

file.js

/*
+ * file.js: Simple file storage engine for nconf files
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+
+var fs = require('fs'),
+    path = require('path'),
+    util = require('util'),
+    formats = require('../formats'),
+    Memory = require('./memory').Memory;
+ 

function File (options)

+ +

@options {Object} Options for this instance

+ +

Constructor function for the File nconf store, a simple abstraction +around the Memory store that can persist configuration to disk.

var File = exports.File = function (options) {
+  if (!options || !options.file) {
+    throw new Error ('Missing required option `files`');
+  }
+
+  Memory.call(this, options);
+
+  this.type   = 'file';
+  this.file   = options.file;
+  this.dir    = options.dir    || process.cwd();
+  this.format = options.format || formats.json;
+};

Inherit from the Memory store

util.inherits(File, Memory);

function save (value, callback)

+ +

@value {Object} Ignored Left here for consistency

+ +

@callback {function} Continuation to respond to when complete.

+ +

Saves the current configuration object to disk at this.file +using the format specified by this.format.

File.prototype.save = function (value, callback) {
+  if (!callback) {
+    callback = value;
+    value = null;
+  }
+  
+  fs.writeFile(this.file, this.format.stringify(this.store), function (err) {
+    return err ? callback(err) : callback();
+  });
+};

function saveSync (value, callback)

+ +

@value {Object} Ignored Left here for consistency

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Saves the current configuration object to disk at this.file +using the format specified by this.format synchronously.

File.prototype.saveSync = function (value) {
+  try {
+    fs.writeFileSync(this.file, this.format.stringify(this.store));
+  }
+  catch (ex) {
+    throw(ex);
+  }
+};

function load (callback)

+ +

@callback {function} Continuation to respond to when complete.

+ +

Responds with an Object representing all keys associated in this instance.

File.prototype.load = function (callback) {
+  var self = this;
+
+  path.exists(self.file, function (exists) {
+    if (!exists) {

If the path we are attempting to load doesn't exist, create it

      self.save({}, function (err) {
+        self.store = {};
+        return callback(err, self.store);
+      });
+    }
+    else {

Else, the path exists, read it from disk

      fs.readFile(self.file, function (err, data) {
+        if (err) {
+          return callback(err);
+        }
+        
+        try {
+          self.store = self.format.parse(data.toString());
+        }
+        catch (ex) {
+          return callback(new Error("Error parsing your JSON configuration file."));
+        }
+        
+        callback(null, self.store);
+      });
+    }
+  });
+};

function load (callback)

+ +

@callback {function} Optional Continuation to respond to when complete.

+ +

Attempts to load the data stored in this.file synchronously and responds appropriately.

File.prototype.loadSync = function () {
+  var data, self = this;
+
+  if (!path.existsSync(self.file)) {

If the path we are attempting to load doesn't exist, create it

    self.saveSync({});
+    self.store = {};
+    data = {};
+  }
+  else {

Else, the path exists, read it from disk

    try {
+      data = this.format.parse(fs.readFileSync(this.file, 'utf8'));
+      this.store = data;
+    }
+    catch (ex) {
+      throw new Error("Error parsing your JSON configuration file.")
+    }
+  }
+
+  return data;
+};

function search (base)

+ +

@base {string} Base directory (or file) to begin searching for the target file.

+ +

Attempts to find this.file by iteratively searching up the +directory structure

File.prototype.search = function (base) {
+  var looking = true,
+      fullpath,
+      previous,
+      stats;
+
+  base = base || process.cwd();
+
+  if (this.file[0] === '/') {

If filename for this instance is a fully qualified path +(i.e. it starts with a '/') then check if it exists

    try {
+      stats = fs.statSync(fs.realpathSync(this.file));
+      if (stats.isFile()) {
+        fullpath = this.file;
+        looking = false;
+      }
+    }
+    catch (ex) {

Ignore errors

    }
+  }
+
+  if (looking && base) {

Attempt to stat the realpath located at base +if the directory does not exist then return false.

    try {
+      var stat = fs.statSync(fs.realpathSync(base));
+      looking = stat.isDirectory();
+    }
+    catch (ex) {
+      return false;
+    }
+  }
+  
+  while (looking) {

Iteratively look up the directory structure from base

    try {
+      stats = fs.statSync(fs.realpathSync(fullpath = path.join(base, this.file)));
+      looking = stats.isDirectory();
+    }
+    catch (ex) {
+      previous = base;
+      base = path.dirname(base);
+
+      if (previous === base) {

If we've reached the top of the directory structure then simply use +the default file path.

        try {
+          stats = fs.statSync(fs.realpathSync(fullpath = path.join(this.dir, this.file)));
+          if (stats.isDirectory()) {
+            fullpath = undefined;
+          }
+        }
+        catch (ex) {

Ignore errors

        }
+        
+        looking = false;
+      }
+    }
+  }

Set the file for this instance to the fullpath +that we have found during the search. In the event that +the search was unsuccessful use the original value for this.file.

  this.file = fullpath || this.file;
+  
+  return fullpath;
+};
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf/stores/memory.html b/mocha/node_modules/nconf/docs/nconf/stores/memory.html new file mode 100644 index 0000000..8867394 --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf/stores/memory.html @@ -0,0 +1,143 @@ + memory.js

memory.js

/*
+ * memory.js: Simple memory storage engine for nconf configuration(s)
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+
+var common = require('../common');

function Memory (options)

+ +

@options {Object} Options for this instance

+ +

Constructor function for the Memory nconf store which maintains +a nested json structure based on key delimiters :.

+ +

e.g. my:nested:key ==> { my: { nested: { key: } } }

var Memory = exports.Memory = function (options) {
+  options       = options || {};
+  this.type     = 'memory';
+  this.store    = {};
+  this.mtimes   = {};
+  this.readOnly = false;
+  this.loadFrom = options.loadFrom || null;
+  
+  if (this.loadFrom) {
+    this.store = common.loadFilesSync(this.loadFrom);
+  }
+};

function get (key)

+ +

@key {string} Key to retrieve for this instance.

+ +

Retrieves the value for the specified key (if any).

Memory.prototype.get = function (key) {
+  var target = this.store, 
+      path   = common.path(key);

Scope into the object to get the appropriate nested context

  while (path.length > 0) {
+    key = path.shift();
+    if (!(target && key in target)) {
+      return;
+    }
+    
+    target = target[key];
+    if (path.length === 0) {
+      return target;
+    }
+  }
+};

function set (key, value)

+ +

@key {string} Key to set in this instance

+ +

@value {literal|Object} Value for the specified key

+ +

Sets the value for the specified key in this instance.

Memory.prototype.set = function (key, value) {
+  if (this.readOnly) {
+    return false;
+  }
+  
+  var target = this.store, 
+      path   = common.path(key);
+  

Update the mtime (modified time) of the key

  this.mtimes[key] = Date.now();
+  

Scope into the object to get the appropriate nested context

  while (path.length > 1) {
+    key = path.shift();
+    if (!target[key] || typeof target[key] !== 'object') {
+      target[key] = {};
+    }
+    
+    target = target[key];
+  }
+  

Set the specified value in the nested JSON structure

  key = path.shift();
+  target[key] = value;
+  return true;
+};

function clear (key)

+ +

@key {string} Key to remove from this instance

+ +

Removes the value for the specified key from this instance.

Memory.prototype.clear = function (key) {
+  if (this.readOnly) {
+    return false;
+  }
+  
+  var target = this.store, 
+      path   = common.path(key);
+  

Remove the key from the set of mtimes (modified times)

  delete this.mtimes[key];
+  

Scope into the object to get the appropriate nested context

  while (path.length > 1) {
+    key = path.shift();
+    if (!target[key]) {
+      return;
+    }
+    
+    target = target[key];
+  }
+  

Delete the key from the nested JSON structure

  key = path.shift();
+  delete target[key];
+  return true;
+};

function merge (key, value)

+ +

@key {string} Key to merge the value into

+ +

@value {literal|Object} Value to merge into the key

+ +

Merges the properties in value into the existing object value +at key. If the existing value key is not an Object, it will be +completely overwritten.

Memory.prototype.merge = function (key, value) {
+  if (this.readOnly) {
+    return false;
+  }
+  

If the key is not an Object or is an Array, +then simply set it. Merging is for Objects.

  if (typeof value !== 'object' || Array.isArray(value)) {
+    return this.set(key, value);
+  }
+  
+  var self    = this,
+      target  = this.store, 
+      path    = common.path(key),
+      fullKey = key;
+  

Update the mtime (modified time) of the key

  this.mtimes[key] = Date.now();
+  

Scope into the object to get the appropriate nested context

  while (path.length > 1) {
+    key = path.shift();
+    if (!target[key]) {
+      target[key] = {};
+    }
+    
+    target = target[key];
+  }

Set the specified value in the nested JSON structure

  key = path.shift();
+  

If the current value at the key target is not an Object, +or is an Array then simply override it because the new value +is an Object.

  if (typeof target[key] !== 'object' || Array.isArray(target[key])) {
+    target[key] = value;
+    return true;
+  }
+  
+  return Object.keys(value).every(function (nested) {
+    return self.merge(fullKey + ':' + nested, value[nested]);
+  });
+};

function reset (callback)

+ +

Clears all keys associated with this instance.

Memory.prototype.reset = function () {
+  if (this.readOnly) {
+    return false;
+  }
+  
+  this.mtimes = {};
+  this.store  = {};
+  return true;
+};
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/docs/nconf/stores/system.html b/mocha/node_modules/nconf/docs/nconf/stores/system.html new file mode 100644 index 0000000..9e89544 --- /dev/null +++ b/mocha/node_modules/nconf/docs/nconf/stores/system.html @@ -0,0 +1,98 @@ + system.js

system.js

/*
+ * system.js: Simple memory-based store for process environment variables and
+ *            command-line arguments.
+ *
+ * (C) 2011, Charlie Robbins
+ *
+ */
+ 
+var util = require('util'),
+    Memory = require('./memory').Memory;
+ 

function System (options)

+ +

@options {Object} Options for this instance.

+ +

Constructor function for the System nconf store, a simple abstraction +around the Memory store that can read process environment variables +and command-line arguments.

var System = exports.System = function (options) {
+  options = options || {};
+  Memory.call(this, options);
+
+  this.type      = 'system';
+  this.overrides = options.overrides || null;
+  this.env       = options.env       || false;
+  this.argv      = options.argv      || false;
+};

Inherit from the Memory store

util.inherits(System, Memory);

function loadSync ()

+ +

Loads the data passed in from process.env into this instance.

System.prototype.loadSync = function () {
+  if (this.env) {
+    this.loadEnv();
+  }
+  
+  if (this.argv) {
+    this.loadArgv();
+  }
+  
+  if (this.overrides) {
+    this.loadOverrides();
+  }
+  
+  return this.store;
+};

function loadOverrides ()

+ +

Loads any overrides set on this instance into +the underlying managed Memory store.

System.prototype.loadOverrides = function () {
+  if (!this.overrides) {
+    return;
+  }
+  
+  var self = this,
+      keys = Object.keys(this.overrides);
+  
+  keys.forEach(function (key) {
+    self.set(key, self.overrides[key]);
+  });
+  
+  return this.store;
+};

function loadArgv ()

+ +

Loads the data passed in from the command-line arguments +into this instance.

System.prototype.loadArgv = function () {
+  var self = this, 
+      argv;
+  
+  if (typeof this.argv === 'object') {
+    argv = require('optimist').options(this.argv).argv;
+  }
+  else if (this.argv) {
+    argv = require('optimist').argv;
+  }
+  
+  if (!argv) {
+    return;
+  }
+  
+  Object.keys(argv).forEach(function (key) {
+    self.set(key, argv[key]);
+  });
+  
+  return this.store;
+};

function loadEnv ()

+ +

Loads the data passed in from process.env into this instance.

System.prototype.loadEnv = function () {
+  var self = this;
+  
+  if (!this.env) {
+    return;
+  }
+  
+  Object.keys(process.env).filter(function (key) {
+    return !self.env.length || self.env.indexOf(key) !== -1;
+  }).forEach(function (key) {
+    self.set(key, process.env[key]);
+  });
+    
+  return this.store;
+};
+
+
\ No newline at end of file diff --git a/mocha/node_modules/nconf/lib/nconf.js b/mocha/node_modules/nconf/lib/nconf.js new file mode 100644 index 0000000..8ae2d76 --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf.js @@ -0,0 +1,40 @@ +/* + * nconf.js: Top-level include for the nconf module + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var fs = require('fs'), + async = require('async'), + common = require('./nconf/common'), + Provider = require('./nconf/provider').Provider, + nconf = module.exports = new Provider(); + +// +// Expose the version from the package.json +// +nconf.version = require('../package.json').version; + +// +// Setup all stores as lazy-loaded getters. +// +fs.readdirSync(__dirname + '/nconf/stores').forEach(function (file) { + var store = file.replace('.js', ''), + name = common.capitalize(store); + + nconf.__defineGetter__(name, function () { + return require('./nconf/stores/' + store)[name]; + }); +}); + +// +// Expose the various components included with nconf +// +nconf.key = common.key; +nconf.path = common.path; +nconf.loadFiles = common.loadFiles; +nconf.loadFilesSync = common.loadFilesSync; +nconf.formats = require('./nconf/formats'); +nconf.Provider = Provider; + diff --git a/mocha/node_modules/nconf/lib/nconf/common.js b/mocha/node_modules/nconf/lib/nconf/common.js new file mode 100644 index 0000000..4e7ba7b --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/common.js @@ -0,0 +1,123 @@ +/* + * utils.js: Utility functions for the nconf module. + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var fs = require('fs'), + async = require('async'), + formats = require('./formats'), + Memory = require('./stores/memory').Memory; + +var common = exports; + +// +// ### function path (key) +// #### @key {string} The ':' delimited key to split +// Returns a fully-qualified path to a nested nconf key. +// If given null or undefined it should return an empty path. +// '' should still be respected as a path. +// +common.path = function (key, separator) { + separator = separator || ':'; + return key == null ? [] : key.split(separator); +}; + +// +// ### function key (arguments) +// Returns a `:` joined string from the `arguments`. +// +common.key = function () { + return Array.prototype.slice.call(arguments).join(':'); +}; + +// +// ### function key (arguments) +// Returns a joined string from the `arguments`, +// first argument is the join delimiter. +// +common.keyed = function () { + return Array.prototype.slice.call(arguments, 1).join(arguments[0]); +}; + +// +// ### function loadFiles (files, callback) +// #### @files {Object|Array} List of files (or settings object) to load. +// #### @callback {function} Continuation to respond to when complete. +// Loads all the data in the specified `files`. +// +common.loadFiles = function (files, callback) { + if (!files) { + return callback(null, {}); + } + + var options = Array.isArray(files) ? { files: files } : files; + + // + // Set the default JSON format if not already + // specified + // + options.format = options.format || formats.json; + + function parseFile (file, next) { + fs.readFile(file, function (err, data) { + return !err + ? next(null, options.format.parse(data.toString())) + : next(err); + }); + } + + async.map(options.files, parseFile, function (err, objs) { + return err ? callback(err) : callback(null, common.merge(objs)); + }); +}; + +// +// ### function loadFilesSync (files) +// #### @files {Object|Array} List of files (or settings object) to load. +// Loads all the data in the specified `files` synchronously. +// +common.loadFilesSync = function (files) { + if (!files) { + return; + } + + // + // Set the default JSON format if not already + // specified + // + var options = Array.isArray(files) ? { files: files } : files; + options.format = options.format || formats.json; + + return common.merge(options.files.map(function (file) { + return options.format.parse(fs.readFileSync(file, 'utf8')); + })); +}; + +// +// ### function merge (objs) +// #### @objs {Array} Array of object literals to merge +// Merges the specified `objs` using a temporary instance +// of `stores.Memory`. +// +common.merge = function (objs) { + var store = new Memory(); + + objs.forEach(function (obj) { + Object.keys(obj).forEach(function (key) { + store.merge(key, obj[key]); + }); + }); + + return store.store; +}; + +// +// ### function capitalize (str) +// #### @str {string} String to capitalize +// Capitalizes the specified `str`. +// +common.capitalize = function (str) { + return str && str[0].toUpperCase() + str.slice(1); +}; diff --git a/mocha/node_modules/nconf/lib/nconf/formats.js b/mocha/node_modules/nconf/lib/nconf/formats.js new file mode 100644 index 0000000..8ef210d --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/formats.js @@ -0,0 +1,28 @@ +/* + * formats.js: Default formats supported by nconf + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var ini = require('ini'); + +var formats = exports; + +// +// ### @json +// Standard JSON format which pretty prints `.stringify()`. +// +formats.json = { + stringify: function (obj, replacer, spacing) { + return JSON.stringify(obj, replacer || null, spacing || 2) + }, + parse: JSON.parse +}; + +// +// ### @ini +// Standard INI format supplied from the `ini` module +// http://en.wikipedia.org/wiki/INI_file +// +formats.ini = ini; diff --git a/mocha/node_modules/nconf/lib/nconf/provider.js b/mocha/node_modules/nconf/lib/nconf/provider.js new file mode 100644 index 0000000..93200a3 --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/provider.js @@ -0,0 +1,568 @@ +/* + * provider.js: Abstraction providing an interface into pluggable configuration storage. + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var async = require('async'), + common = require('./common'); + +// +// ### function Provider (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Provider object responsible +// for exposing the pluggable storage features of `nconf`. +// +var Provider = exports.Provider = function (options) { + // + // Setup default options for working with `stores`, + // `overrides`, `process.env` and `process.argv`. + // + options = options || {}; + this.stores = {}; + this.sources = []; + this.init(options); +}; + +// +// Define wrapper functions for using basic stores +// in this instance +// + +['argv', 'env'].forEach(function (type) { + Provider.prototype[type] = function () { + var args = [type].concat(Array.prototype.slice.call(arguments)); + return this.add.apply(this, args); + }; +}); + +// +// ### function file (key, options) +// #### @key {string|Object} Fully qualified options, name of file store, or path. +// #### @path {string|Object} **Optional** Full qualified options, or path. +// Adds a new `File` store to this instance. Accepts the following options +// +// nconf.file({ file: '.jitsuconf', dir: process.env.HOME, search: true }); +// nconf.file('path/to/config/file'); +// nconf.file('userconfig', 'path/to/config/file'); +// nconf.file('userconfig', { file: '.jitsuconf', search: true }); +// +Provider.prototype.file = function (key, options) { + if (arguments.length == 1) { + options = typeof key === 'string' ? { file: key } : key; + key = 'file'; + } + else { + options = typeof options === 'string' + ? { file: options } + : options; + } + + options.type = 'file'; + return this.add(key, options); +}; + +// +// Define wrapper functions for using +// overrides and defaults +// +['defaults', 'overrides'].forEach(function (type) { + Provider.prototype[type] = function (options) { + options = options || {}; + if (!options.type) { + options.type = 'literal'; + } + + return this.add(type, options); + }; +}); + +// +// ### function use (name, options) +// #### @type {string} Type of the nconf store to use. +// #### @options {Object} Options for the store instance. +// Adds (or replaces) a new store with the specified `name` +// and `options`. If `options.type` is not set, then `name` +// will be used instead: +// +// provider.use('file'); +// provider.use('file', { type: 'file', filename: '/path/to/userconf' }) +// +Provider.prototype.use = function (name, options) { + options = options || {}; + var type = options.type || name; + + function sameOptions (store) { + return Object.keys(options).every(function (key) { + return options[key] === store[key]; + }); + } + + var store = this.stores[name], + update = store && !sameOptions(store); + + if (!store || update) { + if (update) { + this.remove(name); + } + + this.add(name, options); + } + + return this; +}; + +// +// ### function add (name, options) +// #### @name {string} Name of the store to add to this instance +// #### @options {Object} Options for the store to create +// Adds a new store with the specified `name` and `options`. If `options.type` +// is not set, then `name` will be used instead: +// +// provider.add('memory'); +// provider.add('userconf', { type: 'file', filename: '/path/to/userconf' }) +// +Provider.prototype.add = function (name, options, usage) { + options = options || {}; + var type = options.type || name; + + if (!require('../nconf')[common.capitalize(type)]) { + throw new Error('Cannot add store with unknown type: ' + type); + } + + this.stores[name] = this.create(type, options, usage); + + if (this.stores[name].loadSync) { + this.stores[name].loadSync(); + } + + return this; +}; + +// +// ### function remove (name) +// #### @name {string} Name of the store to remove from this instance +// Removes a store with the specified `name` from this instance. Users +// are allowed to pass in a type argument (e.g. `memory`) as name if +// this was used in the call to `.add()`. +// +Provider.prototype.remove = function (name) { + delete this.stores[name]; + return this; +}; + +// +// ### function create (type, options) +// #### @type {string} Type of the nconf store to use. +// #### @options {Object} Options for the store instance. +// Creates a store of the specified `type` using the +// specified `options`. +// +Provider.prototype.create = function (type, options, usage) { + return new (require('../nconf')[common.capitalize(type.toLowerCase())])(options, usage); +}; + +// +// ### function init (options) +// #### @options {Object} Options to initialize this instance with. +// Initializes this instance with additional `stores` or `sources` in the +// `options` supplied. +// +Provider.prototype.init = function (options) { + var self = this; + + // + // Add any stores passed in through the options + // to this instance. + // + if (options.type) { + this.add(options.type, options); + } + else if (options.store) { + this.add(options.store.name || options.store.type, options.store); + } + else if (options.stores) { + Object.keys(options.stores).forEach(function (name) { + var store = options.stores[name]; + self.add(store.name || name || store.type, store); + }); + } + + // + // Add any read-only sources to this instance + // + if (options.source) { + this.sources.push(this.create(options.source.type || options.source.name, options.source)); + } + else if (options.sources) { + Object.keys(options.sources).forEach(function (name) { + var source = options.sources[name]; + self.sources.push(self.create(source.type || source.name || name, source)); + }); + } +}; + +// +// ### function get (key, callback) +// #### @key {string} Key to retrieve for this instance. +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Retrieves the value for the specified key (if any). +// +Provider.prototype.get = function (key, callback) { + // + // If there is no callback we can short-circuit into the default + // logic for traversing stores. + // + if (!callback) { + return this._execute('get', 1, key, callback); + } + + // + // Otherwise the asynchronous, hierarchical `get` is + // slightly more complicated because we do not need to traverse + // the entire set of stores, but up until there is a defined value. + // + var current = 0, + names = Object.keys(this.stores), + self = this, + response, + mergeObjs = []; + + async.whilst(function () { + return typeof response === 'undefined' && current < names.length; + }, function (next) { + var store = self.stores[names[current]]; + current++; + + if (store.get.length >= 2) { + return store.get(key, function (err, value) { + if (err) { + return next(err); + } + + response = value; + + // Merge objects if necessary + if (typeof response === 'object' && !Array.isArray(response)) { + mergeObjs.push(response); + response = undefined; + } + + next(); + }); + } + + response = store.get(key); + + // Merge objects if necessary + if (typeof response === 'object' && !Array.isArray(response)) { + mergeObjs.push(response); + response = undefined; + } + + next(); + }, function (err) { + if (!err && mergeObjs.length) { + response = common.merge(mergeObjs.reverse()); + } + return err ? callback(err) : callback(null, response); + }); +}; + +// +// ### function set (key, value, callback) +// #### @key {string} Key to set in this instance +// #### @value {literal|Object} Value for the specified key +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Sets the `value` for the specified `key` in this instance. +// +Provider.prototype.set = function (key, value, callback) { + return this._execute('set', 2, key, value, callback); +}; + +// +// ### function reset (callback) +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Clears all keys associated with this instance. +// +Provider.prototype.reset = function (callback) { + return this._execute('reset', 0, callback); +}; + +// +// ### function clear (key, callback) +// #### @key {string} Key to remove from this instance +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Removes the value for the specified `key` from this instance. +// +Provider.prototype.clear = function (key, callback) { + return this._execute('clear', 1, key, callback); +}; + +// +// ### function merge ([key,] value [, callback]) +// #### @key {string} Key to merge the value into +// #### @value {literal|Object} Value to merge into the key +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Merges the properties in `value` into the existing object value at `key`. +// +// 1. If the existing value `key` is not an Object, it will be completely overwritten. +// 2. If `key` is not supplied, then the `value` will be merged into the root. +// +Provider.prototype.merge = function () { + var self = this, + args = Array.prototype.slice.call(arguments), + callback = typeof args[args.length - 1] === 'function' && args.pop(), + value = args.pop(), + key = args.pop(); + + function mergeProperty (prop, next) { + return self._execute('merge', 2, prop, value[prop], next); + } + + if (!key) { + if (Array.isArray(value) || typeof value !== 'object') { + return onError(new Error('Cannot merge non-Object into top-level.'), callback); + } + + return async.forEach(Object.keys(value), mergeProperty, callback || function () { }) + } + + return this._execute('merge', 2, key, value, callback); +}; + +// +// ### function load (callback) +// #### @callback {function} Continuation to respond to when complete. +// Responds with an Object representing all keys associated in this instance. +// +Provider.prototype.load = function (callback) { + var self = this; + + function getStores () { + var stores = Object.keys(self.stores); + stores.reverse(); + return stores.map(function (name) { + return self.stores[name]; + }); + } + + function loadStoreSync(store) { + if (!store.loadSync) { + throw new Error('nconf store ' + store.type + ' has no loadSync() method'); + } + + return store.loadSync(); + } + + function loadStore(store, next) { + if (!store.load && !store.loadSync) { + return next(new Error('nconf store ' + store.type + ' has no load() method')); + } + + return store.loadSync + ? next(null, store.loadSync()) + : store.load(next); + } + + function loadBatch (targets, done) { + if (!done) { + return common.merge(targets.map(loadStoreSync)); + } + + async.map(targets, loadStore, function (err, objs) { + return err ? done(err) : done(null, common.merge(objs)); + }); + } + + function mergeSources (data) { + // + // If `data` was returned then merge it into + // the system store. + // + if (data && typeof data === 'object') { + self.use('sources', { + type: 'literal', + store: data + }); + } + } + + function loadSources () { + var sourceHierarchy = self.sources.splice(0); + sourceHierarchy.reverse(); + + // + // If we don't have a callback and the current + // store is capable of loading synchronously + // then do so. + // + if (!callback) { + mergeSources(loadBatch(sourceHierarchy)); + return loadBatch(getStores()); + } + + loadBatch(sourceHierarchy, function (err, data) { + if (err) { + return callback(err); + } + + mergeSources(data); + return loadBatch(getStores(), callback); + }); + } + + return self.sources.length + ? loadSources() + : loadBatch(getStores(), callback); +}; + +// +// ### function save (callback) +// #### @callback {function} **optional** Continuation to respond to when +// complete. +// Instructs each provider to save. If a callback is provided, we will attempt +// asynchronous saves on the providers, falling back to synchronous saves if +// this isn't possible. If a provider does not know how to save, it will be +// ignored. Returns an object consisting of all of the data which was +// actually saved. +// +Provider.prototype.save = function (value, callback) { + if (!callback && typeof value === 'function') { + callback = value; + value = null; + } + + var self = this, + names = Object.keys(this.stores); + + function saveStoreSync(memo, name) { + var store = self.stores[name]; + + // + // If the `store` doesn't have a `saveSync` method, + // just ignore it and continue. + // + if (store.saveSync) { + var ret = store.saveSync(); + if (typeof ret == 'object' && ret !== null) { + memo.push(ret); + } + } + return memo; + } + + function saveStore(memo, name, next) { + var store = self.stores[name]; + + // + // If the `store` doesn't have a `save` or saveSync` + // method(s), just ignore it and continue. + // + + if (store.save) { + return store.save(function (err, data) { + if (err) { + return next(err); + } + + if (typeof data == 'object' && data !== null) { + memo.push(data); + } + + next(null, memo); + }); + } + else if (store.saveSync) { + memo.push(store.saveSync()); + } + + next(null, memo); + } + + // + // If we don't have a callback and the current + // store is capable of saving synchronously + // then do so. + // + if (!callback) { + return common.merge(names.reduce(saveStoreSync, [])); + } + + async.reduce(names, [], saveStore, function (err, objs) { + return err ? callback(err) : callback(null, common.merge(objs)); + }); +}; + +// +// ### @private function _execute (action, syncLength, [arguments]) +// #### @action {string} Action to execute on `this.store`. +// #### @syncLength {number} Function length of the sync version. +// #### @arguments {Array} Arguments array to apply to the action +// Executes the specified `action` on all stores for this instance, ensuring a callback supplied +// to a synchronous store function is still invoked. +// +Provider.prototype._execute = function (action, syncLength /* [arguments] */) { + var args = Array.prototype.slice.call(arguments, 2), + callback = typeof args[args.length - 1] === 'function' && args.pop(), + destructive = ['set', 'clear', 'merge', 'reset'].indexOf(action) !== -1, + self = this, + response, + mergeObjs = [], + keys = Object.keys(this.stores); + + + function runAction (name, next) { + var store = self.stores[name]; + + if (destructive && store.readOnly) { + return next(); + } + + return store[action].length > syncLength + ? store[action].apply(store, args.concat(next)) + : next(null, store[action].apply(store, args)); + } + + if (callback) { + return async.forEach(keys, runAction, function (err) { + return err ? callback(err) : callback(); + }); + } + + keys.forEach(function (name) { + if (typeof response === 'undefined') { + var store = self.stores[name]; + + if (destructive && store.readOnly) { + return; + } + + response = store[action].apply(store, args); + + // Merge objects if necessary + if (response && action === 'get' && typeof response === 'object' && !Array.isArray(response)) { + mergeObjs.push(response); + response = undefined; + } + } + }); + + if (mergeObjs.length) { + response = common.merge(mergeObjs.reverse()); + } + + return response; +} + +// +// Throw the `err` if a callback is not supplied +// +function onError(err, callback) { + if (callback) { + return callback(err); + } + + throw err; +} diff --git a/mocha/node_modules/nconf/lib/nconf/stores/argv.js b/mocha/node_modules/nconf/lib/nconf/stores/argv.js new file mode 100644 index 0000000..359cb8d --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/stores/argv.js @@ -0,0 +1,69 @@ +/* + * argv.js: Simple memory-based store for command-line arguments. + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var util = require('util'), + Memory = require('./memory').Memory; + +// +// ### function Argv (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Argv nconf store, a simple abstraction +// around the Memory store that can read command-line arguments. +// +var Argv = exports.Argv = function (options, usage) { + Memory.call(this, options); + + this.type = 'argv'; + this.readOnly = true; + this.options = options || false; + this.usage = usage; +}; + +// Inherit from the Memory store +util.inherits(Argv, Memory); + +// +// ### function loadSync () +// Loads the data passed in from `process.argv` into this instance. +// +Argv.prototype.loadSync = function () { + this.loadArgv(); + return this.store; +}; + +// +// ### function loadArgv () +// Loads the data passed in from the command-line arguments +// into this instance. +// +Argv.prototype.loadArgv = function () { + var self = this, + optimist, argv; + + optimist = typeof this.options === 'object' + ? require('optimist')(process.argv.slice(2)).options(this.options) + : require('optimist')(process.argv.slice(2)); + + if (typeof this.usage === 'string') { optimist.usage(this.usage) } + + argv = optimist.argv + + if (!argv) { + return; + } + + this.readOnly = false; + Object.keys(argv).forEach(function (key) { + self.set(key, argv[key]); + }); + + this.showHelp = optimist.showHelp + this.help = optimist.help + + this.readOnly = true; + return this.store; +}; \ No newline at end of file diff --git a/mocha/node_modules/nconf/lib/nconf/stores/env.js b/mocha/node_modules/nconf/lib/nconf/stores/env.js new file mode 100644 index 0000000..aa775f3 --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/stores/env.js @@ -0,0 +1,82 @@ +/* + * env.js: Simple memory-based store for environment variables + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var util = require('util'), + common = require('../common'), + Memory = require('./memory').Memory; + +// +// ### function Env (options) +// #### @options {Object} Options for this instance. +// Constructor function for the Env nconf store, a simple abstraction +// around the Memory store that can read process environment variables. +// +var Env = exports.Env = function (options) { + Memory.call(this, options); + + options = options || {}; + this.type = 'env'; + this.readOnly = true; + this.whitelist = options.whitelist || []; + this.separator = options.separator || ''; + + if (typeof options.match === 'function' + && typeof options !== 'string') { + this.match = options.match; + } + + if (options instanceof Array) { + this.whitelist = options; + } + if (typeof(options) === 'string') { + this.separator = options; + } +}; + +// Inherit from the Memory store +util.inherits(Env, Memory); + +// +// ### function loadSync () +// Loads the data passed in from `process.env` into this instance. +// +Env.prototype.loadSync = function () { + this.loadEnv(); + return this.store; +}; + +// +// ### function loadEnv () +// Loads the data passed in from `process.env` into this instance. +// +Env.prototype.loadEnv = function () { + var self = this; + + this.readOnly = false; + Object.keys(process.env).filter(function (key) { + if (self.match && self.whitelist.length) { + return key.match(self.match) || self.whitelist.indexOf(key) !== -1 + } + else if (self.match) { + return key.match(self.match); + } + else { + return !self.whitelist.length || self.whitelist.indexOf(key) !== -1 + } + }).forEach(function (key) { + if (self.separator) { + self.set(common.key.apply(common, key.split(self.separator)), process.env[key]); + } + else { + self.set(key, process.env[key]); + } + }); + + this.readOnly = true; + return this.store; +}; + diff --git a/mocha/node_modules/nconf/lib/nconf/stores/file.js b/mocha/node_modules/nconf/lib/nconf/stores/file.js new file mode 100644 index 0000000..f3caaac --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/stores/file.js @@ -0,0 +1,237 @@ +/* + * file.js: Simple file storage engine for nconf files + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var fs = require('fs'), + path = require('path'), + util = require('util'), + formats = require('../formats'), + Memory = require('./memory').Memory, + exists = fs.exists || path.exists, + existsSync = fs.existsSync || path.existsSync; + +// +// ### function File (options) +// #### @options {Object} Options for this instance +// Constructor function for the File nconf store, a simple abstraction +// around the Memory store that can persist configuration to disk. +// +var File = exports.File = function (options) { + if (!options || !options.file) { + throw new Error ('Missing required option `file`'); + } + + Memory.call(this, options); + + this.type = 'file'; + this.file = options.file; + this.dir = options.dir || process.cwd(); + this.format = options.format || formats.json; + this.json_spacing = options.json_spacing || 2; + + if (options.search) { + this.search(this.dir); + } +}; + +// Inherit from the Memory store +util.inherits(File, Memory); + +// +// ### function save (value, callback) +// #### @value {Object} _Ignored_ Left here for consistency +// #### @callback {function} Continuation to respond to when complete. +// Saves the current configuration object to disk at `this.file` +// using the format specified by `this.format`. +// +File.prototype.save = function (value, callback) { + if (!callback) { + callback = value; + value = null; + } + + fs.writeFile(this.file, this.format.stringify(this.store, null, this.json_spacing), function (err) { + return err ? callback(err) : callback(); + }); +}; + +// +// ### function saveSync (value, callback) +// #### @value {Object} _Ignored_ Left here for consistency +// #### @callback {function} **Optional** Continuation to respond to when complete. +// Saves the current configuration object to disk at `this.file` +// using the format specified by `this.format` synchronously. +// +File.prototype.saveSync = function (value) { + try { + fs.writeFileSync(this.file, this.format.stringify(this.store, null, this.json_spacing)); + } + catch (ex) { + throw(ex); + } + return this.store; +}; + +// +// ### function load (callback) +// #### @callback {function} Continuation to respond to when complete. +// Responds with an Object representing all keys associated in this instance. +// +File.prototype.load = function (callback) { + var self = this; + + exists(self.file, function (exists) { + if (!exists) { + return callback(null, {}); + } + + // + // Else, the path exists, read it from disk + // + fs.readFile(self.file, function (err, data) { + if (err) { + return callback(err); + } + + try { + //deals with string that include BOM + var stringData = data.toString(); + + if (stringData.charAt(0) === '\uFEFF') stringData = stringData.substr(1); + self.store = self.format.parse(stringData); + + } + catch (ex) { + return callback(new Error("Error parsing your configuration file: [" + self.file + ']: ' + ex.message)); + } + + callback(null, self.store); + }); + }); +}; + +// +// ### function loadSync (callback) +// Attempts to load the data stored in `this.file` synchronously +// and responds appropriately. +// +File.prototype.loadSync = function () { + var data, self = this; + + if (!existsSync(self.file)) { + self.store = {}; + data = {}; + } + else { + // + // Else, the path exists, read it from disk + // + try { + //deals with file that include BOM + var fileData = fs.readFileSync(this.file, 'utf8'); + if (fileData.charAt(0) === '\uFEFF') fileData = fileData.substr(1); + + data = this.format.parse(fileData); + this.store = data; + } + catch (ex) { + throw new Error("Error parsing your configuration file: [" + self.file + ']: ' + ex.message); + } + } + + return data; +}; + +// +// ### function search (base) +// #### @base {string} Base directory (or file) to begin searching for the target file. +// Attempts to find `this.file` by iteratively searching up the +// directory structure +// +File.prototype.search = function (base) { + var looking = true, + fullpath, + previous, + stats; + + base = base || process.cwd(); + + if (this.file[0] === '/') { + // + // If filename for this instance is a fully qualified path + // (i.e. it starts with a `'/'`) then check if it exists + // + try { + stats = fs.statSync(fs.realpathSync(this.file)); + if (stats.isFile()) { + fullpath = this.file; + looking = false; + } + } + catch (ex) { + // + // Ignore errors + // + } + } + + if (looking && base) { + // + // Attempt to stat the realpath located at `base` + // if the directory does not exist then return false. + // + try { + var stat = fs.statSync(fs.realpathSync(base)); + looking = stat.isDirectory(); + } + catch (ex) { + return false; + } + } + + while (looking) { + // + // Iteratively look up the directory structure from `base` + // + try { + stats = fs.statSync(fs.realpathSync(fullpath = path.join(base, this.file))); + looking = stats.isDirectory(); + } + catch (ex) { + previous = base; + base = path.dirname(base); + + if (previous === base) { + // + // If we've reached the top of the directory structure then simply use + // the default file path. + // + try { + stats = fs.statSync(fs.realpathSync(fullpath = path.join(this.dir, this.file))); + if (stats.isDirectory()) { + fullpath = undefined; + } + } + catch (ex) { + // + // Ignore errors + // + } + + looking = false; + } + } + } + + // + // Set the file for this instance to the fullpath + // that we have found during the search. In the event that + // the search was unsuccessful use the original value for `this.file`. + // + this.file = fullpath || this.file; + + return fullpath; +}; diff --git a/mocha/node_modules/nconf/lib/nconf/stores/literal.js b/mocha/node_modules/nconf/lib/nconf/stores/literal.js new file mode 100644 index 0000000..b2aab0f --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/stores/literal.js @@ -0,0 +1,29 @@ +/* + * literal.js: Simple literal Object store for nconf. + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var util = require('util'), + Memory = require('./memory').Memory + +var Literal = exports.Literal = function Literal (options) { + Memory.call(this, options); + + options = options || {} + this.type = 'literal'; + this.readOnly = true; + this.store = options.store || options; +}; + +// Inherit from Memory store. +util.inherits(Literal, Memory); + +// +// ### function loadSync (callback) +// Returns the data stored in `this.store` synchronously. +// +Literal.prototype.loadSync = function () { + return this.store; +}; \ No newline at end of file diff --git a/mocha/node_modules/nconf/lib/nconf/stores/memory.js b/mocha/node_modules/nconf/lib/nconf/stores/memory.js new file mode 100644 index 0000000..60afc01 --- /dev/null +++ b/mocha/node_modules/nconf/lib/nconf/stores/memory.js @@ -0,0 +1,225 @@ +/* + * memory.js: Simple memory storage engine for nconf configuration(s) + * + * (C) 2011, Charlie Robbins and the Contributors. + * + */ + +var common = require('../common'); + +// +// ### function Memory (options) +// #### @options {Object} Options for this instance +// Constructor function for the Memory nconf store which maintains +// a nested json structure based on key delimiters `:`. +// +// e.g. `my:nested:key` ==> `{ my: { nested: { key: } } }` +// +var Memory = exports.Memory = function (options) { + options = options || {}; + this.type = 'memory'; + this.store = {}; + this.mtimes = {}; + this.readOnly = false; + this.loadFrom = options.loadFrom || null; + this.logicalSeparator = options.logicalSeparator || ':'; + + if (this.loadFrom) { + this.store = common.loadFilesSync(this.loadFrom); + } +}; + +// +// ### function get (key) +// #### @key {string} Key to retrieve for this instance. +// Retrieves the value for the specified key (if any). +// +Memory.prototype.get = function (key) { + var target = this.store, + path = common.path(key, this.logicalSeparator); + + // + // Scope into the object to get the appropriate nested context + // + while (path.length > 0) { + key = path.shift(); + if (target && target.hasOwnProperty(key)) { + target = target[key]; + continue; + } + return undefined; + } + + return target; +}; + +// +// ### function set (key, value) +// #### @key {string} Key to set in this instance +// #### @value {literal|Object} Value for the specified key +// Sets the `value` for the specified `key` in this instance. +// +Memory.prototype.set = function (key, value) { + if (this.readOnly) { + return false; + } + + var target = this.store, + path = common.path(key, this.logicalSeparator); + + if (path.length === 0) { + // + // Root must be an object + // + if (!value || typeof value !== 'object') { + return false; + } + else { + this.reset(); + this.store = value; + return true; + } + } + + // + // Update the `mtime` (modified time) of the key + // + this.mtimes[key] = Date.now(); + + // + // Scope into the object to get the appropriate nested context + // + while (path.length > 1) { + key = path.shift(); + if (!target[key] || typeof target[key] !== 'object') { + target[key] = {}; + } + + target = target[key]; + } + + // Set the specified value in the nested JSON structure + key = path.shift(); + target[key] = value; + return true; +}; + +// +// ### function clear (key) +// #### @key {string} Key to remove from this instance +// Removes the value for the specified `key` from this instance. +// +Memory.prototype.clear = function (key) { + if (this.readOnly) { + return false; + } + + var target = this.store, + value = target, + path = common.path(key, this.logicalSeparator); + + // + // Remove the key from the set of `mtimes` (modified times) + // + delete this.mtimes[key]; + + // + // Scope into the object to get the appropriate nested context + // + for (var i = 0; i < path.length - 1; i++) { + key = path[i]; + value = target[key]; + if (typeof value !== 'function' && typeof value !== 'object') { + return false; + } + target = value; + } + + // Delete the key from the nested JSON structure + key = path[i]; + delete target[key]; + return true; +}; + +// +// ### function merge (key, value) +// #### @key {string} Key to merge the value into +// #### @value {literal|Object} Value to merge into the key +// Merges the properties in `value` into the existing object value +// at `key`. If the existing value `key` is not an Object, it will be +// completely overwritten. +// +Memory.prototype.merge = function (key, value) { + if (this.readOnly) { + return false; + } + + // + // If the key is not an `Object` or is an `Array`, + // then simply set it. Merging is for Objects. + // + if (typeof value !== 'object' || Array.isArray(value) || value === null) { + return this.set(key, value); + } + + var self = this, + target = this.store, + path = common.path(key, this.logicalSeparator), + fullKey = key; + + // + // Update the `mtime` (modified time) of the key + // + this.mtimes[key] = Date.now(); + + // + // Scope into the object to get the appropriate nested context + // + while (path.length > 1) { + key = path.shift(); + if (!target[key]) { + target[key] = {}; + } + + target = target[key]; + } + + // Set the specified value in the nested JSON structure + key = path.shift(); + + // + // If the current value at the key target is not an `Object`, + // or is an `Array` then simply override it because the new value + // is an Object. + // + if (typeof target[key] !== 'object' || Array.isArray(target[key])) { + target[key] = value; + return true; + } + + return Object.keys(value).every(function (nested) { + return self.merge(common.keyed(self.logicalSeparator, fullKey, nested), value[nested]); + }); +}; + +// +// ### function reset (callback) +// Clears all keys associated with this instance. +// +Memory.prototype.reset = function () { + if (this.readOnly) { + return false; + } + + this.mtimes = {}; + this.store = {}; + return true; +}; + +// +// ### function loadSync +// Returns the store managed by this instance +// +Memory.prototype.loadSync = function () { + return this.store || {}; +}; diff --git a/mocha/node_modules/nconf/node_modules/async/.travis.yml b/mocha/node_modules/nconf/node_modules/async/.travis.yml new file mode 100644 index 0000000..6e5919d --- /dev/null +++ b/mocha/node_modules/nconf/node_modules/async/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - "0.10" diff --git a/mocha/node_modules/nconf/node_modules/async/LICENSE b/mocha/node_modules/nconf/node_modules/async/LICENSE new file mode 100644 index 0000000..8f29698 --- /dev/null +++ b/mocha/node_modules/nconf/node_modules/async/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2010-2014 Caolan McMahon + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/mocha/node_modules/nconf/node_modules/async/README.md b/mocha/node_modules/nconf/node_modules/async/README.md new file mode 100644 index 0000000..0bea531 --- /dev/null +++ b/mocha/node_modules/nconf/node_modules/async/README.md @@ -0,0 +1,1646 @@ +# Async.js + +[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async) + + +Async is a utility module which provides straight-forward, powerful functions +for working with asynchronous JavaScript. Although originally designed for +use with [Node.js](http://nodejs.org), it can also be used directly in the +browser. Also supports [component](https://github.com/component/component). + +Async provides around 20 functions that include the usual 'functional' +suspects (`map`, `reduce`, `filter`, `each`…) as well as some common patterns +for asynchronous control flow (`parallel`, `series`, `waterfall`…). All these +functions assume you follow the Node.js convention of providing a single +callback as the last argument of your `async` function. + + +## Quick Examples + +```javascript +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); + +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); + +async.parallel([ + function(){ ... }, + function(){ ... } +], callback); + +async.series([ + function(){ ... }, + function(){ ... } +]); +``` + +There are many more functions available so take a look at the docs below for a +full list. This module aims to be comprehensive, so if you feel anything is +missing please create a GitHub issue for it. + +## Common Pitfalls + +### Binding a context to an iterator + +This section is really about `bind`, not about `async`. If you are wondering how to +make `async` execute your iterators in a given context, or are confused as to why +a method of another library isn't working as an iterator, study this example: + +```js +// Here is a simple object with an (unnecessarily roundabout) squaring method +var AsyncSquaringLibrary = { + squareExponent: 2, + square: function(number, callback){ + var result = Math.pow(number, this.squareExponent); + setTimeout(function(){ + callback(null, result); + }, 200); + } +}; + +async.map([1, 2, 3], AsyncSquaringLibrary.square, function(err, result){ + // result is [NaN, NaN, NaN] + // This fails because the `this.squareExponent` expression in the square + // function is not evaluated in the context of AsyncSquaringLibrary, and is + // therefore undefined. +}); + +async.map([1, 2, 3], AsyncSquaringLibrary.square.bind(AsyncSquaringLibrary), function(err, result){ + // result is [1, 4, 9] + // With the help of bind we can attach a context to the iterator before + // passing it to async. Now the square function will be executed in its + // 'home' AsyncSquaringLibrary context and the value of `this.squareExponent` + // will be as expected. +}); +``` + +## Download + +The source is available for download from +[GitHub](http://github.com/caolan/async). +Alternatively, you can install using Node Package Manager (`npm`): + + npm install async + +__Development:__ [async.js](https://github.com/caolan/async/raw/master/lib/async.js) - 29.6kb Uncompressed + +## In the Browser + +So far it's been tested in IE6, IE7, IE8, FF3.6 and Chrome 5. + +Usage: + +```html + + +``` + +## Documentation + +### Collections + +* [`each`](#each) +* [`eachSeries`](#eachSeries) +* [`eachLimit`](#eachLimit) +* [`map`](#map) +* [`mapSeries`](#mapSeries) +* [`mapLimit`](#mapLimit) +* [`filter`](#filter) +* [`filterSeries`](#filterSeries) +* [`reject`](#reject) +* [`rejectSeries`](#rejectSeries) +* [`reduce`](#reduce) +* [`reduceRight`](#reduceRight) +* [`detect`](#detect) +* [`detectSeries`](#detectSeries) +* [`sortBy`](#sortBy) +* [`some`](#some) +* [`every`](#every) +* [`concat`](#concat) +* [`concatSeries`](#concatSeries) + +### Control Flow + +* [`series`](#seriestasks-callback) +* [`parallel`](#parallel) +* [`parallelLimit`](#parallellimittasks-limit-callback) +* [`whilst`](#whilst) +* [`doWhilst`](#doWhilst) +* [`until`](#until) +* [`doUntil`](#doUntil) +* [`forever`](#forever) +* [`waterfall`](#waterfall) +* [`compose`](#compose) +* [`seq`](#seq) +* [`applyEach`](#applyEach) +* [`applyEachSeries`](#applyEachSeries) +* [`queue`](#queue) +* [`priorityQueue`](#priorityQueue) +* [`cargo`](#cargo) +* [`auto`](#auto) +* [`retry`](#retry) +* [`iterator`](#iterator) +* [`apply`](#apply) +* [`nextTick`](#nextTick) +* [`times`](#times) +* [`timesSeries`](#timesSeries) + +### Utils + +* [`memoize`](#memoize) +* [`unmemoize`](#unmemoize) +* [`log`](#log) +* [`dir`](#dir) +* [`noConflict`](#noConflict) + + +## Collections + + + +### each(arr, iterator, callback) + +Applies the function `iterator` to each item in `arr`, in parallel. +The `iterator` is called with an item from the list, and a callback for when it +has finished. If the `iterator` passes an error to its `callback`, the main +`callback` (for the `each` function) is immediately called with the error. + +Note, that since this function applies `iterator` to each item in parallel, +there is no guarantee that the iterator functions will complete in order. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err)` which must be called once it has + completed. If no error has occured, the `callback` should be run without + arguments or with an explicit `null` argument. +* `callback(err)` - A callback which is called when all `iterator` functions + have finished, or an error occurs. + +__Examples__ + + +```js +// assuming openFiles is an array of file names and saveFile is a function +// to save the modified contents of that file: + +async.each(openFiles, saveFile, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +```js +// assuming openFiles is an array of file names + +async.each(openFiles, function( file, callback) { + + // Perform operation on file here. + console.log('Processing file ' + file); + + if( file.length > 32 ) { + console.log('This file name is too long'); + callback('File name too long'); + } else { + // Do work to process file here + console.log('File processed'); + callback(); + } +}, function(err){ + // if any of the file processing produced an error, err would equal that error + if( err ) { + // One of the iterations produced an error. + // All processing will now stop. + console.log('A file failed to process'); + } else { + console.log('All files have been processed successfully'); + } +}); +``` + +--------------------------------------- + + + +### eachSeries(arr, iterator, callback) + +The same as [`each`](#each), only `iterator` is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +This means the `iterator` functions will complete in order. + + +--------------------------------------- + + + +### eachLimit(arr, limit, iterator, callback) + +The same as [`each`](#each), only no more than `limit` `iterator`s will be simultaneously +running at any time. + +Note that the items in `arr` are not processed in batches, so there is no guarantee that +the first `limit` `iterator` functions will complete before any others are started. + +__Arguments__ + +* `arr` - An array to iterate over. +* `limit` - The maximum number of `iterator`s to run at any time. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err)` which must be called once it has + completed. If no error has occured, the callback should be run without + arguments or with an explicit `null` argument. +* `callback(err)` - A callback which is called when all `iterator` functions + have finished, or an error occurs. + +__Example__ + +```js +// Assume documents is an array of JSON objects and requestApi is a +// function that interacts with a rate-limited REST api. + +async.eachLimit(documents, 20, requestApi, function(err){ + // if any of the saves produced an error, err would equal that error +}); +``` + +--------------------------------------- + + +### map(arr, iterator, callback) + +Produces a new array of values by mapping each value in `arr` through +the `iterator` function. The `iterator` is called with an item from `arr` and a +callback for when it has finished processing. Each of these callback takes 2 arguments: +an `error`, and the transformed item from `arr`. If `iterator` passes an error to this +callback, the main `callback` (for the `map` function) is immediately called with the error. + +Note, that since this function applies the `iterator` to each item in parallel, +there is no guarantee that the `iterator` functions will complete in order. +However, the results array will be in the same order as the original `arr`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, transformed)` which must be called once + it has completed with an error (which can be `null`) and a transformed item. +* `callback(err, results)` - A callback which is called when all `iterator` + functions have finished, or an error occurs. Results is an array of the + transformed items from the `arr`. + +__Example__ + +```js +async.map(['file1','file2','file3'], fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + +### mapSeries(arr, iterator, callback) + +The same as [`map`](#map), only the `iterator` is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +The results array will be in the same order as the original. + + +--------------------------------------- + + +### mapLimit(arr, limit, iterator, callback) + +The same as [`map`](#map), only no more than `limit` `iterator`s will be simultaneously +running at any time. + +Note that the items are not processed in batches, so there is no guarantee that +the first `limit` `iterator` functions will complete before any others are started. + +__Arguments__ + +* `arr` - An array to iterate over. +* `limit` - The maximum number of `iterator`s to run at any time. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, transformed)` which must be called once + it has completed with an error (which can be `null`) and a transformed item. +* `callback(err, results)` - A callback which is called when all `iterator` + calls have finished, or an error occurs. The result is an array of the + transformed items from the original `arr`. + +__Example__ + +```js +async.mapLimit(['file1','file2','file3'], 1, fs.stat, function(err, results){ + // results is now an array of stats for each file +}); +``` + +--------------------------------------- + + + +### filter(arr, iterator, callback) + +__Alias:__ `select` + +Returns a new array of all the values in `arr` which pass an async truth test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. This operation is +performed in parallel, but the results array will be in the same order as the +original. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The `iterator` is passed a `callback(truthValue)`, which must be called with a + boolean argument once it has completed. +* `callback(results)` - A callback which is called after all the `iterator` + functions have finished. + +__Example__ + +```js +async.filter(['file1','file2','file3'], fs.exists, function(results){ + // results now equals an array of the existing files +}); +``` + +--------------------------------------- + + + +### filterSeries(arr, iterator, callback) + +__Alias:__ `selectSeries` + +The same as [`filter`](#filter) only the `iterator` is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +The results array will be in the same order as the original. + +--------------------------------------- + + +### reject(arr, iterator, callback) + +The opposite of [`filter`](#filter). Removes values that pass an `async` truth test. + +--------------------------------------- + + +### rejectSeries(arr, iterator, callback) + +The same as [`reject`](#reject), only the `iterator` is applied to each item in `arr` +in series. + + +--------------------------------------- + + +### reduce(arr, memo, iterator, callback) + +__Aliases:__ `inject`, `foldl` + +Reduces `arr` into a single value using an async `iterator` to return +each successive step. `memo` is the initial state of the reduction. +This function only operates in series. + +For performance reasons, it may make sense to split a call to this function into +a parallel map, and then use the normal `Array.prototype.reduce` on the results. +This function is for situations where each step in the reduction needs to be async; +if you can get the data before reducing it, then it's probably a good idea to do so. + +__Arguments__ + +* `arr` - An array to iterate over. +* `memo` - The initial state of the reduction. +* `iterator(memo, item, callback)` - A function applied to each item in the + array to produce the next step in the reduction. The `iterator` is passed a + `callback(err, reduction)` which accepts an optional error as its first + argument, and the state of the reduction as the second. If an error is + passed to the callback, the reduction is stopped and the main `callback` is + immediately called with the error. +* `callback(err, result)` - A callback which is called after all the `iterator` + functions have finished. Result is the reduced value. + +__Example__ + +```js +async.reduce([1,2,3], 0, function(memo, item, callback){ + // pointless async: + process.nextTick(function(){ + callback(null, memo + item) + }); +}, function(err, result){ + // result is now equal to the last value of memo, which is 6 +}); +``` + +--------------------------------------- + + +### reduceRight(arr, memo, iterator, callback) + +__Alias:__ `foldr` + +Same as [`reduce`](#reduce), only operates on `arr` in reverse order. + + +--------------------------------------- + + +### detect(arr, iterator, callback) + +Returns the first value in `arr` that passes an async truth test. The +`iterator` is applied in parallel, meaning the first iterator to return `true` will +fire the detect `callback` with that result. That means the result might not be +the first item in the original `arr` (in terms of order) that passes the test. + +If order within the original `arr` is important, then look at [`detectSeries`](#detectSeries). + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in `arr`. + The iterator is passed a `callback(truthValue)` which must be called with a + boolean argument once it has completed. +* `callback(result)` - A callback which is called as soon as any iterator returns + `true`, or after all the `iterator` functions have finished. Result will be + the first item in the array that passes the truth test (iterator) or the + value `undefined` if none passed. + +__Example__ + +```js +async.detect(['file1','file2','file3'], fs.exists, function(result){ + // result now equals the first file in the list that exists +}); +``` + +--------------------------------------- + + +### detectSeries(arr, iterator, callback) + +The same as [`detect`](#detect), only the `iterator` is applied to each item in `arr` +in series. This means the result is always the first in the original `arr` (in +terms of array order) that passes the truth test. + + +--------------------------------------- + + +### sortBy(arr, iterator, callback) + +Sorts a list by the results of running each `arr` value through an async `iterator`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, sortValue)` which must be called once it + has completed with an error (which can be `null`) and a value to use as the sort + criteria. +* `callback(err, results)` - A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is the items from + the original `arr` sorted by the values returned by the `iterator` calls. + +__Example__ + +```js +async.sortBy(['file1','file2','file3'], function(file, callback){ + fs.stat(file, function(err, stats){ + callback(err, stats.mtime); + }); +}, function(err, results){ + // results is now the original array of files sorted by + // modified date +}); +``` + +__Sort Order__ + +By modifying the callback parameter the sorting order can be influenced: + +```js +//ascending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(err, x); +}, function(err,result){ + //result callback +} ); + +//descending order +async.sortBy([1,9,3,5], function(x, callback){ + callback(err, x*-1); //<- x*-1 instead of x, turns the order around +}, function(err,result){ + //result callback +} ); +``` + +--------------------------------------- + + +### some(arr, iterator, callback) + +__Alias:__ `any` + +Returns `true` if at least one element in the `arr` satisfies an async test. +_The callback for each iterator call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. Once any iterator +call returns `true`, the main `callback` is immediately called. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a callback(truthValue) which must be + called with a boolean argument once it has completed. +* `callback(result)` - A callback which is called as soon as any iterator returns + `true`, or after all the iterator functions have finished. Result will be + either `true` or `false` depending on the values of the async tests. + +__Example__ + +```js +async.some(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then at least one of the files exists +}); +``` + +--------------------------------------- + + +### every(arr, iterator, callback) + +__Alias:__ `all` + +Returns `true` if every element in `arr` satisfies an async test. +_The callback for each `iterator` call only accepts a single argument of `true` or +`false`; it does not accept an error argument first!_ This is in-line with the +way node libraries work with truth tests like `fs.exists`. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A truth test to apply to each item in the array + in parallel. The iterator is passed a callback(truthValue) which must be + called with a boolean argument once it has completed. +* `callback(result)` - A callback which is called after all the `iterator` + functions have finished. Result will be either `true` or `false` depending on + the values of the async tests. + +__Example__ + +```js +async.every(['file1','file2','file3'], fs.exists, function(result){ + // if result is true then every file exists +}); +``` + +--------------------------------------- + + +### concat(arr, iterator, callback) + +Applies `iterator` to each item in `arr`, concatenating the results. Returns the +concatenated list. The `iterator`s are called in parallel, and the results are +concatenated as they return. There is no guarantee that the results array will +be returned in the original order of `arr` passed to the `iterator` function. + +__Arguments__ + +* `arr` - An array to iterate over. +* `iterator(item, callback)` - A function to apply to each item in `arr`. + The iterator is passed a `callback(err, results)` which must be called once it + has completed with an error (which can be `null`) and an array of results. +* `callback(err, results)` - A callback which is called after all the `iterator` + functions have finished, or an error occurs. Results is an array containing + the concatenated results of the `iterator` function. + +__Example__ + +```js +async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files){ + // files is now a list of filenames that exist in the 3 directories +}); +``` + +--------------------------------------- + + +### concatSeries(arr, iterator, callback) + +Same as [`concat`](#concat), but executes in series instead of parallel. + + +## Control Flow + + +### series(tasks, [callback]) + +Run the functions in the `tasks` array in series, each one running once the previous +function has completed. If any functions in the series pass an error to its +callback, no more functions are run, and `callback` is immediately called with the value of the error. +Otherwise, `callback` receives an array of results when `tasks` have completed. + +It is also possible to use an object instead of an array. Each property will be +run as a function, and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`series`](#series). + +**Note** that while many implementations preserve the order of object properties, the +[ECMAScript Language Specifcation](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) +explicitly states that + +> The mechanics and order of enumerating the properties is not specified. + +So if you rely on the order in which your series of functions are executed, and want +this to work on all platforms, consider using an array. + +__Arguments__ + +* `tasks` - An array or object containing functions to run, each function is passed + a `callback(err, result)` it must call on completion with an error `err` (which can + be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the `task` callbacks. + +__Example__ + +```js +async.series([ + function(callback){ + // do some stuff ... + callback(null, 'one'); + }, + function(callback){ + // do some more stuff ... + callback(null, 'two'); + } +], +// optional callback +function(err, results){ + // results is now equal to ['one', 'two'] +}); + + +// an example using an object instead of an array +async.series({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equal to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallel(tasks, [callback]) + +Run the `tasks` array of functions in parallel, without waiting until the previous +function has completed. If any of the functions pass an error to its +callback, the main `callback` is immediately called with the value of the error. +Once the `tasks` have completed, the results are passed to the final `callback` as an +array. + +It is also possible to use an object instead of an array. Each property will be +run as a function and the results will be passed to the final `callback` as an object +instead of an array. This can be a more readable way of handling results from +[`parallel`](#parallel). + + +__Arguments__ + +* `tasks` - An array or object containing functions to run. Each function is passed + a `callback(err, result)` which it must call on completion with an error `err` + (which can be `null`) and an optional `result` value. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the task callbacks. + +__Example__ + +```js +async.parallel([ + function(callback){ + setTimeout(function(){ + callback(null, 'one'); + }, 200); + }, + function(callback){ + setTimeout(function(){ + callback(null, 'two'); + }, 100); + } +], +// optional callback +function(err, results){ + // the results array will equal ['one','two'] even though + // the second function had a shorter timeout. +}); + + +// an example using an object instead of an array +async.parallel({ + one: function(callback){ + setTimeout(function(){ + callback(null, 1); + }, 200); + }, + two: function(callback){ + setTimeout(function(){ + callback(null, 2); + }, 100); + } +}, +function(err, results) { + // results is now equals to: {one: 1, two: 2} +}); +``` + +--------------------------------------- + + +### parallelLimit(tasks, limit, [callback]) + +The same as [`parallel`](#parallel), only `tasks` are executed in parallel +with a maximum of `limit` tasks executing at any time. + +Note that the `tasks` are not executed in batches, so there is no guarantee that +the first `limit` tasks will complete before any others are started. + +__Arguments__ + +* `tasks` - An array or object containing functions to run, each function is passed + a `callback(err, result)` it must call on completion with an error `err` (which can + be `null`) and an optional `result` value. +* `limit` - The maximum number of `tasks` to run at any time. +* `callback(err, results)` - An optional callback to run once all the functions + have completed. This function gets a results array (or object) containing all + the result arguments passed to the `task` callbacks. + +--------------------------------------- + + +### whilst(test, fn, callback) + +Repeatedly call `fn`, while `test` returns `true`. Calls `callback` when stopped, +or an error occurs. + +__Arguments__ + +* `test()` - synchronous truth test to perform before each execution of `fn`. +* `fn(callback)` - A function which is called each time `test` passes. The function is + passed a `callback(err)`, which must be called once it has completed with an + optional `err` argument. +* `callback(err)` - A callback which is called after the test fails and repeated + execution of `fn` has stopped. + +__Example__ + +```js +var count = 0; + +async.whilst( + function () { return count < 5; }, + function (callback) { + count++; + setTimeout(callback, 1000); + }, + function (err) { + // 5 seconds have passed + } +); +``` + +--------------------------------------- + + +### doWhilst(fn, test, callback) + +The post-check version of [`whilst`](#whilst). To reflect the difference in +the order of operations, the arguments `test` and `fn` are switched. + +`doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + +--------------------------------------- + + +### until(test, fn, callback) + +Repeatedly call `fn` until `test` returns `true`. Calls `callback` when stopped, +or an error occurs. + +The inverse of [`whilst`](#whilst). + +--------------------------------------- + + +### doUntil(fn, test, callback) + +Like [`doWhilst`](#doWhilst), except the `test` is inverted. Note the argument ordering differs from `until`. + +--------------------------------------- + + +### forever(fn, errback) + +Calls the asynchronous function `fn` with a callback parameter that allows it to +call itself again, in series, indefinitely. + +If an error is passed to the callback then `errback` is called with the +error, and execution stops, otherwise it will never be called. + +```js +async.forever( + function(next) { + // next is suitable for passing to things that need a callback(err [, whatever]); + // it will result in this function being called again. + }, + function(err) { + // if next is called with a value in its first parameter, it will appear + // in here as 'err', and execution will stop. + } +); +``` + +--------------------------------------- + + +### waterfall(tasks, [callback]) + +Runs the `tasks` array of functions in series, each passing their results to the next in +the array. However, if any of the `tasks` pass an error to their own callback, the +next function is not executed, and the main `callback` is immediately called with +the error. + +__Arguments__ + +* `tasks` - An array of functions to run, each function is passed a + `callback(err, result1, result2, ...)` it must call on completion. The first + argument is an error (which can be `null`) and any further arguments will be + passed as arguments in order to the next task. +* `callback(err, [results])` - An optional callback to run once all the functions + have completed. This will be passed the results of the last task's callback. + + + +__Example__ + +```js +async.waterfall([ + function(callback){ + callback(null, 'one', 'two'); + }, + function(arg1, arg2, callback){ + // arg1 now equals 'one' and arg2 now equals 'two' + callback(null, 'three'); + }, + function(arg1, callback){ + // arg1 now equals 'three' + callback(null, 'done'); + } +], function (err, result) { + // result now equals 'done' +}); +``` + +--------------------------------------- + +### compose(fn1, fn2...) + +Creates a function which is a composition of the passed asynchronous +functions. Each function consumes the return value of the function that +follows. Composing functions `f()`, `g()`, and `h()` would produce the result of +`f(g(h()))`, only this version uses callbacks to obtain the return values. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* `functions...` - the asynchronous functions to compose + + +__Example__ + +```js +function add1(n, callback) { + setTimeout(function () { + callback(null, n + 1); + }, 10); +} + +function mul3(n, callback) { + setTimeout(function () { + callback(null, n * 3); + }, 10); +} + +var add1mul3 = async.compose(mul3, add1); + +add1mul3(4, function (err, result) { + // result now equals 15 +}); +``` + +--------------------------------------- + +### seq(fn1, fn2...) + +Version of the compose function that is more natural to read. +Each following function consumes the return value of the latter function. + +Each function is executed with the `this` binding of the composed function. + +__Arguments__ + +* functions... - the asynchronous functions to compose + + +__Example__ + +```js +// Requires lodash (or underscore), express3 and dresende's orm2. +// Part of an app, that fetches cats of the logged user. +// This example uses `seq` function to avoid overnesting and error +// handling clutter. +app.get('/cats', function(request, response) { + function handleError(err, data, callback) { + if (err) { + console.error(err); + response.json({ status: 'error', message: err.message }); + } + else { + callback(data); + } + } + var User = request.models.User; + async.seq( + _.bind(User.get, User), // 'User.get' has signature (id, callback(err, data)) + handleError, + function(user, fn) { + user.getCats(fn); // 'getCats' has signature (callback(err, data)) + }, + handleError, + function(cats) { + response.json({ status: 'ok', message: 'Cats found', data: cats }); + } + )(req.session.user_id); + } +}); +``` + +--------------------------------------- + +### applyEach(fns, args..., callback) + +Applies the provided arguments to each function in the array, calling +`callback` after all functions have completed. If you only provide the first +argument, then it will return a function which lets you pass in the +arguments as if it were a single function call. + +__Arguments__ + +* `fns` - the asynchronous functions to all call with the same arguments +* `args...` - any number of separate arguments to pass to the function +* `callback` - the final argument should be the callback, called when all + functions have completed processing + + +__Example__ + +```js +async.applyEach([enableSearch, updateSchema], 'bucket', callback); + +// partial application example: +async.each( + buckets, + async.applyEach([enableSearch, updateSchema]), + callback +); +``` + +--------------------------------------- + + +### applyEachSeries(arr, iterator, callback) + +The same as [`applyEach`](#applyEach) only the functions are applied in series. + +--------------------------------------- + + +### queue(worker, concurrency) + +Creates a `queue` object with the specified `concurrency`. Tasks added to the +`queue` are processed in parallel (up to the `concurrency` limit). If all +`worker`s are in progress, the task is queued until one becomes available. +Once a `worker` completes a `task`, that `task`'s callback is called. + +__Arguments__ + +* `worker(task, callback)` - An asynchronous function for processing a queued + task, which must call its `callback(err)` argument when finished, with an + optional `error` as an argument. +* `concurrency` - An `integer` for determining how many `worker` functions should be + run in parallel. + +__Queue objects__ + +The `queue` object returned by this function has the following properties and +methods: + +* `length()` - a function returning the number of items waiting to be processed. +* `started` - a function returning whether or not any items have been pushed and processed by the queue +* `running()` - a function returning the number of items currently being processed. +* `idle()` - a function returning false if there are items waiting or being processed, or true if not. +* `concurrency` - an integer for determining how many `worker` functions should be + run in parallel. This property can be changed after a `queue` is created to + alter the concurrency on-the-fly. +* `push(task, [callback])` - add a new task to the `queue`. Calls `callback` once + the `worker` has finished processing the task. Instead of a single task, a `tasks` array + can be submitted. The respective callback is used for every task in the list. +* `unshift(task, [callback])` - add a new task to the front of the `queue`. +* `saturated` - a callback that is called when the `queue` length hits the `concurrency` limit, + and further tasks will be queued. +* `empty` - a callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - a callback that is called when the last item from the `queue` has returned from the `worker`. +* `paused` - a boolean for determining whether the queue is in a paused state +* `pause()` - a function that pauses the processing of tasks until `resume()` is called. +* `resume()` - a function that resumes the processing of queued tasks when the queue is paused. +* `kill()` - a function that empties remaining tasks from the queue forcing it to go idle. + +__Example__ + +```js +// create a queue object with concurrency 2 + +var q = async.queue(function (task, callback) { + console.log('hello ' + task.name); + callback(); +}, 2); + + +// assign a callback +q.drain = function() { + console.log('all items have been processed'); +} + +// add some items to the queue + +q.push({name: 'foo'}, function (err) { + console.log('finished processing foo'); +}); +q.push({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); + +// add some items to the queue (batch-wise) + +q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function (err) { + console.log('finished processing bar'); +}); + +// add some items to the front of the queue + +q.unshift({name: 'bar'}, function (err) { + console.log('finished processing bar'); +}); +``` + + +--------------------------------------- + + +### priorityQueue(worker, concurrency) + +The same as [`queue`](#queue) only tasks are assigned a priority and completed in ascending priority order. There are two differences between `queue` and `priorityQueue` objects: + +* `push(task, priority, [callback])` - `priority` should be a number. If an array of + `tasks` is given, all tasks will be assigned the same priority. +* The `unshift` method was removed. + +--------------------------------------- + + +### cargo(worker, [payload]) + +Creates a `cargo` object with the specified payload. Tasks added to the +cargo will be processed altogether (up to the `payload` limit). If the +`worker` is in progress, the task is queued until it becomes available. Once +the `worker` has completed some tasks, each callback of those tasks is called. +Check out [this animation](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) for how `cargo` and `queue` work. + +While [queue](#queue) passes only one task to one of a group of workers +at a time, cargo passes an array of tasks to a single worker, repeating +when the worker is finished. + +__Arguments__ + +* `worker(tasks, callback)` - An asynchronous function for processing an array of + queued tasks, which must call its `callback(err)` argument when finished, with + an optional `err` argument. +* `payload` - An optional `integer` for determining how many tasks should be + processed per round; if omitted, the default is unlimited. + +__Cargo objects__ + +The `cargo` object returned by this function has the following properties and +methods: + +* `length()` - A function returning the number of items waiting to be processed. +* `payload` - An `integer` for determining how many tasks should be + process per round. This property can be changed after a `cargo` is created to + alter the payload on-the-fly. +* `push(task, [callback])` - Adds `task` to the `queue`. The callback is called + once the `worker` has finished processing the task. Instead of a single task, an array of `tasks` + can be submitted. The respective callback is used for every task in the list. +* `saturated` - A callback that is called when the `queue.length()` hits the concurrency and further tasks will be queued. +* `empty` - A callback that is called when the last item from the `queue` is given to a `worker`. +* `drain` - A callback that is called when the last item from the `queue` has returned from the `worker`. + +__Example__ + +```js +// create a cargo object with payload 2 + +var cargo = async.cargo(function (tasks, callback) { + for(var i=0; i +### auto(tasks, [callback]) + +Determines the best order for running the functions in `tasks`, based on their +requirements. Each function can optionally depend on other functions being completed +first, and each function is run as soon as its requirements are satisfied. + +If any of the functions pass an error to their callback, it will not +complete (so any other functions depending on it will not run), and the main +`callback` is immediately called with the error. Functions also receive an +object containing the results of functions which have completed so far. + +Note, all functions are called with a `results` object as a second argument, +so it is unsafe to pass functions in the `tasks` object which cannot handle the +extra argument. + +For example, this snippet of code: + +```js +async.auto({ + readData: async.apply(fs.readFile, 'data.txt', 'utf-8') +}, callback); +``` + +will have the effect of calling `readFile` with the results object as the last +argument, which will fail: + +```js +fs.readFile('data.txt', 'utf-8', cb, {}); +``` + +Instead, wrap the call to `readFile` in a function which does not forward the +`results` object: + +```js +async.auto({ + readData: function(cb, results){ + fs.readFile('data.txt', 'utf-8', cb); + } +}, callback); +``` + +__Arguments__ + +* `tasks` - An object. Each of its properties is either a function or an array of + requirements, with the function itself the last item in the array. The object's key + of a property serves as the name of the task defined by that property, + i.e. can be used when specifying requirements for other tasks. + The function receives two arguments: (1) a `callback(err, result)` which must be + called when finished, passing an `error` (which can be `null`) and the result of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions. +* `callback(err, results)` - An optional callback which is called when all the + tasks have been completed. It receives the `err` argument if any `tasks` + pass an error to their callback. Results are always returned; however, if + an error occurs, no further `tasks` will be performed, and the results + object will only contain partial results. + + +__Example__ + +```js +async.auto({ + get_data: function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + make_folder: function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + }, + write_file: ['get_data', 'make_folder', function(callback, results){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + callback(null, 'filename'); + }], + email_link: ['write_file', function(callback, results){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + // results.write_file contains the filename returned by write_file. + callback(null, {'file':results.write_file, 'email':'user@example.com'}); + }] +}, function(err, results) { + console.log('err = ', err); + console.log('results = ', results); +}); +``` + +This is a fairly trivial example, but to do this using the basic parallel and +series functions would look like this: + +```js +async.parallel([ + function(callback){ + console.log('in get_data'); + // async code to get some data + callback(null, 'data', 'converted to array'); + }, + function(callback){ + console.log('in make_folder'); + // async code to create a directory to store a file in + // this is run at the same time as getting the data + callback(null, 'folder'); + } +], +function(err, results){ + async.series([ + function(callback){ + console.log('in write_file', JSON.stringify(results)); + // once there is some data and the directory exists, + // write the data to a file in the directory + results.push('filename'); + callback(null); + }, + function(callback){ + console.log('in email_link', JSON.stringify(results)); + // once the file is written let's email a link to it... + callback(null, {'file':results.pop(), 'email':'user@example.com'}); + } + ]); +}); +``` + +For a complicated series of `async` tasks, using the [`auto`](#auto) function makes adding +new tasks much easier (and the code more readable). + + +--------------------------------------- + + +### retry([times = 5], task, [callback]) + +Attempts to get a successful response from `task` no more than `times` times before +returning an error. If the task is successful, the `callback` will be passed the result +of the successfull task. If all attemps fail, the callback will be passed the error and +result (if any) of the final attempt. + +__Arguments__ + +* `times` - An integer indicating how many times to attempt the `task` before giving up. Defaults to 5. +* `task(callback, results)` - A function which receives two arguments: (1) a `callback(err, result)` + which must be called when finished, passing `err` (which can be `null`) and the `result` of + the function's execution, and (2) a `results` object, containing the results of + the previously executed functions (if nested inside another control flow). +* `callback(err, results)` - An optional callback which is called when the + task has succeeded, or after the final failed attempt. It receives the `err` and `result` arguments of the last attempt at completing the `task`. + +The [`retry`](#retry) function can be used as a stand-alone control flow by passing a +callback, as shown below: + +```js +async.retry(3, apiMethod, function(err, result) { + // do something with the result +}); +``` + +It can also be embeded within other control flow functions to retry individual methods +that are not as reliable, like this: + +```js +async.auto({ + users: api.getUsers.bind(api), + payments: async.retry(3, api.getPayments.bind(api)) +}, function(err, results) { + // do something with the results +}); +``` + + +--------------------------------------- + + +### iterator(tasks) + +Creates an iterator function which calls the next function in the `tasks` array, +returning a continuation to call the next one after that. It's also possible to +“peek” at the next iterator with `iterator.next()`. + +This function is used internally by the `async` module, but can be useful when +you want to manually control the flow of functions in series. + +__Arguments__ + +* `tasks` - An array of functions to run. + +__Example__ + +```js +var iterator = async.iterator([ + function(){ sys.p('one'); }, + function(){ sys.p('two'); }, + function(){ sys.p('three'); } +]); + +node> var iterator2 = iterator(); +'one' +node> var iterator3 = iterator2(); +'two' +node> iterator3(); +'three' +node> var nextfn = iterator2.next(); +node> nextfn(); +'three' +``` + +--------------------------------------- + + +### apply(function, arguments..) + +Creates a continuation function with some arguments already applied. + +Useful as a shorthand when combined with other control flow functions. Any arguments +passed to the returned function are added to the arguments originally passed +to apply. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to automatically apply when the + continuation is called. + +__Example__ + +```js +// using apply + +async.parallel([ + async.apply(fs.writeFile, 'testfile1', 'test1'), + async.apply(fs.writeFile, 'testfile2', 'test2'), +]); + + +// the same process without using apply + +async.parallel([ + function(callback){ + fs.writeFile('testfile1', 'test1', callback); + }, + function(callback){ + fs.writeFile('testfile2', 'test2', callback); + } +]); +``` + +It's possible to pass any number of additional arguments when calling the +continuation: + +```js +node> var fn = async.apply(sys.puts, 'one'); +node> fn('two', 'three'); +one +two +three +``` + +--------------------------------------- + + +### nextTick(callback) + +Calls `callback` on a later loop around the event loop. In Node.js this just +calls `process.nextTick`; in the browser it falls back to `setImmediate(callback)` +if available, otherwise `setTimeout(callback, 0)`, which means other higher priority +events may precede the execution of `callback`. + +This is used internally for browser-compatibility purposes. + +__Arguments__ + +* `callback` - The function to call on a later loop around the event loop. + +__Example__ + +```js +var call_order = []; +async.nextTick(function(){ + call_order.push('two'); + // call_order now equals ['one','two'] +}); +call_order.push('one') +``` + + +### times(n, callback) + +Calls the `callback` function `n` times, and accumulates results in the same manner +you would use with [`map`](#map). + +__Arguments__ + +* `n` - The number of times to run the function. +* `callback` - The function to call `n` times. + +__Example__ + +```js +// Pretend this is some complicated async factory +var createUser = function(id, callback) { + callback(null, { + id: 'user' + id + }) +} +// generate 5 users +async.times(5, function(n, next){ + createUser(n, function(err, user) { + next(err, user) + }) +}, function(err, users) { + // we should now have 5 users +}); +``` + + +### timesSeries(n, callback) + +The same as [`times`](#times), only the iterator is applied to each item in `arr` in +series. The next `iterator` is only called once the current one has completed. +The results array will be in the same order as the original. + + +## Utils + + +### memoize(fn, [hasher]) + +Caches the results of an `async` function. When creating a hash to store function +results against, the callback is omitted from the hash and an optional hash +function can be used. + +The cache of results is exposed as the `memo` property of the function returned +by `memoize`. + +__Arguments__ + +* `fn` - The function to proxy and cache results from. +* `hasher` - Tn optional function for generating a custom hash for storing + results. It has all the arguments applied to it apart from the callback, and + must be synchronous. + +__Example__ + +```js +var slow_fn = function (name, callback) { + // do something + callback(null, result); +}; +var fn = async.memoize(slow_fn); + +// fn can now be used as if it were slow_fn +fn('some name', function () { + // callback +}); +``` + + +### unmemoize(fn) + +Undoes a [`memoize`](#memoize)d function, reverting it to the original, unmemoized +form. Handy for testing. + +__Arguments__ + +* `fn` - the memoized function + + +### log(function, arguments) + +Logs the result of an `async` function to the `console`. Only works in Node.js or +in browsers that support `console.log` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.log` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, 'hello ' + name); + }, 1000); +}; +``` +```js +node> async.log(hello, 'world'); +'hello world' +``` + +--------------------------------------- + + +### dir(function, arguments) + +Logs the result of an `async` function to the `console` using `console.dir` to +display the properties of the resulting object. Only works in Node.js or +in browsers that support `console.dir` and `console.error` (such as FF and Chrome). +If multiple arguments are returned from the async function, `console.dir` is +called on each argument in order. + +__Arguments__ + +* `function` - The function you want to eventually apply all arguments to. +* `arguments...` - Any number of arguments to apply to the function. + +__Example__ + +```js +var hello = function(name, callback){ + setTimeout(function(){ + callback(null, {hello: name}); + }, 1000); +}; +``` +```js +node> async.dir(hello, 'world'); +{hello: 'world'} +``` + +--------------------------------------- + + +### noConflict() + +Changes the value of `async` back to its original value, returning a reference to the +`async` object. diff --git a/mocha/node_modules/nconf/node_modules/async/component.json b/mocha/node_modules/nconf/node_modules/async/component.json new file mode 100644 index 0000000..bbb0115 --- /dev/null +++ b/mocha/node_modules/nconf/node_modules/async/component.json @@ -0,0 +1,11 @@ +{ + "name": "async", + "repo": "caolan/async", + "description": "Higher-order functions and common patterns for asynchronous code", + "version": "0.1.23", + "keywords": [], + "dependencies": {}, + "development": {}, + "main": "lib/async.js", + "scripts": [ "lib/async.js" ] +} diff --git a/mocha/node_modules/nconf/node_modules/async/lib/async.js b/mocha/node_modules/nconf/node_modules/async/lib/async.js new file mode 100644 index 0000000..01e8afc --- /dev/null +++ b/mocha/node_modules/nconf/node_modules/async/lib/async.js @@ -0,0 +1,1123 @@ +/*! + * async + * https://github.com/caolan/async + * + * Copyright 2010-2014 Caolan McMahon + * Released under the MIT license + */ +/*jshint onevar: false, indent:4 */ +/*global setImmediate: false, setTimeout: false, console: false */ +(function () { + + var async = {}; + + // global on the server, window in the browser + var root, previous_async; + + root = this; + if (root != null) { + previous_async = root.async; + } + + async.noConflict = function () { + root.async = previous_async; + return async; + }; + + function only_once(fn) { + var called = false; + return function() { + if (called) throw new Error("Callback was already called."); + called = true; + fn.apply(root, arguments); + } + } + + //// cross-browser compatiblity functions //// + + var _toString = Object.prototype.toString; + + var _isArray = Array.isArray || function (obj) { + return _toString.call(obj) === '[object Array]'; + }; + + var _each = function (arr, iterator) { + if (arr.forEach) { + return arr.forEach(iterator); + } + for (var i = 0; i < arr.length; i += 1) { + iterator(arr[i], i, arr); + } + }; + + var _map = function (arr, iterator) { + if (arr.map) { + return arr.map(iterator); + } + var results = []; + _each(arr, function (x, i, a) { + results.push(iterator(x, i, a)); + }); + return results; + }; + + var _reduce = function (arr, iterator, memo) { + if (arr.reduce) { + return arr.reduce(iterator, memo); + } + _each(arr, function (x, i, a) { + memo = iterator(memo, x, i, a); + }); + return memo; + }; + + var _keys = function (obj) { + if (Object.keys) { + return Object.keys(obj); + } + var keys = []; + for (var k in obj) { + if (obj.hasOwnProperty(k)) { + keys.push(k); + } + } + return keys; + }; + + //// exported async module functions //// + + //// nextTick implementation with browser-compatible fallback //// + if (typeof process === 'undefined' || !(process.nextTick)) { + if (typeof setImmediate === 'function') { + async.nextTick = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + async.setImmediate = async.nextTick; + } + else { + async.nextTick = function (fn) { + setTimeout(fn, 0); + }; + async.setImmediate = async.nextTick; + } + } + else { + async.nextTick = process.nextTick; + if (typeof setImmediate !== 'undefined') { + async.setImmediate = function (fn) { + // not a direct alias for IE10 compatibility + setImmediate(fn); + }; + } + else { + async.setImmediate = async.nextTick; + } + } + + async.each = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + _each(arr, function (x) { + iterator(x, only_once(done) ); + }); + function done(err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(); + } + } + } + }; + async.forEach = async.each; + + async.eachSeries = function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length) { + return callback(); + } + var completed = 0; + var iterate = function () { + iterator(arr[completed], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + if (completed >= arr.length) { + callback(); + } + else { + iterate(); + } + } + }); + }; + iterate(); + }; + async.forEachSeries = async.eachSeries; + + async.eachLimit = function (arr, limit, iterator, callback) { + var fn = _eachLimit(limit); + fn.apply(null, [arr, iterator, callback]); + }; + async.forEachLimit = async.eachLimit; + + var _eachLimit = function (limit) { + + return function (arr, iterator, callback) { + callback = callback || function () {}; + if (!arr.length || limit <= 0) { + return callback(); + } + var completed = 0; + var started = 0; + var running = 0; + + (function replenish () { + if (completed >= arr.length) { + return callback(); + } + + while (running < limit && started < arr.length) { + started += 1; + running += 1; + iterator(arr[started - 1], function (err) { + if (err) { + callback(err); + callback = function () {}; + } + else { + completed += 1; + running -= 1; + if (completed >= arr.length) { + callback(); + } + else { + replenish(); + } + } + }); + } + })(); + }; + }; + + + var doParallel = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.each].concat(args)); + }; + }; + var doParallelLimit = function(limit, fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [_eachLimit(limit)].concat(args)); + }; + }; + var doSeries = function (fn) { + return function () { + var args = Array.prototype.slice.call(arguments); + return fn.apply(null, [async.eachSeries].concat(args)); + }; + }; + + + var _asyncMap = function (eachfn, arr, iterator, callback) { + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + if (!callback) { + eachfn(arr, function (x, callback) { + iterator(x.value, function (err) { + callback(err); + }); + }); + } else { + var results = []; + eachfn(arr, function (x, callback) { + iterator(x.value, function (err, v) { + results[x.index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + async.map = doParallel(_asyncMap); + async.mapSeries = doSeries(_asyncMap); + async.mapLimit = function (arr, limit, iterator, callback) { + return _mapLimit(limit)(arr, iterator, callback); + }; + + var _mapLimit = function(limit) { + return doParallelLimit(limit, _asyncMap); + }; + + // reduce only has a series version, as doing reduce in parallel won't + // work in many situations. + async.reduce = function (arr, memo, iterator, callback) { + async.eachSeries(arr, function (x, callback) { + iterator(memo, x, function (err, v) { + memo = v; + callback(err); + }); + }, function (err) { + callback(err, memo); + }); + }; + // inject alias + async.inject = async.reduce; + // foldl alias + async.foldl = async.reduce; + + async.reduceRight = function (arr, memo, iterator, callback) { + var reversed = _map(arr, function (x) { + return x; + }).reverse(); + async.reduce(reversed, memo, iterator, callback); + }; + // foldr alias + async.foldr = async.reduceRight; + + var _filter = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.filter = doParallel(_filter); + async.filterSeries = doSeries(_filter); + // select alias + async.select = async.filter; + async.selectSeries = async.filterSeries; + + var _reject = function (eachfn, arr, iterator, callback) { + var results = []; + arr = _map(arr, function (x, i) { + return {index: i, value: x}; + }); + eachfn(arr, function (x, callback) { + iterator(x.value, function (v) { + if (!v) { + results.push(x); + } + callback(); + }); + }, function (err) { + callback(_map(results.sort(function (a, b) { + return a.index - b.index; + }), function (x) { + return x.value; + })); + }); + }; + async.reject = doParallel(_reject); + async.rejectSeries = doSeries(_reject); + + var _detect = function (eachfn, arr, iterator, main_callback) { + eachfn(arr, function (x, callback) { + iterator(x, function (result) { + if (result) { + main_callback(x); + main_callback = function () {}; + } + else { + callback(); + } + }); + }, function (err) { + main_callback(); + }); + }; + async.detect = doParallel(_detect); + async.detectSeries = doSeries(_detect); + + async.some = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (v) { + main_callback(true); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(false); + }); + }; + // any alias + async.any = async.some; + + async.every = function (arr, iterator, main_callback) { + async.each(arr, function (x, callback) { + iterator(x, function (v) { + if (!v) { + main_callback(false); + main_callback = function () {}; + } + callback(); + }); + }, function (err) { + main_callback(true); + }); + }; + // all alias + async.all = async.every; + + async.sortBy = function (arr, iterator, callback) { + async.map(arr, function (x, callback) { + iterator(x, function (err, criteria) { + if (err) { + callback(err); + } + else { + callback(null, {value: x, criteria: criteria}); + } + }); + }, function (err, results) { + if (err) { + return callback(err); + } + else { + var fn = function (left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + }; + callback(null, _map(results.sort(fn), function (x) { + return x.value; + })); + } + }); + }; + + async.auto = function (tasks, callback) { + callback = callback || function () {}; + var keys = _keys(tasks); + var remainingTasks = keys.length + if (!remainingTasks) { + return callback(); + } + + var results = {}; + + var listeners = []; + var addListener = function (fn) { + listeners.unshift(fn); + }; + var removeListener = function (fn) { + for (var i = 0; i < listeners.length; i += 1) { + if (listeners[i] === fn) { + listeners.splice(i, 1); + return; + } + } + }; + var taskComplete = function () { + remainingTasks-- + _each(listeners.slice(0), function (fn) { + fn(); + }); + }; + + addListener(function () { + if (!remainingTasks) { + var theCallback = callback; + // prevent final callback from calling itself if it errors + callback = function () {}; + + theCallback(null, results); + } + }); + + _each(keys, function (k) { + var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]]; + var taskCallback = function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + if (err) { + var safeResults = {}; + _each(_keys(results), function(rkey) { + safeResults[rkey] = results[rkey]; + }); + safeResults[k] = args; + callback(err, safeResults); + // stop subsequent errors hitting callback multiple times + callback = function () {}; + } + else { + results[k] = args; + async.setImmediate(taskComplete); + } + }; + var requires = task.slice(0, Math.abs(task.length - 1)) || []; + var ready = function () { + return _reduce(requires, function (a, x) { + return (a && results.hasOwnProperty(x)); + }, true) && !results.hasOwnProperty(k); + }; + if (ready()) { + task[task.length - 1](taskCallback, results); + } + else { + var listener = function () { + if (ready()) { + removeListener(listener); + task[task.length - 1](taskCallback, results); + } + }; + addListener(listener); + } + }); + }; + + async.retry = function(times, task, callback) { + var DEFAULT_TIMES = 5; + var attempts = []; + // Use defaults if times not passed + if (typeof times === 'function') { + callback = task; + task = times; + times = DEFAULT_TIMES; + } + // Make sure times is a number + times = parseInt(times, 10) || DEFAULT_TIMES; + var wrappedTask = function(wrappedCallback, wrappedResults) { + var retryAttempt = function(task, finalAttempt) { + return function(seriesCallback) { + task(function(err, result){ + seriesCallback(!err || finalAttempt, {err: err, result: result}); + }, wrappedResults); + }; + }; + while (times) { + attempts.push(retryAttempt(task, !(times-=1))); + } + async.series(attempts, function(done, data){ + data = data[data.length - 1]; + (wrappedCallback || callback)(data.err, data.result); + }); + } + // If a callback is passed, run this as a controll flow + return callback ? wrappedTask() : wrappedTask + }; + + async.waterfall = function (tasks, callback) { + callback = callback || function () {}; + if (!_isArray(tasks)) { + var err = new Error('First argument to waterfall must be an array of functions'); + return callback(err); + } + if (!tasks.length) { + return callback(); + } + var wrapIterator = function (iterator) { + return function (err) { + if (err) { + callback.apply(null, arguments); + callback = function () {}; + } + else { + var args = Array.prototype.slice.call(arguments, 1); + var next = iterator.next(); + if (next) { + args.push(wrapIterator(next)); + } + else { + args.push(callback); + } + async.setImmediate(function () { + iterator.apply(null, args); + }); + } + }; + }; + wrapIterator(async.iterator(tasks))(); + }; + + var _parallel = function(eachfn, tasks, callback) { + callback = callback || function () {}; + if (_isArray(tasks)) { + eachfn.map(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + eachfn.each(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.parallel = function (tasks, callback) { + _parallel({ map: async.map, each: async.each }, tasks, callback); + }; + + async.parallelLimit = function(tasks, limit, callback) { + _parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback); + }; + + async.series = function (tasks, callback) { + callback = callback || function () {}; + if (_isArray(tasks)) { + async.mapSeries(tasks, function (fn, callback) { + if (fn) { + fn(function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + callback.call(null, err, args); + }); + } + }, callback); + } + else { + var results = {}; + async.eachSeries(_keys(tasks), function (k, callback) { + tasks[k](function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (args.length <= 1) { + args = args[0]; + } + results[k] = args; + callback(err); + }); + }, function (err) { + callback(err, results); + }); + } + }; + + async.iterator = function (tasks) { + var makeCallback = function (index) { + var fn = function () { + if (tasks.length) { + tasks[index].apply(null, arguments); + } + return fn.next(); + }; + fn.next = function () { + return (index < tasks.length - 1) ? makeCallback(index + 1): null; + }; + return fn; + }; + return makeCallback(0); + }; + + async.apply = function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + return function () { + return fn.apply( + null, args.concat(Array.prototype.slice.call(arguments)) + ); + }; + }; + + var _concat = function (eachfn, arr, fn, callback) { + var r = []; + eachfn(arr, function (x, cb) { + fn(x, function (err, y) { + r = r.concat(y || []); + cb(err); + }); + }, function (err) { + callback(err, r); + }); + }; + async.concat = doParallel(_concat); + async.concatSeries = doSeries(_concat); + + async.whilst = function (test, iterator, callback) { + if (test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.whilst(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doWhilst = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + var args = Array.prototype.slice.call(arguments, 1); + if (test.apply(null, args)) { + async.doWhilst(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.until = function (test, iterator, callback) { + if (!test()) { + iterator(function (err) { + if (err) { + return callback(err); + } + async.until(test, iterator, callback); + }); + } + else { + callback(); + } + }; + + async.doUntil = function (iterator, test, callback) { + iterator(function (err) { + if (err) { + return callback(err); + } + var args = Array.prototype.slice.call(arguments, 1); + if (!test.apply(null, args)) { + async.doUntil(iterator, test, callback); + } + else { + callback(); + } + }); + }; + + async.queue = function (worker, concurrency) { + if (concurrency === undefined) { + concurrency = 1; + } + function _insert(q, data, pos, callback) { + if (!q.started){ + q.started = true; + } + if (!_isArray(data)) { + data = [data]; + } + if(data.length == 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + if (q.drain) { + q.drain(); + } + }); + } + _each(data, function(task) { + var item = { + data: task, + callback: typeof callback === 'function' ? callback : null + }; + + if (pos) { + q.tasks.unshift(item); + } else { + q.tasks.push(item); + } + + if (q.saturated && q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + var workers = 0; + var q = { + tasks: [], + concurrency: concurrency, + saturated: null, + empty: null, + drain: null, + started: false, + paused: false, + push: function (data, callback) { + _insert(q, data, false, callback); + }, + kill: function () { + q.drain = null; + q.tasks = []; + }, + unshift: function (data, callback) { + _insert(q, data, true, callback); + }, + process: function () { + if (!q.paused && workers < q.concurrency && q.tasks.length) { + var task = q.tasks.shift(); + if (q.empty && q.tasks.length === 0) { + q.empty(); + } + workers += 1; + var next = function () { + workers -= 1; + if (task.callback) { + task.callback.apply(task, arguments); + } + if (q.drain && q.tasks.length + workers === 0) { + q.drain(); + } + q.process(); + }; + var cb = only_once(next); + worker(task.data, cb); + } + }, + length: function () { + return q.tasks.length; + }, + running: function () { + return workers; + }, + idle: function() { + return q.tasks.length + workers === 0; + }, + pause: function () { + if (q.paused === true) { return; } + q.paused = true; + q.process(); + }, + resume: function () { + if (q.paused === false) { return; } + q.paused = false; + q.process(); + } + }; + return q; + }; + + async.priorityQueue = function (worker, concurrency) { + + function _compareTasks(a, b){ + return a.priority - b.priority; + }; + + function _binarySearch(sequence, item, compare) { + var beg = -1, + end = sequence.length - 1; + while (beg < end) { + var mid = beg + ((end - beg + 1) >>> 1); + if (compare(item, sequence[mid]) >= 0) { + beg = mid; + } else { + end = mid - 1; + } + } + return beg; + } + + function _insert(q, data, priority, callback) { + if (!q.started){ + q.started = true; + } + if (!_isArray(data)) { + data = [data]; + } + if(data.length == 0) { + // call drain immediately if there are no tasks + return async.setImmediate(function() { + if (q.drain) { + q.drain(); + } + }); + } + _each(data, function(task) { + var item = { + data: task, + priority: priority, + callback: typeof callback === 'function' ? callback : null + }; + + q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item); + + if (q.saturated && q.tasks.length === q.concurrency) { + q.saturated(); + } + async.setImmediate(q.process); + }); + } + + // Start with a normal queue + var q = async.queue(worker, concurrency); + + // Override push to accept second parameter representing priority + q.push = function (data, priority, callback) { + _insert(q, data, priority, callback); + }; + + // Remove unshift function + delete q.unshift; + + return q; + }; + + async.cargo = function (worker, payload) { + var working = false, + tasks = []; + + var cargo = { + tasks: tasks, + payload: payload, + saturated: null, + empty: null, + drain: null, + drained: true, + push: function (data, callback) { + if (!_isArray(data)) { + data = [data]; + } + _each(data, function(task) { + tasks.push({ + data: task, + callback: typeof callback === 'function' ? callback : null + }); + cargo.drained = false; + if (cargo.saturated && tasks.length === payload) { + cargo.saturated(); + } + }); + async.setImmediate(cargo.process); + }, + process: function process() { + if (working) return; + if (tasks.length === 0) { + if(cargo.drain && !cargo.drained) cargo.drain(); + cargo.drained = true; + return; + } + + var ts = typeof payload === 'number' + ? tasks.splice(0, payload) + : tasks.splice(0, tasks.length); + + var ds = _map(ts, function (task) { + return task.data; + }); + + if(cargo.empty) cargo.empty(); + working = true; + worker(ds, function () { + working = false; + + var args = arguments; + _each(ts, function (data) { + if (data.callback) { + data.callback.apply(null, args); + } + }); + + process(); + }); + }, + length: function () { + return tasks.length; + }, + running: function () { + return working; + } + }; + return cargo; + }; + + var _console_fn = function (name) { + return function (fn) { + var args = Array.prototype.slice.call(arguments, 1); + fn.apply(null, args.concat([function (err) { + var args = Array.prototype.slice.call(arguments, 1); + if (typeof console !== 'undefined') { + if (err) { + if (console.error) { + console.error(err); + } + } + else if (console[name]) { + _each(args, function (x) { + console[name](x); + }); + } + } + }])); + }; + }; + async.log = _console_fn('log'); + async.dir = _console_fn('dir'); + /*async.info = _console_fn('info'); + async.warn = _console_fn('warn'); + async.error = _console_fn('error');*/ + + async.memoize = function (fn, hasher) { + var memo = {}; + var queues = {}; + hasher = hasher || function (x) { + return x; + }; + var memoized = function () { + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + var key = hasher.apply(null, args); + if (key in memo) { + async.nextTick(function () { + callback.apply(null, memo[key]); + }); + } + else if (key in queues) { + queues[key].push(callback); + } + else { + queues[key] = [callback]; + fn.apply(null, args.concat([function () { + memo[key] = arguments; + var q = queues[key]; + delete queues[key]; + for (var i = 0, l = q.length; i < l; i++) { + q[i].apply(null, arguments); + } + }])); + } + }; + memoized.memo = memo; + memoized.unmemoized = fn; + return memoized; + }; + + async.unmemoize = function (fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); + }; + }; + + async.times = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.map(counter, iterator, callback); + }; + + async.timesSeries = function (count, iterator, callback) { + var counter = []; + for (var i = 0; i < count; i++) { + counter.push(i); + } + return async.mapSeries(counter, iterator, callback); + }; + + async.seq = function (/* functions... */) { + var fns = arguments; + return function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + async.reduce(fns, args, function (newargs, fn, cb) { + fn.apply(that, newargs.concat([function () { + var err = arguments[0]; + var nextargs = Array.prototype.slice.call(arguments, 1); + cb(err, nextargs); + }])) + }, + function (err, results) { + callback.apply(that, [err].concat(results)); + }); + }; + }; + + async.compose = function (/* functions... */) { + return async.seq.apply(null, Array.prototype.reverse.call(arguments)); + }; + + var _applyEach = function (eachfn, fns /*args...*/) { + var go = function () { + var that = this; + var args = Array.prototype.slice.call(arguments); + var callback = args.pop(); + return eachfn(fns, function (fn, cb) { + fn.apply(that, args.concat([cb])); + }, + callback); + }; + if (arguments.length > 2) { + var args = Array.prototype.slice.call(arguments, 2); + return go.apply(this, args); + } + else { + return go; + } + }; + async.applyEach = doParallel(_applyEach); + async.applyEachSeries = doSeries(_applyEach); + + async.forever = function (fn, callback) { + function next(err) { + if (err) { + if (callback) { + return callback(err); + } + throw err; + } + fn(next); + } + next(); + }; + + // Node.js + if (typeof module !== 'undefined' && module.exports) { + module.exports = async; + } + // AMD / RequireJS + else if (typeof define !== 'undefined' && define.amd) { + define([], function () { + return async; + }); + } + // included directly via + + \ No newline at end of file diff --git a/webapp/src/main/webapp/index.jsp b/webapp/src/main/webapp/index.jsp new file mode 100644 index 0000000..c38169b --- /dev/null +++ b/webapp/src/main/webapp/index.jsp @@ -0,0 +1,5 @@ + + +

Hello World!

+ + diff --git a/webapp/src/main/webapp/js/main.js b/webapp/src/main/webapp/js/main.js new file mode 100644 index 0000000..ff4fd6a --- /dev/null +++ b/webapp/src/main/webapp/js/main.js @@ -0,0 +1,104 @@ +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 24/11/14 + * Time: 11:32 + * To change this template use File | Settings | File Templates. + */ +'use strict'; +(function() { + + var votable = document.cookie.indexOf('hpDevopsDemoApp') < 0; + + function setupVote() { + var bandStrips = document.querySelectorAll('.bandStrip'), contentTitleEl = document.getElementById('contentTitle'), i, l; + if(votable) { + contentTitleEl.textContent = 'raise your voice and make your choice'; + } else { + contentTitleEl.textContent = 'you have already stated your favorite, yet can cheet though :]'; + } + for(i = 0, l = bandStrips.length; i < l; i++) { + if(votable) { + bandStrips[i].onmouseenter = function() { + this.style.background = 'linear-gradient(0deg, #ccf, #aaf, #ccf)'; + }; + bandStrips[i].onmouseleave = function() { + this.style.background = 'linear-gradient(0deg, #eee, #ccc, #eee)'; + }; + bandStrips[i].onclick = function() { + vote(this.dataset.bandId, function(error, votes) { + var stripEl, totalVotes = 0; + if(error) {console.error(error);} else { + votes.forEach(function(vote) { + stripEl = document.querySelector('div[data-band-id="' + vote.id + '"]'); + stripEl.querySelector('.bandVotes').textContent = vote.votes; + totalVotes += vote.votes; + }); + votable = false; + document.getElementById('totalVotes').textContent = 'total votes: ' + totalVotes; + setupVote(); + } + }); + }; + } else { + bandStrips[i].style.background = 'linear-gradient(0deg, #eee, #ccc, #eee)'; + bandStrips[i].onmouseenter = null; + bandStrips[i].onmouseleave = null; + bandStrips[i].onclick = null; + } + } + } + + function vote(bandId, callback) { + var xhr = new XMLHttpRequest(); + xhr.open('put', '/api/band/' + bandId + '/vote'); + xhr.onerror = function() {callback('failed to get the bands data');}; + xhr.onload = function() { + var votes; + try { + votes = JSON.parse(xhr.responseText); + callback(null, votes); + } catch(e) {callback(e);} + }; + xhr.send(); + } + + function loadBands(callback) { + var xhr = new XMLHttpRequest(), bands; + xhr.open('get', '/api/bands'); + xhr.onerror = function() {callback('failed to get the bands data');}; + xhr.onload = function() { + try { + bands = JSON.parse(xhr.responseText); + callback(null, bands); + } catch(e) {callback(e);} + }; + xhr.send(); + } + + function renderBands(bands) { + var template, listElement, tmpElement, totalVotes = 0; + template = document.getElementById('bandStripTemplate'); + listElement = document.getElementById('bandsList'); + bands.forEach(function(band) { + template.content.querySelector('.bandStrip').dataset.bandId = band.id; + template.content.querySelector('.bandLogo').src = band.logo; + template.content.querySelector('.bandTitle').textContent = band.name.toUpperCase(); + template.content.querySelector('.bandVotes').textContent = band.votes; + template.content.querySelector('.bandSong').src = band.song; + tmpElement = document.importNode(template.content, true); + tmpElement = listElement.appendChild(tmpElement); + totalVotes += band.votes; + }); + document.getElementById('totalVotes').textContent = 'total votes: ' + totalVotes; + } + + loadBands(function(error, bands) { + if(error) { + console.error(error); + } else { + renderBands(bands); + setupVote(); + } + }); +})(); \ No newline at end of file diff --git a/webapp/src/main/webapp/teepoc.html b/webapp/src/main/webapp/teepoc.html new file mode 100644 index 0000000..93892b2 --- /dev/null +++ b/webapp/src/main/webapp/teepoc.html @@ -0,0 +1,597 @@ + + + + + Internal TEE Runner + + + + + +
+ +
+ + + +

+ + +

+

+
+ +
+
+ +
+ + + +
+ + + + + \ No newline at end of file diff --git a/webapp/src/main/webapp/testlist.html b/webapp/src/main/webapp/testlist.html new file mode 100644 index 0000000..db74b53 --- /dev/null +++ b/webapp/src/main/webapp/testlist.html @@ -0,0 +1,212 @@ + + + + + + + + + + + + + + + +
Test classTest NameFramework
+ +
+
+ + + + + + + + + + + + + + + + + + + + + +
Parameter NameParameter Value
+
+
+
+ + + + + \ No newline at end of file diff --git a/webapp/src/test/java/com/hp/devops/demoapp/BandTest.java b/webapp/src/test/java/com/hp/devops/demoapp/BandTest.java new file mode 100644 index 0000000..31ab68a --- /dev/null +++ b/webapp/src/test/java/com/hp/devops/demoapp/BandTest.java @@ -0,0 +1,78 @@ +package com.hp.devops.demoapp; + +import org.json.JSONObject; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.security.InvalidParameterException; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 25/11/14 + * Time: 14:21 + * To change this template use File | Settings | File Templates. + */ +public class BandTest { + //private String NON_RELATED; + private JSONObject test; + + @Before + public void beforeEach() { + test = new JSONObject(); + test.put("id", 1); + test.put("name", "Name"); + test.put("logo", "Logo"); + test.put("song", "Song"); + test.put("votes", 10); + } + + @Test + public void bandTestA() { + try { + Band band = new Band(null); + Assert.fail("the flow MUST have been fallen before"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), NullPointerException.class); + } + } + + @Test + public void bandTestB() { + try { + Band band = new Band(new JSONObject()); + Assert.fail("the flow MUST have been fallen before"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), InvalidParameterException.class); + Assert.assertEquals(e.getMessage(), "json must have an id property"); + } + } + + @Test + public void bandTestC() { + test.remove("name"); + test.remove("logo"); + Band band = new Band(test); + Assert.assertEquals(band.id, 1); + Assert.assertEquals(band.name, ""); + Assert.assertEquals(band.logo, ""); + Assert.assertEquals(band.song, "Song"); + Assert.assertEquals(band.votes, 10); + } + + @Test + public void bandTestD() { + Band band = new Band(test); + Assert.assertEquals(test.toString(), band.toJSON().toString()); + } + + @Test + public void bandTestE() { + Band band = new Band(test); + JSONObject tmp = new JSONObject(); + tmp.put("id", test.get("id")); + tmp.put("votes", test.get("votes")); + Assert.assertEquals(tmp.toString(), band.toJSONVotes().toString()); + } +} diff --git a/webapp/src/test/java/com/hp/devops/demoapp/CalcsTest.java b/webapp/src/test/java/com/hp/devops/demoapp/CalcsTest.java new file mode 100644 index 0000000..97f50c4 --- /dev/null +++ b/webapp/src/test/java/com/hp/devops/demoapp/CalcsTest.java @@ -0,0 +1,62 @@ +package com.hp.devops.demoapp; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Created by gullery on 17/02/2016. + */ +public class CalcsTest { + + @Test + public void sum_test_A() { + assertEquals(3, Calcs.sum(1, 2)); + } + + @Test + public void sub_test_A() { + assertEquals(3, Calcs.sub(5, 2)); + } + + @Test + public void sub_test_B() { + assertEquals(2, Calcs.sub(-1, -3)); + } + + @Test + public void sub_test_C() { + assertEquals(3, Calcs.sub(10, 7)); + } + + @Test + public void eq_test_A() { + assertTrue(Calcs.equal(1, 1)); + } + + @Test + public void eq_test_B() { + assertTrue(Calcs.equal(-1, -1)); + } + + @Test + public void neq_test_A() { + assertTrue(Calcs.nonEqual(0, 1)); + } + + @Test + public void neq_test_B() { + assertTrue(Calcs.nonEqual(-1, 0)); + } + + @Test + public void neq_test_C_BrokenTest() { + assertTrue(Calcs.nonEqual(5, 5)); + } + + @Test + public void always_true_A() { + assertTrue(Calcs.alwaysTrue()); + } +} diff --git a/webapp/src/test/java/com/hp/devops/demoapp/DataManagerTest.java b/webapp/src/test/java/com/hp/devops/demoapp/DataManagerTest.java new file mode 100644 index 0000000..adadc27 --- /dev/null +++ b/webapp/src/test/java/com/hp/devops/demoapp/DataManagerTest.java @@ -0,0 +1,72 @@ +package com.hp.devops.demoapp; + +import org.junit.Assert; +import org.junit.Test; + +import java.security.InvalidParameterException; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 25/11/14 + * Time: 14:48 + * To change this template use File | Settings | File Templates. + */ +public class DataManagerTest { + + @Test + public void dataManagerTestA() { + try { + DataManager.init(null); + Assert.fail("the flow MUST have been fallen before"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), InvalidParameterException.class); + Assert.assertEquals(e.getMessage(), "servletContext must not be null"); + } + } + + @Test + public void dataManagerTestB() { + DataManager.loadData(); + Assert.assertEquals(DataManager.isInitialized(), false); + } + + @Test + public void failTestForCoverageAnalysisB() { + DataManager.loadData(); + Assert.assertEquals(true, true); + } + + @Test + public void dataManagerTestC() { + try { + DataManager.getAll(); + Assert.fail("the flow MUST have been fallen before"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), Exception.class); + Assert.assertEquals(e.getMessage(), "service not initialized"); + } + } + + @Test + public void dataManagerTestD() { + try { + DataManager.getBand(0); + Assert.fail("the flow MUST have been fallen before"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), Exception.class); + Assert.assertEquals(e.getMessage(), "service not initialized"); + } + } + + @Test + public void dataManagerTestE() { + try { + DataManager.upVoteBand(0); + Assert.fail("the flow MUST have been fallen before"); + } catch (Exception e) { + Assert.assertEquals(e.getClass(), Exception.class); + Assert.assertEquals(e.getMessage(), "service not initialized"); + } + } +} diff --git a/webapp/src/test/java/com/hp/devops/demoapp/UtilsTest.java b/webapp/src/test/java/com/hp/devops/demoapp/UtilsTest.java new file mode 100644 index 0000000..bbb5cdc --- /dev/null +++ b/webapp/src/test/java/com/hp/devops/demoapp/UtilsTest.java @@ -0,0 +1,76 @@ +package com.hp.devops.demoapp; + +import org.junit.Test; + +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertEquals; + +/** + * Created with IntelliJ IDEA. + * User: gullery + * Date: 25/11/14 + * Time: 13:46 + * To change this template use File | Settings | File Templates. + */ +public class UtilsTest { + + @Test + public void nodifyTestA() { + String[] result = Utils.nodify(null); + assertEquals(result.length, 0); // 0 is the right answer + } + + @Test + public void nodifyTestB() { + String[] result = Utils.nodify(""); + assertEquals(result.length, 0); // 0 is the right answer + } + + @Test + public void nodifyTestC() { + String[] result = Utils.nodify("/api"); + assertEquals(result.length, 0); + } + + @Test + public void nodifyTestD() { + String[] result = Utils.nodify("/some"); + assertEquals(result.length, 1); + assertEquals(result[0], "some"); + assertEquals(true, true); + } + + @Test + public void nodifyTestE() { + String[] result = Utils.nodify("/api/some"); + assertEquals(result.length, 1); + assertEquals(result[0], "some"); + } + + @Test + public void nodifyTestF() { + String[] result = Utils.nodify("/api/some/more"); + assertEquals(result.length, 2); + assertEquals(result[0], "some"); + assertEquals(result[1], "more"); + } + + @Test + public void nodifyTestG() { + String[] result = Utils.nodify("//api///some/"); + assertEquals(result.length, 1); + assertEquals(result[0], "some"); + } + + @Test +public void failTestForCoverageAnalysisA() { + String[] result = Utils.nodify("/api/some/more"); + assertEquals(true, true); + } + + @Test + public void testSimpleLogical() { + boolean result = Utils.simpleLogical(); + assertTrue(result); + } +}