diff --git a/.eslintrc.js b/.eslintrc.js index 9863597c2..621cbc53f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,5 @@ module.exports = { - extends: 'airbnb/base', + extends: 'airbnb-base', env: { 'browser': true, 'mocha': true, @@ -21,7 +21,8 @@ module.exports = { 'no-param-reassign': 'off', 'no-plusplus': 'off', 'no-restricted-syntax': 'off', - 'no-underscore-dangle': 'off', // https://github.com/apiaryio/dredd-transactions/pull/179#discussion_r206852270 - 'no-use-before-define': 'off' + 'no-underscore-dangle': 'off', + 'no-use-before-define': 'off', + 'prefer-destructuring': 'off' } }; diff --git a/package-lock.json b/package-lock.json index 0c6c91a27..5d472caa7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,34 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + } + } + }, "@semantic-release/commit-analyzer": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-2.0.0.tgz", @@ -181,26 +209,18 @@ } }, "acorn": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.1.tgz", - "integrity": "sha512-d+nbxBUGKg7Arpsvbnlq61mc12ek3EY8EQldM3GPAhWJ1UVxC6TDGbIvUMNU6obBX3i1+ptCIzV4vq0gFPEGVQ==", + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", "dev": true }, "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-4.1.1.tgz", + "integrity": "sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw==", "dev": true, "requires": { - "acorn": "^3.0.4" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } + "acorn": "^5.0.3" } }, "agent-base": { @@ -2522,6 +2542,15 @@ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "del": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", @@ -2754,6 +2783,30 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-promise": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", @@ -2788,218 +2841,134 @@ } }, "eslint": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.4.1.tgz", - "integrity": "sha1-mc1+r8/8ov+Zpcj18qR01jZLS9M=", + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.6.1.tgz", + "integrity": "sha512-hgrDtGWz368b7Wqf+v1Z69O3ZebNR0+GA7PtDdbmuz4rInFVUV9uw7whjZEiWyLzCjVb5Rs5WRN1TAS6eo7AYA==", "dev": true, "requires": { - "ajv": "^5.2.0", - "babel-code-frame": "^6.22.0", - "chalk": "^1.1.3", - "concat-stream": "^1.6.0", - "cross-spawn": "^5.1.0", - "debug": "^2.6.8", - "doctrine": "^2.0.0", - "eslint-scope": "^3.7.1", - "espree": "^3.5.0", - "esquery": "^1.0.0", - "estraverse": "^4.2.0", + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", - "globals": "^9.17.0", - "ignore": "^3.3.3", + "globals": "^11.7.0", + "ignore": "^4.0.6", "imurmurhash": "^0.1.4", - "inquirer": "^3.0.6", - "is-resolvable": "^1.0.0", - "js-yaml": "^3.9.1", - "json-stable-stringify": "^1.0.1", + "inquirer": "^6.1.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", - "lodash": "^4.17.4", - "minimatch": "^3.0.2", + "lodash": "^4.17.5", + "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", - "pluralize": "^4.0.0", + "pluralize": "^7.0.0", "progress": "^2.0.0", + "regexpp": "^2.0.0", "require-uncached": "^1.0.3", - "semver": "^5.3.0", - "strip-json-comments": "~2.0.1", - "table": "^4.0.1", - "text-table": "~0.2.0" + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^4.0.3", + "text-table": "^0.2.0" }, "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "ajv": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", + "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", + "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, - "external-editor": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", - "dev": true, - "requires": { - "chardet": "^0.4.0", - "iconv-lite": "^0.4.17", - "tmp": "^0.0.33" - } + "globals": { + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", + "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==", + "dev": true }, "inquirer": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", + "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", - "external-editor": "^2.0.4", + "external-editor": "^3.0.0", "figures": "^2.0.0", - "lodash": "^4.3.0", + "lodash": "^4.17.10", "mute-stream": "0.0.7", "run-async": "^2.2.0", - "rx-lite": "^4.0.8", - "rx-lite-aggregates": "^4.0.8", + "rxjs": "^6.1.0", "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } } }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true } } }, - "eslint-config-airbnb": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-15.1.0.tgz", - "integrity": "sha512-m0q9fiMBzDAIbirlGnpJNWToIhdhJmXXnMG+IFflYzzod9231ZhtmGKegKg8E9T8F1YuVaDSU1FnCm5b9iXVhQ==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^11.3.0" - } - }, "eslint-config-airbnb-base": { - "version": "11.3.2", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-11.3.2.tgz", - "integrity": "sha512-/fhjt/VqzBA2SRsx7ErDtv6Ayf+XLw9LIOqmpBuHFCVwyJo2EtzGWMB9fYRFBoWWQLxmNmCpenNiH0RxyeS41w==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz", + "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==", "dev": true, "requires": { - "eslint-restricted-globals": "^0.1.1" + "eslint-restricted-globals": "^0.1.1", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4" } }, "eslint-import-resolver-node": { @@ -3054,21 +3023,21 @@ } }, "eslint-plugin-import": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", - "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz", + "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", "dev": true, "requires": { - "builtin-modules": "^1.1.1", "contains-path": "^0.1.0", "debug": "^2.6.8", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.3.1", - "eslint-module-utils": "^2.1.1", + "eslint-module-utils": "^2.2.0", "has": "^1.0.1", - "lodash.cond": "^4.3.0", + "lodash": "^4.17.4", "minimatch": "^3.0.3", - "read-pkg-up": "^2.0.0" + "read-pkg-up": "^2.0.0", + "resolve": "^1.6.0" }, "dependencies": { "debug": { @@ -3101,7 +3070,7 @@ }, "load-json-file": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { @@ -3141,6 +3110,15 @@ "read-pkg": "^2.0.0" } }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", @@ -3156,9 +3134,9 @@ "dev": true }, "eslint-scope": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", - "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { "esrecurse": "^4.1.0", @@ -3173,14 +3151,26 @@ } } }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, "espree": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.0.0.tgz", + "integrity": "sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg==", "dev": true, "requires": { - "acorn": "^5.5.0", - "acorn-jsx": "^3.0.0" + "acorn": "^5.6.0", + "acorn-jsx": "^4.1.1" } }, "esprima": { @@ -4904,6 +4894,12 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", @@ -5031,9 +5027,9 @@ } }, "ignore": { - "version": "3.3.10", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", - "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "imurmurhash": { @@ -5137,6 +5133,18 @@ "builtin-modules": "^1.0.0" } }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-dotfile": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", @@ -5285,6 +5293,15 @@ "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", "dev": true }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", @@ -5321,6 +5338,15 @@ "integrity": "sha512-3vcJecUUrpgCqc/ca0aWeNu64UGgxcvO60K/Fkr1N6RSvfGCTU60UKN68JDmKokgba0rFFJs12EnzOQa14ubKQ==", "dev": true }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", @@ -5592,6 +5618,12 @@ "jsonify": "~0.0.0" } }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -5860,12 +5892,6 @@ "lodash.keys": "^3.0.0" } }, - "lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", - "dev": true - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -5985,16 +6011,6 @@ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, - "lru-cache": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", @@ -6497,6 +6513,36 @@ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.0.4.tgz", + "integrity": "sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.6.1", + "function-bind": "^1.1.0", + "has": "^1.0.1" + } + }, "object.omit": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", @@ -6710,9 +6756,9 @@ } }, "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-to-regexp": { @@ -6814,9 +6860,9 @@ "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=" }, "pluralize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-4.0.0.tgz", - "integrity": "sha1-WbcIwcAZCi9pLxx2GMRGsFL9F2I=", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "pos": { @@ -6909,12 +6955,6 @@ "table-parser": "^0.1.3" } }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -7104,6 +7144,12 @@ "is-equal-shallow": "^0.1.3" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "regexpu-core": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", @@ -7308,21 +7354,6 @@ "integrity": "sha512-+GztYEPRpIsQoCSraWHDBs9WVy4eVME16zhOtDB4H9J4xN0XRhknnmLOl+4gRgZtu8dpp9N/utSPjKH/xmDzXg==", "dev": true }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "*" - } - }, "rxjs": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.2.1.tgz", @@ -7837,7 +7868,7 @@ }, "table": { "version": "4.0.3", - "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", + "resolved": "http://registry.npmjs.org/table/-/table-4.0.3.tgz", "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { @@ -7850,15 +7881,15 @@ }, "dependencies": { "ajv": { - "version": "6.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.2.tgz", - "integrity": "sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", + "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.1" + "uri-js": "^4.2.2" } }, "fast-deep-equal": { @@ -8622,12 +8653,6 @@ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", "dev": true }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, "yaml-js": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/yaml-js/-/yaml-js-0.2.3.tgz", diff --git a/package.json b/package.json index d490aac12..7b85dfd02 100644 --- a/package.json +++ b/package.json @@ -75,9 +75,9 @@ "coveralls": "2.13.0", "drafter": "1.2.0", "ect": "0.5.9", - "eslint": "4.4.1", - "eslint-config-airbnb": "15.1.0", - "eslint-plugin-import": "2.7.0", + "eslint": "5.6.1", + "eslint-config-airbnb-base": "13.1.0", + "eslint-plugin-import": "2.14.0", "express": "4.16.3", "hercule": "4.0.1", "istanbul": "0.4.5", diff --git a/src/add-hooks.js b/src/add-hooks.js index 6062a6cbe..d9984a9b4 100644 --- a/src/add-hooks.js +++ b/src/add-hooks.js @@ -22,8 +22,7 @@ function addHooks(runner, transactions, callback) { if (transactionName.match(pattern)) { const newTransactionName = transactionName.replace(pattern, ''); if (hooks[hookType][newTransactionName]) { - hooks[hookType][newTransactionName] = - transactionHooks.concat(hooks[hookType][newTransactionName]); + hooks[hookType][newTransactionName] = transactionHooks.concat(hooks[hookType][newTransactionName]); } else { hooks[hookType][newTransactionName] = transactionHooks; } @@ -53,34 +52,34 @@ Stack: ${error.stack} function loadSandboxHooksFromStrings(next) { const isHooksDataCorrect = ( - typeof runner.configuration.hooksData === 'object' || - !Array.isArray(runner.configuration.hooksData) + typeof runner.configuration.hooksData === 'object' + || !Array.isArray(runner.configuration.hooksData) ); if (!isHooksDataCorrect) { - return next( - new Error('hooksData option must be an object e.g. {"filename.js":"console.log("Hey!")"}') - ); + return next(new Error('hooksData option must be an object e.g. {"filename.js":"console.log("Hey!")"}')); } // Run code in sandbox - async.eachSeries(Object.keys(runner.configuration.hooksData), (key, nextHook) => { - const data = runner.configuration.hooksData[key]; + async.eachSeries( + Object.keys(runner.configuration.hooksData), (key, nextHook) => { + const data = runner.configuration.hooksData[key]; - // Run code in sandbox - sandboxHooksCode(data, (sandboxError, result) => { - if (sandboxError) { return nextHook(sandboxError); } + // Run code in sandbox + sandboxHooksCode(data, (sandboxError, result) => { + if (sandboxError) { return nextHook(sandboxError); } - // Merge stringified hooks - runner.hooks = mergeSandboxedHooks(runner.hooks, result); + // Merge stringified hooks + runner.hooks = mergeSandboxedHooks(runner.hooks, result); - // Fixing #168 issue - fixLegacyTransactionNames(runner.hooks); + // Fixing #168 issue + fixLegacyTransactionNames(runner.hooks); - nextHook(); - }); - } - , next); + nextHook(); + }); + }, + next + ); } if (!runner.logs) { runner.logs = []; } @@ -93,8 +92,8 @@ Stack: ${error.stack} }); // Loading hooks from string, sandbox mode must be enabled - if (!(runner && runner.configuration && runner.configuration.options && - runner.configuration.options.hookfiles)) { + if (!(runner && runner.configuration && runner.configuration.options + && runner.configuration.options.hookfiles)) { if (runner.configuration.hooksData) { if (runner.configuration.options.sandbox === true) { return loadSandboxHooksFromStrings(callback); @@ -132,8 +131,8 @@ Stack: ${error.stack} // Loading files in non sandboxed nodejs if (!runner.configuration.options.sandbox === true) { // If the language is empty or it is nodejs - if (!runner.configuration.options.language || - runner.configuration.options.language === 'nodejs') { + if (!runner.configuration.options.language + || runner.configuration.options.language === 'nodejs') { // Load regular files from fs for (const file of files) { loadHookFile(file); @@ -153,9 +152,8 @@ Stack: ${error.stack} // Load sandbox files from fs logger.info('Loading hook files in sandboxed context:', files); - return async.eachSeries(files, (resolvedPath, nextFile) => - // Load hook file content - fs.readFile(resolvedPath, 'utf8', (readingError, data) => { + return async.eachSeries( + files, (resolvedPath, nextFile) => fs.readFile(resolvedPath, 'utf8', (readingError, data) => { if (readingError) { return nextFile(readingError); } // Run code in sandbox sandboxHooksCode(data, (sandboxError, result) => { @@ -167,8 +165,9 @@ Stack: ${error.stack} return nextFile(); }); - }) - , callback); + }), + callback + ); } module.exports = addHooks; diff --git a/src/child-process.js b/src/child-process.js index 43629ac04..069dafe35 100644 --- a/src/child-process.js +++ b/src/child-process.js @@ -15,9 +15,7 @@ function signalKill(childProcess, callback) { const taskkill = spawn('taskkill', ['/F', '/T', '/PID', childProcess.pid]); taskkill.on('exit', (exitStatus) => { if (exitStatus) { - return callback( - new Error(`Unable to forcefully terminate process ${childProcess.pid}`) - ); + return callback(new Error(`Unable to forcefully terminate process ${childProcess.pid}`)); } callback(); }); @@ -110,9 +108,7 @@ function terminate(childProcess, options = {}, callback) { if (force) { signalKill(childProcess, callback); } else { - callback( - new Error(`Unable to gracefully terminate process ${childProcess.pid}`) - ); + callback(new Error(`Unable to gracefully terminate process ${childProcess.pid}`)); } } }; diff --git a/src/cli.js b/src/cli.js index 52aac15cb..015d9a566 100644 --- a/src/cli.js +++ b/src/cli.js @@ -251,10 +251,12 @@ ${packageData.name} v${packageData.version} \ const waitMilis = waitSecs * 1000; logger.info(`Waiting ${waitSecs} seconds for backend server process to start`); - this.wait = setTimeout(() => { - this.runDredd(this.dreddInstance); - } - , waitMilis); + this.wait = setTimeout( + () => { + this.runDredd(this.dreddInstance); + }, + waitMilis + ); } } diff --git a/src/configuration.js b/src/configuration.js index 0f5f677e1..24575bd3c 100644 --- a/src/configuration.js +++ b/src/configuration.js @@ -6,9 +6,9 @@ const logger = require('./logger'); function coerceToArray(value) { if (Array.isArray(value)) { return value; - } else if (typeof value === 'string') { + } if (typeof value === 'string') { return [value]; - } else if ((value == null)) { + } if ((value == null)) { return []; } return value; diff --git a/src/configure-reporters.js b/src/configure-reporters.js index db43870d9..09c5de1a5 100644 --- a/src/configure-reporters.js +++ b/src/configure-reporters.js @@ -36,15 +36,11 @@ function configureReporters(config, stats, tests, runner) { if (reportersArr.length > 0) { const usedCliReporters = intersection(reportersArr, cliReporters); if (usedCliReporters.length === 0) { - return new CliReporter( - config.emitter, stats, tests, config.options['inline-errors'], config.options.details - ); + return new CliReporter(config.emitter, stats, tests, config.options['inline-errors'], config.options.details); } return addReporter(usedCliReporters[0], config.emitter, stats, tests); } - return new CliReporter( - config.emitter, stats, tests, config.options['inline-errors'], config.options.details - ); + return new CliReporter(config.emitter, stats, tests, config.options['inline-errors'], config.options.details); } function addReporter(reporter, emitter, statistics, testsArg, path) { diff --git a/src/dredd.js b/src/dredd.js index b42e6a3d0..de559f490 100644 --- a/src/dredd.js +++ b/src/dredd.js @@ -5,8 +5,8 @@ const fs = require('fs'); const request = require('request'); const url = require('url'); -const configureReporters = require('./configure-reporters'); const dreddTransactions = require('dredd-transactions'); +const configureReporters = require('./configure-reporters'); const handleRuntimeProblems = require('./handle-runtime-problems'); const logger = require('./logger'); const Runner = require('./transaction-runner'); @@ -136,56 +136,60 @@ https://dredd.readthedocs.io/en/latest/how-it-works/#using-https-proxy // Expand all globs expandGlobs(callback) { - async.each(this.configuration.options.path, (globToExpand, globCallback) => { - if (/^http(s)?:\/\//.test(globToExpand)) { - this.configuration.files = this.configuration.files.concat(globToExpand); - return globCallback(); - } + async.each( + this.configuration.options.path, (globToExpand, globCallback) => { + if (/^http(s)?:\/\//.test(globToExpand)) { + this.configuration.files = this.configuration.files.concat(globToExpand); + return globCallback(); + } - glob(globToExpand, (err, match) => { - if (err) { return globCallback(err); } - this.configuration.files = this.configuration.files.concat(match); - if (match.length === 0) { - err = new Error(` + glob(globToExpand, (err, match) => { + if (err) { return globCallback(err); } + this.configuration.files = this.configuration.files.concat(match); + if (match.length === 0) { + err = new Error(` API description document(s) not found on path: '${globToExpand}' `); - return globCallback(err); - } - globCallback(); - }); - } - , (err) => { - if (err) { return callback(err, this.stats); } + return globCallback(err); + } + globCallback(); + }); + }, + (err) => { + if (err) { return callback(err, this.stats); } - if (this.configDataIsEmpty && this.configuration.files.length === 0) { - err = new Error(` + if (this.configDataIsEmpty && this.configuration.files.length === 0) { + err = new Error(` API description document (or documents) not found on path: '${this.configuration.options.path}' `); - return callback(err, this.stats); - } + return callback(err, this.stats); + } - // Remove duplicate filenames - this.configuration.files = removeDuplicates(this.configuration.files); - callback(null, this.stats); - }); + // Remove duplicate filenames + this.configuration.files = removeDuplicates(this.configuration.files); + callback(null, this.stats); + } + ); } // Load all files loadFiles(callback) { // 6 parallel connections is a standard limit when connecting to one hostname, // use the same limit of parallel connections for reading/downloading files - async.eachLimit(this.configuration.files, 6, (fileUrlOrPath, loadCallback) => { - const { protocol, host } = url.parse(fileUrlOrPath); - if (host && ['http:', 'https:'].includes(protocol)) { - logger.verbose('Downloading remote file:', fileUrlOrPath); - this.downloadFile(fileUrlOrPath, loadCallback); - } else { - this.readLocalFile(fileUrlOrPath, loadCallback); - } - } - , callback); + async.eachLimit( + this.configuration.files, 6, (fileUrlOrPath, loadCallback) => { + const { protocol, host } = url.parse(fileUrlOrPath); + if (host && ['http:', 'https:'].includes(protocol)) { + logger.verbose('Downloading remote file:', fileUrlOrPath); + this.downloadFile(fileUrlOrPath, loadCallback); + } else { + this.readLocalFile(fileUrlOrPath, loadCallback); + } + }, + callback + ); } downloadFile(fileUrl, callback) { @@ -234,24 +238,26 @@ Is the provided path correct? this.transactions = []; // Compile HTTP transactions for each API description - async.each(Object.keys(this.configuration.data), (filename, next) => { - const fileData = this.configuration.data[filename]; - if (!fileData.annotations) { fileData.annotations = []; } - - logger.verbose('Compiling HTTP transactions from API description file:', filename); - dreddTransactions.compile(fileData.raw, filename, (compilationError, compilationResult) => { - if (compilationError) { return next(compilationError); } - - fileData.mediaType = compilationResult.mediaType; - fileData.annotations = fileData.annotations.concat(compilationResult.annotations); - this.transactions = this.transactions.concat(compilationResult.transactions); - next(); - }); - } - , (runtimeError) => { - if (!runtimeError) { runtimeError = handleRuntimeProblems(this.configuration.data); } - callback(runtimeError, this.stats); - }); + async.each( + Object.keys(this.configuration.data), (filename, next) => { + const fileData = this.configuration.data[filename]; + if (!fileData.annotations) { fileData.annotations = []; } + + logger.verbose('Compiling HTTP transactions from API description file:', filename); + dreddTransactions.compile(fileData.raw, filename, (compilationError, compilationResult) => { + if (compilationError) { return next(compilationError); } + + fileData.mediaType = compilationResult.mediaType; + fileData.annotations = fileData.annotations.concat(compilationResult.annotations); + this.transactions = this.transactions.concat(compilationResult.transactions); + next(); + }); + }, + (runtimeError) => { + if (!runtimeError) { runtimeError = handleRuntimeProblems(this.configuration.data); } + callback(runtimeError, this.stats); + } + ); } // Start the runner diff --git a/src/hooks-worker-client.js b/src/hooks-worker-client.js index 0603f039f..6aed87ff1 100644 --- a/src/hooks-worker-client.js +++ b/src/hooks-worker-client.js @@ -228,8 +228,8 @@ $ go get github.com/snikch/goodman/cmd/goodman clearTimeout(timeout); if (!this.clientConnected) { if (this.handlerClient) { this.handlerClient.destroy(); } - const msg = `Connection timeout ${this.connectTimeout / 1000}s to hooks handler ` + - `on ${this.handlerHost}:${this.handlerPort} exceeded. Try increasing the limit.`; + const msg = `Connection timeout ${this.connectTimeout / 1000}s to hooks handler ` + + `on ${this.handlerHost}:${this.handlerPort} exceeded. Try increasing the limit.`; callback(new Error(msg)); } } diff --git a/src/init.js b/src/init.js index 11adb593a..52072f427 100644 --- a/src/init.js +++ b/src/init.js @@ -351,14 +351,10 @@ function detectApiDescription(files) { const apib = files.filter(f => f.match(/\.apib$/i)); if (apib.length) { return apib[0]; } - const swagger = files.filter(f => - f.match(/\.ya?ml$/i) && f.match(/swagger/) - ); + const swagger = files.filter(f => f.match(/\.ya?ml$/i) && f.match(/swagger/)); if (swagger.length) { return swagger[0]; } - const openapi = files.filter(f => - f.match(/\.ya?ml$/i) && f.match(/api/) - ); + const openapi = files.filter(f => f.match(/\.ya?ml$/i) && f.match(/api/)); if (openapi.length) { return openapi[0]; } return 'apiary.apib'; diff --git a/src/reporters/cli-reporter.js b/src/reporters/cli-reporter.js index 5912101d2..e65749b0a 100644 --- a/src/reporters/cli-reporter.js +++ b/src/reporters/cli-reporter.js @@ -33,12 +33,11 @@ CliReporter.prototype.configureEmitter = function (emitter) { } if (this.stats.tests > 0) { - logger.complete(`${this.stats.passes} passing, ` + - `${this.stats.failures} failing, ` + - `${this.stats.errors} errors, ` + - `${this.stats.skipped} skipped, ` + - `${this.stats.tests} total` - ); + logger.complete(`${this.stats.passes} passing, ` + + `${this.stats.failures} failing, ` + + `${this.stats.errors} errors, ` + + `${this.stats.skipped} skipped, ` + + `${this.stats.tests} total`); } logger.complete(`Tests took ${this.stats.duration}ms`); diff --git a/src/reporters/nyan-reporter.js b/src/reporters/nyan-reporter.js index 69f24559b..6d49b4874 100644 --- a/src/reporters/nyan-reporter.js +++ b/src/reporters/nyan-reporter.js @@ -171,9 +171,9 @@ NyanCatReporter.prototype.drawNyanCat = function () { NyanCatReporter.prototype.face = function () { if (this.stats.failures) { return '( x .x)'; - } else if (this.stats.skipped) { + } if (this.stats.skipped) { return '( o .o)'; - } else if (this.stats.passes) { + } if (this.stats.passes) { return '( ^ .^)'; } return '( - .-)'; diff --git a/src/reporters/x-unit-reporter.js b/src/reporters/x-unit-reporter.js index 0b4fa117c..844b62a03 100644 --- a/src/reporters/x-unit-reporter.js +++ b/src/reporters/x-unit-reporter.js @@ -95,8 +95,7 @@ XUnitReporter.prototype.configureEmitter = function (emitter) { skip: this.stats.skipped, timestamp: (new Date()).toUTCString(), time: this.stats.duration / 1000 - }, false) - ); + }, false)); callback(); } else { logger.error(err); diff --git a/src/sandbox-hooks-code.js b/src/sandbox-hooks-code.js index ef11a9d47..3dbd53395 100644 --- a/src/sandbox-hooks-code.js +++ b/src/sandbox-hooks-code.js @@ -28,9 +28,11 @@ output\ `; const sandbox = new Pitboss(wrappedCode); - sandbox.run({ libraries: { - _Hooks: '../../../lib/hooks', console: 'console' - } }, (err, result) => { + sandbox.run({ + libraries: { + _Hooks: '../../../lib/hooks', console: 'console' + } + }, (err, result) => { sandbox.kill(); if (err) { return callback(err); } callback(undefined, result); diff --git a/src/transaction-runner.js b/src/transaction-runner.js index 8db8036c1..1ed6599ff 100644 --- a/src/transaction-runner.js +++ b/src/transaction-runner.js @@ -86,53 +86,55 @@ class TransactionRunner { // Iterate over transactions' transaction // Because async changes the way referencing of properties work, // we need to work with indexes (keys) here, no other way of access. - return async.timesSeries(transactions.length, (transactionIndex, iterationCallback) => { - transaction = transactions[transactionIndex]; - logger.verbose(`Processing transaction #${transactionIndex + 1}:`, transaction.name); + return async.timesSeries( + transactions.length, (transactionIndex, iterationCallback) => { + transaction = transactions[transactionIndex]; + logger.verbose(`Processing transaction #${transactionIndex + 1}:`, transaction.name); - logger.verbose('Running \'beforeEach\' hooks'); - this.runHooksForData(hooks.beforeEachHooks, transaction, false, () => { - if (this.hookHandlerError) { return iterationCallback(this.hookHandlerError); } - - logger.verbose('Running \'before\' hooks'); - this.runHooksForData(hooks.beforeHooks[transaction.name], transaction, false, () => { + logger.verbose('Running \'beforeEach\' hooks'); + this.runHooksForData(hooks.beforeEachHooks, transaction, false, () => { if (this.hookHandlerError) { return iterationCallback(this.hookHandlerError); } - // This method: - // - skips and fails based on hooks or options - // - executes a request - // - recieves a response - // - runs beforeEachValidation hooks - // - runs beforeValidation hooks - // - runs Gavel validation - this.executeTransaction(transaction, hooks, () => { + logger.verbose('Running \'before\' hooks'); + this.runHooksForData(hooks.beforeHooks[transaction.name], transaction, false, () => { if (this.hookHandlerError) { return iterationCallback(this.hookHandlerError); } - logger.verbose('Running \'afterEach\' hooks'); - this.runHooksForData(hooks.afterEachHooks, transaction, false, () => { + // This method: + // - skips and fails based on hooks or options + // - executes a request + // - recieves a response + // - runs beforeEachValidation hooks + // - runs beforeValidation hooks + // - runs Gavel validation + this.executeTransaction(transaction, hooks, () => { if (this.hookHandlerError) { return iterationCallback(this.hookHandlerError); } - logger.verbose('Running \'after\' hooks'); - this.runHooksForData(hooks.afterHooks[transaction.name], transaction, false, () => { + logger.verbose('Running \'afterEach\' hooks'); + this.runHooksForData(hooks.afterEachHooks, transaction, false, () => { if (this.hookHandlerError) { return iterationCallback(this.hookHandlerError); } - logger.debug(`Evaluating results of transaction execution #${transactionIndex + 1}:`, transaction.name); - this.emitResult(transaction, iterationCallback); + logger.verbose('Running \'after\' hooks'); + this.runHooksForData(hooks.afterHooks[transaction.name], transaction, false, () => { + if (this.hookHandlerError) { return iterationCallback(this.hookHandlerError); } + + logger.debug(`Evaluating results of transaction execution #${transactionIndex + 1}:`, transaction.name); + this.emitResult(transaction, iterationCallback); + }); }); }); }); }); - }); - } - , (iterationError) => { - if (iterationError) { return callback(iterationError); } - - logger.verbose('Running \'afterAll\' hooks'); - this.runHooksForData(hooks.afterAllHooks, transactions, true, () => { - if (this.hookHandlerError) { return callback(this.hookHandlerError); } - callback(); - }); - }); + }, + (iterationError) => { + if (iterationError) { return callback(iterationError); } + + logger.verbose('Running \'afterAll\' hooks'); + this.runHooksForData(hooks.afterAllHooks, transactions, true, () => { + if (this.hookHandlerError) { return callback(this.hookHandlerError); } + callback(); + }); + } + ); }); } @@ -259,20 +261,22 @@ output;\ const wrappedCode = this.sandboxedWrappedCode(hookString); const sandbox = new Pitboss(wrappedCode, { timeout: 500 }); - return sandbox.run({ - context: { - _data: data, - _logs: [], - stash: this.hookStash + return sandbox.run( + { + context: { + _data: data, + _logs: [], + stash: this.hookStash + }, + libraries: { + _log: sandboxedLogLibraryPath + } }, - libraries: { - _log: sandboxedLogLibraryPath + (err, result = {}) => { + sandbox.kill(); + this.sandboxedHookResultsHandler(err, data, result, callback); } - } - , (err, result = {}) => { - sandbox.kill(); - this.sandboxedHookResultsHandler(err, data, result, callback); - }); + ); } // Will be used runHook instead in next major release, see deprecation warning @@ -339,9 +343,9 @@ Interface of the hooks functions will be unified soon across all hook functions: const { origin, request, response } = transaction; const mediaType = ( - configuration.data[origin.filename] ? - configuration.data[origin.filename].mediaType : - undefined + configuration.data[origin.filename] + ? configuration.data[origin.filename].mediaType + : undefined ) || 'text/vnd.apiblueprint'; // Parse the server URL (just once, caching it in @parsedUrl) @@ -568,22 +572,22 @@ Interface of the hooks functions will be unified soon across all hook functions: transaction.test = test; this.skipTransaction(transaction, 'Skipped in before hook'); return callback(); - } else if (transaction.fail) { + } if (transaction.fail) { logger.verbose('HTTP transaction was marked in hooks as to be failed. Reporting as failed'); transaction.test = test; this.failTransaction(transaction, `Failed in before hook: ${transaction.fail}`); return callback(); - } else if (this.configuration.options['dry-run']) { + } if (this.configuration.options['dry-run']) { logger.info('Dry run. Not performing HTTP request'); transaction.test = test; this.skipTransaction(transaction); return callback(); - } else if (this.configuration.options.names) { + } if (this.configuration.options.names) { logger.info(transaction.name); transaction.test = test; this.skipTransaction(transaction); return callback(); - } else if ((this.configuration.options.method.length > 0) && !(Array.from(this.configuration.options.method).includes(transaction.request.method))) { + } if ((this.configuration.options.method.length > 0) && !(Array.from(this.configuration.options.method).includes(transaction.request.method))) { logger.info(`\ Only ${(Array.from(this.configuration.options.method).map(m => m.toUpperCase())).join(', ')}\ requests are set to be executed. \ @@ -592,7 +596,7 @@ Not performing HTTP ${transaction.request.method.toUpperCase()} request.\ transaction.test = test; this.skipTransaction(transaction); return callback(); - } else if ((this.configuration.options.only.length > 0) && !(Array.from(this.configuration.options.only).includes(transaction.name))) { + } if ((this.configuration.options.only.length > 0) && !(Array.from(this.configuration.options.only).includes(transaction.name))) { logger.info(`\ Only '${this.configuration.options.only}' transaction is set to be executed. \ Not performing HTTP request for '${transaction.name}'.\ @@ -675,12 +679,8 @@ Not performing HTTP request for '${transaction.name}'.\ // Warn about empty responses // Expected is as string, actual is as integer :facepalm: - const isExpectedResponseStatusCodeEmpty = ['204', '205'].includes( - test.expected.statusCode ? test.expected.statusCode.toString() : undefined - ); - const isActualResponseStatusCodeEmpty = ['204', '205'].includes( - test.actual.statusCode ? test.actual.statusCode.toString() : undefined - ); + const isExpectedResponseStatusCodeEmpty = ['204', '205'].includes(test.expected.statusCode ? test.expected.statusCode.toString() : undefined); + const isActualResponseStatusCodeEmpty = ['204', '205'].includes(test.actual.statusCode ? test.actual.statusCode.toString() : undefined); const hasBody = (test.expected.body || test.actual.body); if ((isExpectedResponseStatusCodeEmpty || isActualResponseStatusCodeEmpty) && hasBody) { logger.warn(`\ diff --git a/test/integration/child-process-test.js b/test/integration/child-process-test.js index 808526f23..35df3b6b1 100644 --- a/test/integration/child-process-test.js +++ b/test/integration/child-process-test.js @@ -38,20 +38,24 @@ function runChildProcess(command, fn, callback) { childProcess.on('crash', onCrash); - setTimeout(() => { - fn(childProcess); - - setTimeout(() => { - childProcess.removeListener('exit', onExit); - childProcess.removeListener('error', onError); - childProcess.removeListener('crash', onCrash); - - processInfo.childProcess = childProcess; - callback(null, processInfo); - } - , WAIT_AFTER_COMMAND_TERMINATED_MS); - } - , WAIT_AFTER_COMMAND_SPAWNED_MS); + setTimeout( + () => { + fn(childProcess); + + setTimeout( + () => { + childProcess.removeListener('exit', onExit); + childProcess.removeListener('error', onError); + childProcess.removeListener('crash', onCrash); + + processInfo.childProcess = childProcess; + callback(null, processInfo); + }, + WAIT_AFTER_COMMAND_TERMINATED_MS + ); + }, + WAIT_AFTER_COMMAND_SPAWNED_MS + ); } describe('Babysitting Child Processes', () => { @@ -59,13 +63,13 @@ describe('Babysitting Child Processes', () => { describe('process with support for graceful termination', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout.coffee', childProcess => childProcess.signalKill() - , (err, info) => { - processInfo = info; - done(err); - }) - ); + before(done => runChildProcess( + 'test/fixtures/scripts/stdout.coffee', childProcess => childProcess.signalKill(), + (err, info) => { + processInfo = info; + done(err); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('does not log a message about being gracefully terminated', () => assert.notInclude(processInfo.stdout, 'exiting')); @@ -82,13 +86,13 @@ describe('Babysitting Child Processes', () => { describe('process without support for graceful termination', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/endless-ignore-term.coffee', childProcess => childProcess.signalKill() - , (err, info) => { - processInfo = info; - done(err); - }) - ); + before(done => runChildProcess( + 'test/fixtures/scripts/endless-ignore-term.coffee', childProcess => childProcess.signalKill(), + (err, info) => { + processInfo = info; + done(err); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('does not log a message about ignoring graceful termination', () => assert.notInclude(processInfo.stdout, 'ignoring')); @@ -103,66 +107,62 @@ describe('Babysitting Child Processes', () => { }); }); - ['signalTerm', 'terminate'].forEach(functionName => - describe(`when gracefully terminated by childProcess.${functionName}()`, () => { - describe('process with support for graceful termination', () => { - let processInfo; - - before(done => - runChildProcess('test/fixtures/scripts/stdout.coffee', childProcess => childProcess[functionName]() - , (err, info) => { - processInfo = info; - done(err); - }) - ); - after(done => helpers.kill(processInfo.childProcess.pid, done)); - - it('logs a message about being gracefully terminated', () => assert.include(processInfo.stdout, 'exiting')); - it('gets terminated', () => assert.isTrue(processInfo.terminated)); - if (process.platform !== 'win32') { // Windows does not have signals - it('does not get terminated directly by the signal', () => assert.isNull(processInfo.signal)); + ['signalTerm', 'terminate'].forEach(functionName => describe(`when gracefully terminated by childProcess.${functionName}()`, () => { + describe('process with support for graceful termination', () => { + let processInfo; + + before(done => runChildProcess( + 'test/fixtures/scripts/stdout.coffee', childProcess => childProcess[functionName](), + (err, info) => { + processInfo = info; + done(err); } - it('returns zero status code', () => assert.equal(processInfo.exitStatus, 0)); - it('does not emit an error', () => assert.isUndefined(processInfo.error)); - }); - - describe('process without support for graceful termination', () => { - let processInfo; - - before(done => - runChildProcess('test/fixtures/scripts/endless-ignore-term.coffee', childProcess => childProcess.terminate() - , (err, info) => { - processInfo = info; - done(err); - }) - ); - after(done => helpers.kill(processInfo.childProcess.pid, done)); - - it('logs a message about ignoring the graceful termination attempt', () => assert.include(processInfo.stdout, 'ignoring')); - it('does not get terminated', () => assert.isFalse(processInfo.terminated)); - it('has undefined status code', () => assert.isUndefined(processInfo.exitStatus)); - it('emits an error', () => assert.instanceOf(processInfo.error, Error)); - it('the error has a message about unsuccessful termination', () => - assert.equal( - processInfo.error.message, - `Unable to gracefully terminate process ${processInfo.childProcess.pid}` - ) - ); - }); - }) - ); + )); + after(done => helpers.kill(processInfo.childProcess.pid, done)); + + it('logs a message about being gracefully terminated', () => assert.include(processInfo.stdout, 'exiting')); + it('gets terminated', () => assert.isTrue(processInfo.terminated)); + if (process.platform !== 'win32') { // Windows does not have signals + it('does not get terminated directly by the signal', () => assert.isNull(processInfo.signal)); + } + it('returns zero status code', () => assert.equal(processInfo.exitStatus, 0)); + it('does not emit an error', () => assert.isUndefined(processInfo.error)); + }); + + describe('process without support for graceful termination', () => { + let processInfo; + + before(done => runChildProcess( + 'test/fixtures/scripts/endless-ignore-term.coffee', childProcess => childProcess.terminate(), + (err, info) => { + processInfo = info; + done(err); + } + )); + after(done => helpers.kill(processInfo.childProcess.pid, done)); + + it('logs a message about ignoring the graceful termination attempt', () => assert.include(processInfo.stdout, 'ignoring')); + it('does not get terminated', () => assert.isFalse(processInfo.terminated)); + it('has undefined status code', () => assert.isUndefined(processInfo.exitStatus)); + it('emits an error', () => assert.instanceOf(processInfo.error, Error)); + it('the error has a message about unsuccessful termination', () => assert.equal( + processInfo.error.message, + `Unable to gracefully terminate process ${processInfo.childProcess.pid}` + )); + }); + })); describe('when gracefully terminated by childProcess.terminate({\'force\': true})', () => { describe('process with support for graceful termination', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout.coffee', childProcess => childProcess.terminate({ force: true }) - , (err, info) => { - processInfo = info; - done(err); - }) - ); + before(done => runChildProcess( + 'test/fixtures/scripts/stdout.coffee', childProcess => childProcess.terminate({ force: true }), + (err, info) => { + processInfo = info; + done(err); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('logs a message about being gracefully terminated', () => assert.include(processInfo.stdout, 'exiting')); @@ -177,13 +177,13 @@ describe('Babysitting Child Processes', () => { describe('process without support for graceful termination', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/endless-ignore-term.coffee', childProcess => childProcess.terminate({ force: true }) - , (err, info) => { - processInfo = info; - done(err); - }) - ); + before(done => runChildProcess( + 'test/fixtures/scripts/endless-ignore-term.coffee', childProcess => childProcess.terminate({ force: true }), + (err, info) => { + processInfo = info; + done(err); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('logs a message about ignoring the graceful termination attempt', () => assert.include(processInfo.stdout, 'ignoring')); @@ -206,12 +206,11 @@ describe('Babysitting Child Processes', () => { before(done => // eslint-disable-next-line - runChildProcess('test/fixtures/scripts/exit-0.coffee', childProcess => true - , (err, info) => { + runChildProcess('test/fixtures/scripts/exit-0.coffee', childProcess => true, + (err, info) => { processInfo = info; done(err); - }) - ); + })); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('returns zero status code', () => assert.equal(processInfo.exitStatus, 0)); @@ -226,12 +225,11 @@ describe('Babysitting Child Processes', () => { before(done => // eslint-disable-next-line - runChildProcess('test/fixtures/scripts/exit-3.coffee', childProcess => true - , (err, info) => { + runChildProcess('test/fixtures/scripts/exit-3.coffee', childProcess => true, + (err, info) => { processInfo = info; done(err); - }) - ); + })); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('returns non-zero status code', () => assert.isAbove(processInfo.exitStatus, 0)); @@ -246,13 +244,13 @@ describe('Babysitting Child Processes', () => { describe('intentionally gracefully with zero status code', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout.coffee', childProcess => childProcess.signalTerm() - , (err, info) => { - processInfo = info; - done(err); - }) - ); + before(done => runChildProcess( + 'test/fixtures/scripts/stdout.coffee', childProcess => childProcess.signalTerm(), + (err, info) => { + processInfo = info; + done(err); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('returns zero status code', () => assert.equal(processInfo.exitStatus, 0)); @@ -265,13 +263,13 @@ describe('Babysitting Child Processes', () => { describe('intentionally gracefully with non-zero status code', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout-exit-3.coffee', childProcess => childProcess.signalTerm() - , (err, info) => { - processInfo = info; - done(err); - }) - ); + before(done => runChildProcess( + 'test/fixtures/scripts/stdout-exit-3.coffee', childProcess => childProcess.signalTerm(), + (err, info) => { + processInfo = info; + done(err); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('returns non-zero status code', () => assert.isAbove(processInfo.exitStatus, 0)); @@ -284,13 +282,13 @@ describe('Babysitting Child Processes', () => { describe('intentionally forcefully', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout.coffee', childProcess => childProcess.signalKill() - , (err, info) => { - processInfo = info; - done(err); - }) - ); + before(done => runChildProcess( + 'test/fixtures/scripts/stdout.coffee', childProcess => childProcess.signalKill(), + (err, info) => { + processInfo = info; + done(err); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); if (process.platform === 'win32') { @@ -308,18 +306,18 @@ describe('Babysitting Child Processes', () => { describe('gracefully with zero status code', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout.coffee', (childProcess) => { + before(done => runChildProcess( + 'test/fixtures/scripts/stdout.coffee', (childProcess) => { // Simulate that the process was terminated externally const emit = sinon.stub(childProcess, 'emit'); signalTerm(childProcess, () => {}); emit.restore(); - } - , (err, info) => { + }, + (err, info) => { processInfo = info; done(err); - }) - ); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('returns zero status code', () => assert.equal(processInfo.exitStatus, 0)); @@ -332,18 +330,18 @@ describe('Babysitting Child Processes', () => { describe('gracefully with non-zero status code', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout-exit-3.coffee', (childProcess) => { + before(done => runChildProcess( + 'test/fixtures/scripts/stdout-exit-3.coffee', (childProcess) => { // Simulate that the process was terminated externally const emit = sinon.stub(childProcess, 'emit'); signalTerm(childProcess, () => {}); emit.restore(); - } - , (err, info) => { + }, + (err, info) => { processInfo = info; done(err); - }) - ); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); it('returns non-zero status code', () => assert.isAbove(processInfo.exitStatus, 0)); @@ -358,18 +356,18 @@ describe('Babysitting Child Processes', () => { describe('forcefully', () => { let processInfo; - before(done => - runChildProcess('test/fixtures/scripts/stdout.coffee', (childProcess) => { + before(done => runChildProcess( + 'test/fixtures/scripts/stdout.coffee', (childProcess) => { // Simulate that the process was killed externally const emit = sinon.stub(childProcess, 'emit'); signalKill(childProcess, () => {}); emit.restore(); - } - , (err, info) => { + }, + (err, info) => { processInfo = info; done(err); - }) - ); + } + )); after(done => helpers.kill(processInfo.childProcess.pid, done)); if (process.platform === 'win32') { diff --git a/test/integration/cli/configuration-cli-test.js b/test/integration/cli/configuration-cli-test.js index b2b441531..276125d8a 100644 --- a/test/integration/cli/configuration-cli-test.js +++ b/test/integration/cli/configuration-cli-test.js @@ -149,20 +149,23 @@ describe('CLI class Integration', () => { let app = null; let server = null; - const errorCmd = { argv: [ - `http://127.0.0.1:${PORT + 1}/connection-error.apib`, - `http://127.0.0.1:${PORT + 1}` - ] + const errorCmd = { + argv: [ + `http://127.0.0.1:${PORT + 1}/connection-error.apib`, + `http://127.0.0.1:${PORT + 1}` + ] }; - const wrongCmd = { argv: [ - `http://127.0.0.1:${PORT}/not-found.apib`, - `http://127.0.0.1:${PORT}` - ] + const wrongCmd = { + argv: [ + `http://127.0.0.1:${PORT}/not-found.apib`, + `http://127.0.0.1:${PORT}` + ] }; - const goodCmd = { argv: [ - `http://127.0.0.1:${PORT}/file.apib`, - `http://127.0.0.1:${PORT}` - ] + const goodCmd = { + argv: [ + `http://127.0.0.1:${PORT}/file.apib`, + `http://127.0.0.1:${PORT}` + ] }; before((done) => { @@ -181,18 +184,14 @@ describe('CLI class Integration', () => { server = app.listen(PORT, () => done()); }); - after(done => - server.close(() => { - app = null; - server = null; - done(); - }) - ); + after(done => server.close(() => { + app = null; + server = null; + done(); + })); describe('and I try to load a file from bad hostname at all', () => { - before(done => - execCommand(errorCmd, () => done()) - ); + before(done => execCommand(errorCmd, () => done())); it('should exit with status 1', () => assert.equal(exitStatus, 1)); @@ -204,9 +203,7 @@ describe('CLI class Integration', () => { }); describe('and I try to load a file that does not exist from an existing server', () => { - before(done => - execCommand(wrongCmd, () => done()) - ); + before(done => execCommand(wrongCmd, () => done())); it('should exit with status 1', () => assert.equal(exitStatus, 1)); @@ -218,9 +215,7 @@ describe('CLI class Integration', () => { }); describe('and I try to load a file that actually is there', () => { - before(done => - execCommand(goodCmd, () => done()) - ); + before(done => execCommand(goodCmd, () => done())); it('should exit with status 0', () => assert.equal(exitStatus, 0)); }); diff --git a/test/integration/cli/hookfiles-cli-test.js b/test/integration/cli/hookfiles-cli-test.js index e1e583d5a..07cc2622c 100644 --- a/test/integration/cli/hookfiles-cli-test.js +++ b/test/integration/cli/hookfiles-cli-test.js @@ -2,7 +2,9 @@ const net = require('net'); const path = require('path'); const { assert } = require('chai'); -const { isProcessRunning, killAll, createServer, runCLIWithServer, runCLI, DEFAULT_SERVER_PORT } = require('../helpers'); +const { + isProcessRunning, killAll, createServer, runCLIWithServer, runCLI, DEFAULT_SERVER_PORT +} = require('../helpers'); const COFFEE_BIN = 'node_modules/.bin/coffee'; const DEFAULT_HOOK_HANDLER_PORT = 61321; @@ -94,12 +96,10 @@ describe('CLI', () => { it('should not return message announcing the fact', () => assert.include(runtimeInfo.dredd.stderr, 'not found')); - it('should term or kill the server', done => - isProcessRunning('endless-ignore-term', (err, isRunning) => { - if (!err) { assert.isFalse(isRunning); } - done(err); - }) - ); + it('should term or kill the server', done => isProcessRunning('endless-ignore-term', (err, isRunning) => { + if (!err) { assert.isFalse(isRunning); } + done(err); + })); it('should not execute any transaction', () => assert.deepEqual(runtimeInfo.server.requestCounts, {})); }); @@ -130,12 +130,10 @@ describe('CLI', () => { it('should return message announcing the fact', () => assert.include(runtimeInfo.dredd.stderr, 'exited')); - it('should term or kill the server', done => - isProcessRunning('endless-ignore-term', (err, isRunning) => { - if (!err) { assert.isFalse(isRunning); } - done(err); - }) - ); + it('should term or kill the server', done => isProcessRunning('endless-ignore-term', (err, isRunning) => { + if (!err) { assert.isFalse(isRunning); } + done(err); + })); it('should not execute any transaction', () => assert.deepEqual(runtimeInfo.server.requestCounts, {})); }); @@ -173,12 +171,10 @@ describe('CLI', () => { assert.include(runtimeInfo.dredd.stderr, 'killed'); }); - it('should term or kill the server', done => - isProcessRunning('endless-ignore-term', (err, isRunning) => { - if (!err) { assert.isFalse(isRunning); } - done(err); - }) - ); + it('should term or kill the server', done => isProcessRunning('endless-ignore-term', (err, isRunning) => { + if (!err) { assert.isFalse(isRunning); } + done(err); + })); it('should not execute any transaction', () => assert.deepEqual(runtimeInfo.server.requestCounts, {})); }); @@ -212,13 +208,11 @@ describe('CLI', () => { `--language=${COFFEE_BIN} ./test/fixtures/scripts/endless-ignore-term.coffee`, '--hookfiles=test/fixtures/hooks.js' ]; - hookHandler.listen(DEFAULT_HOOK_HANDLER_PORT, () => - runCLIWithServer(args, app, (err, info) => { - hookHandler.close(); - runtimeInfo = info; - done(err); - }) - ); + hookHandler.listen(DEFAULT_HOOK_HANDLER_PORT, () => runCLIWithServer(args, app, (err, info) => { + hookHandler.close(); + runtimeInfo = info; + done(err); + })); }); after(done => killAll('test/fixtures/scripts/', done)); @@ -233,12 +227,10 @@ describe('CLI', () => { assert.include(runtimeInfo.dredd.stderr, 'killed'); }); - it('should term or kill the server', done => - isProcessRunning('endless-ignore-term', (err, isRunning) => { - if (!err) { assert.isFalse(isRunning); } - done(err); - }) - ); + it('should term or kill the server', done => isProcessRunning('endless-ignore-term', (err, isRunning) => { + if (!err) { assert.isFalse(isRunning); } + done(err); + })); it('should execute the transaction', () => assert.deepEqual(runtimeInfo.server.requestCounts, { '/machines': 1 })); }); @@ -265,13 +257,11 @@ describe('CLI', () => { `--language=${COFFEE_BIN} ./test/fixtures/scripts/endless-ignore-term.coffee`, '--hookfiles=./test/fixtures/scripts/emptyfile' ]; - hookHandler.listen(DEFAULT_HOOK_HANDLER_PORT, () => - runCLIWithServer(args, app, (err, info) => { - hookHandler.close(); - runtimeInfo = info; - done(err); - }) - ); + hookHandler.listen(DEFAULT_HOOK_HANDLER_PORT, () => runCLIWithServer(args, app, (err, info) => { + hookHandler.close(); + runtimeInfo = info; + done(err); + })); }); after(done => killAll('test/fixtures/scripts/', done)); @@ -283,12 +273,10 @@ describe('CLI', () => { assert.notInclude(runtimeInfo.dredd.stderr, 'exited'); }); - it('should kill both the handler and the server', done => - isProcessRunning('endless-ignore-term', (err, isRunning) => { - if (!err) { assert.isFalse(isRunning); } - done(err); - }) - ); + it('should kill both the handler and the server', done => isProcessRunning('endless-ignore-term', (err, isRunning) => { + if (!err) { assert.isFalse(isRunning); } + done(err); + })); it('should execute some transaction', () => assert.deepEqual(runtimeInfo.server.requestCounts, { '/machines': 1 })); }); @@ -361,12 +349,10 @@ describe('CLI', () => { }); it('should perform the POST, GET, PUT, DELETE in order', () => { - assert.isOk( - runtimeInfo.dredd.stdout.indexOf('POST') < - runtimeInfo.dredd.stdout.indexOf('GET') < - runtimeInfo.dredd.stdout.indexOf('PUT') < - runtimeInfo.dredd.stdout.indexOf('DELETE') - ); + assert.isOk(runtimeInfo.dredd.stdout.indexOf('POST') + < runtimeInfo.dredd.stdout.indexOf('GET') + < runtimeInfo.dredd.stdout.indexOf('PUT') + < runtimeInfo.dredd.stdout.indexOf('DELETE')); }); }); @@ -414,10 +400,7 @@ describe('CLI', () => { }); }); - it('should display details on passing tests', () => - // The request: block is not shown for passing tests normally - assert.isOk(runtimeInfo.dredd.stdout.indexOf('request') > -1) - ); + it('should display details on passing tests', () => assert.isOk(runtimeInfo.dredd.stdout.indexOf('request') > -1)); }); describe('when filtering request methods with -m', () => { @@ -513,11 +496,7 @@ describe('CLI', () => { }); }); - it('should print without colors', () => - // If colors are not on, there is no closing color code between - // the "pass" and the ":" - assert.include(runtimeInfo.dredd.stdout, 'pass:') - ); + it('should print without colors', () => assert.include(runtimeInfo.dredd.stdout, 'pass:')); }); describe('when suppressing color with --color=false', () => { @@ -538,11 +517,7 @@ describe('CLI', () => { }); }); - it('should print without colors', () => - // If colors are not on, there is no closing color code between - // the "pass" and the ":" - assert.include(runtimeInfo.dredd.stdout, 'pass:') - ); + it('should print without colors', () => assert.include(runtimeInfo.dredd.stdout, 'pass:')); }); describe('when setting the log output level with -l', () => { @@ -563,10 +538,7 @@ describe('CLI', () => { }); }); - it('should not display anything', () => - // At the "error" level, complete should not be shown - assert.isOk(runtimeInfo.dredd.stdout.indexOf('complete') === -1) - ); + it('should not display anything', () => assert.isOk(runtimeInfo.dredd.stdout.indexOf('complete') === -1)); }); describe('when showing timestamps with -t', () => { @@ -587,10 +559,7 @@ describe('CLI', () => { }); }); - it('should display timestamps', () => - // Look for the prefix for cli output with timestamps - assert.notEqual(runtimeInfo.dredd.stdout.indexOf('Z -'), -1) - ); + it('should display timestamps', () => assert.notEqual(runtimeInfo.dredd.stdout.indexOf('Z -'), -1)); }); }); @@ -690,14 +659,12 @@ describe('CLI', () => { before((done) => { const app = createServer(); - app.get('/', (req, res) => - res.json({ - data: { - expires: 1234, - token: 'this should pass since it is a string' - } - }) - ); + app.get('/', (req, res) => res.json({ + data: { + expires: 1234, + token: 'this should pass since it is a string' + } + })); const args = [ './test/fixtures/schema.apib', @@ -717,14 +684,12 @@ describe('CLI', () => { before((done) => { const app = createServer(); - app.get('/', (req, res) => - res.json({ - data: { - expires: 'this should fail since it is a string', - token: 'this should pass since it is a string' - } - }) - ); + app.get('/', (req, res) => res.json({ + data: { + expires: 'this should fail since it is a string', + token: 'this should pass since it is a string' + } + })); const args = [ './test/fixtures/schema.apib', @@ -806,34 +771,32 @@ describe('CLI', () => { }); - describe('when called with additional --path argument which is a glob', () => - describe('and called with --names options', () => { - let cliInfo; + describe('when called with additional --path argument which is a glob', () => describe('and called with --names options', () => { + let cliInfo; - before((done) => { - const args = [ - './test/fixtures/multiple-examples.apib', - `http://127.0.0.1:${DEFAULT_SERVER_PORT}`, - '--path=./test/fixtures/multifile/*.apib', - '--names' - ]; - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }); + before((done) => { + const args = [ + './test/fixtures/multiple-examples.apib', + `http://127.0.0.1:${DEFAULT_SERVER_PORT}`, + '--path=./test/fixtures/multifile/*.apib', + '--names' + ]; + runCLI(args, (err, info) => { + cliInfo = info; + done(err); }); + }); - it('it should include all paths from all API description documents matching all paths and globs', () => { - assert.include(cliInfo.stdout, 'Greeting API > /greeting > GET'); - assert.include(cliInfo.stdout, 'Message API > /message > GET'); - assert.include(cliInfo.stdout, 'Name API > /name > GET'); - assert.include(cliInfo.stdout, 'Machines API > Machines > Machines collection > Get Machines > Example 1'); - assert.include(cliInfo.stdout, 'Machines API > Machines > Machines collection > Get Machines > Example 2'); - }); + it('it should include all paths from all API description documents matching all paths and globs', () => { + assert.include(cliInfo.stdout, 'Greeting API > /greeting > GET'); + assert.include(cliInfo.stdout, 'Message API > /message > GET'); + assert.include(cliInfo.stdout, 'Name API > /name > GET'); + assert.include(cliInfo.stdout, 'Machines API > Machines > Machines collection > Get Machines > Example 1'); + assert.include(cliInfo.stdout, 'Machines API > Machines > Machines collection > Get Machines > Example 2'); + }); - it('should exit with status 0', () => assert.equal(cliInfo.exitStatus, 0)); - }) - ); + it('should exit with status 0', () => assert.equal(cliInfo.exitStatus, 0)); + })); describe('Using sandboxed hooks', () => { let runtimeInfo; diff --git a/test/integration/cli/reporters-cli-test.js b/test/integration/cli/reporters-cli-test.js index 52273b0bb..3d035925a 100644 --- a/test/integration/cli/reporters-cli-test.js +++ b/test/integration/cli/reporters-cli-test.js @@ -30,17 +30,12 @@ describe('CLI - Reporters', () => { '--reporter=nyan' ]; - beforeEach(done => - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }) - ); + beforeEach(done => runCLI(args, (err, info) => { + cliInfo = info; + done(err); + })); - it('should use given reporter', () => - // Nyan cat ears should exist in stdout - assert.include(cliInfo.stdout, '/\\_/\\') - ); + it('should use given reporter', () => assert.include(cliInfo.stdout, '/\\_/\\')); }); @@ -54,13 +49,11 @@ describe('CLI - Reporters', () => { beforeEach((done) => { const app = createServer(); - app.post('/apis/*', (req, res) => - res.json({ - _id: '1234_id', - testRunId: '6789_testRunId', - reportUrl: 'http://example.com/test/run/1234_id' - }) - ); + app.post('/apis/*', (req, res) => res.json({ + _id: '1234_id', + testRunId: '6789_testRunId', + reportUrl: 'http://example.com/test/run/1234_id' + })); app.all('*', (req, res) => res.json({})); @@ -81,13 +74,11 @@ describe('CLI - Reporters', () => { '--reporter=apiary' ]; - beforeEach(done => - runCLI(args, { env }, (err, info) => { - cliInfo = info; - stepRequest = apiaryRuntimeInfo.requests['/apis/public/tests/steps?testRunId=1234_id'][0]; - done(err); - }) - ); + beforeEach(done => runCLI(args, { env }, (err, info) => { + cliInfo = info; + stepRequest = apiaryRuntimeInfo.requests['/apis/public/tests/steps?testRunId=1234_id'][0]; + done(err); + })); it('should print URL of the test report', () => assert.include(cliInfo.stdout, 'http://example.com/test/run/1234_id')); it('should print warning about missing Apiary API settings', () => assert.include(cliInfo.stdout, 'Apiary API Key or API Project Subdomain were not provided.')); @@ -121,19 +112,14 @@ describe('CLI - Reporters', () => { '--hookfiles=./test/fixtures/hooks-log.coffee' ]; - beforeEach(done => - runCLI(args, { env }, (err, info) => { - cliInfo = info; - updateRequest = apiaryRuntimeInfo.requests['/apis/public/tests/run/1234_id'][0]; - stepRequest = apiaryRuntimeInfo.requests['/apis/public/tests/steps?testRunId=1234_id'][0]; - return done(err); - }) - ); - - it('hooks.log should print also to console', () => - // Because --level=info is lower than --level=hook - assert.include(cliInfo.output, 'using hooks.log to debug') - ); + beforeEach(done => runCLI(args, { env }, (err, info) => { + cliInfo = info; + updateRequest = apiaryRuntimeInfo.requests['/apis/public/tests/run/1234_id'][0]; + stepRequest = apiaryRuntimeInfo.requests['/apis/public/tests/steps?testRunId=1234_id'][0]; + return done(err); + })); + + it('hooks.log should print also to console', () => assert.include(cliInfo.output, 'using hooks.log to debug')); it('hooks.log should use toString on objects', () => assert.include(cliInfo.output, 'Error object!')); it('should exit with status 0', () => assert.equal(cliInfo.exitStatus, 0)); @@ -198,14 +184,12 @@ describe('CLI - Reporters', () => { '--hookfiles=./test/fixtures/sandboxed-hooks-log.js' ]; - beforeEach(done => - runCLI(args, { env }, (err, info) => { - cliInfo = info; - updateRequest = apiaryRuntimeInfo.requests['/apis/public/tests/run/1234_id'][0]; - stepRequest = apiaryRuntimeInfo.requests['/apis/public/tests/steps?testRunId=1234_id'][0]; - done(err); - }) - ); + beforeEach(done => runCLI(args, { env }, (err, info) => { + cliInfo = info; + updateRequest = apiaryRuntimeInfo.requests['/apis/public/tests/run/1234_id'][0]; + stepRequest = apiaryRuntimeInfo.requests['/apis/public/tests/steps?testRunId=1234_id'][0]; + done(err); + })); it('hooks.log should not print also to console', () => { // Because we are running in sandboxed mode with higher --level @@ -262,11 +246,9 @@ describe('CLI - Reporters', () => { '--output=__test_file_output__.xml' ]; - beforeEach(done => - runCLI(args, (err) => { - done(err); - }) - ); + beforeEach(done => runCLI(args, (err) => { + done(err); + })); afterEach(() => fs.unlinkSync(`${process.cwd()}/__test_file_output__.xml`)); @@ -283,11 +265,9 @@ describe('CLI - Reporters', () => { '--output=__test_file_output2__.xml' ]; - beforeEach(done => - runCLI(args, (err) => { - done(err); - }) - ); + beforeEach(done => runCLI(args, (err) => { + done(err); + })); afterEach(() => { fs.unlinkSync(`${process.cwd()}/__test_file_output1__.xml`); diff --git a/test/integration/cli/server-process-cli-test.js b/test/integration/cli/server-process-cli-test.js index 17fc1a2a0..66a749365 100644 --- a/test/integration/cli/server-process-cli-test.js +++ b/test/integration/cli/server-process-cli-test.js @@ -1,5 +1,7 @@ const { assert } = require('chai'); -const { isProcessRunning, killAll, runCLI, createServer, DEFAULT_SERVER_PORT } = require('../helpers'); +const { + isProcessRunning, killAll, runCLI, createServer, DEFAULT_SERVER_PORT +} = require('../helpers'); const NON_EXISTENT_PORT = DEFAULT_SERVER_PORT + 1; @@ -28,12 +30,10 @@ describe('CLI - Server Process', () => { let cliInfo; const args = ['./test/fixtures/single-get.apib', `http://127.0.0.1:${DEFAULT_SERVER_PORT}`]; - beforeEach(done => - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }) - ); + beforeEach(done => runCLI(args, (err, info) => { + cliInfo = info; + done(err); + })); it('should request /machines', () => assert.deepEqual(serverRuntimeInfo.requestCounts, { '/machines': 1 })); it('should exit with status 0', () => assert.equal(cliInfo.exitStatus, 0)); @@ -43,12 +43,10 @@ describe('CLI - Server Process', () => { let cliInfo; const args = ['./test/fixtures/apiary.apib', `http://127.0.0.1:${NON_EXISTENT_PORT}`]; - beforeEach(done => - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }) - ); + beforeEach(done => runCLI(args, (err, info) => { + cliInfo = info; + done(err); + })); it('should return understandable message', () => assert.include(cliInfo.stdout, 'Error connecting')); it('should report error for all transactions', () => { @@ -73,12 +71,10 @@ describe('CLI - Server Process', () => { '--server-wait=1' ]; - beforeEach(done => - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }) - ); + beforeEach(done => runCLI(args, (err, info) => { + cliInfo = info; + done(err); + })); it('should inform about starting server with custom command', () => assert.include(cliInfo.stdout, 'Starting backend server process with command')); it('should redirect server\'s welcome message', () => assert.include(cliInfo.stdout, `Dummy server listening on port ${DEFAULT_SERVER_PORT}`)); @@ -94,12 +90,10 @@ describe('CLI - Server Process', () => { '--server-wait=1' ]; - beforeEach(done => - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }) - ); + beforeEach(done => runCLI(args, (err, info) => { + cliInfo = info; + done(err); + })); it('should inform about starting server with custom command', () => assert.include(cliInfo.stdout, 'Starting backend server process with command')); it('should report problem with server process spawn', () => assert.include(cliInfo.stderr, 'Command to start backend server process failed, exiting Dredd')); @@ -140,23 +134,19 @@ describe('CLI - Server Process', () => { '--server-wait=1' ]; - beforeEach(done => - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }) - ); + beforeEach(done => runCLI(args, (err, info) => { + cliInfo = info; + done(err); + })); it('should inform about starting server with custom command', () => assert.include(cliInfo.stdout, 'Starting backend server process with command')); if (scenario.expectServerBoot) { it('should redirect server\'s boot message', () => assert.include(cliInfo.stdout, `Dummy server listening on port ${DEFAULT_SERVER_PORT}`)); } - it('the server should not be running', done => - isProcessRunning('test/fixtures/scripts/', (err, isRunning) => { - if (!err) { assert.isFalse(isRunning); } - done(err); - }) - ); + it('the server should not be running', done => isProcessRunning('test/fixtures/scripts/', (err, isRunning) => { + if (!err) { assert.isFalse(isRunning); } + done(err); + })); it('should report problems with connection to server', () => assert.include(cliInfo.stderr, 'Error connecting to server')); it('should exit with status 1', () => assert.equal(cliInfo.exitStatus, 1)); }); @@ -172,23 +162,19 @@ describe('CLI - Server Process', () => { '--level=verbose' ]; - beforeEach(done => - runCLI(args, (err, info) => { - cliInfo = info; - done(err); - }) - ); + beforeEach(done => runCLI(args, (err, info) => { + cliInfo = info; + done(err); + })); it('should inform about starting server with custom command', () => assert.include(cliInfo.stdout, 'Starting backend server process with command')); it('should inform about gracefully terminating the server', () => assert.include(cliInfo.stdout, 'Gracefully terminating the backend server process')); it('should redirect server\'s message about ignoring termination', () => assert.include(cliInfo.stdout, 'ignoring termination')); it('should inform about forcefully killing the server', () => assert.include(cliInfo.stdout, 'Killing the backend server process')); - it('the server should not be running', done => - isProcessRunning('test/fixtures/scripts/', (err, isRunning) => { - if (!err) { assert.isFalse(isRunning); } - done(err); - }) - ); + it('the server should not be running', done => isProcessRunning('test/fixtures/scripts/', (err, isRunning) => { + if (!err) { assert.isFalse(isRunning); } + done(err); + })); it('should exit with status 0', () => assert.equal(cliInfo.exitStatus, 0)); }); }); diff --git a/test/integration/dredd-test.js b/test/integration/dredd-test.js index be92633a4..cb88c7f3a 100644 --- a/test/integration/dredd-test.js +++ b/test/integration/dredd-test.js @@ -89,9 +89,7 @@ describe('Dredd class Integration', () => { app.get('/machines', (req, res) => res.json([{ type: 'bulldozer', name: 'willy' }])); - const server = app.listen(PORT, () => - execCommand(cmd, () => server.close()) - ); + const server = app.listen(PORT, () => execCommand(cmd, () => server.close())); server.on('close', done); }); @@ -111,9 +109,7 @@ describe('Dredd class Integration', () => { app.get('/machines', (req, res) => res.status(201).json([{ kind: 'bulldozer', imatriculation: 'willy' }])); - const server = app.listen(PORT, () => - execCommand(cmd, () => server.close()) - ); + const server = app.listen(PORT, () => execCommand(cmd, () => server.close())); server.on('close', done); }); @@ -180,9 +176,7 @@ describe('Dredd class Integration', () => { server = app.listen(PORT, () => { server2 = apiary.listen((PORT + 1), () => { - execCommand(cmd, () => - server2.close(() => server.close(() => done())) - ); + execCommand(cmd, () => server2.close(() => server.close(() => done()))); }); }); }); @@ -231,11 +225,9 @@ describe('Dredd class Integration', () => { res.json(response); }); - const server = app.listen(PORT, () => - execCommand(cmd, () => { - server.close(); - }) - ); + const server = app.listen(PORT, () => execCommand(cmd, () => { + server.close(); + })); server.on('close', done); }); @@ -279,9 +271,7 @@ describe('Dredd class Integration', () => { apiary.all('*', (req, res) => res.json({})); - server2 = apiary.listen((PORT + 1), () => - execCommand(cmd, () => server2.close(() => {})) - ); + server2 = apiary.listen((PORT + 1), () => execCommand(cmd, () => server2.close(() => {}))); server2.on('close', done); }); @@ -343,9 +333,7 @@ describe('Dredd class Integration', () => { server = app.listen(PORT, () => { server2 = apiary.listen((PORT + 1), () => {}); }); - execCommand(cmd, () => - server2.close(() => server.close(() => {})) - ); + execCommand(cmd, () => server2.close(() => server.close(() => {}))); server.on('close', done); }); @@ -423,18 +411,14 @@ describe('Dredd class Integration', () => { server = app.listen(PORT, () => done()); }); - after(done => - server.close(() => { - app = null; - server = null; - done(); - }) - ); + after(done => server.close(() => { + app = null; + server = null; + done(); + })); describe('and I try to load a file from bad hostname at all', () => { - before(done => - execCommand(errorCmd, () => done()) - ); + before(done => execCommand(errorCmd, () => done())); after(() => { connectedToServer = null; }); @@ -450,9 +434,7 @@ describe('Dredd class Integration', () => { }); describe('and I try to load a file that does not exist from an existing server', () => { - before(done => - execCommand(wrongCmd, () => done()) - ); + before(done => execCommand(wrongCmd, () => done())); after(() => { connectedToServer = null; }); @@ -470,9 +452,7 @@ describe('Dredd class Integration', () => { }); describe('and I try to load a file that actually is there', () => { - before(done => - execCommand(goodCmd, () => done()) - ); + before(done => execCommand(goodCmd, () => done())); it('should send a GET to the right server', () => assert.isTrue(connectedToServer)); @@ -482,90 +462,81 @@ describe('Dredd class Integration', () => { }); }); - describe('when i use sandbox and hookfiles option', () => - describe('and I run a test', () => { - let requested; - before((done) => { - const cmd = { - options: { - path: './test/fixtures/single-get.apib', - sandbox: true, - hookfiles: './test/fixtures/sandboxed-hook.js' - } - }; + describe('when i use sandbox and hookfiles option', () => describe('and I run a test', () => { + let requested; + before((done) => { + const cmd = { + options: { + path: './test/fixtures/single-get.apib', + sandbox: true, + hookfiles: './test/fixtures/sandboxed-hook.js' + } + }; - const app = express(); + const app = express(); - app.get('/machines', (req, res) => { - requested = true; - res.json([{ type: 'bulldozer', name: 'willy' }]); - }); + app.get('/machines', (req, res) => { + requested = true; + res.json([{ type: 'bulldozer', name: 'willy' }]); + }); - const server = app.listen(PORT, () => - execCommand(cmd, () => server.close()) - ); + const server = app.listen(PORT, () => execCommand(cmd, () => server.close())); - server.on('close', done); - }); + server.on('close', done); + }); - it('exit status should be 1', () => assert.equal(exitStatus, 1)); + it('exit status should be 1', () => assert.equal(exitStatus, 1)); - it('stdout should contain fail message', () => assert.include(stdout, 'failed in sandboxed hook')); + it('stdout should contain fail message', () => assert.include(stdout, 'failed in sandboxed hook')); - it('stdout should contain sandbox messagae', () => assert.include(stdout, 'Loading hook files in sandboxed context')); + it('stdout should contain sandbox messagae', () => assert.include(stdout, 'Loading hook files in sandboxed context')); - it('should perform the request', () => assert.isTrue(requested)); - }) - ); + it('should perform the request', () => assert.isTrue(requested)); + })); - describe('when i use sandbox and hookData option', () => - describe('and I run a test', () => { - let requested; - before((done) => { - const cmd = { - hooksData: { - './test/fixtures/single-get.apib': `\ + describe('when i use sandbox and hookData option', () => describe('and I run a test', () => { + let requested; + before((done) => { + const cmd = { + hooksData: { + './test/fixtures/single-get.apib': `\ after('Machines > Machines collection > Get Machines', function(transaction){ transaction['fail'] = 'failed in sandboxed hook from string'; });\ ` - }, - options: { - path: './test/fixtures/single-get.apib', - sandbox: true - } - }; + }, + options: { + path: './test/fixtures/single-get.apib', + sandbox: true + } + }; - const app = express(); + const app = express(); - app.get('/machines', (req, res) => { - requested = true; - res.json([{ type: 'bulldozer', name: 'willy' }]); - }); + app.get('/machines', (req, res) => { + requested = true; + res.json([{ type: 'bulldozer', name: 'willy' }]); + }); - const server = app.listen(PORT, () => - execCommand(cmd, () => server.close()) - ); + const server = app.listen(PORT, () => execCommand(cmd, () => server.close())); - server.on('close', done); - }); + server.on('close', done); + }); - it('exit status should be 1', () => assert.equal(exitStatus, 1)); + it('exit status should be 1', () => assert.equal(exitStatus, 1)); - it('stdout should contain fail message', () => assert.include(stdout, 'failed in sandboxed hook from string')); + it('stdout should contain fail message', () => assert.include(stdout, 'failed in sandboxed hook from string')); - it('stdout should not sandbox messagae', () => assert.notInclude(stdout, 'Loading hook files in sandboxed context')); + it('stdout should not sandbox messagae', () => assert.notInclude(stdout, 'Loading hook files in sandboxed context')); - it('should perform the request', () => assert.isTrue(requested)); - }) - ); + it('should perform the request', () => assert.isTrue(requested)); + })); - describe('when use old buggy (#168) path with leading whitespace in hooks', () => - describe('and I run a test', () => { - before((done) => { - const cmd = { - hooksData: { - 'hooks.js': `\ + describe('when use old buggy (#168) path with leading whitespace in hooks', () => describe('and I run a test', () => { + before((done) => { + const cmd = { + hooksData: { + 'hooks.js': `\ before(' > Machines collection > Get Machines', function(transaction){ throw(new Error('Whitespace transaction name')); }); @@ -575,55 +546,56 @@ before('Machines collection > Get Machines', function(transaction){ }); \ ` - }, - options: { - path: './test/fixtures/single-get-nogroup.apib', - sandbox: true - } - }; + }, + options: { + path: './test/fixtures/single-get-nogroup.apib', + sandbox: true + } + }; - const app = express(); + const app = express(); - app.get('/machines', (req, res) => { - res.json([{ type: 'bulldozer', name: 'willy' }]); - }); + app.get('/machines', (req, res) => { + res.json([{ type: 'bulldozer', name: 'willy' }]); + }); - const server = app.listen(PORT, () => - execCommand(cmd, () => server.close()) - ); + const server = app.listen(PORT, () => execCommand(cmd, () => server.close())); - server.on('close', done); - }); + server.on('close', done); + }); - it('should execute hook with whitespaced name', () => assert.include(stderr, 'Whitespace transaction name')); + it('should execute hook with whitespaced name', () => assert.include(stderr, 'Whitespace transaction name')); - it('should execute hook with fuxed name', () => assert.include(stderr, 'Fixed transaction name')); - }) - ); + it('should execute hook with fuxed name', () => assert.include(stderr, 'Fixed transaction name')); + })); describe('when Swagger document has multiple responses', () => { const reTransaction = /(\w+): (\w+) \((\d+)\) \/honey/g; let actual; - before(done => - execCommand({ + before(done => execCommand( + { options: { path: './test/fixtures/multiple-responses.yaml' } - } - , (err) => { + }, + (err) => { let groups; const matches = []; // eslint-disable-next-line while (groups = reTransaction.exec(stdout)) { matches.push(groups); } actual = matches.map((match) => { - const keyMap = { 0: 'name', 1: 'action', 2: 'method', 3: 'statusCode' }; - return match.reduce((result, element, i) => Object.assign(result, { [keyMap[i]]: element }) - , {}); + const keyMap = { + 0: 'name', 1: 'action', 2: 'method', 3: 'statusCode' + }; + return match.reduce( + (result, element, i) => Object.assign(result, { [keyMap[i]]: element }), + {} + ); }); done(err); - }) - ); + } + )); it('recognizes all 3 transactions', () => assert.equal(actual.length, 3)); @@ -631,38 +603,40 @@ before('Machines collection > Get Machines', function(transaction){ { action: 'skip', statusCode: '400' }, { action: 'skip', statusCode: '500' }, { action: 'fail', statusCode: '200' } - ].forEach((expected, i) => - context(`the transaction #${i + 1}`, () => { - it(`has status code ${expected.statusCode}`, () => assert.equal(expected.statusCode, actual[i].statusCode)); - it(`is ${expected.action === 'skip' ? '' : 'not '}skipped by default`, () => assert.equal(expected.action, actual[i].action)); - }) - ); + ].forEach((expected, i) => context(`the transaction #${i + 1}`, () => { + it(`has status code ${expected.statusCode}`, () => assert.equal(expected.statusCode, actual[i].statusCode)); + it(`is ${expected.action === 'skip' ? '' : 'not '}skipped by default`, () => assert.equal(expected.action, actual[i].action)); + })); }); describe('when Swagger document has multiple responses and hooks unskip some of them', () => { const reTransaction = /(\w+): (\w+) \((\d+)\) \/honey/g; let actual; - before(done => - execCommand({ + before(done => execCommand( + { options: { path: './test/fixtures/multiple-responses.yaml', hookfiles: './test/fixtures/swagger-multiple-responses.js' } - } - , (err) => { + }, + (err) => { let groups; const matches = []; // eslint-disable-next-line while (groups = reTransaction.exec(stdout)) { matches.push(groups); } actual = matches.map((match) => { - const keyMap = { 0: 'name', 1: 'action', 2: 'method', 3: 'statusCode' }; - return match.reduce((result, element, i) => Object.assign(result, { [keyMap[i]]: element }) - , {}); + const keyMap = { + 0: 'name', 1: 'action', 2: 'method', 3: 'statusCode' + }; + return match.reduce( + (result, element, i) => Object.assign(result, { [keyMap[i]]: element }), + {} + ); }); done(err); - }) - ); + } + )); it('recognizes all 3 transactions', () => assert.equal(actual.length, 3)); @@ -670,43 +644,39 @@ before('Machines collection > Get Machines', function(transaction){ { action: 'skip', statusCode: '400' }, { action: 'fail', statusCode: '200' }, { action: 'fail', statusCode: '500' } // Unskipped in hooks - ].forEach((expected, i) => - context(`the transaction #${i + 1}`, () => { - it(`has status code ${expected.statusCode}`, () => assert.equal(expected.statusCode, actual[i].statusCode)); - - const defaultMessage = `is ${expected.action === 'skip' ? '' : 'not '}skipped by default`; - const unskippedMessage = 'is unskipped in hooks'; - it(`${expected.statusCode === '500' ? unskippedMessage : defaultMessage}`, () => assert.equal(expected.action, actual[i].action)); - }) - ); + ].forEach((expected, i) => context(`the transaction #${i + 1}`, () => { + it(`has status code ${expected.statusCode}`, () => assert.equal(expected.statusCode, actual[i].statusCode)); + + const defaultMessage = `is ${expected.action === 'skip' ? '' : 'not '}skipped by default`; + const unskippedMessage = 'is unskipped in hooks'; + it(`${expected.statusCode === '500' ? unskippedMessage : defaultMessage}`, () => assert.equal(expected.action, actual[i].action)); + })); }); describe('when using Swagger document with hooks', () => { const reTransactionName = /hook: (.+)/g; let matches; - beforeEach(done => - execCommand({ + beforeEach(done => execCommand( + { options: { path: './test/fixtures/multiple-responses.yaml', hookfiles: './test/fixtures/swagger-transaction-names.js' } - } - , (err) => { + }, + (err) => { let groups; matches = []; // eslint-disable-next-line while (groups = reTransactionName.exec(stdout)) { matches.push(groups[1]); } done(err); - }) - ); - - it('transaction names contain status code and content type', () => - assert.deepEqual(matches, [ - '/honey > GET > 200 > application/json', - '/honey > GET > 400 > application/json', - '/honey > GET > 500 > application/json' - ]) - ); + } + )); + + it('transaction names contain status code and content type', () => assert.deepEqual(matches, [ + '/honey > GET > 200 > application/json', + '/honey > GET > 400 > application/json', + '/honey > GET > 500 > application/json' + ])); }); }); diff --git a/test/integration/helpers.js b/test/integration/helpers.js index a0f4719c7..a2c1afd4f 100644 --- a/test/integration/helpers.js +++ b/test/integration/helpers.js @@ -133,13 +133,15 @@ function runDredd(dredd, serverPort, callback) { let stats; - recordLogging(next => dredd.run(next) - , (err, args, logging) => { + recordLogging( + next => dredd.run(next), + (err, args, logging) => { if (err) { return callback(err); } [err, stats] = Array.from(args); callback(null, { err, stats, logging }); - }); + } + ); } // Runs given Express.js server instance and then runs given Dredd class instance. @@ -150,9 +152,7 @@ function runDreddWithServer(dredd, app, serverPort, callback) { const server = app.listen(serverPort, (err, serverRuntimeInfo) => { if (err) { return callback(err); } - runDredd(dredd, serverPort, (error, dreddRuntimeInfo) => - server.close(() => callback(error, { server: serverRuntimeInfo, dredd: dreddRuntimeInfo })) - ); + runDredd(dredd, serverPort, (error, dreddRuntimeInfo) => server.close(() => callback(error, { server: serverRuntimeInfo, dredd: dreddRuntimeInfo }))); }); } @@ -177,7 +177,9 @@ function runCommand(command, args, spawnOptions = {}, callback) { output += data; }); - cli.on('exit', exitStatus => callback(null, { stdout, stderr, output, exitStatus })); + cli.on('exit', exitStatus => callback(null, { + stdout, stderr, output, exitStatus + })); } // Runs Dredd as a CLI command, with given arguments. @@ -191,9 +193,7 @@ function runCLIWithServer(args, app, serverPort, callback) { const server = app.listen(serverPort, (err, serverRuntimeInfo) => { if (err) { return callback(err); } - runCLI(args, (error, cliInfo) => - server.close(() => callback(error, { server: serverRuntimeInfo, dredd: cliInfo })) - ); + runCLI(args, (error, cliInfo) => server.close(() => callback(error, { server: serverRuntimeInfo, dredd: cliInfo }))); }); } @@ -224,8 +224,10 @@ function killAll(pattern, callback) { return ps.lookup({ arguments: pattern }, (err, processList) => { if (err || !processList.length) { return callback(err); } - async.each(processList, (processListItem, next) => kill(processListItem.pid, next) - , callback); + async.each( + processList, (processListItem, next) => kill(processListItem.pid, next), + callback + ); }); } diff --git a/test/integration/proxy-test.js b/test/integration/proxy-test.js index d2816db02..7af37ac3a 100644 --- a/test/integration/proxy-test.js +++ b/test/integration/proxy-test.js @@ -2,7 +2,9 @@ const http = require('http'); const url = require('url'); const { assert } = require('chai'); -const { runDredd, recordLogging, createServer, DEFAULT_SERVER_PORT } = require('./helpers'); +const { + runDredd, recordLogging, createServer, DEFAULT_SERVER_PORT +} = require('./helpers'); const Dredd = require('../../src/dredd'); const PROXY_PORT = DEFAULT_SERVER_PORT + 1; @@ -25,12 +27,10 @@ function createAndRunDredd(configuration, done) { dredd = new Dredd(configuration); dredd.configuration.http.strictSSL = false; next(); - }, (err, args, dreddInitLogging) => - runDredd(dredd, (error, info) => { - info.logging = `${dreddInitLogging}\n${info.logging}`; - done(error, info); - }) - ); + }, (err, args, dreddInitLogging) => runDredd(dredd, (error, info) => { + info.logging = `${dreddInitLogging}\n${info.logging}`; + done(error, info); + })); } // Creates dummy proxy server for given protocol. Records details @@ -137,7 +137,7 @@ function test(scenario) { it('requests the proxy with regular HTTP method', () => assert.oneOf(proxyRequestInfo.method, REGULAR_HTTP_METHODS)); it('requests the proxy, using the original URL as a path', () => assert.equal(proxyRequestInfo.url, scenario.expectedUrl)); return; - } else if (scenario.protocol === 'https') { + } if (scenario.protocol === 'https') { it('requests the proxy with CONNECT', () => assert.equal(proxyRequestInfo.method, 'CONNECT')); it('asks the proxy to tunnel SSL connection to the original hostname', () => { const hostname = `${url.parse(scenario.expectedUrl).hostname}:${DEFAULT_SERVER_PORT}`; @@ -169,18 +169,16 @@ ${protocol}_proxy=${PROXY_URL}\ beforeEach(() => { process.env[`${protocol}_proxy`] = PROXY_URL; }); afterEach(() => delete process.env[`${protocol}_proxy`]); - describe('Requesting Server Under Test', () => - test({ - protocol, - configureDredd(configuration) { - configuration.server = serverUrl; - configuration.options.path = './test/fixtures/single-get.apib'; - }, - expectedLog, - expectedDestination: 'server', - expectedUrl: '/machines' - }) - ); + describe('Requesting Server Under Test', () => test({ + protocol, + configureDredd(configuration) { + configuration.server = serverUrl; + configuration.options.path = './test/fixtures/single-get.apib'; + }, + expectedLog, + expectedDestination: 'server', + expectedUrl: '/machines' + })); describe('Using Apiary Reporter', () => { beforeEach(() => { process.env.APIARY_API_URL = serverUrl; }); @@ -199,18 +197,16 @@ ${protocol}_proxy=${PROXY_URL}\ }); }); - describe('Downloading API Description Document', () => - test({ - protocol, - configureDredd(configuration) { - configuration.server = DUMMY_URL; - configuration.options.path = `${serverUrl}/example.apib`; - }, - expectedLog, - expectedDestination: 'proxy', - expectedUrl: `${serverUrl}/example.apib` - }) - ); + describe('Downloading API Description Document', () => test({ + protocol, + configureDredd(configuration) { + configuration.server = DUMMY_URL; + configuration.options.path = `${serverUrl}/example.apib`; + }, + expectedLog, + expectedDestination: 'proxy', + expectedUrl: `${serverUrl}/example.apib` + })); }); }); @@ -231,18 +227,16 @@ http_proxy=${PROXY_URL}, no_proxy=${SERVER_HOST}\ delete process.env.no_proxy; }); - describe('Requesting Server Under Test', () => - test({ - protocol: 'http', - configureDredd(configuration) { - configuration.server = serverUrl; - configuration.options.path = './test/fixtures/single-get.apib'; - }, - expectedLog, - expectedDestination: 'server', - expectedUrl: '/machines' - }) - ); + describe('Requesting Server Under Test', () => test({ + protocol: 'http', + configureDredd(configuration) { + configuration.server = serverUrl; + configuration.options.path = './test/fixtures/single-get.apib'; + }, + expectedLog, + expectedDestination: 'server', + expectedUrl: '/machines' + })); describe('Using Apiary Reporter', () => { beforeEach(() => { process.env.APIARY_API_URL = serverUrl; }); @@ -261,16 +255,14 @@ http_proxy=${PROXY_URL}, no_proxy=${SERVER_HOST}\ }); }); - describe('Downloading API Description Document', () => - test({ - protocol: 'http', - configureDredd(configuration) { - configuration.server = DUMMY_URL; - configuration.options.path = `${serverUrl}/example.apib`; - }, - expectedLog, - expectedDestination: 'server', - expectedUrl: '/example.apib' - }) - ); + describe('Downloading API Description Document', () => test({ + protocol: 'http', + configureDredd(configuration) { + configuration.server = DUMMY_URL; + configuration.options.path = `${serverUrl}/example.apib`; + }, + expectedLog, + expectedDestination: 'server', + expectedUrl: '/example.apib' + })); }); diff --git a/test/integration/regressions/regression-152-test.js b/test/integration/regressions/regression-152-test.js index 523a9af37..9a363d188 100644 --- a/test/integration/regressions/regression-152-test.js +++ b/test/integration/regressions/regression-152-test.js @@ -3,29 +3,27 @@ const { assert } = require('chai'); const Dredd = require('../../../src/dredd'); const { runDreddWithServer, createServer } = require('../helpers'); -describe('Regression: Issue #152', () => - describe('Modify transaction object inside beforeAll combined with beforeEach helper', () => { - let runtimeInfo; +describe('Regression: Issue #152', () => describe('Modify transaction object inside beforeAll combined with beforeEach helper', () => { + let runtimeInfo; - before((done) => { - const app = createServer(); - app.get('/machines', (req, res) => res.json([{ type: 'bulldozer', name: 'willy' }])); + before((done) => { + const app = createServer(); + app.get('/machines', (req, res) => res.json([{ type: 'bulldozer', name: 'willy' }])); - const dredd = new Dredd({ - options: { - path: './test/fixtures/single-get.apib', - hookfiles: './test/fixtures/regression-152.coffee' - } - }); + const dredd = new Dredd({ + options: { + path: './test/fixtures/single-get.apib', + hookfiles: './test/fixtures/regression-152.coffee' + } + }); - runDreddWithServer(dredd, app, (...args) => { - let err; - // eslint-disable-next-line + runDreddWithServer(dredd, app, (...args) => { + let err; + // eslint-disable-next-line [err, runtimeInfo] = Array.from(args); - done(err); - }); + done(err); }); + }); - it('should modify the transaction with hooks', () => assert.deepEqual(Object.keys(runtimeInfo.server.requests), ['/machines?api-key=23456'])); - }) -); + it('should modify the transaction with hooks', () => assert.deepEqual(Object.keys(runtimeInfo.server.requests), ['/machines?api-key=23456'])); +})); diff --git a/test/integration/regressions/regression-319-354-test.js b/test/integration/regressions/regression-319-354-test.js index f824a4252..d5e851e42 100644 --- a/test/integration/regressions/regression-319-354-test.js +++ b/test/integration/regressions/regression-319-354-test.js @@ -47,7 +47,9 @@ function parseDreddStdout(stdout) { }); // Re-arrange data from entries - const results = { summary: '', failures: [], bodies: [], schemas: [] }; + const results = { + summary: '', failures: [], bodies: [], schemas: [] + }; for (entry of entries) { switch (entry.label) { case 'body': results.bodies.push(parseIfJson(entry.body)); break; @@ -160,10 +162,7 @@ describe('Regression: Issues #319 and #354', () => { }); }); - it('outputs no failures', () => - // Intentionally not testing just '.length' as this approach will output the difference - assert.deepEqual(results.failures, []) - ); + it('outputs no failures', () => assert.deepEqual(results.failures, [])); it('results in exactly four tests', () => assert.include(results.summary, '4 total')); it('results in four passing tests', () => assert.include(results.summary, '4 passing')); diff --git a/test/integration/regressions/regression-615-test.js b/test/integration/regressions/regression-615-test.js index cc0d011d2..09b06eed1 100644 --- a/test/integration/regressions/regression-615-test.js +++ b/test/integration/regressions/regression-615-test.js @@ -21,8 +21,5 @@ describe('Regression: Issue #615', () => { it('outputs no failures', () => assert.equal(runtimeInfo.dredd.stats.failures, 0)); it('results in exactly three tests', () => assert.equal(runtimeInfo.dredd.stats.tests, 3)); - it('results in three passing tests', () => - // Ensures just the 200 responses were selected, because the server returns only 200s - assert.equal(runtimeInfo.dredd.stats.passes, 3) - ); + it('results in three passing tests', () => assert.equal(runtimeInfo.dredd.stats.passes, 3)); }); diff --git a/test/integration/request-test.js b/test/integration/request-test.js index a58c4de0b..189cd4d22 100644 --- a/test/integration/request-test.js +++ b/test/integration/request-test.js @@ -44,52 +44,50 @@ describe('Sending \'application/json\' request', () => { path: './test/fixtures/request/multipart-form-data.yaml', supportsContentTypes: false } -].forEach(apiDescription => - describe(`Sending 'multipart/form-data' request described in ${apiDescription.name}`, () => { - let runtimeInfo; - const contentType = 'multipart/form-data'; - - before((done) => { - const app = createServer({ bodyParser: bodyParser.text({ type: contentType }) }); - app.post('/data', (req, res) => res.json({ test: 'OK' })); - const dredd = new Dredd({ options: { path: apiDescription.path } }); - - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); - }); +].forEach(apiDescription => describe(`Sending 'multipart/form-data' request described in ${apiDescription.name}`, () => { + let runtimeInfo; + const contentType = 'multipart/form-data'; - it('results in one request being delivered to the server', () => assert.isTrue(runtimeInfo.server.requestedOnce)); - it('the request has the expected Content-Type', () => assert.include(runtimeInfo.server.lastRequest.headers['content-type'], 'multipart/form-data')); - it('the request has the expected format', () => { - let lines = [ - '--CUSTOM-BOUNDARY', - 'Content-Disposition: form-data; name="text"', - 'Content-Type: text/plain', - '', - 'test equals to 42', - '--CUSTOM-BOUNDARY', - 'Content-Disposition: form-data; name="json"', - 'Content-Type: application/json', - '', - '{"test": 42}', - '', - '--CUSTOM-BOUNDARY--', - '' - ]; - if (!apiDescription.supportsContentTypes) { - lines = lines.filter(line => !line.match(/^Content-Type:/)); - } + before((done) => { + const app = createServer({ bodyParser: bodyParser.text({ type: contentType }) }); + app.post('/data', (req, res) => res.json({ test: 'OK' })); + const dredd = new Dredd({ options: { path: apiDescription.path } }); - assert.equal(runtimeInfo.server.lastRequest.body, lines.join('\r\n')); - }); - it('results in one passing test', () => { - assert.equal(runtimeInfo.dredd.stats.tests, 1); - assert.equal(runtimeInfo.dredd.stats.passes, 1); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - }) -); + }); + + it('results in one request being delivered to the server', () => assert.isTrue(runtimeInfo.server.requestedOnce)); + it('the request has the expected Content-Type', () => assert.include(runtimeInfo.server.lastRequest.headers['content-type'], 'multipart/form-data')); + it('the request has the expected format', () => { + let lines = [ + '--CUSTOM-BOUNDARY', + 'Content-Disposition: form-data; name="text"', + 'Content-Type: text/plain', + '', + 'test equals to 42', + '--CUSTOM-BOUNDARY', + 'Content-Disposition: form-data; name="json"', + 'Content-Type: application/json', + '', + '{"test": 42}', + '', + '--CUSTOM-BOUNDARY--', + '' + ]; + if (!apiDescription.supportsContentTypes) { + lines = lines.filter(line => !line.match(/^Content-Type:/)); + } + + assert.equal(runtimeInfo.server.lastRequest.body, lines.join('\r\n')); + }); + it('results in one passing test', () => { + assert.equal(runtimeInfo.dredd.stats.tests, 1); + assert.equal(runtimeInfo.dredd.stats.passes, 1); + }); +})); [{ name: 'API Blueprint', @@ -99,34 +97,29 @@ describe('Sending \'application/json\' request', () => { name: 'Swagger', path: './test/fixtures/request/application-x-www-form-urlencoded.yaml' } -].forEach(apiDescription => - describe(`Sending 'application/x-www-form-urlencoded' request described in ${apiDescription.name}`, () => { - let runtimeInfo; - const contentType = 'application/x-www-form-urlencoded'; - - before((done) => { - const app = createServer({ bodyParser: bodyParser.text({ type: contentType }) }); - app.post('/data', (req, res) => res.json({ test: 'OK' })); - const dredd = new Dredd({ options: { path: apiDescription.path } }); - - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); - }); +].forEach(apiDescription => describe(`Sending 'application/x-www-form-urlencoded' request described in ${apiDescription.name}`, () => { + let runtimeInfo; + const contentType = 'application/x-www-form-urlencoded'; - it('results in one request being delivered to the server', () => assert.isTrue(runtimeInfo.server.requestedOnce)); - it('the request has the expected Content-Type', () => assert.equal(runtimeInfo.server.lastRequest.headers['content-type'], contentType)); - it('the request has the expected format', () => - // API Blueprint adds extra \n at the end: https://github.com/apiaryio/dredd/issues/67 - assert.equal(runtimeInfo.server.lastRequest.body.trim(), 'test=42') - ); - it('results in one passing test', () => { - assert.equal(runtimeInfo.dredd.stats.tests, 1); - assert.equal(runtimeInfo.dredd.stats.passes, 1); + before((done) => { + const app = createServer({ bodyParser: bodyParser.text({ type: contentType }) }); + app.post('/data', (req, res) => res.json({ test: 'OK' })); + const dredd = new Dredd({ options: { path: apiDescription.path } }); + + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - }) -); + }); + + it('results in one request being delivered to the server', () => assert.isTrue(runtimeInfo.server.requestedOnce)); + it('the request has the expected Content-Type', () => assert.equal(runtimeInfo.server.lastRequest.headers['content-type'], contentType)); + it('the request has the expected format', () => assert.equal(runtimeInfo.server.lastRequest.body.trim(), 'test=42')); + it('results in one passing test', () => { + assert.equal(runtimeInfo.dredd.stats.tests, 1); + assert.equal(runtimeInfo.dredd.stats.passes, 1); + }); +})); describe('Sending \'text/plain\' request', () => { let runtimeInfo; @@ -161,45 +154,37 @@ describe('Sending \'text/plain\' request', () => { name: 'Swagger', path: './test/fixtures/request/application-octet-stream.yaml' } -].forEach(apiDescription => - describe(`Sending 'application/octet-stream' request described in ${apiDescription.name}`, () => { - let runtimeInfo; - const contentType = 'application/octet-stream'; - - before((done) => { - const app = createServer({ bodyParser: bodyParser.raw({ type: contentType }) }); - app.post('/binary', (req, res) => res.json({ test: 'OK' })); - - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/request/application-octet-stream-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); - }); +].forEach(apiDescription => describe(`Sending 'application/octet-stream' request described in ${apiDescription.name}`, () => { + let runtimeInfo; + const contentType = 'application/octet-stream'; + + before((done) => { + const app = createServer({ bodyParser: bodyParser.raw({ type: contentType }) }); + app.post('/binary', (req, res) => res.json({ test: 'OK' })); - it('results in one request being delivered to the server', () => - assert.isTrue(runtimeInfo.server.requestedOnce) - ); - it('the request has the expected Content-Type', () => - assert.equal(runtimeInfo.server.lastRequest.headers['content-type'], contentType) - ); - it('the request has the expected format', () => - assert.equal( - runtimeInfo.server.lastRequest.body.toString('base64'), - Buffer.from([0xFF, 0xEF, 0xBF, 0xBE]).toString('base64') - ) - ); - it('results in one passing test', () => { - assert.equal(runtimeInfo.dredd.stats.tests, 1); - assert.equal(runtimeInfo.dredd.stats.passes, 1); + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/request/application-octet-stream-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - }) -); + }); + + it('results in one request being delivered to the server', () => assert.isTrue(runtimeInfo.server.requestedOnce)); + it('the request has the expected Content-Type', () => assert.equal(runtimeInfo.server.lastRequest.headers['content-type'], contentType)); + it('the request has the expected format', () => assert.equal( + runtimeInfo.server.lastRequest.body.toString('base64'), + Buffer.from([0xFF, 0xEF, 0xBF, 0xBE]).toString('base64') + )); + it('results in one passing test', () => { + assert.equal(runtimeInfo.dredd.stats.tests, 1); + assert.equal(runtimeInfo.dredd.stats.passes, 1); + }); +})); [ { @@ -210,42 +195,34 @@ describe('Sending \'text/plain\' request', () => { name: 'Swagger', path: './test/fixtures/request/image-png.yaml' } -].forEach(apiDescription => - describe(`Sending 'image/png' request described in ${apiDescription.name}`, () => { - let runtimeInfo; - const contentType = 'image/png'; - - before((done) => { - const app = createServer({ bodyParser: bodyParser.raw({ type: contentType }) }); - app.put('/image.png', (req, res) => res.json({ test: 'OK' })); - - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/request/image-png-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); - }); +].forEach(apiDescription => describe(`Sending 'image/png' request described in ${apiDescription.name}`, () => { + let runtimeInfo; + const contentType = 'image/png'; - it('results in one request being delivered to the server', () => - assert.isTrue(runtimeInfo.server.requestedOnce) - ); - it('the request has the expected Content-Type', () => - assert.equal(runtimeInfo.server.lastRequest.headers['content-type'], contentType) - ); - it('the request has the expected format', () => - assert.equal( - runtimeInfo.server.lastRequest.body.toString('base64'), - fs.readFileSync(path.join(__dirname, '../fixtures/image.png')).toString('base64') - ) - ); - it('results in one passing test', () => { - assert.equal(runtimeInfo.dredd.stats.tests, 1); - assert.equal(runtimeInfo.dredd.stats.passes, 1); + before((done) => { + const app = createServer({ bodyParser: bodyParser.raw({ type: contentType }) }); + app.put('/image.png', (req, res) => res.json({ test: 'OK' })); + + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/request/image-png-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - }) -); + }); + + it('results in one request being delivered to the server', () => assert.isTrue(runtimeInfo.server.requestedOnce)); + it('the request has the expected Content-Type', () => assert.equal(runtimeInfo.server.lastRequest.headers['content-type'], contentType)); + it('the request has the expected format', () => assert.equal( + runtimeInfo.server.lastRequest.body.toString('base64'), + fs.readFileSync(path.join(__dirname, '../fixtures/image.png')).toString('base64') + )); + it('results in one passing test', () => { + assert.equal(runtimeInfo.dredd.stats.tests, 1); + assert.equal(runtimeInfo.dredd.stats.passes, 1); + }); +})); diff --git a/test/integration/response-test.js b/test/integration/response-test.js index 4aea1cfb7..5c1aec4e9 100644 --- a/test/integration/response-test.js +++ b/test/integration/response-test.js @@ -12,43 +12,41 @@ const Dredd = require('../../src/dredd'); name: 'Swagger', path: './test/fixtures/response/empty-body-empty-schema.yaml' } -].forEach(apiDescription => - describe(`Specifying neither response body nor schema in the ${apiDescription.name}`, () => { - describe('when the server returns non-empty responses', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource.json', (req, res) => res.json({ test: 'OK' })); - app.get('/resource.csv', (req, res) => res.type('text/csv').send('test,OK\n')); - const dredd = new Dredd({ options: { path: apiDescription.path } }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); +].forEach(apiDescription => describe(`Specifying neither response body nor schema in the ${apiDescription.name}`, () => { + describe('when the server returns non-empty responses', () => { + let runtimeInfo; + + before((done) => { + const app = createServer(); + app.get('/resource.json', (req, res) => res.json({ test: 'OK' })); + app.get('/resource.csv', (req, res) => res.type('text/csv').send('test,OK\n')); + const dredd = new Dredd({ options: { path: apiDescription.path } }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); }); - describe('when the server returns empty responses', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource.json', (req, res) => res.type('json').send()); - app.get('/resource.csv', (req, res) => res.type('text/csv').send()); - const dredd = new Dredd({ options: { path: apiDescription.path } }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); - }); + it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); + }); - it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); + describe('when the server returns empty responses', () => { + let runtimeInfo; + + before((done) => { + const app = createServer(); + app.get('/resource.json', (req, res) => res.type('json').send()); + app.get('/resource.csv', (req, res) => res.type('text/csv').send()); + const dredd = new Dredd({ options: { path: apiDescription.path } }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); + }); }); - }) -); + + it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); + }); +})); [{ name: 'API Blueprint', @@ -58,42 +56,40 @@ const Dredd = require('../../src/dredd'); name: 'Swagger', path: './test/fixtures/response/empty-body.yaml' } -].forEach(apiDescription => - describe(`Specifying no response body in the ${apiDescription.name}, but specifying a schema`, () => { - describe('when the server returns a response not valid according to the schema', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource', (req, res) => res.json({ name: 123 })); - const dredd = new Dredd({ options: { path: apiDescription.path } }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); +].forEach(apiDescription => describe(`Specifying no response body in the ${apiDescription.name}, but specifying a schema`, () => { + describe('when the server returns a response not valid according to the schema', () => { + let runtimeInfo; + + before((done) => { + const app = createServer(); + app.get('/resource', (req, res) => res.json({ name: 123 })); + const dredd = new Dredd({ options: { path: apiDescription.path } }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates the response as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, failures: 1 })); - it('prints JSON Schema validation error', () => assert.include(runtimeInfo.dredd.logging, 'At \'/name\' Invalid type: number (expected string)')); }); - describe('when the server returns a response valid according to the schema', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource', (req, res) => res.json({ name: 'test' })); - const dredd = new Dredd({ options: { path: apiDescription.path } }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); - }); + it('evaluates the response as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, failures: 1 })); + it('prints JSON Schema validation error', () => assert.include(runtimeInfo.dredd.logging, 'At \'/name\' Invalid type: number (expected string)')); + }); + + describe('when the server returns a response valid according to the schema', () => { + let runtimeInfo; - it('evaluates the response as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, passes: 1 })); + before((done) => { + const app = createServer(); + app.get('/resource', (req, res) => res.json({ name: 'test' })); + const dredd = new Dredd({ options: { path: apiDescription.path } }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); + }); }); - }) -); + + it('evaluates the response as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, passes: 1 })); + }); +})); [{ name: 'API Blueprint', @@ -103,54 +99,52 @@ const Dredd = require('../../src/dredd'); name: 'Swagger', path: './test/fixtures/response/empty-body-empty-schema.yaml' } -].forEach(apiDescription => - describe(`Specifying no response body in the ${apiDescription.name} and having hooks ensuring empty response`, () => { - describe('when the server returns a non-empty responses', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource.json', (req, res) => res.json({ test: 'OK' })); - app.get('/resource.csv', (req, res) => res.type('text/csv').send('test,OK\n')); - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/response/empty-body-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); +].forEach(apiDescription => describe(`Specifying no response body in the ${apiDescription.name} and having hooks ensuring empty response`, () => { + describe('when the server returns a non-empty responses', () => { + let runtimeInfo; + + before((done) => { + const app = createServer(); + app.get('/resource.json', (req, res) => res.json({ test: 'OK' })); + app.get('/resource.csv', (req, res) => res.type('text/csv').send('test,OK\n')); + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/response/empty-body-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, failures: 2 })); - it('prints the error message from hooks', () => assert.include(runtimeInfo.dredd.logging, 'The response body must be empty')); }); - describe('when the server returns an empty responses', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource.json', (req, res) => res.send()); - app.get('/resource.csv', (req, res) => res.type('text/csv').send()); - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/response/empty-body-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); + it('evaluates the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, failures: 2 })); + it('prints the error message from hooks', () => assert.include(runtimeInfo.dredd.logging, 'The response body must be empty')); + }); + + describe('when the server returns an empty responses', () => { + let runtimeInfo; + + before((done) => { + const app = createServer(); + app.get('/resource.json', (req, res) => res.send()); + app.get('/resource.csv', (req, res) => res.type('text/csv').send()); + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/response/empty-body-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); }); - }) -); + + it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); + }); +})); [{ name: 'API Blueprint', @@ -160,54 +154,52 @@ const Dredd = require('../../src/dredd'); name: 'Swagger', path: './test/fixtures/response/empty-body-empty-schema.yaml' } -].forEach(apiDescription => - describe(`Specifying no response body in the ${apiDescription.name} and having hooks ensuring empty response`, () => { - describe('when the server returns non-empty responses', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource.json', (req, res) => res.json({ test: 'OK' })); - app.get('/resource.csv', (req, res) => res.type('text/csv').send('test,OK\n')); - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/response/empty-body-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); +].forEach(apiDescription => describe(`Specifying no response body in the ${apiDescription.name} and having hooks ensuring empty response`, () => { + describe('when the server returns non-empty responses', () => { + let runtimeInfo; + + before((done) => { + const app = createServer(); + app.get('/resource.json', (req, res) => res.json({ test: 'OK' })); + app.get('/resource.csv', (req, res) => res.type('text/csv').send('test,OK\n')); + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/response/empty-body-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, failures: 2 })); - it('prints the error message from hooks', () => assert.include(runtimeInfo.dredd.logging, 'The response body must be empty')); }); - describe('when the server returns empty responses', () => { - let runtimeInfo; - - before((done) => { - const app = createServer(); - app.get('/resource.json', (req, res) => res.send()); - app.get('/resource.csv', (req, res) => res.type('text/csv').send()); - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/response/empty-body-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); + it('evaluates the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, failures: 2 })); + it('prints the error message from hooks', () => assert.include(runtimeInfo.dredd.logging, 'The response body must be empty')); + }); + + describe('when the server returns empty responses', () => { + let runtimeInfo; + + before((done) => { + const app = createServer(); + app.get('/resource.json', (req, res) => res.send()); + app.get('/resource.csv', (req, res) => res.type('text/csv').send()); + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/response/empty-body-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); }); - }) -); + + it('evaluates the responses as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 2, passes: 2 })); + }); +})); [{ name: 'API Blueprint', @@ -217,78 +209,56 @@ const Dredd = require('../../src/dredd'); name: 'Swagger', path: './test/fixtures/response/204-205-body.yaml' } -].forEach(apiDescription => - describe(`Working with HTTP 204 and 205 responses in the ${apiDescription.name}`, () => { - describe('when the actual response is non-empty', () => { - let runtimeInfo; - - before((done) => { - // It's not trivial to create an actual server sending HTTP 204 or 205 - // with non-empty body, because it's against specs. That's why we're - // returning HTTP 200 here and in the assertions we're making sure - // the failures are there only because of non-matching status codes. - const app = createServer(); - app.get('*', (req, res) => res.type('text/plain').send('test\n')); - - const dredd = new Dredd({ options: { path: apiDescription.path } }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); +].forEach(apiDescription => describe(`Working with HTTP 204 and 205 responses in the ${apiDescription.name}`, () => { + describe('when the actual response is non-empty', () => { + let runtimeInfo; + + before((done) => { + // It's not trivial to create an actual server sending HTTP 204 or 205 + // with non-empty body, because it's against specs. That's why we're + // returning HTTP 200 here and in the assertions we're making sure + // the failures are there only because of non-matching status codes. + const app = createServer(); + app.get('*', (req, res) => res.type('text/plain').send('test\n')); + + const dredd = new Dredd({ options: { path: apiDescription.path } }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates all the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 4, failures: 4 })); - it('prints four warnings for each of the responses', () => - assert.equal(runtimeInfo.dredd.logging.match( - /HTTP 204 and 205 responses must not include a message body/g - ).length, 4) - ); - it('prints four failures for each non-matching status code', () => - assert.equal(runtimeInfo.dredd.logging.match( - /fail: statusCode: Status code is '200' instead of/g - ).length, 4) - ); - it('does not print any failures regarding response bodies', () => assert.isNull(runtimeInfo.dredd.logging.match(/fail: body:/g))); }); - describe('when the actual response is empty', () => { - let runtimeInfo; - - before((done) => { - // It's not trivial to create an actual server sending HTTP 204 or 205 - // sending a Content-Type header, because it's against specs. That's - // why we're returning HTTP 200 here and in the assertions we're making - // sure the extra failures are there only because of non-matching status - // codes. - const app = createServer(); - app.get('*', (req, res) => res.type('text/plain').send()); - - const dredd = new Dredd({ options: { path: apiDescription.path } }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); + it('evaluates all the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 4, failures: 4 })); + it('prints four warnings for each of the responses', () => assert.equal(runtimeInfo.dredd.logging.match(/HTTP 204 and 205 responses must not include a message body/g).length, 4)); + it('prints four failures for each non-matching status code', () => assert.equal(runtimeInfo.dredd.logging.match(/fail: statusCode: Status code is '200' instead of/g).length, 4)); + it('does not print any failures regarding response bodies', () => assert.isNull(runtimeInfo.dredd.logging.match(/fail: body:/g))); + }); + + describe('when the actual response is empty', () => { + let runtimeInfo; + + before((done) => { + // It's not trivial to create an actual server sending HTTP 204 or 205 + // sending a Content-Type header, because it's against specs. That's + // why we're returning HTTP 200 here and in the assertions we're making + // sure the extra failures are there only because of non-matching status + // codes. + const app = createServer(); + app.get('*', (req, res) => res.type('text/plain').send()); + + const dredd = new Dredd({ options: { path: apiDescription.path } }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates all the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 4, failures: 4 })); - it('prints two warnings for each of the non-empty expectations', () => - assert.equal(runtimeInfo.dredd.logging.match( - /HTTP 204 and 205 responses must not include a message body/g - ).length, 2) - ); - it('prints two failures for each non-matching body (and status code)', () => - assert.equal(runtimeInfo.dredd.logging.match( - /fail: body: Real and expected data does not match.\nstatusCode: Status code is '200' instead of/g - ).length, 2) - ); - it('prints two failures for each non-matching status code', () => - assert.equal(runtimeInfo.dredd.logging.match( - /fail: statusCode: Status code is '200' instead of/g - ).length, 2) - ); }); - }) -); + + it('evaluates all the responses as invalid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 4, failures: 4 })); + it('prints two warnings for each of the non-empty expectations', () => assert.equal(runtimeInfo.dredd.logging.match(/HTTP 204 and 205 responses must not include a message body/g).length, 2)); + it('prints two failures for each non-matching body (and status code)', () => assert.equal(runtimeInfo.dredd.logging.match(/fail: body: Real and expected data does not match.\nstatusCode: Status code is '200' instead of/g).length, 2)); + it('prints two failures for each non-matching status code', () => assert.equal(runtimeInfo.dredd.logging.match(/fail: statusCode: Status code is '200' instead of/g).length, 2)); + }); +})); [ { @@ -299,54 +269,46 @@ const Dredd = require('../../src/dredd'); name: 'Swagger', path: './test/fixtures/response/binary.yaml' } -].forEach(apiDescription => - describe(`Working with binary responses in the ${apiDescription.name}`, () => { - const imagePath = path.join(__dirname, '../fixtures/image.png'); - const app = createServer(); - app.get('/image.png', (req, res) => - res.type('image/png').sendFile(imagePath) - ); - - describe('when the body is described as empty and there are hooks to remove the real body', () => { - let runtimeInfo; - - before((done) => { - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/response/binary-ignore-body-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); +].forEach(apiDescription => describe(`Working with binary responses in the ${apiDescription.name}`, () => { + const imagePath = path.join(__dirname, '../fixtures/image.png'); + const app = createServer(); + app.get('/image.png', (req, res) => res.type('image/png').sendFile(imagePath)); + + describe('when the body is described as empty and there are hooks to remove the real body', () => { + let runtimeInfo; + + before((done) => { + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/response/binary-ignore-body-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); }); - - it('evaluates the response as valid', () => - assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, passes: 1 }) - ); }); - describe('when the body is described as empty and there are hooks to assert the real body', () => { - let runtimeInfo; - - before((done) => { - const dredd = new Dredd({ - options: { - path: apiDescription.path, - hookfiles: './test/fixtures/response/binary-assert-body-hooks.js' - } - }); - runDreddWithServer(dredd, app, (err, info) => { - runtimeInfo = info; - done(err); - }); - }); + it('evaluates the response as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, passes: 1 })); + }); + + describe('when the body is described as empty and there are hooks to assert the real body', () => { + let runtimeInfo; - it('evaluates the response as valid', () => - assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, passes: 1 }) - ); + before((done) => { + const dredd = new Dredd({ + options: { + path: apiDescription.path, + hookfiles: './test/fixtures/response/binary-assert-body-hooks.js' + } + }); + runDreddWithServer(dredd, app, (err, info) => { + runtimeInfo = info; + done(err); + }); }); - }) -); + + it('evaluates the response as valid', () => assert.deepInclude(runtimeInfo.dredd.stats, { tests: 1, passes: 1 })); + }); +})); diff --git a/test/integration/sanitation-test.js b/test/integration/sanitation-test.js index 6ebd35b56..c3d31badd 100644 --- a/test/integration/sanitation-test.js +++ b/test/integration/sanitation-test.js @@ -72,11 +72,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does not contain request body', () => assert.equal(events[2].test.request.body, '')); it('sensitive data cannot be found anywhere in the emitted test data', () => { const test = JSON.stringify(events); @@ -107,11 +105,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does not contain response body', () => { assert.equal(events[2].test.actual.body, ''); assert.equal(events[2].test.expected.body, ''); @@ -145,11 +141,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does not contain confidential body attribute', () => { const attrs = Object.keys(JSON.parse(events[2].test.request.body)); assert.deepEqual(attrs, ['name']); @@ -183,11 +177,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does not contain confidential body attribute', () => { let attrs = Object.keys(JSON.parse(events[2].test.actual.body)); assert.deepEqual(attrs, ['name']); @@ -224,11 +216,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does contain the sensitive data censored', () => { assert.include(events[2].test.actual.body, '--- CENSORED ---'); assert.include(events[2].test.expected.body, '--- CENSORED ---'); @@ -255,11 +245,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does not contain confidential header', () => { const names = Object.keys(events[2].test.request.headers).map(name => name.toLowerCase()); assert.notInclude(names, sensitiveHeaderName); @@ -294,11 +282,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does not contain confidential header', () => { let names = Object.keys(events[2].test.actual.headers).map(name => name.toLowerCase()); assert.notInclude(names, sensitiveHeaderName); @@ -336,11 +322,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does contain the sensitive data censored', () => assert.include(events[2].test.request.uri, 'CENSORED')); it('sensitive data cannot be found anywhere in the emitted test data', () => assert.notInclude(JSON.stringify(events), sensitiveValue)); it('sensitive data cannot be found anywhere in Dredd output', () => assert.notInclude(dreddRuntimeInfo.logging, sensitiveValue)); @@ -366,11 +350,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does contain the sensitive data censored', () => assert.include(JSON.stringify(events), 'CENSORED')); it('sensitive data cannot be found anywhere in the emitted test data', () => assert.notInclude(JSON.stringify(events), sensitiveValue)); it('sensitive data cannot be found anywhere in Dredd output', () => assert.notInclude(dreddRuntimeInfo.logging, sensitiveValue)); @@ -394,11 +376,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('sensitive data cannot be found anywhere in the emitted test data', () => { const test = JSON.stringify(events); assert.notInclude(test, sensitiveValue); @@ -425,11 +405,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.passes, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test pass', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test pass', 'end' + ])); it('emitted test data does not contain request body', () => assert.equal(events[2].test.request.body, '')); it('sensitive data cannot be found anywhere in the emitted test data', () => { const test = JSON.stringify(events); @@ -460,11 +438,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test is failed', () => { assert.equal(events[2].test.status, 'fail'); assert.include(events[2].test.results.general.results[0].message.toLowerCase(), 'fail'); @@ -499,11 +475,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('emitted test data does not contain request body', () => assert.equal(events[2].test.request.body, '')); it('emitted test is failed', () => { assert.equal(events[2].test.status, 'fail'); @@ -539,11 +513,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.skipped, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test skip', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test skip', 'end' + ])); it('emitted test is skipped', () => { assert.equal(events[2].test.status, 'skip'); assert.deepEqual(Object.keys(events[2].test.results), ['general']); @@ -578,11 +550,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.errors, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test error', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test error', 'end' + ])); it('sensitive data leak to emitted test data', () => { const test = JSON.stringify(events); assert.include(test, sensitiveKey); @@ -612,11 +582,9 @@ describe('Sanitation of Reported Data', () => { assert.equal(dreddRuntimeInfo.stats.failures, 1); assert.equal(dreddRuntimeInfo.stats.tests, 1); }); - it('emits expected events in expected order', () => - assert.deepEqual((Array.from(events).map(event => event.name)), [ - 'start', 'test start', 'test fail', 'end' - ]) - ); + it('emits expected events in expected order', () => assert.deepEqual((Array.from(events).map(event => event.name)), [ + 'start', 'test start', 'test fail', 'end' + ])); it('sensitive data cannot be found anywhere in the emitted test data', () => { const test = JSON.stringify(events); assert.notInclude(test, sensitiveKey); diff --git a/test/unit/add-hooks-test.js b/test/unit/add-hooks-test.js index 6eb12da33..1e636f12a 100644 --- a/test/unit/add-hooks-test.js +++ b/test/unit/add-hooks-test.js @@ -43,29 +43,25 @@ describe('addHooks(runner, transactions, callback)', () => { } }; - it('should create hooks instance at runner.hooks', done => - addHooks(runner, transactions, (err) => { - if (err) { return err; } - assert.isDefined(runner.hooks); - assert.instanceOf(runner.hooks, hooksStub); - assert.strictEqual(runner.hooks, runner.hooks); - assert.nestedProperty(runner, 'hooks.transactions'); - done(); - }) - ); - - - it('should pass runner.logs to runner.hooks.logs', done => - addHooks(runner, transactions, (err) => { - if (err) { return err; } - assert.isDefined(runner.hooks); - assert.instanceOf(runner.hooks, hooksStub); - assert.nestedProperty(runner, 'hooks.logs'); - assert.isDefined(runner.hooks.logs); - assert.strictEqual(runner.hooks.logs, runner.logs); - done(); - }) - ); + it('should create hooks instance at runner.hooks', done => addHooks(runner, transactions, (err) => { + if (err) { return err; } + assert.isDefined(runner.hooks); + assert.instanceOf(runner.hooks, hooksStub); + assert.strictEqual(runner.hooks, runner.hooks); + assert.nestedProperty(runner, 'hooks.transactions'); + done(); + })); + + + it('should pass runner.logs to runner.hooks.logs', done => addHooks(runner, transactions, (err) => { + if (err) { return err; } + assert.isDefined(runner.hooks); + assert.instanceOf(runner.hooks, hooksStub); + assert.nestedProperty(runner, 'hooks.logs'); + assert.isDefined(runner.hooks.logs); + assert.strictEqual(runner.hooks.logs, runner.logs); + done(); + })); }); @@ -86,12 +82,10 @@ describe('addHooks(runner, transactions, callback)', () => { after(() => globStub.sync.restore()); - it('should not expand any glob', done => - addHooks(runner, transactions, () => { - assert.isOk(globStub.sync.notCalled); - done(); - }) - ); + it('should not expand any glob', done => addHooks(runner, transactions, () => { + assert.isOk(globStub.sync.notCalled); + done(); + })); }); describe('with non `nodejs` language option', () => { @@ -112,13 +106,11 @@ describe('addHooks(runner, transactions, callback)', () => { afterEach(() => hooksWorkerClientStub.prototype.start.restore()); - it('should start the hooks worker client', done => - addHooks(runner, transactions, (err) => { - if (err) { return done(err); } - assert.isTrue(hooksWorkerClientStub.prototype.start.called); - done(); - }) - ); + it('should start the hooks worker client', done => addHooks(runner, transactions, (err) => { + if (err) { return done(err); } + assert.isTrue(hooksWorkerClientStub.prototype.start.called); + done(); + })); }); @@ -144,18 +136,16 @@ describe('addHooks(runner, transactions, callback)', () => { }); }); - it('should return files with resolved paths', done => - addHooks(runner, transactions, (err) => { - if (err) { return done(err); } + it('should return files with resolved paths', done => addHooks(runner, transactions, (err) => { + if (err) { return done(err); } - assert.deepEqual(runner.hooks.configuration.options.hookfiles, [ - pathStub.resolve(process.cwd(), './test/fixtures/multifile/multifile_hooks.coffee'), - pathStub.resolve(process.cwd(), './test/fixtures/test2_hooks.js'), - pathStub.resolve(process.cwd(), './test/fixtures/test_hooks.coffee') - ]); - done(); - }) - ); + assert.deepEqual(runner.hooks.configuration.options.hookfiles, [ + pathStub.resolve(process.cwd(), './test/fixtures/multifile/multifile_hooks.coffee'), + pathStub.resolve(process.cwd(), './test/fixtures/test2_hooks.js'), + pathStub.resolve(process.cwd(), './test/fixtures/test_hooks.coffee') + ]); + done(); + })); describe('when files are valid js/coffeescript', () => { runner = null; @@ -176,23 +166,19 @@ describe('addHooks(runner, transactions, callback)', () => { pathStub.resolve.restore(); }); - it('should load the files', done => - addHooks(runner, transactions, (err) => { - if (err) { return done(err); } - assert.isOk(pathStub.resolve.called); - done(); - }) - ); - - it('should add configuration object to the hooks object proxyquired to the each hookfile', done => - addHooks(runner, transactions, (err) => { - if (err) { return done(err); } - const call = proxyquireSpy.getCall(0); - const hooksObject = call.args[1].hooks; - assert.property(hooksObject, 'configuration'); - done(); - }) - ); + it('should load the files', done => addHooks(runner, transactions, (err) => { + if (err) { return done(err); } + assert.isOk(pathStub.resolve.called); + done(); + })); + + it('should add configuration object to the hooks object proxyquired to the each hookfile', done => addHooks(runner, transactions, (err) => { + if (err) { return done(err); } + const call = proxyquireSpy.getCall(0); + const hooksObject = call.args[1].hooks; + assert.property(hooksObject, 'configuration'); + done(); + })); }); }); @@ -226,37 +212,29 @@ describe('addHooks(runner, transactions, callback)', () => { done(); }); - it('should not use proxyquire', done => - addHooks(runner, transactions, (err) => { - if (err) { return done(err); } - assert.isFalse(proxyquireSpy.called); - done(); - }) - ); + it('should not use proxyquire', done => addHooks(runner, transactions, (err) => { + if (err) { return done(err); } + assert.isFalse(proxyquireSpy.called); + done(); + })); - it('should load files from the filesystem', done => - addHooks(runner, transactions, (err) => { - if (err) { return done(err); } - assert.isTrue(fsStub.readFile.called); - done(); - }) - ); + it('should load files from the filesystem', done => addHooks(runner, transactions, (err) => { + if (err) { return done(err); } + assert.isTrue(fsStub.readFile.called); + done(); + })); - it('should run the loaded code', done => - addHooks(runner, transactions, (err) => { - if (err) { return err; } - assert.isTrue(sandboxHooksCodeSpy.called); - done(); - }) - ); + it('should run the loaded code', done => addHooks(runner, transactions, (err) => { + if (err) { return err; } + assert.isTrue(sandboxHooksCodeSpy.called); + done(); + })); - it('should add hook functions strings to the runner object', done => - addHooks(runner, transactions, (err) => { - if (err) { return err; } - assert.property(runner.hooks.afterHooks, 'Machines > Machines collection > Get Machines'); - done(); - }) - ); + it('should add hook functions strings to the runner object', done => addHooks(runner, transactions, (err) => { + if (err) { return err; } + assert.property(runner.hooks.afterHooks, 'Machines > Machines collection > Get Machines'); + done(); + })); }); describe('when hookfiles option is not given and hooks are passed as a string from Dredd class', () => { @@ -292,29 +270,23 @@ after('Machines > Machines collection > Get Machines', function(transaction){ sandboxHooksCodeSpy.resetHistory(); }); - it('should not use proxyquire', done => - addHooks(runner, transactions, (err) => { - if (err) { return done(err); } - assert.isFalse(proxyquireSpy.called); - done(); - }) - ); + it('should not use proxyquire', done => addHooks(runner, transactions, (err) => { + if (err) { return done(err); } + assert.isFalse(proxyquireSpy.called); + done(); + })); - it('should run the loaded code', done => - addHooks(runner, transactions, (err) => { - if (err) { return err; } - assert.isTrue(sandboxHooksCodeSpy.called); - done(); - }) - ); + it('should run the loaded code', done => addHooks(runner, transactions, (err) => { + if (err) { return err; } + assert.isTrue(sandboxHooksCodeSpy.called); + done(); + })); - it('should add hook functions strings to the runner object', done => - addHooks(runner, transactions, (err) => { - if (err) { return err; } - assert.property(runner.hooks.afterHooks, 'Machines > Machines collection > Get Machines'); - done(); - }) - ); + it('should add hook functions strings to the runner object', done => addHooks(runner, transactions, (err) => { + if (err) { return err; } + assert.property(runner.hooks.afterHooks, 'Machines > Machines collection > Get Machines'); + done(); + })); }); describe('when hooks are passed as a string from Dredd class', () => { @@ -334,23 +306,20 @@ after('Machines > Machines collection > Get Machines', function(transaction){ }; }); - it('should throw a "not implemented" exception', done => - addHooks(runner, transactions, (err) => { - assert.isDefined(err); - assert.include(err.message, 'not implemented'); - done(); - }) - ); + it('should throw a "not implemented" exception', done => addHooks(runner, transactions, (err) => { + assert.isDefined(err); + assert.include(err.message, 'not implemented'); + done(); + })); }); - describe('when buggy transaction name is used (#168)', () => - describe('when sandboxed', () => { - it('should remove leading " > " from transaction names', (done) => { - const runner = { - configuration: { - hooksData: { - 'hookfile.js': `\ + describe('when buggy transaction name is used (#168)', () => describe('when sandboxed', () => { + it('should remove leading " > " from transaction names', (done) => { + const runner = { + configuration: { + hooksData: { + 'hookfile.js': `\ after(' > Machines collection > Get Machines', function(transaction){ transaction['fail'] = 'failed in sandboxed hook'; }); @@ -358,25 +327,25 @@ before(' > Machines collection > Get Machines', function(transaction){ transaction['fail'] = 'failed in sandboxed hook'; });\ ` - }, - options: { - sandbox: true - } + }, + options: { + sandbox: true } - }; + } + }; - addHooks(runner, transactions, () => { - assert.notProperty(runner.hooks.afterHooks, ' > Machines collection > Get Machines'); - assert.notProperty(runner.hooks.afterHooks, ' > Machines collection > Get Machines'); - done(); - }); + addHooks(runner, transactions, () => { + assert.notProperty(runner.hooks.afterHooks, ' > Machines collection > Get Machines'); + assert.notProperty(runner.hooks.afterHooks, ' > Machines collection > Get Machines'); + done(); }); + }); - it('should contain transaction with fixed name', (done) => { - const runner = { - configuration: { - hooksData: { - 'hookfile.js': `\ + it('should contain transaction with fixed name', (done) => { + const runner = { + configuration: { + hooksData: { + 'hookfile.js': `\ after(' > Machines collection > Get Machines', function(transaction){ transaction['fail'] = 'failed in sandboxed hook'; }); @@ -384,21 +353,20 @@ before(' > Machines collection > Get Machines', function(transaction){ transaction['fail'] = 'failed in sandboxed hook'; });\ ` - }, - options: { - sandbox: true - } + }, + options: { + sandbox: true } - }; + } + }; - addHooks(runner, transactions, () => { - assert.property(runner.hooks.afterHooks, 'Machines collection > Get Machines'); - assert.property(runner.hooks.afterHooks, 'Machines collection > Get Machines'); - done(); - }); + addHooks(runner, transactions, () => { + assert.property(runner.hooks.afterHooks, 'Machines collection > Get Machines'); + assert.property(runner.hooks.afterHooks, 'Machines collection > Get Machines'); + done(); }); - }) - ); + }); + })); }); describe('when not sandboxed', () => { diff --git a/test/unit/blueprint-utils-test.js b/test/unit/blueprint-utils-test.js index a7e3232d8..c1d2c8252 100644 --- a/test/unit/blueprint-utils-test.js +++ b/test/unit/blueprint-utils-test.js @@ -8,21 +8,17 @@ describe('blueprintUtils', () => { const options = { type: 'refract' }; describe('characterIndexToPosition()', () => { - describe('under standard circumstances', () => - it('returns an object with non-zero-based row', () => { - const str = 'first\nsecond\nthird lines\ncontent continues'; - const position = blueprintUtils.characterIndexToPosition(str.indexOf('lines', str), str); - assert.deepEqual(position, { row: 3 }); - }) - ); - - describe('when given one-line input and zero index', () => - it('returns an object with row 1', () => { - const str = 'hello\n'; - const position = blueprintUtils.characterIndexToPosition(str.indexOf('hello', str), str); - assert.deepEqual(position, { row: 1 }); - }) - ); + describe('under standard circumstances', () => it('returns an object with non-zero-based row', () => { + const str = 'first\nsecond\nthird lines\ncontent continues'; + const position = blueprintUtils.characterIndexToPosition(str.indexOf('lines', str), str); + assert.deepEqual(position, { row: 3 }); + })); + + describe('when given one-line input and zero index', () => it('returns an object with row 1', () => { + const str = 'hello\n'; + const position = blueprintUtils.characterIndexToPosition(str.indexOf('hello', str), str); + assert.deepEqual(position, { row: 1 }); + })); }); describe('warningLocationToRanges()', () => { @@ -93,17 +89,14 @@ describe('blueprintUtils', () => { }); describe('rangesToLinesText()', () => { - describe('when tested on fake locations', () => - - it('should return a string of line(s) separated with comma', () => { - const line = blueprintUtils.rangesToLinesText([ - { start: 2, end: 4 }, - { start: 8, end: 8 }, - { start: 10, end: 15 } - ]); - assert.strictEqual(line, 'lines 2-4, line 8, lines 10-15'); - }) - ); + describe('when tested on fake locations', () => it('should return a string of line(s) separated with comma', () => { + const line = blueprintUtils.rangesToLinesText([ + { start: 2, end: 4 }, + { start: 8, end: 8 }, + { start: 10, end: 15 } + ]); + assert.strictEqual(line, 'lines 2-4, line 8, lines 10-15'); + })); describe('for a real API description document', () => { let warnings = 0; diff --git a/test/unit/cli-test.js b/test/unit/cli-test.js index aee78c011..ff84c68eb 100644 --- a/test/unit/cli-test.js +++ b/test/unit/cli-test.js @@ -53,12 +53,12 @@ function execCommand(custom = {}, cb) { (new CLIStub({ custom }, ((code) => { - if (!finished) { - finished = true; - exitStatus = code || 0; - return cb(null, stdout, stderr, (code != null ? code : 0)); - } - })).run()); + if (!finished) { + finished = true; + exitStatus = code || 0; + return cb(null, stdout, stderr, (code != null ? code : 0)); + } + })).run()); } describe('CLI class', () => { @@ -117,9 +117,10 @@ describe('CLI class', () => { let hasCalledExit; before(() => { - dc = new CLIStub({ exit() { - hasCalledExit = true; - } + dc = new CLIStub({ + exit() { + hasCalledExit = true; + } }); dc.run(); }); @@ -255,9 +256,7 @@ describe('CLI class', () => { describe('when called w/ OR wo/ exiting arguments', () => { describe('--help', () => { - before(done => - execCommand({ argv: ['--help'] }, () => done()) - ); + before(done => execCommand({ argv: ['--help'] }, () => done())); it('prints out some really nice help text with all options descriptions', () => { assert.include(stderr, 'Usage:'); @@ -268,9 +267,7 @@ describe('CLI class', () => { }); describe('--version', () => { - before(done => - execCommand({ argv: ['--version'] }, () => done()) - ); + before(done => execCommand({ argv: ['--version'] }, () => done())); it('prints out version', () => assert.include(stdout, `${packageData.name} v${packageData.version}`)); }); @@ -290,9 +287,7 @@ describe('CLI class', () => { }); describe('without argv', () => { - before(done => - execCommand({ argv: [] }, () => done()) - ); + before(done => execCommand({ argv: [] }, () => done())); it('prints out an error message', () => assert.include(stderr, 'Error: Must specify')); }); @@ -320,34 +315,33 @@ describe('CLI class', () => { sinon.stub(fsStub, 'existsSync').callsFake(() => true); - sinon.stub(configUtilsStub, 'load').callsFake(() => - ({ - _: ['blueprint', 'endpoint'], - 'dry-run': true, - hookfiles: null, - sandbox: false, - save: null, - load: null, - server: null, - init: false, - custom: [], - names: false, - only: [], - reporter: [], - output: [], - header: [], - sorted: false, - user: null, - 'inline-errors': false, - details: false, - method: [], - color: true, - level: 'info', - timestamp: false, - silent: false, - path: [], - $0: 'node ./bin/dredd' - })); + sinon.stub(configUtilsStub, 'load').callsFake(() => ({ + _: ['blueprint', 'endpoint'], + 'dry-run': true, + hookfiles: null, + sandbox: false, + save: null, + load: null, + server: null, + init: false, + custom: [], + names: false, + only: [], + reporter: [], + output: [], + header: [], + sorted: false, + user: null, + 'inline-errors': false, + details: false, + method: [], + color: true, + level: 'info', + timestamp: false, + silent: false, + path: [], + $0: 'node ./bin/dredd' + })); execCommand({ argv: ['--names'] }, () => done()); }); @@ -377,12 +371,13 @@ describe('CLI class', () => { beforeEach((done) => { sinon.stub(crossSpawnStub, 'spawn').callsFake(); sinon.stub(transactionRunner.prototype, 'executeAllTransactions').callsFake((transactions, hooks, cb) => cb()); - execCommand({ argv: [ - './test/fixtures/single-get.apib', - `http://127.0.0.1:${PORT}`, - '--server', - 'foo/bar' - ] + execCommand({ + argv: [ + './test/fixtures/single-get.apib', + `http://127.0.0.1:${PORT}`, + '--server', + 'foo/bar' + ] }, () => done()); }); diff --git a/test/unit/config-utils-test.js b/test/unit/config-utils-test.js index 5286e42df..317a4fe9a 100644 --- a/test/unit/config-utils-test.js +++ b/test/unit/config-utils-test.js @@ -128,24 +128,20 @@ describe('configUtils', () => { assert.isOk(yamlStub.dump.called); }); - describe('when path is not given', () => - it('should save to ./dredd.yml', () => { - configUtils.save(argv); - const call = fsStub.writeFileSync.getCall(0); - const { args } = call; - assert.include(args[0], 'dredd.yml'); - }) - ); - - describe('when path is given', () => - it('should save to that path', () => { - const path = 'some-other-location.yml '; - configUtils.save(argv, path); - const call = fsStub.writeFileSync.getCall(0); - const { args } = call; - assert.include(args[0], path); - }) - ); + describe('when path is not given', () => it('should save to ./dredd.yml', () => { + configUtils.save(argv); + const call = fsStub.writeFileSync.getCall(0); + const { args } = call; + assert.include(args[0], 'dredd.yml'); + })); + + describe('when path is given', () => it('should save to that path', () => { + const path = 'some-other-location.yml '; + configUtils.save(argv, path); + const call = fsStub.writeFileSync.getCall(0); + const { args } = call; + assert.include(args[0], path); + })); }); describe('load(path)', () => { @@ -183,24 +179,20 @@ endpoint: endpoint\ it('should be a defined function', () => assert.isFunction(configUtils.load)); - describe('if no path is given', () => - it('should load from ./dredd.yml', () => { - configUtils.load(); - const call = fsStub.readFileSync.getCall(0); - const { args } = call; - assert.include(args[0], 'dredd.yml'); - }) - ); - - describe('when path is given', () => - it('should load from that path', () => { - const path = 'some-other-location.yml '; - configUtils.load(path); - const call = fsStub.readFileSync.getCall(0); - const { args } = call; - assert.include(args[0], path); - }) - ); + describe('if no path is given', () => it('should load from ./dredd.yml', () => { + configUtils.load(); + const call = fsStub.readFileSync.getCall(0); + const { args } = call; + assert.include(args[0], 'dredd.yml'); + })); + + describe('when path is given', () => it('should load from that path', () => { + const path = 'some-other-location.yml '; + configUtils.load(path); + const call = fsStub.readFileSync.getCall(0); + const { args } = call; + assert.include(args[0], path); + })); it('should move blueprint and enpoint to an array under _ key', () => { const output = configUtils.load(); diff --git a/test/unit/configuration-test.js b/test/unit/configuration-test.js index d4e454194..92649ab4f 100644 --- a/test/unit/configuration-test.js +++ b/test/unit/configuration-test.js @@ -24,19 +24,15 @@ describe('configuration.applyLoggingOptions()', () => { assert.equal(logger.transports.console.level, 'debug'); }); - describe('with color set to legacy \'true\' string value', () => - it('resulting configuration should contain \'color\' set to boolean true', () => { - const options = configuration.applyLoggingOptions({ color: 'true' }); - assert.propertyVal(options, 'color', true); - }) - ); - - describe('with color option set to legacy \'false\' string value', () => - it('resulting configuration should contain \'color\' set to boolean false', () => { - const options = configuration.applyLoggingOptions({ color: 'false' }); - assert.propertyVal(options, 'color', false); - }) - ); + describe('with color set to legacy \'true\' string value', () => it('resulting configuration should contain \'color\' set to boolean true', () => { + const options = configuration.applyLoggingOptions({ color: 'true' }); + assert.propertyVal(options, 'color', true); + })); + + describe('with color option set to legacy \'false\' string value', () => it('resulting configuration should contain \'color\' set to boolean false', () => { + const options = configuration.applyLoggingOptions({ color: 'false' }); + assert.propertyVal(options, 'color', false); + })); }); describe('configuration.applyConfiguration()', () => { diff --git a/test/unit/dredd-test.js b/test/unit/dredd-test.js index c435c0a34..fc627fb4c 100644 --- a/test/unit/dredd-test.js +++ b/test/unit/dredd-test.js @@ -1,13 +1,13 @@ const bodyParser = require('body-parser'); const express = require('express'); const fsStub = require('fs'); -const loggerStub = require('../../src/logger'); const proxyquire = require('proxyquire').noCallThru(); const requestStub = require('request'); const sinon = require('sinon'); const { assert } = require('chai'); const dreddTransactionsStub = require('dredd-transactions'); +const loggerStub = require('../../src/logger'); const Dredd = proxyquire('../../src/dredd', { request: requestStub, @@ -128,51 +128,41 @@ describe('Dredd class', () => { dredd = new Dredd(configuration); }); - beforeEach(() => - sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback()) - ); + beforeEach(() => sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback())); afterEach(() => dredd.runner.executeTransaction.restore()); - it('should expand all glob patterns and resolved paths should be unique', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.equal(dredd.configuration.files.length, 3); - assert.include(dredd.configuration.files, './test/fixtures/multifile/message.apib'); - done(); - }) - ); - - it('should remove globs from config', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.notInclude(dredd.configuration.files, './test/fixtures/multifile/*.apib'); - done(); - }) - ); - - it('should load file contents on paths to config', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.isObject(dredd.configuration.data); - assert.property(dredd.configuration.data, './test/fixtures/multifile/greeting.apib'); - assert.isObject(dredd.configuration.data['./test/fixtures/multifile/greeting.apib']); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'filename'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'raw'); - done(); - }) - ); + it('should expand all glob patterns and resolved paths should be unique', done => dredd.run((error) => { + if (error) { return done(error); } + assert.equal(dredd.configuration.files.length, 3); + assert.include(dredd.configuration.files, './test/fixtures/multifile/message.apib'); + done(); + })); - it('should parse loaded files', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.isObject(dredd.configuration.data['./test/fixtures/multifile/greeting.apib']); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'annotations'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'filename'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'raw'); - done(); - }) - ); + it('should remove globs from config', done => dredd.run((error) => { + if (error) { return done(error); } + assert.notInclude(dredd.configuration.files, './test/fixtures/multifile/*.apib'); + done(); + })); + + it('should load file contents on paths to config', done => dredd.run((error) => { + if (error) { return done(error); } + assert.isObject(dredd.configuration.data); + assert.property(dredd.configuration.data, './test/fixtures/multifile/greeting.apib'); + assert.isObject(dredd.configuration.data['./test/fixtures/multifile/greeting.apib']); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'filename'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'raw'); + done(); + })); + + it('should parse loaded files', done => dredd.run((error) => { + if (error) { return done(error); } + assert.isObject(dredd.configuration.data['./test/fixtures/multifile/greeting.apib']); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'annotations'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'filename'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'raw'); + done(); + })); }); @@ -188,18 +178,14 @@ describe('Dredd class', () => { dredd = new Dredd(configuration); }); - beforeEach(() => - sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback()) - ); + beforeEach(() => sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback())); afterEach(() => dredd.runner.executeTransaction.restore()); - it('should return error', done => - dredd.run((error) => { - assert.isOk(error); - done(); - }) - ); + it('should return error', done => dredd.run((error) => { + assert.isOk(error); + done(); + })); }); @@ -215,18 +201,14 @@ describe('Dredd class', () => { dredd = new Dredd(configuration); }); - beforeEach(() => - sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback()) - ); + beforeEach(() => sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback())); afterEach(() => dredd.runner.executeTransaction.restore()); - it('should return error', done => - dredd.run((error) => { - assert.isOk(error); - done(); - }) - ); + it('should return error', done => dredd.run((error) => { + assert.isOk(error); + done(); + })); }); @@ -265,35 +247,29 @@ GET /url afterEach(() => dredd.runner.executeTransaction.restore()); - it('should not expand any glob patterns', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.lengthOf(dredd.configuration.files, 0); - done(); - }) - ); - - it('should pass data contents to config', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.isObject(dredd.configuration.data); - assert.notNestedProperty(dredd, 'configuration.data.testingDirectObject'); - assert.nestedPropertyVal(dredd, 'configuration.data.testingDirectObjectFilename.filename', 'testingDirectObjectFilename'); - assert.nestedProperty(dredd, 'configuration.data.testingDirectObjectFilename.raw'); - assert.nestedPropertyVal(dredd, 'configuration.data.testingDirectBlueprintString.filename', 'testingDirectBlueprintString'); - assert.nestedProperty(dredd, 'configuration.data.testingDirectBlueprintString.raw'); - done(); - }) - ); + it('should not expand any glob patterns', done => dredd.run((error) => { + if (error) { return done(error); } + assert.lengthOf(dredd.configuration.files, 0); + done(); + })); + + it('should pass data contents to config', done => dredd.run((error) => { + if (error) { return done(error); } + assert.isObject(dredd.configuration.data); + assert.notNestedProperty(dredd, 'configuration.data.testingDirectObject'); + assert.nestedPropertyVal(dredd, 'configuration.data.testingDirectObjectFilename.filename', 'testingDirectObjectFilename'); + assert.nestedProperty(dredd, 'configuration.data.testingDirectObjectFilename.raw'); + assert.nestedPropertyVal(dredd, 'configuration.data.testingDirectBlueprintString.filename', 'testingDirectBlueprintString'); + assert.nestedProperty(dredd, 'configuration.data.testingDirectBlueprintString.raw'); + done(); + })); - it('should parse passed data contents', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.nestedProperty(dredd, 'configuration.data.testingDirectObjectFilename.annotations'); - assert.nestedProperty(dredd, 'configuration.data.testingDirectBlueprintString.annotations'); - done(); - }) - ); + it('should parse passed data contents', done => dredd.run((error) => { + if (error) { return done(error); } + assert.nestedProperty(dredd, 'configuration.data.testingDirectObjectFilename.annotations'); + assert.nestedProperty(dredd, 'configuration.data.testingDirectBlueprintString.annotations'); + done(); + })); describe('and I also set configuration.options.path to an existing file', () => { let localdredd; @@ -306,25 +282,23 @@ GET /url afterEach(() => localdredd.runner.executeTransaction.restore()); - it('should fill configuration data with data and one file at that path', done => - localdredd.run((error) => { - if (error) { return done(error); } - assert.lengthOf(localdredd.configuration.files, 1); - assert.isObject(localdredd.configuration.data); - assert.lengthOf(Object.keys(localdredd.configuration.data), 3); - assert.property(localdredd.configuration.data, './test/fixtures/apiary.apib'); - assert.propertyVal(localdredd.configuration.data['./test/fixtures/apiary.apib'], 'filename', './test/fixtures/apiary.apib'); - assert.property(localdredd.configuration.data['./test/fixtures/apiary.apib'], 'raw'); - assert.property(localdredd.configuration.data['./test/fixtures/apiary.apib'], 'annotations'); - assert.nestedPropertyVal(localdredd, 'configuration.data.testingDirectObjectFilename.filename', 'testingDirectObjectFilename'); - assert.nestedProperty(localdredd, 'configuration.data.testingDirectObjectFilename.raw'); - assert.nestedProperty(localdredd, 'configuration.data.testingDirectObjectFilename.annotations'); - assert.nestedPropertyVal(localdredd, 'configuration.data.testingDirectBlueprintString.filename', 'testingDirectBlueprintString'); - assert.nestedProperty(localdredd, 'configuration.data.testingDirectBlueprintString.raw'); - assert.nestedProperty(localdredd, 'configuration.data.testingDirectBlueprintString.annotations'); - done(); - }) - ); + it('should fill configuration data with data and one file at that path', done => localdredd.run((error) => { + if (error) { return done(error); } + assert.lengthOf(localdredd.configuration.files, 1); + assert.isObject(localdredd.configuration.data); + assert.lengthOf(Object.keys(localdredd.configuration.data), 3); + assert.property(localdredd.configuration.data, './test/fixtures/apiary.apib'); + assert.propertyVal(localdredd.configuration.data['./test/fixtures/apiary.apib'], 'filename', './test/fixtures/apiary.apib'); + assert.property(localdredd.configuration.data['./test/fixtures/apiary.apib'], 'raw'); + assert.property(localdredd.configuration.data['./test/fixtures/apiary.apib'], 'annotations'); + assert.nestedPropertyVal(localdredd, 'configuration.data.testingDirectObjectFilename.filename', 'testingDirectObjectFilename'); + assert.nestedProperty(localdredd, 'configuration.data.testingDirectObjectFilename.raw'); + assert.nestedProperty(localdredd, 'configuration.data.testingDirectObjectFilename.annotations'); + assert.nestedPropertyVal(localdredd, 'configuration.data.testingDirectBlueprintString.filename', 'testingDirectBlueprintString'); + assert.nestedProperty(localdredd, 'configuration.data.testingDirectBlueprintString.raw'); + assert.nestedProperty(localdredd, 'configuration.data.testingDirectBlueprintString.annotations'); + done(); + })); }); }); @@ -346,139 +320,118 @@ GET /url }); }); - beforeEach(() => - sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback()) - ); + beforeEach(() => sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback())); afterEach(() => dredd.runner.executeTransaction.restore()); describe('when all URLs can be downloaded', () => { before(() => // eslint-disable-next-line - sinon.stub(requestStub, 'get').callsFake((receivedArgs = {}, cb) => cb(null, { statusCode: 200 }, blueprintCode)) - ); + sinon.stub(requestStub, 'get').callsFake((receivedArgs = {}, cb) => cb(null, { statusCode: 200 }, blueprintCode))); after(() => requestStub.get.restore()); - it('should expand glob pattern and resolved paths should be unique', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.lengthOf(dredd.configuration.files, 5); - assert.sameMembers(dredd.configuration.files, [ - 'http://some.path.to/file.apib', - 'https://another.path.to/apiary.apib', - './test/fixtures/multifile/message.apib', - './test/fixtures/multifile/greeting.apib', - './test/fixtures/multifile/name.apib' - ]); - done(); - }) - ); - - it('should remove globs from config', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.notInclude(dredd.configuration.files, './test/fixtures/multifile/*.apib'); - done(); - }) - ); - - it('should load file contents on paths to config and parse these files', done => - dredd.run((error) => { - if (error) { return done(error); } - assert.isObject(dredd.configuration.data); - assert.property(dredd.configuration.data, './test/fixtures/multifile/greeting.apib'); - assert.property(dredd.configuration.data, 'http://some.path.to/file.apib'); - assert.property(dredd.configuration.data, 'https://another.path.to/apiary.apib'); - - assert.isObject(dredd.configuration.data['./test/fixtures/multifile/name.apib']); - assert.property(dredd.configuration.data['./test/fixtures/multifile/name.apib'], 'filename'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/name.apib'], 'raw'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/name.apib'], 'annotations'); - - assert.isObject(dredd.configuration.data['./test/fixtures/multifile/message.apib']); - assert.property(dredd.configuration.data['./test/fixtures/multifile/message.apib'], 'filename'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/message.apib'], 'raw'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/message.apib'], 'annotations'); - - assert.isObject(dredd.configuration.data['./test/fixtures/multifile/greeting.apib']); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'filename'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'raw'); - assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'annotations'); - - assert.isObject(dredd.configuration.data['http://some.path.to/file.apib']); - assert.property(dredd.configuration.data['http://some.path.to/file.apib'], 'filename'); - assert.property(dredd.configuration.data['http://some.path.to/file.apib'], 'raw'); - assert.property(dredd.configuration.data['http://some.path.to/file.apib'], 'annotations'); - - assert.isObject(dredd.configuration.data['https://another.path.to/apiary.apib']); - assert.property(dredd.configuration.data['https://another.path.to/apiary.apib'], 'filename'); - assert.property(dredd.configuration.data['https://another.path.to/apiary.apib'], 'raw'); - assert.property(dredd.configuration.data['https://another.path.to/apiary.apib'], 'annotations'); - done(); - }) - ); + it('should expand glob pattern and resolved paths should be unique', done => dredd.run((error) => { + if (error) { return done(error); } + assert.lengthOf(dredd.configuration.files, 5); + assert.sameMembers(dredd.configuration.files, [ + 'http://some.path.to/file.apib', + 'https://another.path.to/apiary.apib', + './test/fixtures/multifile/message.apib', + './test/fixtures/multifile/greeting.apib', + './test/fixtures/multifile/name.apib' + ]); + done(); + })); + + it('should remove globs from config', done => dredd.run((error) => { + if (error) { return done(error); } + assert.notInclude(dredd.configuration.files, './test/fixtures/multifile/*.apib'); + done(); + })); + + it('should load file contents on paths to config and parse these files', done => dredd.run((error) => { + if (error) { return done(error); } + assert.isObject(dredd.configuration.data); + assert.property(dredd.configuration.data, './test/fixtures/multifile/greeting.apib'); + assert.property(dredd.configuration.data, 'http://some.path.to/file.apib'); + assert.property(dredd.configuration.data, 'https://another.path.to/apiary.apib'); + + assert.isObject(dredd.configuration.data['./test/fixtures/multifile/name.apib']); + assert.property(dredd.configuration.data['./test/fixtures/multifile/name.apib'], 'filename'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/name.apib'], 'raw'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/name.apib'], 'annotations'); + + assert.isObject(dredd.configuration.data['./test/fixtures/multifile/message.apib']); + assert.property(dredd.configuration.data['./test/fixtures/multifile/message.apib'], 'filename'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/message.apib'], 'raw'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/message.apib'], 'annotations'); + + assert.isObject(dredd.configuration.data['./test/fixtures/multifile/greeting.apib']); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'filename'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'raw'); + assert.property(dredd.configuration.data['./test/fixtures/multifile/greeting.apib'], 'annotations'); + + assert.isObject(dredd.configuration.data['http://some.path.to/file.apib']); + assert.property(dredd.configuration.data['http://some.path.to/file.apib'], 'filename'); + assert.property(dredd.configuration.data['http://some.path.to/file.apib'], 'raw'); + assert.property(dredd.configuration.data['http://some.path.to/file.apib'], 'annotations'); + + assert.isObject(dredd.configuration.data['https://another.path.to/apiary.apib']); + assert.property(dredd.configuration.data['https://another.path.to/apiary.apib'], 'filename'); + assert.property(dredd.configuration.data['https://another.path.to/apiary.apib'], 'raw'); + assert.property(dredd.configuration.data['https://another.path.to/apiary.apib'], 'annotations'); + done(); + })); }); describe('when an URL for one API description document returns 404 not-found', () => { - before(() => - sinon.stub(requestStub, 'get').callsFake((receivedArgs = {}, cb) => { - if ((receivedArgs ? receivedArgs.url : undefined) === 'https://another.path.to/apiary.apib') { - return cb(null, { statusCode: 404 }, 'Page Not Found'); - } - cb(null, { statusCode: 200 }, blueprintCode); - }) - ); + before(() => sinon.stub(requestStub, 'get').callsFake((receivedArgs = {}, cb) => { + if ((receivedArgs ? receivedArgs.url : undefined) === 'https://another.path.to/apiary.apib') { + return cb(null, { statusCode: 404 }, 'Page Not Found'); + } + cb(null, { statusCode: 200 }, blueprintCode); + })); after(() => requestStub.get.restore()); - it('should exit with an error', done => - dredd.run((error) => { - assert.isOk(error); - assert.instanceOf(error, Error); - assert.property(error, 'message'); - assert.include(error.message, 'Unable to load file from URL'); - done(); - }) - ); - - it('should not execute any transaction', done => - dredd.run(() => { - assert.notOk(dredd.runner.executeTransaction.called); - done(); - }) - ); + it('should exit with an error', done => dredd.run((error) => { + assert.isOk(error); + assert.instanceOf(error, Error); + assert.property(error, 'message'); + assert.include(error.message, 'Unable to load file from URL'); + done(); + })); + + it('should not execute any transaction', done => dredd.run(() => { + assert.notOk(dredd.runner.executeTransaction.called); + done(); + })); }); describe('when an URL for one API description document is unreachable (erroneous)', () => { - before(() => - sinon.stub(requestStub, 'get').callsFake((receivedArgs = {}, cb) => { - if ((receivedArgs ? receivedArgs.url : undefined) === 'http://some.path.to/file.apib') { - // Server not found on - return cb({ code: 'ENOTFOUND' }); - } - cb(null, { statusCode: 200 }, blueprintCode); - }) - ); + before(() => sinon.stub(requestStub, 'get').callsFake((receivedArgs = {}, cb) => { + if ((receivedArgs ? receivedArgs.url : undefined) === 'http://some.path.to/file.apib') { + // Server not found on + return cb({ code: 'ENOTFOUND' }); + } + cb(null, { statusCode: 200 }, blueprintCode); + })); after(() => requestStub.get.restore()); - it('should exit with an error', done => - dredd.run((error) => { - assert.isOk(error); - assert.instanceOf(error, Error); - assert.property(error, 'message'); - assert.include(error.message, 'Error when loading file from URL'); - done(); - }) - ); - - it('should not execute any transaction', done => - dredd.run(() => { - assert.notOk(dredd.runner.executeTransaction.called); - done(); - }) - ); + it('should exit with an error', done => dredd.run((error) => { + assert.isOk(error); + assert.instanceOf(error, Error); + assert.property(error, 'message'); + assert.include(error.message, 'Error when loading file from URL'); + done(); + })); + + it('should not execute any transaction', done => dredd.run(() => { + assert.notOk(dredd.runner.executeTransaction.called); + done(); + })); }); }); }); @@ -495,25 +448,19 @@ GET /url dredd = new Dredd(configuration); }); - beforeEach(() => - sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback()) - ); + beforeEach(() => sinon.stub(dredd.runner, 'executeTransaction').callsFake((transaction, hooks, callback) => callback())); afterEach(() => dredd.runner.executeTransaction.restore()); - it('should exit with an error', done => - dredd.run((error) => { - assert.isOk(error); - done(); - }) - ); + it('should exit with an error', done => dredd.run((error) => { + assert.isOk(error); + done(); + })); - it('should NOT execute any transaction', done => - dredd.run(() => { - assert.notOk(dredd.runner.executeTransaction.called); - done(); - }) - ); + it('should NOT execute any transaction', done => dredd.run(() => { + assert.notOk(dredd.runner.executeTransaction.called); + done(); + })); }); describe('when API description document parsing warning', () => { @@ -538,19 +485,15 @@ GET /url loggerStub.warn.restore(); }); - it('should execute the runtime', done => - dredd.run(() => { - assert.isOk(dredd.runner.run.called); - done(); - }) - ); + it('should execute the runtime', done => dredd.run(() => { + assert.isOk(dredd.runner.run.called); + done(); + })); - it('should write warnings to warn logger', done => - dredd.run(() => { - assert.isOk(loggerStub.warn.called); - done(); - }) - ); + it('should write warnings to warn logger', done => dredd.run(() => { + assert.isOk(loggerStub.warn.called); + done(); + })); }); describe('when non existing API description document path', () => { @@ -568,19 +511,15 @@ GET /url afterEach(() => dredd.runner.executeTransaction.resetHistory()); - it('should pass the error to the callback function', done => - dredd.run((error) => { - assert.isOk(error); - done(); - }) - ); + it('should pass the error to the callback function', done => dredd.run((error) => { + assert.isOk(error); + done(); + })); - it('should NOT execute any transaction', done => - dredd.run(() => { - assert.notOk(dredd.runner.executeTransaction.called); - done(); - }) - ); + it('should NOT execute any transaction', done => dredd.run(() => { + assert.notOk(dredd.runner.executeTransaction.called); + done(); + })); }); describe('when runtime contains any error', () => { @@ -599,19 +538,15 @@ GET /url afterEach(() => dredd.runner.executeTransaction.resetHistory()); - it('should NOT execute any transaction', done => - dredd.run(() => { - assert.notOk(dredd.runner.executeTransaction.called); - done(); - }) - ); + it('should NOT execute any transaction', done => dredd.run(() => { + assert.notOk(dredd.runner.executeTransaction.called); + done(); + })); - it('should exit with an error', done => - dredd.run((error) => { - assert.isOk(error); - done(); - }) - ); + it('should exit with an error', done => dredd.run((error) => { + assert.isOk(error); + done(); + })); }); describe('when runtime contains any warning', () => { @@ -633,26 +568,20 @@ GET /url loggerStub.warn.restore(); }); - it('should execute some transaction', done => - dredd.run(() => { - assert.isOk(dredd.runner.executeTransaction.called); - done(); - }) - ); + it('should execute some transaction', done => dredd.run(() => { + assert.isOk(dredd.runner.executeTransaction.called); + done(); + })); - it('should print runtime warnings to stdout', done => - dredd.run(() => { - assert.isOk(loggerStub.warn.called); - done(); - }) - ); + it('should print runtime warnings to stdout', done => dredd.run(() => { + assert.isOk(loggerStub.warn.called); + done(); + })); - it('should not exit', done => - dredd.run((error) => { - assert.notOk(error); - done(); - }) - ); + it('should not exit', done => dredd.run((error) => { + assert.notOk(error); + done(); + })); }); describe('when runtime is without errors and warnings', () => { @@ -670,12 +599,10 @@ GET /url afterEach(() => dredd.runner.executeTransaction.resetHistory()); - it('should execute the runtime', done => - dredd.run(() => { - assert.isOk(dredd.runner.executeTransaction.called); - done(); - }) - ); + it('should execute the runtime', done => dredd.run(() => { + assert.isOk(dredd.runner.executeTransaction.called); + done(); + })); }); describe('#emitStart', () => { @@ -705,22 +632,18 @@ GET /url const apiary = express(); apiary.use(bodyParser.json({ size: '5mb' })); - apiary.post('/apis/*', (req, res) => - res.status(201).json({ - _id: '1234_id', - testRunId: '6789_testRunId', - reportUrl: 'http://url.me/test/run/1234_id' - }) - ); + apiary.post('/apis/*', (req, res) => res.status(201).json({ + _id: '1234_id', + testRunId: '6789_testRunId', + reportUrl: 'http://url.me/test/run/1234_id' + })); apiary.all('*', (req, res) => res.json({})); apiaryServer = apiary.listen((PORT + 1), () => done()); }); - afterEach(done => - apiaryServer.close(() => done()) - ); + afterEach(done => apiaryServer.close(() => done())); it('should call the callback', (done) => { @@ -770,12 +693,10 @@ GET /url dredd.emitStart(callback); }); - it('should print the error', done => - dredd.emitStart(() => { - assert.isTrue(errorLogger.called); - done(); - }) - ); + it('should print the error', done => dredd.emitStart(() => { + assert.isTrue(errorLogger.called); + done(); + })); }); }); @@ -792,11 +713,10 @@ GET /url }); afterEach(() => delete process.env.http_proxy); - it('logs about the setting', () => - assert.include(verboseLogger.lastCall.args[0], - 'HTTP(S) proxy specified by environment variables: http_proxy=http://proxy.example.com' - ) - ); + it('logs about the setting', () => assert.include( + verboseLogger.lastCall.args[0], + 'HTTP(S) proxy specified by environment variables: http_proxy=http://proxy.example.com' + )); }); describe('when the proxy is set by uppercase environment variable', () => { @@ -806,12 +726,11 @@ GET /url }); afterEach(() => delete process.env.HTTPS_PROXY); - it('logs about the setting', () => - assert.include(verboseLogger.lastCall.args[0], - 'HTTP(S) proxy specified by environment variables: ' + - 'HTTPS_PROXY=http://proxy.example.com' - ) - ); + it('logs about the setting', () => assert.include( + verboseLogger.lastCall.args[0], + 'HTTP(S) proxy specified by environment variables: ' + + 'HTTPS_PROXY=http://proxy.example.com' + )); }); describe('when NO_PROXY environment variable is set', () => { @@ -825,13 +744,12 @@ GET /url delete process.env.NO_PROXY; }); - it('logs about the setting', () => - assert.include(verboseLogger.lastCall.args[0], - 'HTTP(S) proxy specified by environment variables: ' + - 'HTTPS_PROXY=http://proxy.example.com, ' + - 'NO_PROXY=whitelisted.example.com' - ) - ); + it('logs about the setting', () => assert.include( + verboseLogger.lastCall.args[0], + 'HTTP(S) proxy specified by environment variables: ' + + 'HTTPS_PROXY=http://proxy.example.com, ' + + 'NO_PROXY=whitelisted.example.com' + )); }); describe('when DUMMY_PROXY environment variable is set', () => { @@ -845,12 +763,11 @@ GET /url delete process.env.NO_PROXY; }); - it('is ignored', () => - assert.include(verboseLogger.lastCall.args[0], - 'HTTP(S) proxy specified by environment variables: ' + - 'NO_PROXY=whitelisted.example.com' - ) - ); + it('is ignored', () => assert.include( + verboseLogger.lastCall.args[0], + 'HTTP(S) proxy specified by environment variables: ' + + 'NO_PROXY=whitelisted.example.com' + )); }); }); }); diff --git a/test/unit/handle-runtime-problems-test.js b/test/unit/handle-runtime-problems-test.js index 8c314e486..9148d0c55 100644 --- a/test/unit/handle-runtime-problems-test.js +++ b/test/unit/handle-runtime-problems-test.js @@ -6,7 +6,8 @@ const dreddTransactions = require('dredd-transactions'); const logger = require('../../src/logger'); -const handleRuntimeProblems = proxyquire('../../src/handle-runtime-problems', +const handleRuntimeProblems = proxyquire( + '../../src/handle-runtime-problems', { './logger': logger } ); @@ -48,13 +49,11 @@ FORMAT: 1A `; const filename = 'dummy-filename.apib'; - beforeEach(done => - prepareData(apiDescriptionDocument, filename, (err, data) => { - if (err) { return done(err); } - error = handleRuntimeProblems(data); - done(); - }) - ); + beforeEach(done => prepareData(apiDescriptionDocument, filename, (err, data) => { + if (err) { return done(err); } + error = handleRuntimeProblems(data); + done(); + })); it('returns error', () => assert.isOk(error)); it('has no warning output', () => assert.equal(warnOutput, '')); @@ -80,13 +79,11 @@ FORMAT: 1A `; const filename = 'dummy-filename.apib'; - beforeEach(done => - prepareData(apiDescriptionDocument, filename, (err, data) => { - if (err) { return done(err); } - error = handleRuntimeProblems(data); - done(); - }) - ); + beforeEach(done => prepareData(apiDescriptionDocument, filename, (err, data) => { + if (err) { return done(err); } + error = handleRuntimeProblems(data); + done(); + })); it('returns no error', () => assert.notOk(error)); it('has no error output', () => assert.equal(errorOutput, '')); @@ -109,13 +106,11 @@ So Long, and Thanks for All the Fish!\ `; const filename = 'dummy-filename.apib'; - beforeEach(done => - prepareData(apiDescriptionDocument, filename, (err, data) => { - if (err) { return done(err); } - error = handleRuntimeProblems(data); - done(); - }) - ); + beforeEach(done => prepareData(apiDescriptionDocument, filename, (err, data) => { + if (err) { return done(err); } + error = handleRuntimeProblems(data); + done(); + })); it('returns no error', () => assert.notOk(error)); it('has no error output', () => assert.equal(errorOutput, '')); diff --git a/test/unit/hooks-test.js b/test/unit/hooks-test.js index 20b294c64..e2e69a1bb 100644 --- a/test/unit/hooks-test.js +++ b/test/unit/hooks-test.js @@ -184,15 +184,13 @@ describe('Hooks', () => { assert.isArray(object[property]); }); - describe(`all array members under property '${property}'`, () => - it('should be a string', () => { - const object = hooks.dumpHooksFunctionsToStrings(); - Object.keys(object[property]).forEach((key) => { - const value = object[property][key]; - assert.isString(value, `on ${property}['${key}']`); - }); - }) - ); + describe(`all array members under property '${property}'`, () => it('should be a string', () => { + const object = hooks.dumpHooksFunctionsToStrings(); + Object.keys(object[property]).forEach((key) => { + const value = object[property][key]; + assert.isString(value, `on ${property}['${key}']`); + }); + })); }); properties = [ diff --git a/test/unit/hooks-worker-client-test.js b/test/unit/hooks-worker-client-test.js index c0cc79a67..a66ecbde8 100644 --- a/test/unit/hooks-worker-client-test.js +++ b/test/unit/hooks-worker-client-test.js @@ -51,15 +51,14 @@ describe('Hooks worker client', () => { runner.hooks = new Hooks({ logs: [], logger: console }); runner.hooks.configuration = { options: {} }; - Array.from(logLevels).forEach(level => - sinon.stub(loggerStub, level).callsFake((msg1, msg2) => { - let text = msg1; - if (msg2) { text += ` ${msg2}`; } - - // Uncomment to enable logging for debug - // console.log text - logs.push(text); - })); + Array.from(logLevels).forEach(level => sinon.stub(loggerStub, level).callsFake((msg1, msg2) => { + let text = msg1; + if (msg2) { text += ` ${msg2}`; } + + // Uncomment to enable logging for debug + // console.log text + logs.push(text); + })); }); afterEach(() => { @@ -123,8 +122,8 @@ describe('Hooks worker client', () => { }); }); - it('should not set the error on worker if process gets intentionally killed by Dredd ' + - 'because it can be killed after all hooks execution if SIGTERM isn\'t handled', (done) => { + it('should not set the error on worker if process gets intentionally killed by Dredd ' + + 'because it can be killed after all hooks execution if SIGTERM isn\'t handled', (done) => { runner.hooks.configuration.options.language = `${COFFEE_BIN} test/fixtures/scripts/endless-ignore-term.coffee`; loadWorkerClient((workerError) => { if (workerError) { return done(workerError); } @@ -133,13 +132,14 @@ describe('Hooks worker client', () => { // finishes, so we need to manually stop it. However, it could happen // we'll stop it before it actually manages to do what we test here, so // we add some timeout here. - setTimeout(() => - hooksWorkerClient.stop((stopError) => { + setTimeout( + () => hooksWorkerClient.stop((stopError) => { if (stopError) { return done(stopError); } assert.isNull(runner.hookHandlerError); done(); - }) - , MIN_COMMAND_EXECUTION_DURATION_MS); + }), + MIN_COMMAND_EXECUTION_DURATION_MS + ); }); }); @@ -152,14 +152,15 @@ describe('Hooks worker client', () => { // finishes, so we need to manually stop it. However, it could happen // we'll stop it before it actually manages to do what we test here, so // we add some timeout here. - setTimeout(() => - hooksWorkerClient.stop((stopError) => { + setTimeout( + () => hooksWorkerClient.stop((stopError) => { if (stopError) { return done(stopError); } assert.isOk(runner.hookHandlerError); assert.include(runner.hookHandlerError.message, '3'); done(); - }) - , MIN_COMMAND_EXECUTION_DURATION_MS); + }), + MIN_COMMAND_EXECUTION_DURATION_MS + ); }); }); @@ -172,13 +173,11 @@ describe('Hooks worker client', () => { }; }); - it('should write a hint that native hooks should be used', done => - loadWorkerClient((err) => { - assert.isOk(err); - assert.include(err.message, 'native Node.js hooks instead'); - done(); - }) - ); + it('should write a hint that native hooks should be used', done => loadWorkerClient((err) => { + assert.isOk(err); + assert.include(err.message, 'native Node.js hooks instead'); + done(); + })); }); describe('when --language=ruby option is given and the worker is installed', () => { @@ -210,30 +209,26 @@ describe('Hooks worker client', () => { HooksWorkerClient.prototype.terminateHandler.restore(); }); - it('should spawn the server process with command "dredd-hooks-ruby"', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should spawn the server process with command "dredd-hooks-ruby"', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.isTrue(crossSpawnStub.spawn.called); - assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-ruby'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.isTrue(crossSpawnStub.spawn.called); + assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-ruby'); + done(); + }); + })); - it('should pass --hookfiles option as an array of arguments', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should pass --hookfiles option as an array of arguments', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.rb'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.rb'); + done(); + }); + })); }); describe('when --language=ruby option is given and the worker is not installed', () => { @@ -251,13 +246,11 @@ describe('Hooks worker client', () => { afterEach(() => whichStub.which.restore()); - it('should write a hint how to install', done => - loadWorkerClient((err) => { - assert.isOk(err); - assert.include(err.message, 'gem install dredd_hooks'); - done(); - }) - ); + it('should write a hint how to install', done => loadWorkerClient((err) => { + assert.isOk(err); + assert.include(err.message, 'gem install dredd_hooks'); + done(); + })); }); describe('when --language=python option is given and the worker is installed', () => { @@ -289,30 +282,26 @@ describe('Hooks worker client', () => { HooksWorkerClient.prototype.terminateHandler.restore(); }); - it('should spawn the server process with command "dredd-hooks-python"', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should spawn the server process with command "dredd-hooks-python"', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.isTrue(crossSpawnStub.spawn.called); - assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-python'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.isTrue(crossSpawnStub.spawn.called); + assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-python'); + done(); + }); + })); - it('should pass --hookfiles option as an array of arguments', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should pass --hookfiles option as an array of arguments', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.py'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.py'); + done(); + }); + })); }); describe('when --language=python option is given and the worker is not installed', () => { @@ -329,13 +318,11 @@ describe('Hooks worker client', () => { afterEach(() => whichStub.which.restore()); - it('should write a hint how to install', done => - loadWorkerClient((err) => { - assert.isOk(err); - assert.include(err.message, 'pip install dredd_hooks'); - done(); - }) - ); + it('should write a hint how to install', done => loadWorkerClient((err) => { + assert.isOk(err); + assert.include(err.message, 'pip install dredd_hooks'); + done(); + })); }); describe('when --language=php option is given and the worker is installed', () => { @@ -367,30 +354,26 @@ describe('Hooks worker client', () => { HooksWorkerClient.prototype.terminateHandler.restore(); }); - it('should spawn the server process with command "dredd-hooks-php"', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should spawn the server process with command "dredd-hooks-php"', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.isTrue(crossSpawnStub.spawn.called); - assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-php'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.isTrue(crossSpawnStub.spawn.called); + assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-php'); + done(); + }); + })); - it('should pass --hookfiles option as an array of arguments', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should pass --hookfiles option as an array of arguments', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.py'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.py'); + done(); + }); + })); }); describe('when --language=php option is given and the worker is not installed', () => { @@ -407,13 +390,11 @@ describe('Hooks worker client', () => { afterEach(() => whichStub.which.restore()); - it('should write a hint how to install', done => - loadWorkerClient((err) => { - assert.isOk(err); - assert.include(err.message, 'composer require ddelnano/dredd-hooks-php --dev'); - done(); - }) - ); + it('should write a hint how to install', done => loadWorkerClient((err) => { + assert.isOk(err); + assert.include(err.message, 'composer require ddelnano/dredd-hooks-php --dev'); + done(); + })); }); describe('when --language=go option is given and the worker is not installed', () => { @@ -440,13 +421,11 @@ describe('Hooks worker client', () => { process.env.GOPATH = goPath; }); - it('should write a hint how to install', done => - loadWorkerClient((err) => { - assert.isOk(err); - assert.include(err.message, 'go get github.com/snikch/goodman/cmd/goodman'); - done(); - }) - ); + it('should write a hint how to install', done => loadWorkerClient((err) => { + assert.isOk(err); + assert.include(err.message, 'go get github.com/snikch/goodman/cmd/goodman'); + done(); + })); }); describe('when --language=go option is given and the worker is installed', () => { @@ -489,30 +468,26 @@ describe('Hooks worker client', () => { process.env.GOPATH = goPath; }); - it('should spawn the server process with command "$GOBIN/goodman"', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should spawn the server process with command "$GOBIN/goodman"', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.isTrue(crossSpawnStub.spawn.called); - assert.equal(crossSpawnStub.spawn.getCall(0).args[0], path.join(dummyPath, 'goodman')); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.isTrue(crossSpawnStub.spawn.called); + assert.equal(crossSpawnStub.spawn.getCall(0).args[0], path.join(dummyPath, 'goodman')); + done(); + }); + })); - it('should pass --hookfiles option as an array of arguments', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should pass --hookfiles option as an array of arguments', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'gobinary'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'gobinary'); + done(); + }); + })); }); describe('when --language=rust option is given and the worker is not installed', () => { @@ -528,13 +503,11 @@ describe('Hooks worker client', () => { }); afterEach(() => whichStub.which.restore()); - it('should write a hint how to install', done => - loadWorkerClient((err) => { - assert.isOk(err); - assert.include(err.message, 'cargo install dredd-hooks'); - done(); - }) - ); + it('should write a hint how to install', done => loadWorkerClient((err) => { + assert.isOk(err); + assert.include(err.message, 'cargo install dredd-hooks'); + done(); + })); }); describe('when --language=rust option is given and the worker is installed', () => { @@ -566,30 +539,26 @@ describe('Hooks worker client', () => { HooksWorkerClient.prototype.terminateHandler.restore(); }); - it('should spawn the server process with command "dredd-hooks-rust"', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should spawn the server process with command "dredd-hooks-rust"', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.isTrue(crossSpawnStub.spawn.called); - assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-rust'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.isTrue(crossSpawnStub.spawn.called); + assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-rust'); + done(); + }); + })); - it('should pass --hookfiles option as an array of arguments', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should pass --hookfiles option as an array of arguments', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'rustbinary'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'rustbinary'); + done(); + }); + })); }); describe('when --language=perl option is given and the worker is installed', () => { @@ -621,30 +590,26 @@ describe('Hooks worker client', () => { HooksWorkerClient.prototype.terminateHandler.restore(); }); - it('should spawn the server process with command "dredd-hooks-perl"', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should spawn the server process with command "dredd-hooks-perl"', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.isTrue(crossSpawnStub.spawn.called); - assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-perl'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.isTrue(crossSpawnStub.spawn.called); + assert.equal(crossSpawnStub.spawn.getCall(0).args[0], 'dredd-hooks-perl'); + done(); + }); + })); - it('should pass --hookfiles option as an array of arguments', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should pass --hookfiles option as an array of arguments', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.py'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'somefile.py'); + done(); + }); + })); }); describe('when --language=perl option is given and the worker is not installed', () => { @@ -661,13 +626,11 @@ describe('Hooks worker client', () => { afterEach(() => whichStub.which.restore()); - it('should write a hint how to install', done => - loadWorkerClient((err) => { - assert.isOk(err); - assert.include(err.message, 'cpanm Dredd::Hooks'); - done(); - }) - ); + it('should write a hint how to install', done => loadWorkerClient((err) => { + assert.isOk(err); + assert.include(err.message, 'cpanm Dredd::Hooks'); + done(); + })); }); describe('when --language=./any/other-command is given', () => { @@ -699,30 +662,26 @@ describe('Hooks worker client', () => { whichStub.which.restore(); }); - it('should spawn the server process with command "./my-fancy-command"', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should spawn the server process with command "./my-fancy-command"', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.isTrue(crossSpawnStub.spawn.called); - assert.equal(crossSpawnStub.spawn.getCall(0).args[0], './my-fancy-command'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.isTrue(crossSpawnStub.spawn.called); + assert.equal(crossSpawnStub.spawn.getCall(0).args[0], './my-fancy-command'); + done(); + }); + })); - it('should pass --hookfiles option as an array of arguments', done => - loadWorkerClient((err) => { - assert.isUndefined(err); + it('should pass --hookfiles option as an array of arguments', done => loadWorkerClient((err) => { + assert.isUndefined(err); - hooksWorkerClient.stop((error) => { - assert.isUndefined(error); - assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'someotherfile'); - done(); - }); - }) - ); + hooksWorkerClient.stop((error) => { + assert.isUndefined(error); + assert.equal(crossSpawnStub.spawn.getCall(0).args[1][0], 'someotherfile'); + done(); + }); + })); }); describe('after loading', () => { @@ -901,7 +860,9 @@ describe('Hooks worker client', () => { describe('when hook handler server is running and modifying transactions', () => { let transaction = { name: 'API > Hello > World', - request: { method: 'POST', uri: '/message', headers: {}, body: 'Hello World!' } + request: { + method: 'POST', uri: '/message', headers: {}, body: 'Hello World!' + } }; return [ @@ -950,10 +911,7 @@ describe('Hooks worker client', () => { // once the hooks worker client finishes processing of data it // got back from the hook handler, it triggers this event - hooksWorkerClient.emitter.on(messageIn.uuid, () => - // -- 7 -- - done() - ); + hooksWorkerClient.emitter.on(messageIn.uuid, () => done()); // -- 5 --, modifying the transaction transaction = getFirstTransaction(messageIn.data); diff --git a/test/unit/init/detectApiDescription-test.js b/test/unit/init/detectApiDescription-test.js index a4cd0c296..9f967f182 100644 --- a/test/unit/init/detectApiDescription-test.js +++ b/test/unit/init/detectApiDescription-test.js @@ -4,60 +4,42 @@ const { _detectApiDescription: detectApiDescription } = require('../../../src/in describe('init._detectApiDescription()', () => { - it('defaults to API Blueprint on empty array', () => - assert.equal(detectApiDescription([]), 'apiary.apib') - ); - - it('defaults to API Blueprint on arbitrary files', () => - assert.equal(detectApiDescription(['foo', 'bar']), 'apiary.apib') - ); - - it('detects the first API Blueprint file', () => - assert.equal( - detectApiDescription(['foo', 'boo.apib', 'bar', 'moo.apib']), - 'boo.apib' - ) - ); - - it('detects the first .yml file containing \'swagger\' as OpenAPI', () => - assert.equal( - detectApiDescription(['foo', 'this-is-swagger.yml', 'bar']), - 'this-is-swagger.yml' - ) - ); - - it('detects the first .yaml file containing \'swagger\' as OpenAPI', () => - assert.equal( - detectApiDescription(['foo', 'this-is-swagger.yaml', 'bar']), - 'this-is-swagger.yaml' - ) - ); - - it('detects the first .yml file containing \'api\' as OpenAPI', () => - assert.equal( - detectApiDescription(['foo', 'openapi.yml', 'bar']), - 'openapi.yml' - ) - ); - - it('detects the first .yaml file containing \'api\' as OpenAPI', () => - assert.equal( - detectApiDescription(['foo', 'openapi.yaml', 'bar']), - 'openapi.yaml' - ) - ); - - it('prefers API Blueprint over OpenAPI', () => - assert.equal( - detectApiDescription(['swagger.yml', 'boo.apib']), - 'boo.apib' - ) - ); - - it('prefers \'swagger\' over \'api\'', () => - assert.equal( - detectApiDescription(['api.yml', 'swagger.yml']), - 'swagger.yml' - ) - ); + it('defaults to API Blueprint on empty array', () => assert.equal(detectApiDescription([]), 'apiary.apib')); + + it('defaults to API Blueprint on arbitrary files', () => assert.equal(detectApiDescription(['foo', 'bar']), 'apiary.apib')); + + it('detects the first API Blueprint file', () => assert.equal( + detectApiDescription(['foo', 'boo.apib', 'bar', 'moo.apib']), + 'boo.apib' + )); + + it('detects the first .yml file containing \'swagger\' as OpenAPI', () => assert.equal( + detectApiDescription(['foo', 'this-is-swagger.yml', 'bar']), + 'this-is-swagger.yml' + )); + + it('detects the first .yaml file containing \'swagger\' as OpenAPI', () => assert.equal( + detectApiDescription(['foo', 'this-is-swagger.yaml', 'bar']), + 'this-is-swagger.yaml' + )); + + it('detects the first .yml file containing \'api\' as OpenAPI', () => assert.equal( + detectApiDescription(['foo', 'openapi.yml', 'bar']), + 'openapi.yml' + )); + + it('detects the first .yaml file containing \'api\' as OpenAPI', () => assert.equal( + detectApiDescription(['foo', 'openapi.yaml', 'bar']), + 'openapi.yaml' + )); + + it('prefers API Blueprint over OpenAPI', () => assert.equal( + detectApiDescription(['swagger.yml', 'boo.apib']), + 'boo.apib' + )); + + it('prefers \'swagger\' over \'api\'', () => assert.equal( + detectApiDescription(['api.yml', 'swagger.yml']), + 'swagger.yml' + )); }); diff --git a/test/unit/init/detectCI-test.js b/test/unit/init/detectCI-test.js index d1a8097b3..1376e3626 100644 --- a/test/unit/init/detectCI-test.js +++ b/test/unit/init/detectCI-test.js @@ -4,30 +4,18 @@ const { _detectCI: detectCI } = require('../../../src/init'); describe('init._detectCI()', () => { - it('detects no CI on empty array', () => - assert.deepEqual(detectCI([]), []) - ); - - it('detects AppVeyor', () => - assert.deepEqual(detectCI(['README', 'appveyor.yml']), ['appveyor']) - ); - - it('detects CircleCI', () => - assert.deepEqual(detectCI(['README', '.circleci']), ['circleci']) - ); - - it('detects Travis CI', () => - assert.deepEqual(detectCI(['README', '.travis.yml']), ['travisci']) - ); - - it('detects Wercker', () => - assert.deepEqual(detectCI(['README', 'wercker.yml']), ['wercker']) - ); - - it('detects multiple CIs', () => - assert.deepEqual( - detectCI(['README', 'wercker.yml', '.circleci']), - ['wercker', 'circleci'] - ) - ); + it('detects no CI on empty array', () => assert.deepEqual(detectCI([]), [])); + + it('detects AppVeyor', () => assert.deepEqual(detectCI(['README', 'appveyor.yml']), ['appveyor'])); + + it('detects CircleCI', () => assert.deepEqual(detectCI(['README', '.circleci']), ['circleci'])); + + it('detects Travis CI', () => assert.deepEqual(detectCI(['README', '.travis.yml']), ['travisci'])); + + it('detects Wercker', () => assert.deepEqual(detectCI(['README', 'wercker.yml']), ['wercker'])); + + it('detects multiple CIs', () => assert.deepEqual( + detectCI(['README', 'wercker.yml', '.circleci']), + ['wercker', 'circleci'] + )); }); diff --git a/test/unit/init/detectLanguage-test.js b/test/unit/init/detectLanguage-test.js index 5e8e9913b..206000e6f 100644 --- a/test/unit/init/detectLanguage-test.js +++ b/test/unit/init/detectLanguage-test.js @@ -4,27 +4,17 @@ const { _detectLanguage: detectLanguage } = require('../../../src/init'); describe('init._detectLanguage()', () => { - it('defaults to JavaScript', () => - assert.equal(detectLanguage([]), 'nodejs') - ); + it('defaults to JavaScript', () => assert.equal(detectLanguage([]), 'nodejs')); [ { name: 'Rust', value: 'rust', file: 'Cargo.toml' }, { name: 'Go', value: 'go', file: 'foo.go' }, { name: 'PHP', value: 'php', file: 'composer.json' } ].forEach(({ name, value, file }) => { - it(`prioritizes ${name} over Python`, () => - assert.equal(detectLanguage(['README', 'Pipfile', file]), value) - ); - it(`prioritizes ${name} over Ruby`, () => - assert.equal(detectLanguage(['README', 'Gemfile', file]), value) - ); + it(`prioritizes ${name} over Python`, () => assert.equal(detectLanguage(['README', 'Pipfile', file]), value)); + it(`prioritizes ${name} over Ruby`, () => assert.equal(detectLanguage(['README', 'Gemfile', file]), value)); }); - it('detects Python', () => - assert.equal(detectLanguage(['README', 'Pipfile']), 'python') - ); - it('detects Ruby', () => - assert.equal(detectLanguage(['README', 'Gemfile']), 'ruby') - ); + it('detects Python', () => assert.equal(detectLanguage(['README', 'Pipfile']), 'python')); + it('detects Ruby', () => assert.equal(detectLanguage(['README', 'Gemfile']), 'ruby')); }); diff --git a/test/unit/init/detectServer-test.js b/test/unit/init/detectServer-test.js index d8b519a1e..b2a15fb91 100644 --- a/test/unit/init/detectServer-test.js +++ b/test/unit/init/detectServer-test.js @@ -4,21 +4,15 @@ const { _detectServer: detectServer } = require('../../../src/init'); describe('init._detectServer()', () => { - it('defaults to \'npm start\' script', () => - assert.equal(detectServer([]), 'npm start') - ); + it('defaults to \'npm start\' script', () => assert.equal(detectServer([]), 'npm start')); - it('assumes Python project means Django application', () => - assert.equal( - detectServer(['README', 'Pipfile']), - 'python manage.py runserver' - ) - ); + it('assumes Python project means Django application', () => assert.equal( + detectServer(['README', 'Pipfile']), + 'python manage.py runserver' + )); - it('assumes Ruby project means RoR application', () => - assert.equal( - detectServer(['README', 'Gemfile']), - 'bundle exec rails server' - ) - ); + it('assumes Ruby project means RoR application', () => assert.equal( + detectServer(['README', 'Gemfile']), + 'bundle exec rails server' + )); }); diff --git a/test/unit/init/updateWercker-test.js b/test/unit/init/updateWercker-test.js index 9938fa290..3b65ec72b 100644 --- a/test/unit/init/updateWercker-test.js +++ b/test/unit/init/updateWercker-test.js @@ -17,9 +17,13 @@ describe('init._updateWercker()', () => { }); it('adds commands to install and run Dredd', () => { - const contents = { build: { steps: [ - { script: { name: 'pipenv-install', code: 'pipenv install' } } - ] } }; + const contents = { + build: { + steps: [ + { script: { name: 'pipenv-install', code: 'pipenv install' } } + ] + } + }; updateWercker(createOptions(contents)); assert.equal(contents.build.steps.length, 3); diff --git a/test/unit/performRequest/createTransactionRes-test.js b/test/unit/performRequest/createTransactionRes-test.js index e5a637614..56cc599f8 100644 --- a/test/unit/performRequest/createTransactionRes-test.js +++ b/test/unit/performRequest/createTransactionRes-test.js @@ -8,12 +8,10 @@ const { describe('performRequest._createTransactionRes()', () => { const res = { statusCode: 200, headers: {} }; - it('sets the status code', () => - assert.deepEqual( - createTransactionRes(res), - { statusCode: 200, headers: {} } - ) - ); + it('sets the status code', () => assert.deepEqual( + createTransactionRes(res), + { statusCode: 200, headers: {} } + )); it('copies the headers', () => { const headers = { 'Content-Type': 'application/json' }; const transactionRes = createTransactionRes({ statusCode: 200, headers }); @@ -24,27 +22,23 @@ describe('performRequest._createTransactionRes()', () => { { statusCode: 200, headers: { 'Content-Type': 'application/json' } } ); }); - it('does not set empty body', () => - assert.deepEqual( - createTransactionRes(res, Buffer.from([])), - { statusCode: 200, headers: {} } - ) - ); - it('sets textual body as a string with UTF-8 encoding', () => - assert.deepEqual( - createTransactionRes(res, Buffer.from('řeřicha')), - { statusCode: 200, headers: {}, body: 'řeřicha', bodyEncoding: 'utf-8' } - ) - ); - it('sets binary body as a string with Base64 encoding', () => - assert.deepEqual( - createTransactionRes(res, Buffer.from([0xFF, 0xBE])), - { - statusCode: 200, - headers: {}, - body: Buffer.from([0xFF, 0xBE]).toString('base64'), - bodyEncoding: 'base64' - } - ) - ); + it('does not set empty body', () => assert.deepEqual( + createTransactionRes(res, Buffer.from([])), + { statusCode: 200, headers: {} } + )); + it('sets textual body as a string with UTF-8 encoding', () => assert.deepEqual( + createTransactionRes(res, Buffer.from('řeřicha')), + { + statusCode: 200, headers: {}, body: 'řeřicha', bodyEncoding: 'utf-8' + } + )); + it('sets binary body as a string with Base64 encoding', () => assert.deepEqual( + createTransactionRes(res, Buffer.from([0xFF, 0xBE])), + { + statusCode: 200, + headers: {}, + body: Buffer.from([0xFF, 0xBE]).toString('base64'), + bodyEncoding: 'base64' + } + )); }); diff --git a/test/unit/performRequest/detectBodyEncoding-test.js b/test/unit/performRequest/detectBodyEncoding-test.js index 6dcd6fd81..16860347f 100644 --- a/test/unit/performRequest/detectBodyEncoding-test.js +++ b/test/unit/performRequest/detectBodyEncoding-test.js @@ -6,22 +6,16 @@ const { describe('performRequest._detectBodyEncoding()', () => { - it('detects binary content as Base64', () => - assert.equal( - detectBodyEncoding(Buffer.from([0xFF, 0xEF, 0xBF, 0xBE])), - 'base64' - ) - ); - it('detects textual content as UTF-8', () => - assert.equal( - detectBodyEncoding(Buffer.from('řeřicha')), - 'utf-8' - ) - ); - it('detects no content as UTF-8', () => - assert.equal( - detectBodyEncoding(Buffer.from([])), - 'utf-8' - ) - ); + it('detects binary content as Base64', () => assert.equal( + detectBodyEncoding(Buffer.from([0xFF, 0xEF, 0xBF, 0xBE])), + 'base64' + )); + it('detects textual content as UTF-8', () => assert.equal( + detectBodyEncoding(Buffer.from('řeřicha')), + 'utf-8' + )); + it('detects no content as UTF-8', () => assert.equal( + detectBodyEncoding(Buffer.from([])), + 'utf-8' + )); }); diff --git a/test/unit/performRequest/getBodyAsBuffer-test.js b/test/unit/performRequest/getBodyAsBuffer-test.js index 2b5ac2e77..afbd5917e 100644 --- a/test/unit/performRequest/getBodyAsBuffer-test.js +++ b/test/unit/performRequest/getBodyAsBuffer-test.js @@ -19,15 +19,9 @@ describe('performRequest._getBodyAsBuffer()', () => { [undefined, null, ''].forEach((body) => { describe(`when the body is ${JSON.stringify(body)}`, () => { - it('returns empty Buffer without encoding', () => - assert.deepEqual(getBodyAsBuffer(body), Buffer.from([])) - ); - it('returns empty Buffer with encoding set to UTF-8', () => - assert.deepEqual(getBodyAsBuffer(body, 'utf-8'), Buffer.from([])) - ); - it('returns empty Buffer with encoding set to Base64', () => - assert.deepEqual(getBodyAsBuffer(body, 'base64'), Buffer.from([])) - ); + it('returns empty Buffer without encoding', () => assert.deepEqual(getBodyAsBuffer(body), Buffer.from([]))); + it('returns empty Buffer with encoding set to UTF-8', () => assert.deepEqual(getBodyAsBuffer(body, 'utf-8'), Buffer.from([]))); + it('returns empty Buffer with encoding set to Base64', () => assert.deepEqual(getBodyAsBuffer(body, 'base64'), Buffer.from([]))); }); }); @@ -39,12 +33,8 @@ describe('performRequest._getBodyAsBuffer()', () => { }); describe('when the body is a string', () => { - it('assumes UTF-8 without encoding', () => - assert.deepEqual(getBodyAsBuffer('abc'), Buffer.from('abc')) - ); - it('respects encoding set to UTF-8', () => - assert.deepEqual(getBodyAsBuffer('abc', 'utf-8'), Buffer.from('abc')) - ); + it('assumes UTF-8 without encoding', () => assert.deepEqual(getBodyAsBuffer('abc'), Buffer.from('abc'))); + it('respects encoding set to UTF-8', () => assert.deepEqual(getBodyAsBuffer('abc', 'utf-8'), Buffer.from('abc'))); it('respects encoding set to Base64', () => { const body = Buffer.from('abc').toString('base64'); assert.deepEqual(getBodyAsBuffer(body, 'base64'), Buffer.from('abc')); diff --git a/test/unit/performRequest/normalizeBodyEncoding-test.js b/test/unit/performRequest/normalizeBodyEncoding-test.js index 445159a30..2e6ca059f 100644 --- a/test/unit/performRequest/normalizeBodyEncoding-test.js +++ b/test/unit/performRequest/normalizeBodyEncoding-test.js @@ -6,24 +6,10 @@ const { describe('performRequest._normalizeBodyEncoding()', () => { - ['utf-8', 'utf8', 'UTF-8', 'UTF8'].forEach(value => - it(`normalizes ${JSON.stringify(value)} to utf-8`, () => - assert.equal(normalizeBodyEncoding(value), 'utf-8') - ) - ); - ['base64', 'Base64'].forEach(value => - it(`normalizes ${JSON.stringify(value)} to base64`, () => - assert.equal(normalizeBodyEncoding(value), 'base64') - ) - ); - [undefined, null, '', false].forEach(value => - it(`defaults ${JSON.stringify(value)} to utf-8`, () => - assert.equal(normalizeBodyEncoding(value), 'utf-8') - ) - ); - it('throws an error on "latin2"', () => - assert.throws(() => { - normalizeBodyEncoding('latin2'); - }, /^unsupported encoding/i) - ); + ['utf-8', 'utf8', 'UTF-8', 'UTF8'].forEach(value => it(`normalizes ${JSON.stringify(value)} to utf-8`, () => assert.equal(normalizeBodyEncoding(value), 'utf-8'))); + ['base64', 'Base64'].forEach(value => it(`normalizes ${JSON.stringify(value)} to base64`, () => assert.equal(normalizeBodyEncoding(value), 'base64'))); + [undefined, null, '', false].forEach(value => it(`defaults ${JSON.stringify(value)} to utf-8`, () => assert.equal(normalizeBodyEncoding(value), 'utf-8'))); + it('throws an error on "latin2"', () => assert.throws(() => { + normalizeBodyEncoding('latin2'); + }, /^unsupported encoding/i)); }); diff --git a/test/unit/performRequest/normalizeContentLengthHeader-test.js b/test/unit/performRequest/normalizeContentLengthHeader-test.js index e9d02abb9..4af7d214a 100644 --- a/test/unit/performRequest/normalizeContentLengthHeader-test.js +++ b/test/unit/performRequest/normalizeContentLengthHeader-test.js @@ -17,12 +17,8 @@ describe('performRequest._normalizeContentLengthHeader()', () => { headers = normalizeContentLengthHeader({}, Buffer.from(''), { logger }); }); - it('does not warn', () => - assert.isFalse(logger.warn.called) - ); - it('has the Content-Length header set to 0', () => - assert.deepPropertyVal(headers, 'Content-Length', '0') - ); + it('does not warn', () => assert.isFalse(logger.warn.called)); + it('has the Content-Length header set to 0', () => assert.deepPropertyVal(headers, 'Content-Length', '0')); }); describe('when there is no body and the Content-Length is set to 0', () => { @@ -32,12 +28,8 @@ describe('performRequest._normalizeContentLengthHeader()', () => { }, Buffer.from(''), { logger }); }); - it('does not warn', () => - assert.isFalse(logger.warn.called) - ); - it('has the Content-Length header set to 0', () => - assert.deepPropertyVal(headers, 'Content-Length', '0') - ); + it('does not warn', () => assert.isFalse(logger.warn.called)); + it('has the Content-Length header set to 0', () => assert.deepPropertyVal(headers, 'Content-Length', '0')); }); describe('when there is body and the Content-Length is not set', () => { @@ -45,12 +37,8 @@ describe('performRequest._normalizeContentLengthHeader()', () => { headers = normalizeContentLengthHeader({}, Buffer.from('abcd'), { logger }); }); - it('does not warn', () => - assert.isFalse(logger.warn.called) - ); - it('has the Content-Length header set to 4', () => - assert.deepPropertyVal(headers, 'Content-Length', '4') - ); + it('does not warn', () => assert.isFalse(logger.warn.called)); + it('has the Content-Length header set to 4', () => assert.deepPropertyVal(headers, 'Content-Length', '4')); }); describe('when there is body and the Content-Length is correct', () => { @@ -60,12 +48,8 @@ describe('performRequest._normalizeContentLengthHeader()', () => { }, Buffer.from('abcd'), { logger }); }); - it('does not warn', () => - assert.isFalse(logger.warn.called) - ); - it('has the Content-Length header set to 4', () => - assert.deepPropertyVal(headers, 'Content-Length', '4') - ); + it('does not warn', () => assert.isFalse(logger.warn.called)); + it('has the Content-Length header set to 4', () => assert.deepPropertyVal(headers, 'Content-Length', '4')); }); describe('when there is no body and the Content-Length is wrong', () => { @@ -75,12 +59,8 @@ describe('performRequest._normalizeContentLengthHeader()', () => { }, Buffer.from(''), { logger }); }); - it('warns about the discrepancy', () => - assert.match(logger.warn.lastCall.args[0], /but the real body length is/) - ); - it('has the Content-Length header set to 0', () => - assert.deepPropertyVal(headers, 'Content-Length', '0') - ); + it('warns about the discrepancy', () => assert.match(logger.warn.lastCall.args[0], /but the real body length is/)); + it('has the Content-Length header set to 0', () => assert.deepPropertyVal(headers, 'Content-Length', '0')); }); describe('when there is body and the Content-Length is wrong', () => { @@ -90,12 +70,8 @@ describe('performRequest._normalizeContentLengthHeader()', () => { }, Buffer.from('abcd'), { logger }); }); - it('warns about the discrepancy', () => - assert.match(logger.warn.lastCall.args[0], /but the real body length is/) - ); - it('has the Content-Length header set to 4', () => - assert.deepPropertyVal(headers, 'Content-Length', '4') - ); + it('warns about the discrepancy', () => assert.match(logger.warn.lastCall.args[0], /but the real body length is/)); + it('has the Content-Length header set to 4', () => assert.deepPropertyVal(headers, 'Content-Length', '4')); }); describe('when the existing header name has unusual casing', () => { @@ -105,9 +81,7 @@ describe('performRequest._normalizeContentLengthHeader()', () => { }, Buffer.from('abcd'), { logger }); }); - it('has the CoNtEnT-lEnGtH header set to 4', () => - assert.deepEqual(headers, { 'CoNtEnT-lEnGtH': '4' }) - ); + it('has the CoNtEnT-lEnGtH header set to 4', () => assert.deepEqual(headers, { 'CoNtEnT-lEnGtH': '4' })); }); describe('when there are modifications to the headers', () => { diff --git a/test/unit/prettify-response-test.js b/test/unit/prettify-response-test.js index 7bd930fe1..40557f712 100644 --- a/test/unit/prettify-response-test.js +++ b/test/unit/prettify-response-test.js @@ -12,7 +12,8 @@ describe('prettifyResponse(response)', () => { 'content-type': 'application/json' }, body: - { a: 'b' } }); + { a: 'b' } + }); const expectedOutput = `\ headers: \n content-type: application/json\n diff --git a/test/unit/reporters/apiary-reporter-test.js b/test/unit/reporters/apiary-reporter-test.js index d709f346e..d9645ca43 100644 --- a/test/unit/reporters/apiary-reporter-test.js +++ b/test/unit/reporters/apiary-reporter-test.js @@ -217,27 +217,23 @@ describe('ApiaryReporter', () => { apiaryApiUrl: 'https://api.example.com:1234/' }; - describe('when provided with root path', () => - it('should use API URL without double slashes', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom }); - apiaryReporter._performRequestAsync('/', 'POST', '', () => { - assert.isOk(loggerStub.verbose.calledWithMatch('POST https://api.example.com:1234/ (without body)')); - done(); - }); - }) - ); + describe('when provided with root path', () => it('should use API URL without double slashes', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom }); + apiaryReporter._performRequestAsync('/', 'POST', '', () => { + assert.isOk(loggerStub.verbose.calledWithMatch('POST https://api.example.com:1234/ (without body)')); + done(); + }); + })); - describe('when provided with non-root path', () => - it('should use API URL without double slashes', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom }); - apiaryReporter._performRequestAsync('/hello?q=1', 'POST', '', () => { - assert.isOk(loggerStub.verbose.calledWithMatch('POST https://api.example.com:1234/hello?q=1 (without body)')); - done(); - }); - }) - ); + describe('when provided with non-root path', () => it('should use API URL without double slashes', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom }); + apiaryReporter._performRequestAsync('/hello?q=1', 'POST', '', () => { + assert.isOk(loggerStub.verbose.calledWithMatch('POST https://api.example.com:1234/hello?q=1 (without body)')); + done(); + }); + })); }); describe('when server is not available', () => { @@ -372,17 +368,15 @@ describe('ApiaryReporter', () => { }); }); - describe('serverError is true', () => - it('should not do anything', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); - apiaryReporter.serverError = true; - emitter.emit('start', blueprintData, () => { - assert.isFalse(call.isDone()); - done(); - }); - }) - ); + describe('serverError is true', () => it('should not do anything', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); + apiaryReporter.serverError = true; + emitter.emit('start', blueprintData, () => { + assert.isFalse(call.isDone()); + done(); + }); + })); }); describe('when adding passing test', () => { @@ -439,18 +433,16 @@ describe('ApiaryReporter', () => { }); }); - describe('serverError is true', () => - it('should not do anything', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); - apiaryReporter.remoteId = runId; - apiaryReporter.serverError = true; - emitter.emit('test pass', test, () => { - assert.isFalse(call.isDone()); - done(); - }); - }) - ); + describe('serverError is true', () => it('should not do anything', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); + apiaryReporter.remoteId = runId; + apiaryReporter.serverError = true; + emitter.emit('test pass', test, () => { + assert.isFalse(call.isDone()); + done(); + }); + })); }); describe('when adding failing test', () => { @@ -475,18 +467,16 @@ describe('ApiaryReporter', () => { }); }); - describe('when serverError is true', () => - it('should not do anything', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); - apiaryReporter.remoteId = runId; - apiaryReporter.serverError = true; - emitter.emit('test fail', test, () => { - assert.isFalse(call.isDone()); - done(); - }); - }) - ); + describe('when serverError is true', () => it('should not do anything', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); + apiaryReporter.remoteId = runId; + apiaryReporter.serverError = true; + emitter.emit('test fail', test, () => { + assert.isFalse(call.isDone()); + done(); + }); + })); }); describe('when adding skipped test', () => { @@ -534,18 +524,16 @@ describe('ApiaryReporter', () => { }); }); - describe('when serverError is true', () => - it('should not do anything', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); - apiaryReporter.remoteId = runId; - apiaryReporter.serverError = true; - emitter.emit('test skip', clonedTest, () => { - assert.isFalse(call.isDone()); - done(); - }); - }) - ); + describe('when serverError is true', () => it('should not do anything', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); + apiaryReporter.remoteId = runId; + apiaryReporter.serverError = true; + emitter.emit('test skip', clonedTest, () => { + assert.isFalse(call.isDone()); + done(); + }); + })); }); @@ -610,8 +598,10 @@ describe('ApiaryReporter', () => { error.code = errType; emitter.emit('test error', error, test, () => { assert.isArray(JSON.parse(requestBody).resultData.result.general); - assert.include(JSON.parse(requestBody).resultData.result.general.map(value => JSON.stringify(value)).join(), - 'Error connecting to server under test!'); + assert.include( + JSON.parse(requestBody).resultData.result.general.map(value => JSON.stringify(value)).join(), + 'Error connecting to server under test!' + ); done(); }); }); @@ -648,27 +638,27 @@ describe('ApiaryReporter', () => { const error = new Error('some error'); emitter.emit('test error', error, test, () => { assert.isArray(JSON.parse(requestBody).resultData.result.general); - assert.include(JSON.parse(requestBody).resultData.result.general.map(value => JSON.stringify(value)).join(), - 'Unhandled error occured when executing the transaction.'); + assert.include( + JSON.parse(requestBody).resultData.result.general.map(value => JSON.stringify(value)).join(), + 'Unhandled error occured when executing the transaction.' + ); done(); }); }); }); - describe('when serverError is true', () => - it('should not do anything', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); - apiaryReporter.remoteId = runId; - apiaryReporter.serverError = true; - const error = new Error('some error'); - emitter.emit('test error', error, test, () => { - assert.isFalse(call.isDone()); - done(); - }); - }) - ); + describe('when serverError is true', () => it('should not do anything', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); + apiaryReporter.remoteId = runId; + apiaryReporter.serverError = true; + const error = new Error('some error'); + emitter.emit('test error', error, test, () => { + assert.isFalse(call.isDone()); + done(); + }); + })); }); describe('when ending', () => { @@ -737,18 +727,16 @@ describe('ApiaryReporter', () => { }); }); - describe('serverError is true', () => - it('should not do enything', (done) => { - emitter = new EventEmitter(); - const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); - apiaryReporter.remoteId = runId; - apiaryReporter.serverError = true; - emitter.emit('end', () => { - assert.isFalse(call.isDone()); - done(); - }); - }) - ); + describe('serverError is true', () => it('should not do enything', (done) => { + emitter = new EventEmitter(); + const apiaryReporter = new ApiaryReporter(emitter, {}, {}, { custom: { apiaryReporterEnv: env } }); + apiaryReporter.remoteId = runId; + apiaryReporter.serverError = true; + emitter.emit('end', () => { + assert.isFalse(call.isDone()); + done(); + }); + })); }); }); diff --git a/test/unit/reporters/base-reporter-test.js b/test/unit/reporters/base-reporter-test.js index c064d4966..b79d0105e 100644 --- a/test/unit/reporters/base-reporter-test.js +++ b/test/unit/reporters/base-reporter-test.js @@ -35,12 +35,10 @@ describe('BaseReporter', () => { stats = { start: null }; }); - it('should set the start date', done => - emitter.emit('start', '', () => { - assert.isOk(stats.start); - done(); - }) - ); + it('should set the start date', done => emitter.emit('start', '', () => { + assert.isOk(stats.start); + done(); + })); }); describe('when ending', () => { @@ -48,12 +46,10 @@ describe('BaseReporter', () => { stats = { start: null }; }); - it('should set the end date', done => - emitter.emit('end', () => { - assert.isOk(stats.end); - done(); - }) - ); + it('should set the end date', done => emitter.emit('end', () => { + assert.isOk(stats.end); + done(); + })); }); describe('when test starts', () => { diff --git a/test/unit/reporters/cli-reporter-test.js b/test/unit/reporters/cli-reporter-test.js index 8b2b9972b..0e687e515 100644 --- a/test/unit/reporters/cli-reporter-test.js +++ b/test/unit/reporters/cli-reporter-test.js @@ -144,21 +144,17 @@ describe('CliReporter', () => { const connectionErrors = ['ECONNRESET', 'ENOTFOUND', 'ESOCKETTIMEDOUT', 'ETIMEDOUT', 'ECONNREFUSED', 'EHOSTUNREACH', 'EPIPE']; - Array.from(connectionErrors).forEach(errType => - describe(`when error type ${errType}`, () => - it('should write error to the console', () => { - const emitter = new EventEmitter(); - (new CliReporter(emitter, {}, {}, false)); - const error = new Error('connect'); - error.code = errType; - emitter.emit('test error', error, test); - - const messages = Object.keys(loggerStub.error.args).map((value, index) => loggerStub.error.args[index][0]); - - assert.include(messages.join(), 'Error connecting'); - }) - ) - ); + Array.from(connectionErrors).forEach(errType => describe(`when error type ${errType}`, () => it('should write error to the console', () => { + const emitter = new EventEmitter(); + (new CliReporter(emitter, {}, {}, false)); + const error = new Error('connect'); + error.code = errType; + emitter.emit('test error', error, test); + + const messages = Object.keys(loggerStub.error.args).map((value, index) => loggerStub.error.args[index][0]); + + assert.include(messages.join(), 'Error connecting'); + }))); }); describe('when adding skipped test', () => { @@ -194,30 +190,24 @@ describe('CliReporter', () => { afterEach(() => loggerStub.complete.restore()); - describe('when there is at least one test', () => - - it('should write to the console', (done) => { - const emitter = new EventEmitter(); - const cliReporter = new CliReporter(emitter, {}, {}, false); - cliReporter.tests = [test]; - cliReporter.stats.tests = 1; - emitter.emit('end', () => { - assert.isOk(loggerStub.complete.calledTwice); - done(); - }); - }) - ); - - describe('when there are no tests', () => + describe('when there is at least one test', () => it('should write to the console', (done) => { + const emitter = new EventEmitter(); + const cliReporter = new CliReporter(emitter, {}, {}, false); + cliReporter.tests = [test]; + cliReporter.stats.tests = 1; + emitter.emit('end', () => { + assert.isOk(loggerStub.complete.calledTwice); + done(); + }); + })); - it('should write to the console', (done) => { - const emitter = new EventEmitter(); - (new CliReporter(emitter, {}, {}, false)); - emitter.emit('end', () => { - assert.isOk(loggerStub.complete.calledOnce); - done(); - }); - }) - ); + describe('when there are no tests', () => it('should write to the console', (done) => { + const emitter = new EventEmitter(); + (new CliReporter(emitter, {}, {}, false)); + emitter.emit('end', () => { + assert.isOk(loggerStub.complete.calledOnce); + done(); + }); + })); }); }); diff --git a/test/unit/reporters/dot-reporter-test.js b/test/unit/reporters/dot-reporter-test.js index 89c8fffce..97a5fa792 100644 --- a/test/unit/reporters/dot-reporter-test.js +++ b/test/unit/reporters/dot-reporter-test.js @@ -42,9 +42,7 @@ describe('DotReporter', () => { afterEach(() => loggerStub.info.restore()); - it('should log that testing has begun', () => - emitter.emit('start', '', () => assert.isOk(loggerStub.info.called)) - ); + it('should log that testing has begun', () => emitter.emit('start', '', () => assert.isOk(loggerStub.info.called))); }); describe('when ending', () => { @@ -59,9 +57,7 @@ describe('DotReporter', () => { dotReporter.write.restore(); }); - it('should log that testing is complete', () => - emitter.emit('end', () => assert.isOk(loggerStub.complete.calledTwice)) - ); + it('should log that testing is complete', () => emitter.emit('end', () => assert.isOk(loggerStub.complete.calledTwice))); describe('when there are failures', () => { before(() => { @@ -80,12 +76,10 @@ describe('DotReporter', () => { afterEach(() => loggerStub.fail.restore()); - it('should log the failures at the end of testing', done => - emitter.emit('end', () => { - assert.isOk(loggerStub.fail.called); - done(); - }) - ); + it('should log the failures at the end of testing', done => emitter.emit('end', () => { + assert.isOk(loggerStub.fail.called); + done(); + })); }); }); diff --git a/test/unit/reporters/html-reporter-test.js b/test/unit/reporters/html-reporter-test.js index f959255fe..60967b1ab 100644 --- a/test/unit/reporters/html-reporter-test.js +++ b/test/unit/reporters/html-reporter-test.js @@ -71,12 +71,10 @@ describe('HtmlReporter', () => { it('should not attempt to delete a file', () => assert.isOk(fsStub.unlinkSync.notCalled)); }); - it('should write the prelude to the buffer', done => - emitter.emit('start', '', () => { - assert.isOk(~htmlReporter.buf.indexOf('Dredd')); - done(); - }) - ); + it('should write the prelude to the buffer', done => emitter.emit('start', '', () => { + assert.isOk(~htmlReporter.buf.indexOf('Dredd')); + done(); + })); }); describe('when ending', () => { @@ -93,13 +91,11 @@ describe('HtmlReporter', () => { fsExtraStub.mkdirp.restore(); }); - it('should write the file', done => - emitter.emit('end', () => { - assert.isOk(fsExtraStub.mkdirp.called); - assert.isOk(fsStub.writeFile.called); - done(); - }) - ); + it('should write the file', done => emitter.emit('end', () => { + assert.isOk(fsExtraStub.mkdirp.called); + assert.isOk(fsStub.writeFile.called); + done(); + })); }); describe('when cannot create output directory', () => { @@ -115,14 +111,12 @@ describe('HtmlReporter', () => { fsExtraStub.mkdirp.restore(); }); - it('should write to log', done => - emitter.emit('end', () => { - assert.isOk(fsExtraStub.mkdirp.called); - assert.isOk(fsStub.writeFile.notCalled); - assert.isOk(loggerStub.error.called); - done(); - }) - ); + it('should write to log', done => emitter.emit('end', () => { + assert.isOk(fsExtraStub.mkdirp.called); + assert.isOk(fsStub.writeFile.notCalled); + assert.isOk(loggerStub.error.called); + done(); + })); }); }); @@ -140,14 +134,11 @@ describe('HtmlReporter', () => { assert.isOk(~htmlReporter.buf.indexOf('Pass')); }); - describe('when details=true', () => - - it('should write details for passing tests', () => { - htmlReporter.details = true; - emitter.emit('test pass', test); - assert.isOk(~htmlReporter.buf.indexOf('Request')); - }) - ); + describe('when details=true', () => it('should write details for passing tests', () => { + htmlReporter.details = true; + emitter.emit('test pass', test); + assert.isOk(~htmlReporter.buf.indexOf('Request')); + })); }); describe('when test is skipped', () => { diff --git a/test/unit/reporters/markdown-reporter-test.js b/test/unit/reporters/markdown-reporter-test.js index 6766fbc80..95ffed1ec 100644 --- a/test/unit/reporters/markdown-reporter-test.js +++ b/test/unit/reporters/markdown-reporter-test.js @@ -76,15 +76,10 @@ describe('MarkdownReporter', () => { }); }); - describe('when starting', () => - - it('should write the title to the buffer', done => - emitter.emit('start', '', () => { - assert.isOk(~mdReporter.buf.indexOf('Dredd')); - done(); - }) - ) - ); + describe('when starting', () => it('should write the title to the buffer', done => emitter.emit('start', '', () => { + assert.isOk(~mdReporter.buf.indexOf('Dredd')); + done(); + }))); describe('when ending', () => { describe('when can create output directory', () => { @@ -119,14 +114,12 @@ describe('MarkdownReporter', () => { fsExtraStub.mkdirp.restore(); }); - it('should write to log', done => - emitter.emit('end', () => { - assert.isOk(fsExtraStub.mkdirp.called); - assert.isOk(fsStub.writeFile.notCalled); - assert.isOk(loggerStub.error.called); - done(); - }) - ); + it('should write to log', done => emitter.emit('end', () => { + assert.isOk(fsExtraStub.mkdirp.called); + assert.isOk(fsStub.writeFile.notCalled); + assert.isOk(loggerStub.error.called); + done(); + })); }); }); @@ -145,15 +138,12 @@ describe('MarkdownReporter', () => { done(); }); - describe('when details=true', () => - - it('should write details for passing tests', (done) => { - mdReporter.details = true; - emitter.emit('test pass', test); - assert.isOk(~mdReporter.buf.indexOf('Request')); - done(); - }) - ); + describe('when details=true', () => it('should write details for passing tests', (done) => { + mdReporter.details = true; + emitter.emit('test pass', test); + assert.isOk(~mdReporter.buf.indexOf('Request')); + done(); + })); }); describe('when test is skipped', () => { diff --git a/test/unit/reporters/nyan-reporter-test.js b/test/unit/reporters/nyan-reporter-test.js index 17a0b414c..87835338a 100644 --- a/test/unit/reporters/nyan-reporter-test.js +++ b/test/unit/reporters/nyan-reporter-test.js @@ -49,13 +49,11 @@ describe('NyanCatReporter', () => { nyanReporter.write.restore(); }); - it('should hide the cursor and draw the cat', done => - emitter.emit('start', '', () => { - assert.isOk(nyanReporter.cursorHide.calledOnce); - assert.isOk(nyanReporter.draw.calledOnce); - done(); - }) - ); + it('should hide the cursor and draw the cat', done => emitter.emit('start', '', () => { + assert.isOk(nyanReporter.cursorHide.calledOnce); + assert.isOk(nyanReporter.draw.calledOnce); + done(); + })); }); describe('when ending', () => { @@ -71,12 +69,10 @@ describe('NyanCatReporter', () => { nyanReporter.write.restore(); }); - it('should log that testing is complete', done => - emitter.emit('end', () => { - assert.isOk(loggerStub.complete.calledTwice); - done(); - }) - ); + it('should log that testing is complete', done => emitter.emit('end', () => { + assert.isOk(loggerStub.complete.calledTwice); + done(); + })); describe('when there are failures', () => { beforeEach(() => { @@ -91,12 +87,10 @@ describe('NyanCatReporter', () => { afterEach(() => loggerStub.fail.restore()); - it('should log the failures at the end of testing', done => - emitter.emit('end', () => { - assert.isOk(loggerStub.fail.calledTwice); - done(); - }) - ); + it('should log the failures at the end of testing', done => emitter.emit('end', () => { + assert.isOk(loggerStub.fail.calledTwice); + done(); + })); }); }); diff --git a/test/unit/reporters/x-unit-reporter-test.js b/test/unit/reporters/x-unit-reporter-test.js index 83eefcbea..4b92de649 100644 --- a/test/unit/reporters/x-unit-reporter-test.js +++ b/test/unit/reporters/x-unit-reporter-test.js @@ -136,33 +136,27 @@ describe('XUnitReporter', () => { assert.isOk(fsStub.appendFileSync.called); }); - describe('when the file writes successfully', () => - - it('should read the file and update the stats', (done) => { - const emitter = new EventEmitter(); - const xUnitReporter = new XUnitReporter(emitter, {}, {}); - xUnitReporter.tests = [test]; - xUnitReporter.stats.tests = 1; - - emitter.emit('end', () => { - assert.isOk(fsStub.writeFile.called); - done(); - }); - }) - ); - }); - - describe('when there are no tests', () => - - it('should write empty suite', (done) => { + describe('when the file writes successfully', () => it('should read the file and update the stats', (done) => { const emitter = new EventEmitter(); - (new XUnitReporter(emitter, {}, {})); + const xUnitReporter = new XUnitReporter(emitter, {}, {}); + xUnitReporter.tests = [test]; + xUnitReporter.stats.tests = 1; + emitter.emit('end', () => { assert.isOk(fsStub.writeFile.called); done(); }); - }) - ); + })); + }); + + describe('when there are no tests', () => it('should write empty suite', (done) => { + const emitter = new EventEmitter(); + (new XUnitReporter(emitter, {}, {})); + emitter.emit('end', () => { + assert.isOk(fsStub.writeFile.called); + done(); + }); + })); }); describe('when test passes', () => { @@ -205,16 +199,13 @@ describe('XUnitReporter', () => { assert.isOk(fsStub.appendFileSync.called); }); - describe('when details=true', () => - - it('should write details for passing tests', () => { - const emitter = new EventEmitter(); - (new XUnitReporter(emitter, {}, {}, 'test.xml', true)); - emitter.emit('test start', test); - emitter.emit('test pass', test); - assert.isOk(fsStub.appendFileSync.called); - }) - ); + describe('when details=true', () => it('should write details for passing tests', () => { + const emitter = new EventEmitter(); + (new XUnitReporter(emitter, {}, {}, 'test.xml', true)); + emitter.emit('test start', test); + emitter.emit('test pass', test); + assert.isOk(fsStub.appendFileSync.called); + })); }); describe('when test is skipped', () => { diff --git a/test/unit/resolve-hookfiles-test.js b/test/unit/resolve-hookfiles-test.js index f1fd19311..617962e2d 100644 --- a/test/unit/resolve-hookfiles-test.js +++ b/test/unit/resolve-hookfiles-test.js @@ -6,60 +6,44 @@ const resolveHookfiles = require('../../src/resolve-hookfiles'); describe('resolveHookfiles()', () => { const cwd = path.join(__filename, '..', '..', 'fixtures'); - describe('when given no paths', () => - it('produces no results', () => { - const paths = resolveHookfiles([], cwd); - assert.deepEqual(paths, []); - }) - ); + describe('when given no paths', () => it('produces no results', () => { + const paths = resolveHookfiles([], cwd); + assert.deepEqual(paths, []); + })); - describe('when given existing absolute filenames', () => - it('resolves them into absolute paths', () => { - const hookfiles = [ - path.join(cwd, 'hooks.js'), - path.join(cwd, 'non-js-hooks.rb') - ]; - const paths = resolveHookfiles(hookfiles, cwd); - assert.deepEqual(paths, hookfiles); - }) - ); + describe('when given existing absolute filenames', () => it('resolves them into absolute paths', () => { + const hookfiles = [ + path.join(cwd, 'hooks.js'), + path.join(cwd, 'non-js-hooks.rb') + ]; + const paths = resolveHookfiles(hookfiles, cwd); + assert.deepEqual(paths, hookfiles); + })); - describe('when given existing relative filenames', () => - it('resolves them into absolute paths', () => { - const paths = resolveHookfiles(['./hooks.js', './non-js-hooks.rb'], cwd); - assert.deepEqual(paths, [ - path.join(cwd, 'hooks.js'), - path.join(cwd, 'non-js-hooks.rb') - ]); - }) - ); + describe('when given existing relative filenames', () => it('resolves them into absolute paths', () => { + const paths = resolveHookfiles(['./hooks.js', './non-js-hooks.rb'], cwd); + assert.deepEqual(paths, [ + path.join(cwd, 'hooks.js'), + path.join(cwd, 'non-js-hooks.rb') + ]); + })); - describe('when given non-existing filenames', () => - it('throws an error', () => - assert.throws( - () => resolveHookfiles(['./hooks.js', './foo/bar/42'], cwd) - , './foo/bar/42' - ) - ) - ); + describe('when given non-existing filenames', () => it('throws an error', () => assert.throws( + () => resolveHookfiles(['./hooks.js', './foo/bar/42'], cwd), + './foo/bar/42' + ))); - describe('when given glob pattern resolving to existing files', () => - it('resolves them into absolute paths', () => { - const paths = resolveHookfiles(['./**/hooks.js'], cwd); - assert.deepEqual(paths, [ - path.join(cwd, 'hooks.js') - ]); - }) - ); + describe('when given glob pattern resolving to existing files', () => it('resolves them into absolute paths', () => { + const paths = resolveHookfiles(['./**/hooks.js'], cwd); + assert.deepEqual(paths, [ + path.join(cwd, 'hooks.js') + ]); + })); - describe('when given glob pattern resolving to no files', () => - it('throws an error', () => - assert.throws( - () => resolveHookfiles(['./**/hooks.js', './**/foo/bar/foobar.js'], cwd) - , './**/foo/bar/foobar.js' - ) - ) - ); + describe('when given glob pattern resolving to no files', () => it('throws an error', () => assert.throws( + () => resolveHookfiles(['./**/hooks.js', './**/foo/bar/foobar.js'], cwd), + './**/foo/bar/foobar.js' + ))); describe('when given both globs and filenames', () => { it('resolves them into absolute paths', () => { @@ -70,19 +54,15 @@ describe('resolveHookfiles()', () => { ]); }); - it('throws an error on non-existing filenams', () => - assert.throws( - () => resolveHookfiles(['./**/hooks.js', './foo/bar/42'], cwd) - , './foo/bar/42' - ) - ); + it('throws an error on non-existing filenams', () => assert.throws( + () => resolveHookfiles(['./**/hooks.js', './foo/bar/42'], cwd), + './foo/bar/42' + )); - it('throws an error on globs resolving to no files', () => - assert.throws( - () => resolveHookfiles(['./hooks.js', './**/foo/bar/foobar.js'], cwd) - , './**/foo/bar/foobar.js' - ) - ); + it('throws an error on globs resolving to no files', () => assert.throws( + () => resolveHookfiles(['./hooks.js', './**/foo/bar/foobar.js'], cwd), + './**/foo/bar/foobar.js' + )); it('returns the absolute paths alphabetically sorted', () => { const paths = resolveHookfiles([ diff --git a/test/unit/sandbox-hooks-code-test.js b/test/unit/sandbox-hooks-code-test.js index 272617a0e..4d326d053 100644 --- a/test/unit/sandbox-hooks-code-test.js +++ b/test/unit/sandbox-hooks-code-test.js @@ -5,15 +5,13 @@ const sandboxHooksCode = require('../../src/sandbox-hooks-code'); describe('sandboxHooksCode(hooksCode, callback)', () => { it('should be a defined function', () => assert.isFunction(sandboxHooksCode)); - describe('when hookscode explodes', () => - it('should return an error in callback', (done) => { - const hooksCode = '\nthrow(new Error("Exploded during sandboxed processing of hook file"));\n'; - sandboxHooksCode(hooksCode, (err) => { - assert.include(err, 'sandbox'); - done(); - }); - }) - ); + describe('when hookscode explodes', () => it('should return an error in callback', (done) => { + const hooksCode = '\nthrow(new Error("Exploded during sandboxed processing of hook file"));\n'; + sandboxHooksCode(hooksCode, (err) => { + assert.include(err, 'sandbox'); + done(); + }); + })); describe('context of code adding hooks', () => { it('should not have access to this context', (done) => { diff --git a/test/unit/transaction-runner-test.js b/test/unit/transaction-runner-test.js index baf1dafa4..b4b9cfe30 100644 --- a/test/unit/transaction-runner-test.js +++ b/test/unit/transaction-runner-test.js @@ -58,48 +58,44 @@ describe('TransactionRunner', () => { }); describe('config(config)', () => { - describe('when single file in data is present', () => - it('should set multiBlueprint to false', () => { - configuration = { - server: 'http://127.0.0.1:3000', - emitter: new EventEmitter(), - data: { file1: { raw: 'blueprint1' } }, - options: { - 'dry-run': false, - method: [], - only: [], - header: [], - reporter: [] - } - }; + describe('when single file in data is present', () => it('should set multiBlueprint to false', () => { + configuration = { + server: 'http://127.0.0.1:3000', + emitter: new EventEmitter(), + data: { file1: { raw: 'blueprint1' } }, + options: { + 'dry-run': false, + method: [], + only: [], + header: [], + reporter: [] + } + }; - runner = new Runner(configuration); - runner.config(configuration); - - assert.notOk(runner.multiBlueprint); - }) - ); - - describe('when multiple files in data are present', () => - it('should set multiBlueprint to true', () => { - configuration = { - server: 'http://127.0.0.1:3000', - emitter: new EventEmitter(), - data: { file1: { raw: 'blueprint1' }, file2: { raw: 'blueprint2' } }, - options: { - 'dry-run': false, - method: [], - only: [], - header: [], - reporter: [] - } - }; - runner = new Runner(configuration); - runner.config(configuration); + runner = new Runner(configuration); + runner.config(configuration); + + assert.notOk(runner.multiBlueprint); + })); + + describe('when multiple files in data are present', () => it('should set multiBlueprint to true', () => { + configuration = { + server: 'http://127.0.0.1:3000', + emitter: new EventEmitter(), + data: { file1: { raw: 'blueprint1' }, file2: { raw: 'blueprint2' } }, + options: { + 'dry-run': false, + method: [], + only: [], + header: [], + reporter: [] + } + }; + runner = new Runner(configuration); + runner.config(configuration); - assert.isOk(runner.multiBlueprint); - }) - ); + assert.isOk(runner.multiBlueprint); + })); }); describe('configureTransaction(transaction)', () => { @@ -144,137 +140,155 @@ describe('TransactionRunner', () => { [{ description: 'is hostname', input: { serverUrl: 'https://127.0.0.1:8000', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'https:', fullPath: '/hello' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'https:', fullPath: '/hello' + } }, { description: 'is IPv4', input: { serverUrl: 'https://127.0.0.1:8000', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'https:', fullPath: '/hello' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'https:', fullPath: '/hello' + } }, { description: 'has path', input: { serverUrl: 'http://127.0.0.1:8000/v1', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/hello' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/hello' + } }, { description: 'has path with trailing slash', input: { serverUrl: 'http://127.0.0.1:8000/v1/', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/hello' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/hello' + } }, { description: 'has path and request path is /', input: { serverUrl: 'http://127.0.0.1:8000/v1', requestPath: '/' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/' + } }, { description: 'has path with trailing slash and request path is /', input: { serverUrl: 'http://127.0.0.1:8000/v1/', requestPath: '/' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/' + } }, { description: 'has path and request has no path', input: { serverUrl: 'http://127.0.0.1:8000/v1', requestPath: '' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1' + } }, { description: 'has path with trailing slash and request has no path', input: { serverUrl: 'http://127.0.0.1:8000/v1/', requestPath: '' }, - expected: { host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/' } + expected: { + host: '127.0.0.1', port: '8000', protocol: 'http:', fullPath: '/v1/' + } }, { description: 'is hostname with no protocol', input: { serverUrl: '127.0.0.1', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' } + expected: { + host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' + } }, { description: 'is IPv4 with no protocol', input: { serverUrl: '127.0.0.1:4000', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: '4000', protocol: 'http:', fullPath: '/hello' } + expected: { + host: '127.0.0.1', port: '4000', protocol: 'http:', fullPath: '/hello' + } }, { description: 'is hostname with // instead of protocol', input: { serverUrl: '//127.0.0.1', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' } + expected: { + host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' + } }, { description: 'is hostname with trailing slash', input: { serverUrl: 'http://127.0.0.1/', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' } + expected: { + host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' + } }, { description: 'is hostname with no protocol and with trailing slash', input: { serverUrl: '127.0.0.1/', requestPath: '/hello' }, - expected: { host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' } + expected: { + host: '127.0.0.1', port: null, protocol: 'http:', fullPath: '/hello' + } } - ].forEach(({ description, input, expected }) => - context(`${description}: '${input.serverUrl}' + '${input.requestPath}'`, () => { - beforeEach(() => { - transaction.request.uri = input.requestPath; - transaction.origin.filename = filename; + ].forEach(({ description, input, expected }) => context(`${description}: '${input.serverUrl}' + '${input.requestPath}'`, () => { + beforeEach(() => { + transaction.request.uri = input.requestPath; + transaction.origin.filename = filename; - runner.configuration.server = input.serverUrl; - if (!runner.configuration.data) { runner.configuration.data = {}; } - if (!runner.configuration.data[filename]) { runner.configuration.data[filename] = {}; } - runner.configuration.data[filename].mediaType = 'text/vnd.apiblueprint'; + runner.configuration.server = input.serverUrl; + if (!runner.configuration.data) { runner.configuration.data = {}; } + if (!runner.configuration.data[filename]) { runner.configuration.data[filename] = {}; } + runner.configuration.data[filename].mediaType = 'text/vnd.apiblueprint'; - configuredTransaction = runner.configureTransaction(transaction); - }); + configuredTransaction = runner.configureTransaction(transaction); + }); - it(`the transaction gets configured with fullPath '${expected.fullPath}' and has expected host, port, and protocol`, () => - assert.deepEqual({ - host: configuredTransaction.host, - port: configuredTransaction.port, - protocol: configuredTransaction.protocol, - fullPath: configuredTransaction.fullPath - }, expected) - ); - }) - ); + it(`the transaction gets configured with fullPath '${expected.fullPath}' and has expected host, port, and protocol`, () => assert.deepEqual({ + host: configuredTransaction.host, + port: configuredTransaction.port, + protocol: configuredTransaction.protocol, + fullPath: configuredTransaction.fullPath + }, expected)); + })); }); describe('when processing Swagger document and given transaction has non-2xx status code', () => { const filename = 'api-description.yml'; let configuredTransaction; - ['100', '400', 199, 300].forEach(status => - context(`status code: ${JSON.stringify(status)}`, () => { - beforeEach(() => { - transaction.response.status = status; - transaction.origin.filename = filename; + ['100', '400', 199, 300].forEach(status => context(`status code: ${JSON.stringify(status)}`, () => { + beforeEach(() => { + transaction.response.status = status; + transaction.origin.filename = filename; - if (!runner.configuration.data) { runner.configuration.data = {}; } - if (!runner.configuration.data[filename]) { runner.configuration.data[filename] = {}; } - runner.configuration.data[filename].mediaType = 'application/swagger+json'; + if (!runner.configuration.data) { runner.configuration.data = {}; } + if (!runner.configuration.data[filename]) { runner.configuration.data[filename] = {}; } + runner.configuration.data[filename].mediaType = 'application/swagger+json'; - configuredTransaction = runner.configureTransaction(transaction); - }); + configuredTransaction = runner.configureTransaction(transaction); + }); - it('skips the transaction by default', () => assert.isTrue(configuredTransaction.skip)); - }) - ); + it('skips the transaction by default', () => assert.isTrue(configuredTransaction.skip)); + })); }); describe('when processing Swagger document and given transaction has 2xx status code', () => { const filename = 'api-description.yml'; let configuredTransaction; - ['200', 299].forEach(status => - context(`status code: ${JSON.stringify(status)}`, () => { - beforeEach(() => { - transaction.response.status = status; - transaction.origin.filename = filename; + ['200', 299].forEach(status => context(`status code: ${JSON.stringify(status)}`, () => { + beforeEach(() => { + transaction.response.status = status; + transaction.origin.filename = filename; - if (!runner.configuration.data) { runner.configuration.data = {}; } - if (!runner.configuration.data[filename]) { runner.configuration.data[filename] = {}; } - runner.configuration.data[filename].mediaType = 'application/swagger+json'; + if (!runner.configuration.data) { runner.configuration.data = {}; } + if (!runner.configuration.data[filename]) { runner.configuration.data[filename] = {}; } + runner.configuration.data[filename].mediaType = 'application/swagger+json'; - configuredTransaction = runner.configureTransaction(transaction); - }); + configuredTransaction = runner.configureTransaction(transaction); + }); - it('does not skip the transaction by default', () => assert.isFalse(configuredTransaction.skip)); - }) - ); + it('does not skip the transaction by default', () => assert.isFalse(configuredTransaction.skip)); + })); }); describe('when processing other than Swagger document and given transaction has non-2xx status code', () => { @@ -295,29 +309,22 @@ describe('TransactionRunner', () => { it('does not skip the transaction by default', () => assert.isFalse(configuredTransaction.skip)); }); - describe('when processing multiple API description documents', () => - it('should include api name in the transaction name', () => { - runner.multiBlueprint = true; - const configuredTransaction = runner.configureTransaction(transaction); - assert.include(configuredTransaction.name, 'Machines API'); - }) - ); - - describe('when processing only single API description document', () => - it('should not include api name in the transaction name', () => { - runner.multiBlueprint = false; - const configuredTransaction = runner.configureTransaction(transaction); - assert.notInclude(configuredTransaction.name, 'Machines API'); - }) - ); + describe('when processing multiple API description documents', () => it('should include api name in the transaction name', () => { + runner.multiBlueprint = true; + const configuredTransaction = runner.configureTransaction(transaction); + assert.include(configuredTransaction.name, 'Machines API'); + })); - describe('when request does not have User-Agent', () => + describe('when processing only single API description document', () => it('should not include api name in the transaction name', () => { + runner.multiBlueprint = false; + const configuredTransaction = runner.configureTransaction(transaction); + assert.notInclude(configuredTransaction.name, 'Machines API'); + })); - it('should add the Dredd User-Agent', () => { - const configuredTransaction = runner.configureTransaction(transaction); - assert.isOk(configuredTransaction.request.headers['User-Agent']); - }) - ); + describe('when request does not have User-Agent', () => it('should add the Dredd User-Agent', () => { + const configuredTransaction = runner.configureTransaction(transaction); + assert.isOk(configuredTransaction.request.headers['User-Agent']); + })); describe('when an additional header has a colon', () => { beforeEach(() => { @@ -332,17 +339,15 @@ describe('TransactionRunner', () => { }); }); - describe('when configuring a transaction', () => - it('should callback with a properly configured transaction', () => { - const configuredTransaction = runner.configureTransaction(transaction); - assert.equal(configuredTransaction.name, 'Group Machine > Machine > Delete Message > Bogus example name'); - assert.equal(configuredTransaction.id, 'POST (202) /machines'); - assert.isOk(configuredTransaction.host); - assert.isOk(configuredTransaction.request); - assert.isOk(configuredTransaction.expected); - assert.strictEqual(transaction.origin, configuredTransaction.origin); - }) - ); + describe('when configuring a transaction', () => it('should callback with a properly configured transaction', () => { + const configuredTransaction = runner.configureTransaction(transaction); + assert.equal(configuredTransaction.name, 'Group Machine > Machine > Delete Message > Bogus example name'); + assert.equal(configuredTransaction.id, 'POST (202) /machines'); + assert.isOk(configuredTransaction.host); + assert.isOk(configuredTransaction.request); + assert.isOk(configuredTransaction.expected); + assert.strictEqual(transaction.origin, configuredTransaction.origin); + })); describe('when endpoint URL contains PORT and path', () => { beforeEach(() => { @@ -387,8 +392,7 @@ describe('TransactionRunner', () => { method: 'POST' }, expected: { - headers: { 'content-type': 'application/json' - }, + headers: { 'content-type': 'application/json' }, body: '{\n "type": "bulldozer",\n "name": "willy",\n "id": "5229c6e8e4b0bd7dbb07e29c"\n}\n', status: '202' }, @@ -415,12 +419,10 @@ describe('TransactionRunner', () => { configuration.options.names = false; }); - it('should print the names and return', done => - runner.executeTransaction(transaction, () => { - assert.isOk(loggerStub.info.called); - done(); - }) - ); + it('should print the names and return', done => runner.executeTransaction(transaction, () => { + assert.isOk(loggerStub.info.called); + done(); + })); }); describe('when a dry run', () => { @@ -436,12 +438,10 @@ describe('TransactionRunner', () => { runner.performRequestAndValidate.restore(); }); - it('should skip the tests', done => - runner.executeTransaction(transaction, () => { - assert.isOk(runner.performRequestAndValidate.notCalled); - done(); - }) - ); + it('should skip the tests', done => runner.executeTransaction(transaction, () => { + assert.isOk(runner.performRequestAndValidate.notCalled); + done(); + })); }); describe('when only certain methods are allowed by the configuration', () => { @@ -456,21 +456,21 @@ describe('TransactionRunner', () => { runner.skipTransaction.restore(); }); - it('should only perform those requests', done => - runner.executeTransaction(transaction, () => { - assert.isOk(runner.skipTransaction.called); - done(); - }) - ); + it('should only perform those requests', done => runner.executeTransaction(transaction, () => { + assert.isOk(runner.skipTransaction.called); + done(); + })); }); describe('when only certain names are allowed by the configuration', () => { beforeEach(() => { server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transaction.expected.status, + .reply( + transaction.expected.status, transaction.expected.body, - { 'Content-Type': 'application/json' }); + { 'Content-Type': 'application/json' } + ); configuration.options.only = ['Group Machine > Machine > Delete Message > Bogus example name']; runner = new Runner(configuration); @@ -483,12 +483,10 @@ describe('TransactionRunner', () => { nock.cleanAll(); }); - it('should not skip transactions with matching names', done => - runner.executeTransaction(transaction, () => { - assert.notOk(runner.skipTransaction.called); - done(); - }) - ); + it('should not skip transactions with matching names', done => runner.executeTransaction(transaction, () => { + assert.notOk(runner.skipTransaction.called); + done(); + })); it('should skip transactions with different names', (done) => { transaction.name = 'Group Machine > Machine > Delete Message > Bogus different example name'; @@ -526,57 +524,49 @@ describe('TransactionRunner', () => { // If you happen to wonder why some of the callbacks in following tests // get executed twice, see try/catch in runHooksForData() in transaction-runner.js - it('should skip the test', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { - assert.isOk(configuration.emitter.emit.calledWith('test skip')); - done(err); - }) - ); - - it('should add skip message as a warning under `general` to the results on transaction', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { - const messages = clonedTransaction.results.general.results.map(value => value.message); - assert.include(messages.join().toLowerCase(), 'skipped'); - done(err); - }) - ); - - it('should add fail message as a warning under `general` to the results on test passed to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map( - value => value.message) - ); - } - assert.include(messages.join().toLowerCase(), 'skipped'); - done(err); - }) - ); - - it('should set status `skip` on test passed to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { - const tests = []; - Object.keys(configuration.emitter.emit.args).forEach((value) => { - const args = configuration.emitter.emit.args[value]; - if (args[0] === 'test skip') { tests.push(args[1]); } - }); + it('should skip the test', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { + assert.isOk(configuration.emitter.emit.calledWith('test skip')); + done(err); + })); + + it('should add skip message as a warning under `general` to the results on transaction', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { + const messages = clonedTransaction.results.general.results.map(value => value.message); + assert.include(messages.join().toLowerCase(), 'skipped'); + done(err); + })); + + it('should add fail message as a warning under `general` to the results on test passed to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map(value => value.message)); + } + assert.include(messages.join().toLowerCase(), 'skipped'); + done(err); + })); + + it('should set status `skip` on test passed to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, (err) => { + const tests = []; + Object.keys(configuration.emitter.emit.args).forEach((value) => { + const args = configuration.emitter.emit.args[value]; + if (args[0] === 'test skip') { tests.push(args[1]); } + }); - assert.equal(tests.length, 1); - assert.equal(tests[0].status, 'skip'); - done(err); - }) - ); + assert.equal(tests.length, 1); + assert.equal(tests[0].status, 'skip'); + done(err); + })); }); describe('when server uses https', () => { beforeEach(() => { server = nock('https://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transaction.expected.status, + .reply( + transaction.expected.status, transaction.expected.body, - { 'Content-Type': 'application/json' }); + { 'Content-Type': 'application/json' } + ); configuration.server = 'https://127.0.0.1:3000'; transaction.protocol = 'https:'; runner = new Runner(configuration); @@ -584,21 +574,21 @@ describe('TransactionRunner', () => { afterEach(() => nock.cleanAll()); - it('should make the request with https', done => - runner.executeTransaction(transaction, () => { - assert.isOk(server.isDone()); - done(); - }) - ); + it('should make the request with https', done => runner.executeTransaction(transaction, () => { + assert.isOk(server.isDone()); + done(); + })); }); describe('when server uses http', () => { beforeEach(() => { server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transaction.expected.status, + .reply( + transaction.expected.status, transaction.expected.body, - { 'Content-Type': 'application/json' }); + { 'Content-Type': 'application/json' } + ); configuration.server = 'http://127.0.0.1:3000'; transaction.protocol = 'http:'; runner = new Runner(configuration); @@ -606,59 +596,55 @@ describe('TransactionRunner', () => { afterEach(() => nock.cleanAll()); - it('should make the request with http', done => - runner.executeTransaction(transaction, () => { - assert.isOk(server.isDone()); - done(); - }) - ); + it('should make the request with http', done => runner.executeTransaction(transaction, () => { + assert.isOk(server.isDone()); + done(); + })); }); describe('when backend responds as it should', () => { beforeEach(() => { server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transaction.expected.status, + .reply( + transaction.expected.status, transaction.expected.body, - { 'Content-Type': 'application/json' }); + { 'Content-Type': 'application/json' } + ); runner = new Runner(configuration); }); afterEach(() => nock.cleanAll()); - it('should perform the request', done => - runner.executeTransaction(transaction, () => { - assert.isOk(server.isDone()); - done(); - }) - ); + it('should perform the request', done => runner.executeTransaction(transaction, () => { + assert.isOk(server.isDone()); + done(); + })); - it('should not return an error', done => - runner.executeTransaction(transaction, (error) => { - assert.notOk(error); - done(); - }) - ); + it('should not return an error', done => runner.executeTransaction(transaction, (error) => { + assert.notOk(error); + done(); + })); }); describe('when backend responds with invalid response', () => { beforeEach(() => { server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(400, + .reply( + 400, 'Foo bar', - { 'Content-Type': 'text/plain' }); + { 'Content-Type': 'text/plain' } + ); runner = new Runner(configuration); }); afterEach(() => nock.cleanAll()); - it('should perform the request', done => - runner.executeTransaction(transaction, () => { - assert.isOk(server.isDone()); - done(); - }) - ); + it('should perform the request', done => runner.executeTransaction(transaction, () => { + assert.isOk(server.isDone()); + done(); + })); }); describe('when backend responds a GET request with a redirection', () => { @@ -670,21 +656,21 @@ describe('TransactionRunner', () => { .get('/machines/latest') .reply(303, '', { Location: '/machines/123' }) .get('/machines/123') - .reply(transaction.expected.status, + .reply( + transaction.expected.status, transaction.expected.body, - { 'Content-Type': 'application/json' }); + { 'Content-Type': 'application/json' } + ); runner = new Runner(configuration); }); afterEach(() => nock.cleanAll()); - it('should not follow the redirect', done => - runner.executeTransaction(transaction, () => { - assert.equal(transaction.real.statusCode, 303); - assert.notOk(server.isDone()); - done(); - }) - ); + it('should not follow the redirect', done => runner.executeTransaction(transaction, () => { + assert.equal(transaction.real.statusCode, 303); + assert.notOk(server.isDone()); + done(); + })); }); describe('when backend responds a POST request with a redirection', () => { @@ -694,21 +680,21 @@ describe('TransactionRunner', () => { .post('/machines') .reply(303, '', { Location: '/machines/123' }) .get('/machines/123') - .reply(transaction.expected.status, + .reply( + transaction.expected.status, transaction.expected.body, - { 'Content-Type': 'application/json' }); + { 'Content-Type': 'application/json' } + ); runner = new Runner(configuration); }); afterEach(() => nock.cleanAll()); - it('should not follow the redirect', done => - runner.executeTransaction(transaction, () => { - assert.equal(transaction.real.statusCode, 303); - assert.notOk(server.isDone()); - done(); - }) - ); + it('should not follow the redirect', done => runner.executeTransaction(transaction, () => { + assert.equal(transaction.real.statusCode, 303); + assert.notOk(server.isDone()); + done(); + })); }); describe('when server is not running', () => { @@ -719,14 +705,12 @@ describe('TransactionRunner', () => { afterEach(() => configuration.emitter.emit.restore()); - it('should report a error', done => - runner.executeTransaction(transaction, () => { - assert.isOk(configuration.emitter.emit.called); - const events = Object.keys(configuration.emitter.emit.args).map(value => configuration.emitter.emit.args[value][0]); - assert.include(events, 'test error'); - done(); - }) - ); + it('should report a error', done => runner.executeTransaction(transaction, () => { + assert.isOk(configuration.emitter.emit.called); + const events = Object.keys(configuration.emitter.emit.args).map(value => configuration.emitter.emit.args[value][0]); + assert.include(events, 'test error'); + done(); + })); }); }); @@ -760,8 +744,7 @@ describe('TransactionRunner', () => { method: 'POST' }, expected: { - headers: { 'content-type': 'application/json' - }, + headers: { 'content-type': 'application/json' }, body: '{\n "type": "bulldozer",\n "name": "willy",\n "id": "5229c6e8e4b0bd7dbb07e29c"\n}\n', statusCode: '202' }, @@ -814,14 +797,16 @@ describe('TransactionRunner', () => { serverNock1 = nock('http://127.0.0.1:3000') .post('/machines1', { type: 'bulldozer', name: 'willy' }) - .reply(transaction.expected.statusCode, + .reply( + transaction.expected.statusCode, transaction.expected.body, { 'Content-Type': 'application/json' } ); serverNock2 = nock('http://127.0.0.1:3000') .post('/machines2', { type: 'bulldozer', name: 'willy' }) - .reply(transaction.expected.statusCode, + .reply( + transaction.expected.statusCode, transaction.expected.body, { 'Content-Type': 'application/json' } ); @@ -843,39 +828,33 @@ describe('TransactionRunner', () => { describe('when the hooks handler is used', () => { describe("and it doesn't crash", () => { - it('should perform all transactions', done => - runner.executeAllTransactions(transactions, hooks, (error) => { - if (error) { return done(error); } - assert.isTrue(serverNock1.isDone(), 'first resource'); - assert.isTrue(serverNock2.isDone(), 'second resource'); - done(); - }) - ); - - it('should execute all ‘all’ hooks once', done => - runner.executeAllTransactions(transactions, hooks, (error) => { - if (error) { return done(error); } - Object.keys(spies).forEach((spyName) => { - if (spyName !== 'beforeAllSpy') { return; } - if (spyName !== 'afterAllSpy') { return; } - assert.isTrue(spies[spyName].called, spyName); - }); - done(); - }) - ); - - it('should execute all other hooks once', done => - runner.executeAllTransactions(transactions, hooks, (error) => { - if (error) { return done(error); } - if (error) { return done(error); } - Object.keys(spies).forEach((spyName) => { - if (spyName !== 'beforeAllSpy') { return; } - if (spyName !== 'afterAllSpy') { return; } - assert.isTrue(spies[spyName].calledTwice, spyName); - }); - done(); - }) - ); + it('should perform all transactions', done => runner.executeAllTransactions(transactions, hooks, (error) => { + if (error) { return done(error); } + assert.isTrue(serverNock1.isDone(), 'first resource'); + assert.isTrue(serverNock2.isDone(), 'second resource'); + done(); + })); + + it('should execute all ‘all’ hooks once', done => runner.executeAllTransactions(transactions, hooks, (error) => { + if (error) { return done(error); } + Object.keys(spies).forEach((spyName) => { + if (spyName !== 'beforeAllSpy') { return; } + if (spyName !== 'afterAllSpy') { return; } + assert.isTrue(spies[spyName].called, spyName); + }); + done(); + })); + + it('should execute all other hooks once', done => runner.executeAllTransactions(transactions, hooks, (error) => { + if (error) { return done(error); } + if (error) { return done(error); } + Object.keys(spies).forEach((spyName) => { + if (spyName !== 'beforeAllSpy') { return; } + if (spyName !== 'afterAllSpy') { return; } + assert.isTrue(spies[spyName].calledTwice, spyName); + }); + done(); + })); }); describe('and it crashes (hook handler error was set)', () => { @@ -1275,8 +1254,7 @@ describe('TransactionRunner', () => { method: 'POST' }, expected: { - headers: { 'content-type': 'application/json' - }, + headers: { 'content-type': 'application/json' }, body: '{\n "type": "bulldozer",\n "name": "willy",\n "id": "5229c6e8e4b0bd7dbb07e29c"\n}\n', statusCode: '202' }, @@ -1292,9 +1270,11 @@ describe('TransactionRunner', () => { server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transaction.expected.statusCode, + .reply( + transaction.expected.statusCode, transaction.expected.body, - { 'Content-Type': 'application/json' }); + { 'Content-Type': 'application/json' } + ); transactions = {}; transactions[transaction.name] = clone(transaction, false); @@ -1332,14 +1312,12 @@ describe('TransactionRunner', () => { afterEach(() => loggerStub.info.restore()); - it('should run the hooks', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.isOk(loggerStub.info.calledWith('before')); - assert.isOk(loggerStub.info.calledWith('beforeValidation')); - assert.isOk(loggerStub.info.calledWith('after')); - done(); - }) - ); + it('should run the hooks', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.isOk(loggerStub.info.calledWith('before')); + assert.isOk(loggerStub.info.calledWith('beforeValidation')); + assert.isOk(loggerStub.info.calledWith('after')); + done(); + })); }); describe('with hooks, but without hooks.transactions set', () => { @@ -1400,13 +1378,11 @@ describe('TransactionRunner', () => { afterEach(() => loggerStub.info.restore()); - it('should run all hooks', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.isOk(loggerStub.info.calledWith('first')); - assert.isOk(loggerStub.info.calledWith('second')); - done(); - }) - ); + it('should run all hooks', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.isOk(loggerStub.info.calledWith('first')); + assert.isOk(loggerStub.info.calledWith('second')); + done(); + })); }); describe('‘*All’ hooks with legacy async interface (fist argument is a callback)', () => { @@ -1422,13 +1398,11 @@ describe('TransactionRunner', () => { runner.hooks.beforeAll(beforeAllStubAnother); }); - it('should run the hooks', done => - runner.executeAllTransactions([], runner.hooks, () => { - assert.isOk(beforeAllStub.called); - assert.isOk(beforeAllStubAnother.called); - done(); - }) - ); + it('should run the hooks', done => runner.executeAllTransactions([], runner.hooks, () => { + assert.isOk(beforeAllStub.called); + assert.isOk(beforeAllStubAnother.called); + done(); + })); }); describe('with an ‘afterAll’ hook', () => { @@ -1443,13 +1417,11 @@ describe('TransactionRunner', () => { runner.hooks.afterAll(afterAllStubAnother); }); - it('should run the hooks', done => - runner.executeAllTransactions([], runner.hooks, () => { - assert.isOk(afterAllStub.called); - assert.isOk(afterAllStubAnother.called); - done(); - }) - ); + it('should run the hooks', done => runner.executeAllTransactions([], runner.hooks, () => { + assert.isOk(afterAllStub.called); + assert.isOk(afterAllStubAnother.called); + done(); + })); }); describe('with multiple hooks for the same events', () => { @@ -1467,16 +1439,14 @@ describe('TransactionRunner', () => { runner.hooks.beforeAll(beforeAllStub2); }); - it('should run all the events in order', done => - runner.executeAllTransactions([], runner.hooks, () => { - assert.isOk(beforeAllStub1.calledBefore(beforeAllStub2)); - assert.isOk(beforeAllStub2.called); - assert.isOk(beforeAllStub2.calledBefore(afterAllStub1)); - assert.isOk(afterAllStub1.calledBefore(afterAllStub2)); - assert.isOk(afterAllStub2.called); - done(); - }) - ); + it('should run all the events in order', done => runner.executeAllTransactions([], runner.hooks, () => { + assert.isOk(beforeAllStub1.calledBefore(beforeAllStub2)); + assert.isOk(beforeAllStub2.called); + assert.isOk(beforeAllStub2.calledBefore(afterAllStub1)); + assert.isOk(afterAllStub1.calledBefore(afterAllStub2)); + assert.isOk(afterAllStub2.called); + done(); + })); }); }); @@ -1489,12 +1459,10 @@ describe('TransactionRunner', () => { beforeEach(() => runner.hooks.beforeAll(beforeAllStub)); - it('should run the hooks', done => - runner.executeAllTransactions([], runner.hooks, () => { - assert.isOk(beforeAllStub.called); - done(); - }) - ); + it('should run the hooks', done => runner.executeAllTransactions([], runner.hooks, () => { + assert.isOk(beforeAllStub.called); + done(); + })); }); describe('with an ‘afterAll’ hook', () => { @@ -1505,12 +1473,10 @@ describe('TransactionRunner', () => { beforeEach(() => runner.hooks.afterAll(afterAllStub)); - it('should run the hooks', done => - runner.executeAllTransactions([], runner.hooks, () => { - assert.isOk(afterAllStub.called); - done(); - }) - ); + it('should run the hooks', done => runner.executeAllTransactions([], runner.hooks, () => { + assert.isOk(afterAllStub.called); + done(); + })); }); describe('with multiple hooks for the same events', () => { @@ -1529,150 +1495,144 @@ describe('TransactionRunner', () => { runner.hooks.beforeAll(beforeAllStub2); }); - it('should run all the events in order', done => - runner.executeAllTransactions([], runner.hooks, () => { - assert.isOk(beforeAllStub1.calledBefore(beforeAllStub2)); - assert.isOk(beforeAllStub2.called); - assert.isOk(beforeAllStub2.calledBefore(afterAllStub1)); - assert.isOk(afterAllStub1.calledBefore(afterAllStub2)); - assert.isOk(afterAllStub2.called); - done(); - }) - ); + it('should run all the events in order', done => runner.executeAllTransactions([], runner.hooks, () => { + assert.isOk(beforeAllStub1.calledBefore(beforeAllStub2)); + assert.isOk(beforeAllStub2.called); + assert.isOk(beforeAllStub2.calledBefore(afterAllStub1)); + assert.isOk(afterAllStub1.calledBefore(afterAllStub2)); + assert.isOk(afterAllStub2.called); + done(); + })); }); }); - describe('‘*All’ hooks with sandboxed API (functions as strings)', () => - describe('with a ‘beforeAll’ hook', () => { - beforeEach(() => - sinon.stub(configuration.emitter, 'emit').callsFake(() => { }) - ); + describe('‘*All’ hooks with sandboxed API (functions as strings)', () => describe('with a ‘beforeAll’ hook', () => { + beforeEach(() => sinon.stub(configuration.emitter, 'emit').callsFake(() => { })); - afterEach(() => configuration.emitter.emit.restore()); + afterEach(() => configuration.emitter.emit.restore()); - it('should run the code and emit an error', (done) => { - const functionString = `\ + it('should run the code and emit an error', (done) => { + const functionString = `\ function(transactions){ throw(new Error('Exploded inside sandbox')); }\ `; - runner.hooks.beforeAll(functionString); + runner.hooks.beforeAll(functionString); - runner.executeAllTransactions([], runner.hooks, (err) => { - assert.isOk(configuration.emitter.emit.calledWith('test error')); - done(err); - }); + runner.executeAllTransactions([], runner.hooks, (err) => { + assert.isOk(configuration.emitter.emit.calledWith('test error')); + done(err); }); + }); - it('should not have access to require', (done) => { - const functionString = `\ + it('should not have access to require', (done) => { + const functionString = `\ function(transactions){ require('fs'); }\ `; - runner.hooks.beforeAll(functionString); + runner.hooks.beforeAll(functionString); - runner.executeAllTransactions([], runner.hooks, (err) => { - const call = configuration.emitter.emit.getCall(0); - assert.isOk(configuration.emitter.emit.calledWith('test error')); - assert.include(call.args[1].message, 'require'); - done(err); - }); + runner.executeAllTransactions([], runner.hooks, (err) => { + const call = configuration.emitter.emit.getCall(0); + assert.isOk(configuration.emitter.emit.calledWith('test error')); + assert.include(call.args[1].message, 'require'); + done(err); }); + }); - it('should not have access to current context', (done) => { - const contextVar = 'this'; - const functionString = `\ + it('should not have access to current context', (done) => { + const contextVar = 'this'; + const functionString = `\ function(transactions){ contextVar = "that"; }\ `; - runner.hooks.beforeAll(functionString); + runner.hooks.beforeAll(functionString); - runner.executeAllTransactions([], runner.hooks, (err) => { - assert.equal(contextVar, 'this'); - done(err); - }); + runner.executeAllTransactions([], runner.hooks, (err) => { + assert.equal(contextVar, 'this'); + done(err); }); + }); - it('should have access to the hook stash', (done) => { - const functionString = `\ + it('should have access to the hook stash', (done) => { + const functionString = `\ function(transactions){ stash.prop = 'that'; }\ `; - runner.hooks.beforeAll(functionString); + runner.hooks.beforeAll(functionString); - runner.executeAllTransactions([], runner.hooks, (err) => { - assert.notOk(configuration.emitter.emit.calledWith('test error')); - done(err); - }); + runner.executeAllTransactions([], runner.hooks, (err) => { + assert.notOk(configuration.emitter.emit.calledWith('test error')); + done(err); }); + }); - it('should be able to modify hook stash', (done) => { - const functionString = `\ + it('should be able to modify hook stash', (done) => { + const functionString = `\ function(transactions){ stash.prop = 'that'; }\ `; - runner.hooks.beforeAll(functionString); + runner.hooks.beforeAll(functionString); - runner.executeAllTransactions([], runner.hooks, (err) => { - assert.notOk(configuration.emitter.emit.calledWith('test error')); - assert.property(runner.hookStash, 'prop'); - done(err); - }); + runner.executeAllTransactions([], runner.hooks, (err) => { + assert.notOk(configuration.emitter.emit.calledWith('test error')); + assert.property(runner.hookStash, 'prop'); + done(err); }); + }); - it('should be able to modify transactions', (done) => { - const functionString = `\ + it('should be able to modify transactions', (done) => { + const functionString = `\ function(transactions){ transactions[0].name = 'Changed!'; }\ `; - runner.hooks.beforeAll(functionString); + runner.hooks.beforeAll(functionString); - transactions = [{ - name: 'Test!', - request: { headers: {}, body: '' }, - skip: true - } - ]; + transactions = [{ + name: 'Test!', + request: { headers: {}, body: '' }, + skip: true + } + ]; - runner.executeAllTransactions(transactions, runner.hooks, (err) => { - assert.notOk(configuration.emitter.emit.calledWith('test error')); - assert.equal(transactions[0].name, 'Changed!'); - done(err); - }); + runner.executeAllTransactions(transactions, runner.hooks, (err) => { + assert.notOk(configuration.emitter.emit.calledWith('test error')); + assert.equal(transactions[0].name, 'Changed!'); + done(err); }); + }); - it('should be able to call "log" from inside the function', (done) => { - const functionString = `\ + it('should be able to call "log" from inside the function', (done) => { + const functionString = `\ function(transactions){ log(transactions[0].name); transactions[0].name = 'Changed!'; }\ `; - runner.hooks.beforeAll(functionString); + runner.hooks.beforeAll(functionString); - transactions = [{ - name: 'Test!', - request: { headers: {}, body: '' }, - skip: true - } - ]; - - runner.executeAllTransactions(transactions, runner.hooks, (err) => { - assert.notOk(configuration.emitter.emit.calledWith('test error')); - assert.equal(transactions[0].name, 'Changed!'); - assert.isArray(runner.logs); - assert.lengthOf(runner.logs, 1); - assert.propertyVal(runner.logs[0], 'content', 'Test!'); - done(err); - }); + transactions = [{ + name: 'Test!', + request: { headers: {}, body: '' }, + skip: true + } + ]; + + runner.executeAllTransactions(transactions, runner.hooks, (err) => { + assert.notOk(configuration.emitter.emit.calledWith('test error')); + assert.equal(transactions[0].name, 'Changed!'); + assert.isArray(runner.logs); + assert.lengthOf(runner.logs, 1); + assert.propertyVal(runner.logs[0], 'content', 'Test!'); + done(err); }); - }) - ); + }); + })); describe('*Each hooks with standard async API (first argument transactions, second callback)', () => { const transactionsForExecution = []; @@ -1694,8 +1654,7 @@ function(transactions){ method: 'POST' }, expected: { - headers: { 'content-type': 'application/json' - }, + headers: { 'content-type': 'application/json' }, body: '{\n "type": "bulldozer",\n "name": "willy",\n "id": "5229c6e8e4b0bd7dbb07e29c"\n}\n', statusCode: '202' }, @@ -1726,7 +1685,8 @@ function(transactions){ runner.hooks.beforeEach(beforeEachStub); server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transactionsForExecution[0].expected.statusCode, + .reply( + transactionsForExecution[0].expected.statusCode, transactionsForExecution[0].expected.body, { 'Content-Type': 'application/json' } ); @@ -1737,19 +1697,15 @@ function(transactions){ nock.cleanAll(); }); - it('should run the hooks', done => - runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { - assert.isOk(beforeEachStub.called); - done(); - }) - ); + it('should run the hooks', done => runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { + assert.isOk(beforeEachStub.called); + done(); + })); - it('should run the hook for each transaction', done => - runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { - assert.equal(beforeEachStub.callCount, transactionsForExecution.length); - done(); - }) - ); + it('should run the hook for each transaction', done => runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { + assert.equal(beforeEachStub.callCount, transactionsForExecution.length); + done(); + })); }); describe('with a ‘beforeEachValidation’ hook', () => { @@ -1765,7 +1721,8 @@ function(transactions){ runner.hooks.beforeEachValidation(beforeEachValidationStub); server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transactionsForExecution[0].expected.statusCode, + .reply( + transactionsForExecution[0].expected.statusCode, transactionsForExecution[0].expected.body, { 'Content-Type': 'application/json' } ); @@ -1794,12 +1751,10 @@ function(transactions){ }); }); - it('should run the hook for each transaction', done => - runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { - assert.equal(beforeEachValidationStub.callCount, transactionsForExecution.length); - done(); - }) - ); + it('should run the hook for each transaction', done => runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { + assert.equal(beforeEachValidationStub.callCount, transactionsForExecution.length); + done(); + })); }); describe('with a ‘afterEach’ hook', () => { @@ -1812,7 +1767,8 @@ function(transactions){ runner.hooks.afterEach(afterEachStub); server = nock('http://127.0.0.1:3000') .post('/machines', { type: 'bulldozer', name: 'willy' }) - .reply(transactionsForExecution[0].expected.statusCode, + .reply( + transactionsForExecution[0].expected.statusCode, transactionsForExecution[0].expected.body, { 'Content-Type': 'application/json' } ); @@ -1823,19 +1779,15 @@ function(transactions){ nock.cleanAll(); }); - it('should run the hooks', done => - runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { - assert.isOk(afterEachStub.called); - done(); - }) - ); + it('should run the hooks', done => runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { + assert.isOk(afterEachStub.called); + done(); + })); - it('should run the hook for each transaction', done => - runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { - assert.equal(afterEachStub.callCount, transactionsForExecution.length); - done(); - }) - ); + it('should run the hook for each transaction', done => runner.executeAllTransactions(transactionsForExecution, runner.hooks, () => { + assert.equal(afterEachStub.callCount, transactionsForExecution.length); + done(); + })); }); describe('with multiple hooks for the same events', () => { @@ -1854,15 +1806,13 @@ function(transactions){ runner.hooks.beforeAll(beforeAllStub2); }); - it('should run all the events in order', done => - runner.executeAllTransactions([], runner.hooks, () => { - assert.isOk(beforeAllStub1.calledBefore(beforeAllStub2)); - assert.isOk(beforeAllStub2.called); - assert.isOk(afterAllStub1.calledBefore(afterAllStub2)); - assert.isOk(afterAllStub2.called); - done(); - }) - ); + it('should run all the events in order', done => runner.executeAllTransactions([], runner.hooks, () => { + assert.isOk(beforeAllStub1.calledBefore(beforeAllStub2)); + assert.isOk(beforeAllStub2.called); + assert.isOk(afterAllStub1.calledBefore(afterAllStub2)); + assert.isOk(afterAllStub2.called); + done(); + })); }); }); @@ -1879,12 +1829,10 @@ function(transactions){ afterEach(() => configuration.emitter.emit.restore()); - it('should report an error with the test', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.isOk(configuration.emitter.emit.calledWith('test error')); - done(); - }) - ); + it('should report an error with the test', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.isOk(configuration.emitter.emit.calledWith('test error')); + done(); + })); }); describe('with ‘after’ hook that throws an error', () => { @@ -1900,12 +1848,10 @@ function(transactions){ afterEach(() => configuration.emitter.emit.restore()); - it('should report an error with the test', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.isOk(configuration.emitter.emit.calledWith('test error')); - done(); - }) - ); + it('should report an error with the test', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.isOk(configuration.emitter.emit.calledWith('test error')); + done(); + })); }); describe('with ‘before’ hook that throws a chai expectation error', () => { @@ -1921,41 +1867,31 @@ function(transactions){ afterEach(() => configuration.emitter.emit.restore()); - it('should not report an error', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.notOk(configuration.emitter.emit.calledWith('test error')); - done(); - }) - ); - - it('should report a fail', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.isOk(configuration.emitter.emit.calledWith('test fail')); - done(); - }) - ); - - it('should add fail message as a error under `general` to the results on transaction', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - const messages = transaction.results.general.results.map(value => value.message); - assert.include(messages.join(), 'expected false to be truthy'); - done(); - }) - ); - - it('should add fail message as a error under `general` to the results on test passed to the emitter', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map( - value => value.message - )); - } - assert.include(messages.join(), 'expected false to be truthy'); - done(); - }) - ); + it('should not report an error', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.notOk(configuration.emitter.emit.calledWith('test error')); + done(); + })); + + it('should report a fail', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.isOk(configuration.emitter.emit.calledWith('test fail')); + done(); + })); + + it('should add fail message as a error under `general` to the results on transaction', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + const messages = transaction.results.general.results.map(value => value.message); + assert.include(messages.join(), 'expected false to be truthy'); + done(); + })); + + it('should add fail message as a error under `general` to the results on test passed to the emitter', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map(value => value.message)); + } + assert.include(messages.join(), 'expected false to be truthy'); + done(); + })); }); describe('with ‘after’ hook that throws a chai expectation error', () => { @@ -1971,48 +1907,36 @@ function(transactions){ afterEach(() => configuration.emitter.emit.restore()); - it('should not report an error', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.notOk(configuration.emitter.emit.calledWith('test error')); - done(); - }) - ); - - it('should report a fail', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.isOk(configuration.emitter.emit.calledWith('test fail')); - done(); - }) - ); - - it('should set test as failed', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - assert.equal(transaction.test.status, 'fail'); - done(); - }) - ); - - it('should add fail message as a error under `general` to the results on transaction', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - const messages = transaction.results.general.results.map(value => value.message); - assert.include(messages.join(), 'expected false to be truthy'); - done(); - }) - ); - - it('should add fail message as a error under `general` to the results on test passed to the emitter', done => - runner.executeAllTransactions([transaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map( - value => value.message - )); - } - assert.include(messages.join(), 'expected false to be truthy'); - done(); - }) - ); + it('should not report an error', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.notOk(configuration.emitter.emit.calledWith('test error')); + done(); + })); + + it('should report a fail', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.isOk(configuration.emitter.emit.calledWith('test fail')); + done(); + })); + + it('should set test as failed', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + assert.equal(transaction.test.status, 'fail'); + done(); + })); + + it('should add fail message as a error under `general` to the results on transaction', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + const messages = transaction.results.general.results.map(value => value.message); + assert.include(messages.join(), 'expected false to be truthy'); + done(); + })); + + it('should add fail message as a error under `general` to the results on test passed to the emitter', done => runner.executeAllTransactions([transaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map(value => value.message)); + } + assert.include(messages.join(), 'expected false to be truthy'); + done(); + })); }); describe('with hook failing the transaction', () => { @@ -2030,122 +1954,98 @@ function(transactions){ afterEach(() => configuration.emitter.emit.restore()); - it('should fail the test', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - assert.isOk(configuration.emitter.emit.calledWith('test fail')); - done(); - }) - ); + it('should fail the test', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + assert.isOk(configuration.emitter.emit.calledWith('test fail')); + done(); + })); - it('should not run the transaction', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - assert.notOk(server.isDone()); - done(); - }) - ); + it('should not run the transaction', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + assert.notOk(server.isDone()); + done(); + })); + + it('should pass the failing message to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + assert.include(messages.join(), 'Message before'); + done(); + })); + + it('should mention before hook in the error message', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + assert.include(messages.join(), 'Failed in before hook:'); + done(); + })); - it('should pass the failing message to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + it('should add fail message as a error under `general` to the results on the transaction', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = clonedTransaction.results.general.results.map(value => value.message); + assert.include(messages.join(), 'Message before'); + done(); + })); + + it('should add fail message as a error under `general` to the results on test passed to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map(value => value.message)); + } + assert.include(messages.join(), 'Message before'); + done(); + })); + + describe('when message is set to fail also in ‘after’ hook', () => { + clonedTransaction = null; + beforeEach(() => { + clonedTransaction = clone(transaction); + runner.hooks.afterHooks = { + 'Group Machine > Machine > Delete Message > Bogus example name': [ + (hookTransaction) => { hookTransaction.fail = 'Message after'; } + ] + }; + }); + + it('should not pass the failing message to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { const messages = []; const { callCount } = configuration.emitter.emit; for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); } - assert.include(messages.join(), 'Message before'); + assert.notInclude(messages.join(), 'Message after fail'); done(); - }) - ); + })); - it('should mention before hook in the error message', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + it('should not mention after hook in the error message', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { const messages = []; const { callCount } = configuration.emitter.emit; for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); } - assert.include(messages.join(), 'Failed in before hook:'); + assert.notInclude(messages.join(), 'Failed in after hook:'); done(); - }) - ); + })); - it('should add fail message as a error under `general` to the results on the transaction', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + it('should not add fail message as a error under `general` to the results on the transaction', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { const messages = clonedTransaction.results.general.results.map(value => value.message); - assert.include(messages.join(), 'Message before'); + assert.notInclude(messages.join(), 'Message after fail'); done(); - }) - ); + })); - it('should add fail message as a error under `general` to the results on test passed to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + it('should not add fail message as a error under `general` to the results on test passed to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { const messages = []; const { callCount } = configuration.emitter.emit; for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map( - value => value.message) - ); + messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map(value => value.message)); } - assert.include(messages.join(), 'Message before'); + assert.notInclude(messages.join(), 'Message after fail'); done(); - }) - ); - - describe('when message is set to fail also in ‘after’ hook', () => { - clonedTransaction = null; - beforeEach(() => { - clonedTransaction = clone(transaction); - runner.hooks.afterHooks = { - 'Group Machine > Machine > Delete Message > Bogus example name': [ - (hookTransaction) => { hookTransaction.fail = 'Message after'; } - ] - }; - }); - - it('should not pass the failing message to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - assert.notInclude(messages.join(), 'Message after fail'); - done(); - }) - ); - - it('should not mention after hook in the error message', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - assert.notInclude(messages.join(), 'Failed in after hook:'); - done(); - }) - ); - - it('should not add fail message as a error under `general` to the results on the transaction', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = clonedTransaction.results.general.results.map(value => value.message); - assert.notInclude(messages.join(), 'Message after fail'); - done(); - }) - ); - - it('should not add fail message as a error under `general` to the results on test passed to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map( - value => value.message - )); - } - assert.notInclude(messages.join(), 'Message after fail'); - done(); - }) - ); + })); }); }); @@ -2168,72 +2068,58 @@ function(transactions){ configuration.emitter.emit.restore(); }); - it('should make the request', done => - runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { - assert.isOk(server.isDone()); - done(); - }) - ); + it('should make the request', done => runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { + assert.isOk(server.isDone()); + done(); + })); - it('should not fail again', done => - runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { - let failCount = 0; - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - if (configuration.emitter.emit.getCall(callNo).args[0] === 'test fail') { failCount++; } - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - assert.equal(failCount, 1); - done(); - }) - ); + it('should not fail again', done => runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { + let failCount = 0; + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + if (configuration.emitter.emit.getCall(callNo).args[0] === 'test fail') { failCount++; } + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + assert.equal(failCount, 1); + done(); + })); - it('should not pass the hook message to the emitter', done => - runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - assert.notInclude(messages, 'Message after fail'); - done(); - }) - ); + it('should not pass the hook message to the emitter', done => runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + assert.notInclude(messages, 'Message after fail'); + done(); + })); - it('should not mention after hook in the error message', done => - runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - assert.notInclude(messages, 'Failed in after hook:'); - done(); - }) - ); + it('should not mention after hook in the error message', done => runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + assert.notInclude(messages, 'Failed in after hook:'); + done(); + })); - it('should not add fail message as a error under `general` to the results on the transaction', done => - runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { - const messages = modifiedTransaction.results.general.results.map(value => value.message); - assert.notInclude(messages.join(), 'Message after fail'); - done(); - }) - ); + it('should not add fail message as a error under `general` to the results on the transaction', done => runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { + const messages = modifiedTransaction.results.general.results.map(value => value.message); + assert.notInclude(messages.join(), 'Message after fail'); + done(); + })); - it('should not add fail message as a error under `general` to the results on test passed to the emitter', done => - runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map( - value => value.message - )); - } - assert.notInclude(messages.join(), 'Message after fail'); - done(); - }) - ); + it('should not add fail message as a error under `general` to the results on test passed to the emitter', done => runner.executeAllTransactions([modifiedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map(value => value.message)); + } + assert.notInclude(messages.join(), 'Message after fail'); + done(); + })); }); describe('in ‘after’ hook when transaction passes ', () => { @@ -2253,79 +2139,61 @@ function(transactions){ configuration.emitter.emit.restore(); }); - it('should make the request', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - assert.isOk(server.isDone()); - done(); - }) - ); + it('should make the request', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + assert.isOk(server.isDone()); + done(); + })); - it('it should fail the test', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - assert.isOk(configuration.emitter.emit.calledWith('test fail')); - done(); - }) - ); + it('it should fail the test', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + assert.isOk(configuration.emitter.emit.calledWith('test fail')); + done(); + })); - it('it should not pass the test', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - assert.notOk(configuration.emitter.emit.calledWith('test pass')); - done(); - }) - ); + it('it should not pass the test', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + assert.notOk(configuration.emitter.emit.calledWith('test pass')); + done(); + })); - it('it should pass the failing message to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - assert.include(messages.join(), 'Message after pass'); - done(); - }) - ); + it('it should pass the failing message to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + assert.include(messages.join(), 'Message after pass'); + done(); + })); - it('should mention after hook in the error message', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - assert.include(messages.join(), 'Failed in after hook:'); - done(); - }) - ); + it('should mention after hook in the error message', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + assert.include(messages.join(), 'Failed in after hook:'); + done(); + })); - it('should set transaction test status to failed', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - assert.equal(clonedTransaction.test.status, 'fail'); - done(); - }) - ); + it('should set transaction test status to failed', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + assert.equal(clonedTransaction.test.status, 'fail'); + done(); + })); - it('should add fail message as a error under `general` to the results', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = clonedTransaction.results.general.results.map(value => value.message); - assert.include(messages.join(), 'Message after pass'); - done(); - }) - ); + it('should add fail message as a error under `general` to the results', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = clonedTransaction.results.general.results.map(value => value.message); + assert.include(messages.join(), 'Message after pass'); + done(); + })); - it('should not add fail message as a error under `general` to the results on test passed to the emitter', done => - runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map( - value => value.message - )); - } - assert.include(messages.join(), 'Message after pass'); - done(); - }) - ); + it('should not add fail message as a error under `general` to the results on test passed to the emitter', done => runner.executeAllTransactions([clonedTransaction], runner.hooks, () => { + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].results.general.results.map(value => value.message)); + } + assert.include(messages.join(), 'Message after pass'); + done(); + })); }); }); @@ -2337,17 +2205,13 @@ function(transactions){ configuration.emitter.emit.restore(); }); - it('should not run the hooks', done => - runner.executeAllTransactions([transaction], runner.hooks, () => done()) - ); + it('should not run the hooks', done => runner.executeAllTransactions([transaction], runner.hooks, () => done())); - it('should pass the transactions', done => - runner.executeAllTransactions([transaction], runner.hooks, (error) => { - if (error) { done(error); } - assert.isOk(configuration.emitter.emit.calledWith('test pass')); - done(); - }) - ); + it('should pass the transactions', done => runner.executeAllTransactions([transaction], runner.hooks, (error) => { + if (error) { done(error); } + assert.isOk(configuration.emitter.emit.calledWith('test pass')); + done(); + })); }); describe('with hook modifying the transaction body and backend Express app using the body parser', () => { @@ -2380,13 +2244,11 @@ function(transactions){ res.json([{ type: 'bulldozer', name: 'willy' }]); }); - server = app.listen(transaction.port, () => - runner.executeAllTransactions([transaction], runner.hooks, () => { - // Should not hang here - assert.isOk(true); - server.close(); - }) - ); + server = app.listen(transaction.port, () => runner.executeAllTransactions([transaction], runner.hooks, () => { + // Should not hang here + assert.isOk(true); + server.close(); + })); server.on('close', () => { assert.equal(receivedRequests.length, 1); @@ -2396,173 +2258,167 @@ function(transactions){ }); }); - describe('runHooksForData(hooks, data, legacy = true, callback)', () => - describe('when legacy is false', () => - describe('and an exception in hook appears', () => { - before(() => { - configuration = { emitter: new EventEmitter() }; + describe('runHooksForData(hooks, data, legacy = true, callback)', () => describe('when legacy is false', () => describe('and an exception in hook appears', () => { + before(() => { + configuration = { emitter: new EventEmitter() }; - runner = new Runner(configuration); + runner = new Runner(configuration); - sinon.stub(configuration.emitter, 'emit'); - }); + sinon.stub(configuration.emitter, 'emit'); + }); - after(() => configuration.emitter.emit.restore()); + after(() => configuration.emitter.emit.restore()); - it('should be called with warning containing error message', (done) => { - const hook = `\ + it('should be called with warning containing error message', (done) => { + const hook = `\ function(transcaction){ throw(new Error("Throwed message")) }\ `; - runner.runHooksForData([hook], {}, false, () => { - assert.isOk(configuration.emitter.emit.calledWith('test error')); - const messages = []; - const { callCount } = configuration.emitter.emit; - for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { - messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); - } - done(); - }); - }); - }) - ) - ); - - describe('runHook(hook, transaction, callback)', () => - describe('when sandbox mode is on (hook function is a string)', () => { - before(() => { - configuration = {}; - runner = new Runner(configuration); + runner.runHooksForData([hook], {}, false, () => { + assert.isOk(configuration.emitter.emit.calledWith('test error')); + const messages = []; + const { callCount } = configuration.emitter.emit; + for (let callNo = 0, end = callCount - 1, asc = end >= 0; asc ? callNo <= end : callNo >= end; asc ? callNo++ : callNo--) { + messages.push(configuration.emitter.emit.getCall(callNo).args[1].message); + } + done(); }); + }); + }))); - it('should execute the code of hook', (done) => { - const hook = `\ + describe('runHook(hook, transaction, callback)', () => describe('when sandbox mode is on (hook function is a string)', () => { + before(() => { + configuration = {}; + runner = new Runner(configuration); + }); + + it('should execute the code of hook', (done) => { + const hook = `\ function(transaction){ throw(new Error('Exploded inside a sandboxed hook')); }\ `; - runner.runHook(hook, {}, (err) => { - assert.include(err, 'sandbox'); - done(); - }); + runner.runHook(hook, {}, (err) => { + assert.include(err, 'sandbox'); + done(); }); + }); - it('should not have aceess to current context', (done) => { - const contextVar = 'this'; - const hook = `\ + it('should not have aceess to current context', (done) => { + const contextVar = 'this'; + const hook = `\ function(transaction){ contextVar = "that"; }\ `; - runner.runHook(hook, {}, () => { - assert.equal(contextVar, 'this'); - done(); - }); + runner.runHook(hook, {}, () => { + assert.equal(contextVar, 'this'); + done(); }); + }); - it('should not have access to require', (done) => { - const hook = `\ + it('should not have access to require', (done) => { + const hook = `\ function(transaction){ require('fs'); }\ `; - runner.runHook(hook, {}, (err) => { - assert.include(err, 'require'); - done(); - }); + runner.runHook(hook, {}, (err) => { + assert.include(err, 'require'); + done(); }); + }); - it('should have access to the hook stash', (done) => { - const hook = `\ + it('should have access to the hook stash', (done) => { + const hook = `\ function(transaction){ stash['prop'] = 'that'; }\ `; - runner.runHook(hook, {}, (err) => { - if (err) { return done(new Error(err)); } - assert.isUndefined(err); - done(); - }); + runner.runHook(hook, {}, (err) => { + if (err) { return done(new Error(err)); } + assert.isUndefined(err); + done(); }); + }); - it('should be able to modify hook stash', (done) => { - const hook = `\ + it('should be able to modify hook stash', (done) => { + const hook = `\ function(transaction){ stash['prop'] = 'that'; }\ `; - runner.runHook(hook, {}, (err) => { - if (err) { return done(new Error(err)); } - assert.property(runner.hookStash, 'prop'); - done(); - }); + runner.runHook(hook, {}, (err) => { + if (err) { return done(new Error(err)); } + assert.property(runner.hookStash, 'prop'); + done(); }); + }); - it('should be able to modify hook stash multiple times', (done) => { - let hook = `\ + it('should be able to modify hook stash multiple times', (done) => { + let hook = `\ function(transaction){ stash['prop'] = 'that'; }\ `; - runner.runHook(hook, {}, (err) => { - if (err) { return done(new Error(err)); } - assert.property(runner.hookStash, 'prop'); + runner.runHook(hook, {}, (err) => { + if (err) { return done(new Error(err)); } + assert.property(runner.hookStash, 'prop'); - hook = `\ + hook = `\ function(transaction){ stash['prop2'] = 'that'; }\ `; - runner.runHook(hook, {}, (error) => { - if (error) { return done(new Error(error)); } - assert.property(runner.hookStash, 'prop'); - assert.property(runner.hookStash, 'prop2'); + runner.runHook(hook, {}, (error) => { + if (error) { return done(new Error(error)); } + assert.property(runner.hookStash, 'prop'); + assert.property(runner.hookStash, 'prop2'); - done(); - }); + done(); }); }); + }); - it('should be able to modify the transaction', (done) => { - const hook = `\ + it('should be able to modify the transaction', (done) => { + const hook = `\ function(transaction){ transaction['prop'] = 'that'; }\ `; - transaction = { some: 'mess' }; - runner.runHook(hook, transaction, (err) => { - if (err) { return done(new Error(err)); } - assert.property(transaction, 'prop'); - done(); - }); + transaction = { some: 'mess' }; + runner.runHook(hook, transaction, (err) => { + if (err) { return done(new Error(err)); } + assert.property(transaction, 'prop'); + done(); }); + }); - it('should have access to log', (done) => { - const hook = `\ + it('should have access to log', (done) => { + const hook = `\ function(transaction){ log('log test'); }\ `; - runner.runHook(hook, {}, (err) => { - if (err) { return done(new Error(err)); } - done(); - }); + runner.runHook(hook, {}, (err) => { + if (err) { return done(new Error(err)); } + done(); }); + }); - it('should NOT have access to console', (done) => { - const hook = `\ + it('should NOT have access to console', (done) => { + const hook = `\ function(transaction){ console.log('console test'); }\ `; - runner.runHook(hook, {}, (err) => { - assert.isDefined(err); - assert.include(err, 'Cannot read property \'log\' of undefined'); - done(); - }); + runner.runHook(hook, {}, (err) => { + assert.isDefined(err); + assert.include(err, 'Cannot read property \'log\' of undefined'); + done(); }); - }) - ); + }); + })); });