From 85470a01c59874ac71c5f837f7507f5f2252e993 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 06:01:59 +0530 Subject: [PATCH 01/13] [caller] Added normalising caller --- src/lib/unit/caller.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/lib/unit/caller.js diff --git a/src/lib/unit/caller.js b/src/lib/unit/caller.js new file mode 100644 index 0000000..a11d8cc --- /dev/null +++ b/src/lib/unit/caller.js @@ -0,0 +1,28 @@ +const { isPromise } = require('../../util'); + +const caller = (test, state) => { + + let value, error; + try { + value = test(state); + } catch (e) { + error = e; + } + + const promise = isPromise(value); + + if (promise) { + return value + .then(res => ({ resolve: res, promise: true })) + .catch(rej => ({ rejection: rej, promise: true })); + } else { + return Promise.resolve({ + ...(!error && {value}), + ...(error && {error}), + promise: false, + }); + } + +}; + +module.exports = caller; From dc8e9f538928bad866e7d1058d666a47ac20f780 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 06:03:27 +0530 Subject: [PATCH 02/13] [testqueue] Added testQueue builder --- src/lib/buildTestQueue.js | 48 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/lib/buildTestQueue.js diff --git a/src/lib/buildTestQueue.js b/src/lib/buildTestQueue.js new file mode 100644 index 0000000..22fe5f0 --- /dev/null +++ b/src/lib/buildTestQueue.js @@ -0,0 +1,48 @@ +/* eslint-disable-next-line */ +const Gunner = require('../gunner'); +const symbols = require('../util/symbols'); + +const wrap = type => unit => ({ type, unit }); + +/** + * runs the test suite + * @param {Gunner} instance + */ +const buildTestTree = instance => { + + const testQueue = []; + + Array.prototype.push.apply(testQueue, + instance.__suite__.beforeHooks[symbols.Start].map(wrap('@start'))); + testQueue.push.apply( + instance.__suite__.afterHooks[symbols.Start].map(wrap('@start'))); + + instance.__suite__.tests.forEach(test => ( + + Array.prototype.push.apply(testQueue, + instance.__suite__.beforeHooks['*'] + .map(wrap('@every'))), + Array.prototype.push.apply(testQueue, + (instance.__suite__.beforeHooks[test.description] || []) + .map(wrap('@this'))), + testQueue.push(wrap('@test')(test)), + Array.prototype.push.apply(testQueue, + (instance.__suite__.afterHooks[test.description] || []) + .map(wrap('@afterTest'))), + Array.prototype.push.apply(testQueue, + (instance.__suite__.afterHooks['*']).map(wrap('@afterEvery'))) + + )); + + testQueue.push.apply( + instance.__suite__.beforeHooks[symbols.End] + .map(wrap('@end'))); + testQueue.push.apply( + instance.__suite__.afterHooks[symbols.End] + .map(wrap(symbols.End))); + + return testQueue; + +}; + +module.exports = buildTestTree; From ef738f7771a94d2389e973c849e3c6e6e39d735b Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 08:23:39 +0530 Subject: [PATCH 03/13] [rewrite] WIP gunner.js --- package.json | 8 +- shrinkwrap.yaml | 303 +++++++++++++++++++++++++++----------------------------- src/gunner.js | 128 +++++++++--------------- 3 files changed, 201 insertions(+), 238 deletions(-) diff --git a/package.json b/package.json index d98d822..c1c5079 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@klenty/gunner", - "version": "0.6.7", + "version": "0.7.0", "description": "Zero magic, fast test-runner and assertion framework. No magic globals.", "main": "index.js", "repository": { @@ -23,9 +23,9 @@ "dependencies": { "@codefeathers/iseq": "^1.2.1", "@codefeathers/promise.object": "^0.9.5", - "bluebird": "^3.5.1", - "chalk": "^2.4.1", - "eslint": "^5.2.0", "json-stringify-safe": "^5.0.1" + }, + "devDependencies": { + "eslint": "^5.2.0" } } diff --git a/shrinkwrap.yaml b/shrinkwrap.yaml index 5d831af..44fa457 100644 --- a/shrinkwrap.yaml +++ b/shrinkwrap.yaml @@ -1,10 +1,9 @@ dependencies: '@codefeathers/iseq': 1.2.1 '@codefeathers/promise.object': 0.9.5 - bluebird: 3.5.1 - chalk: 2.4.1 - eslint: 5.2.0 json-stringify-safe: 5.0.1 +devDependencies: + eslint: 5.2.0 packages: /@codefeathers/iseq/1.2.1: dev: false @@ -17,11 +16,11 @@ packages: /acorn-jsx/4.1.1: dependencies: acorn: 5.7.1 - dev: false + dev: true resolution: integrity: sha512-JY+iV6r+cO21KtntVvFkD+iqjtdpRUpGqKWgfkCdZq1R+kbreEl8EcdcJR4SmiIgsIQT33s6QzheQ9a275Q8xw== /acorn/5.7.1: - dev: false + dev: true engines: node: '>=0.4.0' hasBin: true @@ -30,7 +29,7 @@ packages: /ajv-keywords/3.2.0/ajv@6.5.2: dependencies: ajv: 6.5.2 - dev: false + dev: true id: registry.npmjs.org/ajv-keywords/3.2.0 peerDependencies: ajv: ^6.0.0 @@ -42,29 +41,29 @@ packages: fast-json-stable-stringify: 2.0.0 json-schema-traverse: 0.4.1 uri-js: 4.2.2 - dev: false + dev: true resolution: integrity: sha512-hOs7GfvI6tUI1LfZddH82ky6mOMyTuY0mk7kE2pWpmhhUSkumzaTO5vbVwij39MdwPQWCV4Zv57Eo06NtL/GVA== /ansi-escapes/3.1.0: - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw== /ansi-regex/2.1.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8= /ansi-regex/3.0.0: - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= /ansi-styles/2.2.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -72,7 +71,7 @@ packages: /ansi-styles/3.2.1: dependencies: color-convert: 1.9.2 - dev: false + dev: true engines: node: '>=4' resolution: @@ -80,25 +79,25 @@ packages: /argparse/1.0.10: dependencies: sprintf-js: 1.0.3 - dev: false + dev: true resolution: integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== /array-union/1.0.2: dependencies: array-uniq: 1.0.3 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= /array-uniq/1.0.3: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= /arrify/1.0.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -108,34 +107,30 @@ packages: chalk: 1.1.3 esutils: 2.0.2 js-tokens: 3.0.2 - dev: false + dev: true resolution: integrity: sha1-Y/1D99weO7fONZR9uP42mj9Yx0s= /balanced-match/1.0.0: - dev: false + dev: true resolution: integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c= - /bluebird/3.5.1: - dev: false - resolution: - integrity: sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA== /brace-expansion/1.1.11: dependencies: balanced-match: 1.0.0 concat-map: 0.0.1 - dev: false + dev: true resolution: integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== /caller-path/0.1.0: dependencies: callsites: 0.2.0 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8= /callsites/0.2.0: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -147,7 +142,7 @@ packages: has-ansi: 2.0.0 strip-ansi: 3.0.1 supports-color: 2.0.0 - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -157,43 +152,43 @@ packages: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.4.0 - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== /chardet/0.4.2: - dev: false + dev: true resolution: integrity: sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I= /circular-json/0.3.3: - dev: false + dev: true resolution: integrity: sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A== /cli-cursor/2.1.0: dependencies: restore-cursor: 2.0.0 - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= /cli-width/2.2.0: - dev: false + dev: true resolution: integrity: sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= /color-convert/1.9.2: dependencies: color-name: 1.1.1 - dev: false + dev: true resolution: integrity: sha512-3NUJZdhMhcdPn8vJ9v2UQJoH0qqoGUkYTgFEPZaPjEtwmmKUfNV46zZmgB2M5M4DCEQHMaCfWHCxiBflLm04Tg== /color-name/1.1.1: - dev: false + dev: true resolution: integrity: sha1-SxQVMEz1ACjqgWQ2Q72C6gWANok= /concat-map/0.0.1: - dev: false + dev: true resolution: integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= /cross-spawn/6.0.5: @@ -203,7 +198,7 @@ packages: semver: 5.5.0 shebang-command: 1.2.0 which: 1.3.1 - dev: false + dev: true engines: node: '>=4.8' resolution: @@ -211,18 +206,18 @@ packages: /debug/3.1.0: dependencies: ms: 2.0.0 - dev: false + dev: true resolution: integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== /deep-is/0.1.3: - dev: false + dev: true resolution: integrity: sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= /define-properties/1.1.2: dependencies: foreach: 2.0.5 object-keys: 1.0.12 - dev: false + dev: true engines: node: '>= 0.4' resolution: @@ -236,7 +231,7 @@ packages: pify: 2.3.0 pinkie-promise: 2.0.1 rimraf: 2.6.2 - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -244,7 +239,7 @@ packages: /doctrine/2.1.0: dependencies: esutils: 2.0.2 - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -256,7 +251,7 @@ packages: has: 1.0.3 is-callable: 1.1.4 is-regex: 1.0.4 - dev: false + dev: true engines: node: '>= 0.4' resolution: @@ -266,13 +261,13 @@ packages: is-callable: 1.1.4 is-date-object: 1.0.1 is-symbol: 1.0.1 - dev: false + dev: true engines: node: '>= 0.4' resolution: integrity: sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0= /escape-string-regexp/1.0.5: - dev: false + dev: true engines: node: '>=0.8.0' resolution: @@ -281,19 +276,19 @@ packages: dependencies: esrecurse: 4.2.1 estraverse: 4.2.0 - dev: false + dev: true engines: node: '>=4.0.0' resolution: integrity: sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA== /eslint-utils/1.3.1: - dev: false + dev: true engines: node: '>=6' resolution: integrity: sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== /eslint-visitor-keys/1.0.0: - dev: false + dev: true engines: node: '>=4' resolution: @@ -339,7 +334,7 @@ packages: strip-json-comments: 2.0.1 table: 4.0.3 text-table: 0.2.0 - dev: false + dev: true engines: node: ^6.14.0 || ^8.10.0 || >=9.10.0 hasBin: true @@ -349,13 +344,13 @@ packages: dependencies: acorn: 5.7.1 acorn-jsx: 4.1.1 - dev: false + dev: true engines: node: '>=6.0.0' resolution: integrity: sha512-kapdTCt1bjmspxStVKX6huolXVV5ZfyZguY1lcfhVVZstce3bqxH9mcLzNn3/mlgW6wQ732+0fuG9v7h0ZQoKg== /esprima/4.0.1: - dev: false + dev: true engines: node: '>=4' hasBin: true @@ -364,7 +359,7 @@ packages: /esquery/1.0.1: dependencies: estraverse: 4.2.0 - dev: false + dev: true engines: node: '>=0.6' resolution: @@ -372,19 +367,19 @@ packages: /esrecurse/4.2.1: dependencies: estraverse: 4.2.0 - dev: false + dev: true engines: node: '>=4.0' resolution: integrity: sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== /estraverse/4.2.0: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= /esutils/2.0.2: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -394,27 +389,27 @@ packages: chardet: 0.4.2 iconv-lite: 0.4.23 tmp: 0.0.33 - dev: false + dev: true engines: node: '>=0.12' resolution: integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A== /fast-deep-equal/2.0.1: - dev: false + dev: true resolution: integrity: sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= /fast-json-stable-stringify/2.0.0: - dev: false + dev: true resolution: integrity: sha1-1RQsDK7msRifh9OnYREGT4bIu/I= /fast-levenshtein/2.0.6: - dev: false + dev: true resolution: integrity: sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= /figures/2.0.0: dependencies: escape-string-regexp: 1.0.5 - dev: false + dev: true engines: node: '>=4' resolution: @@ -423,7 +418,7 @@ packages: dependencies: flat-cache: 1.3.0 object-assign: 4.1.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -434,25 +429,25 @@ packages: del: 2.2.2 graceful-fs: 4.1.11 write: 0.2.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE= /foreach/2.0.5: - dev: false + dev: true resolution: integrity: sha1-C+4AUBiusmDQo6865ljdATbsG5k= /fs.realpath/1.0.0: - dev: false + dev: true resolution: integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8= /function-bind/1.1.1: - dev: false + dev: true resolution: integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== /functional-red-black-tree/1.0.1: - dev: false + dev: true resolution: integrity: sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= /glob/7.1.2: @@ -463,11 +458,11 @@ packages: minimatch: 3.0.4 once: 1.4.0 path-is-absolute: 1.0.1 - dev: false + dev: true resolution: integrity: sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== /globals/11.7.0: - dev: false + dev: true engines: node: '>=4' resolution: @@ -480,13 +475,13 @@ packages: object-assign: 4.1.1 pify: 2.3.0 pinkie-promise: 2.0.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= /graceful-fs/4.1.11: - dev: false + dev: true engines: node: '>=0.4.0' resolution: @@ -494,19 +489,19 @@ packages: /has-ansi/2.0.0: dependencies: ansi-regex: 2.1.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= /has-flag/3.0.0: - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0= /has-symbols/1.0.0: - dev: false + dev: true engines: node: '>= 0.4' resolution: @@ -514,7 +509,7 @@ packages: /has/1.0.3: dependencies: function-bind: 1.1.1 - dev: false + dev: true engines: node: '>= 0.4.0' resolution: @@ -522,19 +517,19 @@ packages: /iconv-lite/0.4.23: dependencies: safer-buffer: 2.1.2 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA== /ignore/4.0.3: - dev: false + dev: true engines: node: '>= 4' resolution: integrity: sha512-Z/vAH2GGIEATQnBVXMclE2IGV6i0GyVngKThcGZ5kHgHMxLo9Ow2+XHRq1aEKEej5vOF1TPJNbvX6J/anT0M7A== /imurmurhash/0.1.4: - dev: false + dev: true engines: node: '>=0.8.19' resolution: @@ -543,11 +538,11 @@ packages: dependencies: once: 1.4.0 wrappy: 1.0.2 - dev: false + dev: true resolution: integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= /inherits/2.0.3: - dev: false + dev: true resolution: integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= /inquirer/5.2.0: @@ -565,31 +560,31 @@ packages: string-width: 2.1.1 strip-ansi: 4.0.0 through: 2.3.8 - dev: false + dev: true engines: node: '>=6.0.0' resolution: integrity: sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ== /is-callable/1.1.4: - dev: false + dev: true engines: node: '>= 0.4' resolution: integrity: sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== /is-date-object/1.0.1: - dev: false + dev: true engines: node: '>= 0.4' resolution: integrity: sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= /is-fullwidth-code-point/2.0.0: - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= /is-path-cwd/1.0.0: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -597,7 +592,7 @@ packages: /is-path-in-cwd/1.0.1: dependencies: is-path-inside: 1.0.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -605,55 +600,55 @@ packages: /is-path-inside/1.0.1: dependencies: path-is-inside: 1.0.2 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-jvW33lBDej/cprToZe96pVy0gDY= /is-promise/2.1.0: - dev: false + dev: true resolution: integrity: sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= /is-regex/1.0.4: dependencies: has: 1.0.3 - dev: false + dev: true engines: node: '>= 0.4' resolution: integrity: sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= /is-resolvable/1.1.0: - dev: false + dev: true resolution: integrity: sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== /is-symbol/1.0.1: - dev: false + dev: true engines: node: '>= 0.4' resolution: integrity: sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI= /isexe/2.0.0: - dev: false + dev: true resolution: integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= /js-tokens/3.0.2: - dev: false + dev: true resolution: integrity: sha1-mGbfOVECEw449/mWvOtlRDIJwls= /js-yaml/3.12.0: dependencies: argparse: 1.0.10 esprima: 4.0.1 - dev: false + dev: true hasBin: true resolution: integrity: sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A== /json-schema-traverse/0.4.1: - dev: false + dev: true resolution: integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== /json-stable-stringify-without-jsonify/1.0.1: - dev: false + dev: true resolution: integrity: sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= /json-stringify-safe/5.0.1: @@ -664,17 +659,17 @@ packages: dependencies: prelude-ls: 1.1.2 type-check: 0.3.2 - dev: false + dev: true engines: node: '>= 0.8.0' resolution: integrity: sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= /lodash/4.17.10: - dev: false + dev: true resolution: integrity: sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== /mimic-fn/1.2.0: - dev: false + dev: true engines: node: '>=4' resolution: @@ -682,44 +677,44 @@ packages: /minimatch/3.0.4: dependencies: brace-expansion: 1.1.11 - dev: false + dev: true resolution: integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== /minimist/0.0.8: - dev: false + dev: true resolution: integrity: sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= /mkdirp/0.5.1: dependencies: minimist: 0.0.8 - dev: false + dev: true hasBin: true resolution: integrity: sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= /ms/2.0.0: - dev: false + dev: true resolution: integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= /mute-stream/0.0.7: - dev: false + dev: true resolution: integrity: sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= /natural-compare/1.4.0: - dev: false + dev: true resolution: integrity: sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= /nice-try/1.0.4: - dev: false + dev: true resolution: integrity: sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA== /object-assign/4.1.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= /object-keys/1.0.12: - dev: false + dev: true engines: node: '>= 0.4' resolution: @@ -727,13 +722,13 @@ packages: /once/1.4.0: dependencies: wrappy: 1.0.2 - dev: false + dev: true resolution: integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E= /onetime/2.0.1: dependencies: mimic-fn: 1.2.0 - dev: false + dev: true engines: node: '>=4' resolution: @@ -746,35 +741,35 @@ packages: prelude-ls: 1.1.2 type-check: 0.3.2 wordwrap: 1.0.0 - dev: false + dev: true engines: node: '>= 0.8.0' resolution: integrity: sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= /os-tmpdir/1.0.2: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= /path-is-absolute/1.0.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18= /path-is-inside/1.0.2: - dev: false + dev: true resolution: integrity: sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= /path-key/2.0.1: - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= /pify/2.3.0: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -782,37 +777,37 @@ packages: /pinkie-promise/2.0.1: dependencies: pinkie: 2.0.4 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-ITXW36ejWMBprJsXh3YogihFD/o= /pinkie/2.0.4: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-clVrgM+g1IqXToDnckjoDtT3+HA= /pluralize/7.0.0: - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== /prelude-ls/1.1.2: - dev: false + dev: true engines: node: '>= 0.8.0' resolution: integrity: sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= /progress/2.0.0: - dev: false + dev: true engines: node: '>=0.4.0' resolution: integrity: sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8= /punycode/2.1.1: - dev: false + dev: true engines: node: '>=6' resolution: @@ -820,13 +815,13 @@ packages: /regexp.prototype.flags/1.2.0: dependencies: define-properties: 1.1.2 - dev: false + dev: true engines: node: '>= 0.4' resolution: integrity: sha512-ztaw4M1VqgMwl9HlPpOuiYgItcHlunW0He2fE6eNfT6E/CF2FtYi9ofOYe4mKntstYk0Fyh/rDRBdS3AnxjlrA== /regexpp/1.1.0: - dev: false + dev: true engines: node: '>=4.0.0' resolution: @@ -835,13 +830,13 @@ packages: dependencies: caller-path: 0.1.0 resolve-from: 1.0.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM= /resolve-from/1.0.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -850,7 +845,7 @@ packages: dependencies: onetime: 2.0.1 signal-exit: 3.0.2 - dev: false + dev: true engines: node: '>=4' resolution: @@ -858,14 +853,14 @@ packages: /rimraf/2.6.2: dependencies: glob: 7.1.2 - dev: false + dev: true hasBin: true resolution: integrity: sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== /run-async/2.3.0: dependencies: is-promise: 2.1.0 - dev: false + dev: true engines: node: '>=0.12.0' resolution: @@ -873,55 +868,55 @@ packages: /rxjs/5.5.11: dependencies: symbol-observable: 1.0.1 - dev: false + dev: true engines: npm: '>=2.0.0' resolution: integrity: sha512-3bjO7UwWfA2CV7lmwYMBzj4fQ6Cq+ftHc2MvUe+WMS7wcdJ1LosDWmdjPQanYp2dBRj572p7PeU81JUxHKOcBA== /safer-buffer/2.1.2: - dev: false + dev: true resolution: integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== /semver/5.5.0: - dev: false + dev: true hasBin: true resolution: integrity: sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== /shebang-command/1.2.0: dependencies: shebang-regex: 1.0.0 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= /shebang-regex/1.0.0: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= /signal-exit/3.0.2: - dev: false + dev: true resolution: integrity: sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= /slice-ansi/1.0.0: dependencies: is-fullwidth-code-point: 2.0.0 - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg== /sprintf-js/1.0.3: - dev: false + dev: true resolution: integrity: sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= /string-width/2.1.1: dependencies: is-fullwidth-code-point: 2.0.0 strip-ansi: 4.0.0 - dev: false + dev: true engines: node: '>=4' resolution: @@ -933,13 +928,13 @@ packages: function-bind: 1.1.1 has-symbols: 1.0.0 regexp.prototype.flags: 1.2.0 - dev: false + dev: true resolution: integrity: sha512-WoZ+B2ypng1dp4iFLF2kmZlwwlE19gmjgKuhL1FJfDgCREWb3ye3SDVHSzLH6bxfnvYmkCxbzkmWcQZHA4P//Q== /strip-ansi/3.0.1: dependencies: ansi-regex: 2.1.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -947,19 +942,19 @@ packages: /strip-ansi/4.0.0: dependencies: ansi-regex: 3.0.0 - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha1-qEeQIusaw2iocTibY1JixQXuNo8= /strip-json-comments/2.0.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-PFMZQukIwml8DsNEhYwobHygpgo= /supports-color/2.0.0: - dev: false + dev: true engines: node: '>=0.8.0' resolution: @@ -967,13 +962,13 @@ packages: /supports-color/5.4.0: dependencies: has-flag: 3.0.0 - dev: false + dev: true engines: node: '>=4' resolution: integrity: sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== /symbol-observable/1.0.1: - dev: false + dev: true engines: node: '>=0.10.0' resolution: @@ -986,23 +981,23 @@ packages: lodash: 4.17.10 slice-ansi: 1.0.0 string-width: 2.1.1 - dev: false + dev: true engines: node: '>=4.0.0' resolution: integrity: sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg== /text-table/0.2.0: - dev: false + dev: true resolution: integrity: sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= /through/2.3.8: - dev: false + dev: true resolution: integrity: sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= /tmp/0.0.33: dependencies: os-tmpdir: 1.0.2 - dev: false + dev: true engines: node: '>=0.6.0' resolution: @@ -1010,7 +1005,7 @@ packages: /type-check/0.3.2: dependencies: prelude-ls: 1.1.2 - dev: false + dev: true engines: node: '>= 0.8.0' resolution: @@ -1018,39 +1013,37 @@ packages: /uri-js/4.2.2: dependencies: punycode: 2.1.1 - dev: false + dev: true resolution: integrity: sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== /which/1.3.1: dependencies: isexe: 2.0.0 - dev: false + dev: true hasBin: true resolution: integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== /wordwrap/1.0.0: - dev: false + dev: true resolution: integrity: sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= /wrappy/1.0.2: - dev: false + dev: true resolution: integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= /write/0.2.1: dependencies: mkdirp: 0.5.1 - dev: false + dev: true engines: node: '>=0.10.0' resolution: integrity: sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c= registry: 'https://registry.npmjs.org/' -shrinkwrapMinorVersion: 8 +shrinkwrapMinorVersion: 9 shrinkwrapVersion: 3 specifiers: '@codefeathers/iseq': ^1.2.1 '@codefeathers/promise.object': ^0.9.5 - bluebird: ^3.5.1 - chalk: ^2.4.1 eslint: ^5.2.0 json-stringify-safe: ^5.0.1 diff --git a/src/gunner.js b/src/gunner.js index 0a7c2f9..968f410 100644 --- a/src/gunner.js +++ b/src/gunner.js @@ -1,126 +1,96 @@ 'use strict'; -const { EOL } = require('os'); -const chalk = require('chalk'); +const { arrayOrPush } = require('./util'); +const caller = require('./lib/unit/caller'); -const Promise = require('bluebird'); -Promise.object = require('@codefeathers/promise.object'); - -const _runTests = require('./lib/runTests'); -const _expect = require('./lib/expect'); -const logger = require('./lib/logger'); +const testrunner = require('./lib/testrunner'); +const { expect, expectMany } = require('./lib/expect'); const symbols = require('./util/symbols'); class Gunner { - constructor (options = {}) { - this.__hooks__ = { - before: { + constructor (name) { + this.name = name; + this.__suite__ = { + tests: [], + beforeHooks: { [symbols.Start]: [], [symbols.End]: [], '*': [], }, - after: { + afterHooks: { [symbols.Start]: [], [symbols.End]: [], '*': [], - }, + } }; - this.__state__ = []; - this.__tests__ = []; - this.name = options.name; } test (description, test) { const existing = ( - this.__tests__ + this.__suite__.tests .find(x => x.description === description) ); if (existing) throw new Error(`Test '${description}' already exists!`); - this.__tests__.push({ + const unit = { description, - test: state => { - try { - return test(_expect, state); - } catch (e) { - // If errors are thrown, reject them - return Promise.reject(e); - } - }, - }); - + type: 'test', + run: state => caller(test, state), + }; + this.__suite__.tests.push(unit); return this; } - before (description, run) { - const hook = { + before (description, run, label) { + const unit = { description, - run, + label, + type: 'hook', + run: state => caller(run, state), }; - - this.__hooks__.before[description] - ? this.__hooks__.before[description].push(hook) - : this.__hooks__.before[description] = [ hook ]; - + arrayOrPush(this.__suite__.beforeHooks, description, unit); return this; } - after (description, run) { - const hook = { + after (description, run, label) { + const unit = { description, - run, + label, + type: 'hook', + run: state => caller(run, state), }; - - this.__hooks__.after[description] - ? this.__hooks__.after[description].push(hook) - : this.__hooks__.after[description] = [ hook ]; - + arrayOrPush(this.__suite__.afterHooks, description, unit); return this; } run (options = {}) { - return _runTests(this, options) - .then(results => { - const success = results.filter(r => r.result === 'pass'); - const successPercent = Math.floor( - success.length/results.length * 100 - ); - - const beforeAfterLine = - successPercent === 100 - ? chalk`{green ------------------------------------}` - : chalk`{red ------------------------------------}`; - - const log = logger.create(options); - log( - EOL, - beforeAfterLine, - EOL, EOL, - chalk`{green ${success.length}}`, - `tests passed of ${results.length}`, - `[${successPercent}% success]`, - EOL, EOL, - beforeAfterLine - ); - - if((successPercent !== 100) && typeof process !== 'undefined') - process.exitCode = 1; - - return results; - }) - .then(results => { - if (options.exit && typeof process !== 'undefined') - process.exit(); - return results; - }); + return testrunner(this, options); + // .then(results => { + // const success = results.filter(r => r.result === 'pass'); + // const successPercent = Math.floor( + // success.length/results.length * 100 + // ); + + // if((successPercent !== 100) && typeof process !== 'undefined') + // process.exitCode = 1; + + // return results; + // }) + // .then(results => { + // if (options.exit && typeof process !== 'undefined') + // process.exit(); + // return results; + // }); } } module.exports = Gunner; -module.exports.expect = _expect; +module.exports.Gunner = Gunner; +module.exports.expect = expect; +module.exports.expectMany = expectMany; module.exports.Start = symbols.Start; module.exports.End = symbols.End; From 2565c1247b1202fed12666e76fdbc9db51ed44c0 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 08:24:14 +0530 Subject: [PATCH 04/13] [assertions] Added assertions --- package.json | 2 +- src/lib/assertPromise.js | 4 +++- src/lib/assertionsLibrary.js | 51 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/package.json b/package.json index c1c5079..232307d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@klenty/gunner", - "version": "0.7.0", + "version": "0.7.5", "description": "Zero magic, fast test-runner and assertion framework. No magic globals.", "main": "index.js", "repository": { diff --git a/src/lib/assertPromise.js b/src/lib/assertPromise.js index eb58992..04bd784 100644 --- a/src/lib/assertPromise.js +++ b/src/lib/assertPromise.js @@ -1,17 +1,19 @@ -const Promise = require('bluebird'); const { isPromise } = require('../util'); const createRejectionStatement = (statement, ...args) => Promise.reject(statement ? statement(...args) : ''); const _assertPromise = (bool, statementTuple) => { + const [ statement, ...args ] = statementTuple; if(isPromise(bool)) return bool.catch(() => createRejectionStatement(statement, ...args)); + return bool ? Promise.resolve() : createRejectionStatement(statement, ...args); + }; module.exports = _assertPromise; diff --git a/src/lib/assertionsLibrary.js b/src/lib/assertionsLibrary.js index d84a35f..470c515 100644 --- a/src/lib/assertionsLibrary.js +++ b/src/lib/assertionsLibrary.js @@ -2,14 +2,16 @@ const isEq = require('@codefeathers/iseq'); const U = require('../util'); const _ = U.taggedStringify; -module.exports.done = [ - () => true, - () => null, -]; -module.exports.fail = [ - () => false, - () => null, -]; +module.exports.done = + [ + resolve => resolve, + () => null, + ]; +module.exports.fail = + [ + () => false, + (_, rejection) => rejection, + ]; module.exports.exists = [ val => typeof val !== 'undefined', @@ -74,11 +76,42 @@ module.exports.resolvesTo = : Promise.reject(`${val} was not a Promise`), (val, thing) => _`'${val}' does not resolve to '${thing}'`, ]; +module.exports.isType = + [ + (val, type) => (type === 'nil' + && (val === 'null' || val === 'undefined')) + || (typeof val === type) + || (Array.isArray(val) && type === "array") + && (val === null && type !== 'object'), + (val, type) => _`'${val}' is not of type '${type}'`, + ]; +module.exports.greaterThan = + [ + (val, compare) => val > compare, + (val, compare) => _`'${val}' is not greater than ${compare}`, + ]; +module.exports.lessThan = + [ + (val, compare) => val < compare, + (val, compare) => _`'${val}' is not less than ${compare}` + ]; +module.exports.gte = + [ + (val, compare) => val >= compare, + (val, compare) => _`'${val}' is less than ${compare}` + ]; +module.exports.lte = + [ + (val, compare) => val <= compare, + (val, compare) => _`'${val}' is greater than ${compare}`, + ]; -/* Convenience methods */ +/* Convenience aliases */ module.exports.success = module.exports.done; module.exports.succeed = module.exports.done; module.exports.failure = module.exports.fail; module.exports.equal = module.exports.equals; module.exports.deepEqual = module.exports.deepEquals; module.exports.match = module.exports.deepEquals; +module.exports.greaterThanOrEqualTo = module.exports.gte; +module.exports.lessThanOrEqualTo = module.exports.lte; From ee8c0c4fa10222030cc4fb6b733ce1610cc4a34c Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 08:24:56 +0530 Subject: [PATCH 05/13] [refactor] Removing bluebird as a dependency --- src/lib/unit/caller.js | 12 +++++++----- src/runner/index.js | 2 -- src/strategy/index.js | 10 +++++----- src/util/requireDeep.js | 1 - src/util/symbols.js | 2 ++ 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/lib/unit/caller.js b/src/lib/unit/caller.js index a11d8cc..639e19f 100644 --- a/src/lib/unit/caller.js +++ b/src/lib/unit/caller.js @@ -2,10 +2,11 @@ const { isPromise } = require('../../util'); const caller = (test, state) => { - let value, error; + let value, error, errored; try { value = test(state); } catch (e) { + errored = true; error = e; } @@ -13,12 +14,13 @@ const caller = (test, state) => { if (promise) { return value - .then(res => ({ resolve: res, promise: true })) - .catch(rej => ({ rejection: rej, promise: true })); + .then(res => ({ status: 'ok', resolve: res, promise: true })) + .catch(rej => ({ status: 'notOk', rejection: rej, promise: true })); } else { return Promise.resolve({ - ...(!error && {value}), - ...(error && {error}), + status: errored ? 'notOk' : 'ok', + ...(!errored && { value }), + ...(errored && { error }), promise: false, }); } diff --git a/src/runner/index.js b/src/runner/index.js index d2155b7..6166f09 100644 --- a/src/runner/index.js +++ b/src/runner/index.js @@ -1,5 +1,3 @@ -const Promise = require('bluebird'); - const { flatten } = require('../util'); const logger = require('../lib/logger'); diff --git a/src/strategy/index.js b/src/strategy/index.js index c7cf5c2..aede770 100644 --- a/src/strategy/index.js +++ b/src/strategy/index.js @@ -1,5 +1,3 @@ -const Promise = require('bluebird'); - const requireDeep = require('../util/requireDeep'); const Runner = require('../runner'); @@ -40,9 +38,11 @@ class Strategy { * @param {string|Array=} options.pattern */ fetchSpecs (options) { - this.__await__.push(Promise.map(requireDeep(options), each => { - this.__gunnerInstances = this.compiler(this)(each); - })); + this.__await__.push( + Promise.all( + requireDeep(options).map( + each => this.__gunnerInstances = this.compiler(this)(each) + ))); return this; } diff --git a/src/util/requireDeep.js b/src/util/requireDeep.js index 1a3d4b7..e58d929 100644 --- a/src/util/requireDeep.js +++ b/src/util/requireDeep.js @@ -1,4 +1,3 @@ -const Promise = require('bluebird'); const fs = require(`fs`).promises; const { map, diff --git a/src/util/symbols.js b/src/util/symbols.js index 602537c..4ada13f 100644 --- a/src/util/symbols.js +++ b/src/util/symbols.js @@ -3,6 +3,8 @@ module.exports = { Start : Symbol('Start'), End : Symbol('End'), + expect: Symbol('expect'), + pass: 'pass', fail: 'fail', From 103b1e5a224ed2bd8e5301298a7e5b6a2bad576c Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 08:27:50 +0530 Subject: [PATCH 06/13] [rewrite] [breakng] expect.js --- package.json | 2 +- src/lib/expect.js | 33 +++++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 232307d..526730c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@klenty/gunner", - "version": "0.7.5", + "version": "0.8.0", "description": "Zero magic, fast test-runner and assertion framework. No magic globals.", "main": "index.js", "repository": { diff --git a/src/lib/expect.js b/src/lib/expect.js index e73546e..d1f2aa3 100644 --- a/src/lib/expect.js +++ b/src/lib/expect.js @@ -1,12 +1,13 @@ -const Promise = require('bluebird'); -const { liftPromise } = require('../util'); -const _assertPromise = require('./assertPromise'); +'use strict'; + +const { liftPromise, lowerCaseFirstLetter } = require('../util'); +const assertPromise = require('./assertPromise'); const expectPromise = (pred, statement, options = {}) => toTest => (...testValues) => liftPromise( - resolvedValue => _assertPromise( + resolvedValue => assertPromise( pred(toTest, ...testValues), [ statement, resolvedValue, ...testValues ], ), @@ -14,7 +15,7 @@ const expectPromise = (pred, statement, options = {}) => ) .catch(rejectedValue => options.shouldCatch - ? _assertPromise( + ? assertPromise( pred(toTest, ...testValues), [ statement, rejectedValue, ...testValues ], ) @@ -36,11 +37,27 @@ const expects = Object.keys(library).reduce((acc, e) => { }, {}); -const expect = thing => +const negateP = prom => + prom.then(Promise.reject, Promise.resolve); + +const expect = (thing, args) => new Proxy({}, { get: function (obj, prop) { - return expects[prop](thing); + const toCheck = args ? thing(...args) : thing; + if (prop.slice(0, 3) === 'not') + return check => + negateP( + expects[ + lowerCaseFirstLetter(prop.slice(3)) + ](toCheck)(check) + ); + return check => expects[prop](toCheck)(check); }, }); -module.exports = expect; +const expectMany = Promise.all.bind(Promise); + +expect(5).notEquals(5).then(console.log).catch(console.log); + +module.exports.expect = expect; +module.exports.expectMany = expectMany; From 6df3482bf6a145b6960aa930a1c49457265e2a9a Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 08:28:15 +0530 Subject: [PATCH 07/13] [assertions] Fix minor issue --- src/lib/assertionsLibrary.js | 2 +- src/lib/buildTestQueue.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/assertionsLibrary.js b/src/lib/assertionsLibrary.js index 470c515..a3b9331 100644 --- a/src/lib/assertionsLibrary.js +++ b/src/lib/assertionsLibrary.js @@ -4,7 +4,7 @@ const _ = U.taggedStringify; module.exports.done = [ - resolve => resolve, + () => true, () => null, ]; module.exports.fail = diff --git a/src/lib/buildTestQueue.js b/src/lib/buildTestQueue.js index 22fe5f0..acb8a92 100644 --- a/src/lib/buildTestQueue.js +++ b/src/lib/buildTestQueue.js @@ -1,3 +1,4 @@ +// Only imported for JSDoc /* eslint-disable-next-line */ const Gunner = require('../gunner'); const symbols = require('../util/symbols'); From 8f4fa925a091348e91392e1e82a6b812385991ad Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 08:45:41 +0530 Subject: [PATCH 08/13] [expect] Minor fix, added utils --- src/lib/expect.js | 6 +++--- src/util/index.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/src/lib/expect.js b/src/lib/expect.js index d1f2aa3..2c418a7 100644 --- a/src/lib/expect.js +++ b/src/lib/expect.js @@ -45,13 +45,13 @@ const expect = (thing, args) => get: function (obj, prop) { const toCheck = args ? thing(...args) : thing; if (prop.slice(0, 3) === 'not') - return check => + return (...check) => negateP( expects[ lowerCaseFirstLetter(prop.slice(3)) - ](toCheck)(check) + ](toCheck)(...check) ); - return check => expects[prop](toCheck)(check); + return (...check) => expects[prop](toCheck)(...check); }, }); diff --git a/src/util/index.js b/src/util/index.js index f76d690..91cb292 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -35,11 +35,17 @@ module.exports = { path => path.reduce((result, segment) => result && result[segment], obj), + /* Picks a key from an object */ + pick : key => obj => obj[key], + /* Pipe a value or promise through any number of unary functions */ pipe: (...fns) => arg => fns.reduce((acc, fn) => liftPromise(fn, acc), arg), + /* Reduces an array */ + reduce : (fn, def) => arr => arr.reduce(fn, def), + /* Flattens an array of arrays to an array */ flatten : arrData => [].concat.apply([], arrData), @@ -92,4 +98,26 @@ module.exports = { /* Fetches last element from list */ last : arr => arr[arr.length - 1], + /* Uppercases first letter of word */ + upperCaseFirstLetter : word => + word[0].toUpperCase() + + word.slice(1), + + /* Lowercases first letter of word */ + lowerCaseFirstLetter : word => + word[0].toLowerCase() + + word.slice(1), + + /* Creates an array or pushes to an existing one */ + arrayOrPush : (obj, key, item) => + Array.isArray(obj[key]) + ? obj[key].push(item) + : obj[key] = [item], + + /* Assigns to key or creates a new object */ + assignToObject : (obj, path) => (key, value) => + isObject(obj[path]) + ? obj[path][key] = value + : obj[path] = { [key]: value }, + }; From d5e57d9d43ed835ccdea0424753d5f42ca145696 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 08:47:15 +0530 Subject: [PATCH 09/13] [version] Bump to 0.8.1 --- package.json | 2 +- src/util/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 526730c..f769dbd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@klenty/gunner", - "version": "0.8.0", + "version": "0.8.1", "description": "Zero magic, fast test-runner and assertion framework. No magic globals.", "main": "index.js", "repository": { diff --git a/src/util/index.js b/src/util/index.js index 91cb292..8cd7189 100644 --- a/src/util/index.js +++ b/src/util/index.js @@ -31,7 +31,7 @@ module.exports = { liftPromise, /* Returns the element found at the given path or undefined */ - path: obj => + path : obj => path => path.reduce((result, segment) => result && result[segment], obj), @@ -39,7 +39,7 @@ module.exports = { pick : key => obj => obj[key], /* Pipe a value or promise through any number of unary functions */ - pipe: (...fns) => + pipe : (...fns) => arg => fns.reduce((acc, fn) => liftPromise(fn, acc), arg), @@ -71,7 +71,7 @@ module.exports = { promiseAll : x => Promise.all(x), /* Pass partial arguments and return a function that accepts the rest */ - partial: (fn, ...args) => (...rest) => fn(...args, ...rest), + partial : (fn, ...args) => (...rest) => fn(...args, ...rest), /* Item is in collection */ isIn : (collection, item) => collection.indexOf(item) !== -1, @@ -85,7 +85,7 @@ module.exports = { stringify, /* Tagged Stringify */ - taggedStringify: (strings, ...expr) => strings.reduce((acc, curr, i) => + taggedStringify : (strings, ...expr) => strings.reduce((acc, curr, i) => acc + curr + (stringify(expr[i]) || ''), ''), /* Short circuits with given value on pred. Else calls function */ From 565b37c08c728b2a23f7f0f4de408c3ba7f1c5cd Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 09:02:37 +0530 Subject: [PATCH 10/13] [rewrite] Added caller, snipStack, testrunner --- src/gunner.js | 25 ++++----- src/lib/caller.js | 30 ++++++++++ src/lib/expect.js | 1 + src/lib/runTests.js | 150 ------------------------------------------------- src/lib/snipStack.js | 21 +++++++ src/lib/testrunner.js | 124 ++++++++++++++++++++++++++++++++++++++++ src/lib/unit/caller.js | 30 ---------- 7 files changed, 186 insertions(+), 195 deletions(-) create mode 100644 src/lib/caller.js delete mode 100644 src/lib/runTests.js create mode 100644 src/lib/snipStack.js create mode 100644 src/lib/testrunner.js delete mode 100644 src/lib/unit/caller.js diff --git a/src/gunner.js b/src/gunner.js index 968f410..d52eff0 100644 --- a/src/gunner.js +++ b/src/gunner.js @@ -67,23 +67,18 @@ class Gunner { } run (options = {}) { - return testrunner(this, options); - // .then(results => { - // const success = results.filter(r => r.result === 'pass'); - // const successPercent = Math.floor( - // success.length/results.length * 100 - // ); + return testrunner(this, options) + .then(results => { + const success = results.filter(r => r.status === 'ok'); + const successPercent = Math.floor( + success.length/results.length * 100 + ); - // if((successPercent !== 100) && typeof process !== 'undefined') - // process.exitCode = 1; + if((successPercent !== 100) && typeof process !== 'undefined') + process.exitCode = 1; - // return results; - // }) - // .then(results => { - // if (options.exit && typeof process !== 'undefined') - // process.exit(); - // return results; - // }); + return results; + }); } } diff --git a/src/lib/caller.js b/src/lib/caller.js new file mode 100644 index 0000000..639e19f --- /dev/null +++ b/src/lib/caller.js @@ -0,0 +1,30 @@ +const { isPromise } = require('../../util'); + +const caller = (test, state) => { + + let value, error, errored; + try { + value = test(state); + } catch (e) { + errored = true; + error = e; + } + + const promise = isPromise(value); + + if (promise) { + return value + .then(res => ({ status: 'ok', resolve: res, promise: true })) + .catch(rej => ({ status: 'notOk', rejection: rej, promise: true })); + } else { + return Promise.resolve({ + status: errored ? 'notOk' : 'ok', + ...(!errored && { value }), + ...(errored && { error }), + promise: false, + }); + } + +}; + +module.exports = caller; diff --git a/src/lib/expect.js b/src/lib/expect.js index 2c418a7..5509a40 100644 --- a/src/lib/expect.js +++ b/src/lib/expect.js @@ -25,6 +25,7 @@ const expectPromise = (pred, statement, options = {}) => const library = require('./assertionsLibrary'); const expects = Object.keys(library).reduce((acc, e) => { + const [ pred, statement, options ] = library[e]; acc[e] = expectPromise( diff --git a/src/lib/runTests.js b/src/lib/runTests.js deleted file mode 100644 index 073a8a0..0000000 --- a/src/lib/runTests.js +++ /dev/null @@ -1,150 +0,0 @@ -'use strict'; - -const Promise = require('bluebird'); -Promise.object = require('@codefeathers/promise.object'); -const chalk = require('chalk'); - -const logger = require('./logger'); -const { isPromise, taggedStringify: _ } = require('../util'); -const constants = require('../util/symbols'); - -const snipStack = e => { - - if (e.stack) - e.stack = e.stack - .split('\n') - .reduceRight( - (acc, x) => - /* eslint-disable-next-line */ - acc.done - ? acc.cur - : x.match(/at Object\.test.*\/src\/gunner\.js/) - ? { cur: x, done: true } - : { cur: [x, acc.cur].join('\n') }, - { cur: '' }) - .cur.trim(); - - return e; - -}; - -const unitReducer = - (units = [], stateMark) => - (state = {}) => - units.reduce( - (accumulator, unit) => - accumulator - .then(thisState => - Promise.resolve( - unit.run({ ...state, [stateMark]: thisState }) - ) - .then(newState => - [ ...thisState, newState ])), - Promise.resolve(state[stateMark] || []), - ); - -const runTests = (instance, options) => { - - const log = logger.create(options); - - const beforeAll = () => - unitReducer( - [ - ...(instance.__hooks__.before[constants.Start] || []), - ...(instance.__hooks__.after[constants.Start] || []), - ], - '@start', - )(); - - const beforeEvery = state => - unitReducer( - instance.__hooks__.before['*'], - '@every', - )(state); - - const runner = state => Promise.mapSeries(instance.__tests__, each => { - - const beforeThis = - unitReducer( - instance.__hooks__.before[each.description], - '@this' - ); - - const afterThis = - unitReducer( - instance.__hooks__.after[each.description], - '@afterThis' - ); - - return Promise.object({ ...state, '@every': beforeEvery(state) }) - .then(state => Promise.object({ ...state, '@this': beforeThis(state) })) - .then(state => { - - const pred = each.test(state); - - /* There are 4 different cases at play: - 1. A plain expect() is returned. - 2. An array of [ expect() ] is returned - 3. A plain expect() is wrapped in a promise - 4. An array of [ expect() ] is wrapped in a promise. - Here we normalise all of them into something we can process */ - - if (!isPromise(pred) && !(pred && isPromise(pred[0]))) - throw new Error(`Malformed test '${each.description}'`); - const toTest = Array.isArray(pred) - ? Promise.all(pred) - : pred.then(x => Array.isArray(x) ? Promise.all(x) : x); - - return ([ - state, - toTest - .then(() => { - log( - `${chalk`{green ✅}`} :: `, - `${each.description}` - ); - return { - description: each.description, - result: constants.pass - }; - }) - .catch(e => { - const error = (e && e.stack) ? snipStack(e) : e; - const trace = (options.trace && error) - ? `\n Traceback:\n ` + _`${error}` - : ''; - log( - `${chalk`{red ❌}`} :: `, - `${each.description}`, - `${trace}` - ); - return { - description: each.description, - result: constants.fail, - error, - }; - }), - ]); - - }) - .then(([state, result]) => afterThis(state).then(() => result)); - - }); - - const afterAll = - unitReducer( - [ - ...(instance.__hooks__.before[constants.End] || []), - ...(instance.__hooks__.after[constants.End] || []), - ], - '@after-all', - ); - - return Promise.object({ '@start': beforeAll() }) - .then(state => Promise.object({ ...state, '@results': runner(state)})) - .then(state => Promise.object({ ...state, '@end': afterAll(state) })) - .then(state => state['@results']); - -}; - -module.exports = runTests; diff --git a/src/lib/snipStack.js b/src/lib/snipStack.js new file mode 100644 index 0000000..c94c812 --- /dev/null +++ b/src/lib/snipStack.js @@ -0,0 +1,21 @@ +const snipStack = e => { + + if (e.stack) + e.stack = e.stack + .split('\n') + .reduceRight( + (acc, x) => + /* eslint-disable-next-line */ + acc.done + ? acc.cur + : x.match(/at Object\.test.*\/src\/gunner\.js/) + ? { cur: x, done: true } + : { cur: [x, acc.cur].join('\n') }, + { cur: '' }) + .cur.trim(); + + return e; + +}; + +module.exports = snipStack; diff --git a/src/lib/testrunner.js b/src/lib/testrunner.js new file mode 100644 index 0000000..85c2a86 --- /dev/null +++ b/src/lib/testrunner.js @@ -0,0 +1,124 @@ +// Only imported for JSDoc +/* eslint-disable-next-line */ +const Gunner = require('../gunner'); +Promise.object = require('@codefeathers/promise.object'); + +const { last, pipe, pick, assignToObject } = require('../util'); + +const buildTestQueue = require('./buildTestQueue'); + +const findSkip = (skip, unit) => { + + const startFailed = skip.findIndex(x => + x.type === '@start'); + const everyFailed = skip.findIndex(x => + x.type === '@every'); + const beforeFailed = skip.findIndex(x => + x.description === unit.description); + + return (startFailed !== -1 + && 'A start hook failed\n' + + skip[startFailed].error) + || (everyFailed !== -1 + && 'An every hook failed\n' + + skip[everyFailed].error) + || (beforeFailed !== -1 + && 'A before test hook failed\n' + + skip[beforeFailed].error); + +}; + +const reduceQueue = + queue => queue.reduce( + (acc, item) => + Promise.resolve(acc) + .then(acc => { + + return Promise.all([last(acc.results), Promise.object(acc.state)]) + .then(([, state]) => { + + const toSkip = findSkip(acc.skip, item.unit); + return [toSkip, state]; + + }) + .then(([toSkip, state]) => { + + return toSkip + ? { status: 'skip', description: toSkip } + : item.unit.run(state); + + }) + .then(result => { + + const { status } = result; + + const identifier = (item.unit.label) + || (queue + .filter(i => i.type === item.type) + .filter(i => (i.unit.description + === item.unit.description)) + .length); + + if (item.type === '@test') { + + const resultObject = { + status, + description: item.unit.description, + ...((status === 'notOk' || status === 'skip') + && {reason : result.error + || result.rejection + || result.description}) + }; + acc.results.push(resultObject); + + } else { + + const stateAddition = + /* eslint-disable-next-line */ + status === 'ok' + ? result.promise ? result.resolve : result.value + : null; + + if (stateAddition) + assignToObject( + acc.state, item.type + )(identifier, stateAddition); + + } + + if (status === 'notOk') { + + acc.skip.push({ + type: item.type, + description: item.unit.description, + error: result.promise + ? result.rejection + : result.error, + }); + + } + + return acc; + + }); + + }), + { results: [], state: {}, skip: [] }, + ); + +/** + * runs the test suite + * @param {Gunner} instance + * @param {object} options + */ +const testrunner = (instance) => { + + return pipe( + buildTestQueue, + reduceQueue, + pick('results'), + )(instance); + +}; + +module.exports = testrunner; diff --git a/src/lib/unit/caller.js b/src/lib/unit/caller.js deleted file mode 100644 index 639e19f..0000000 --- a/src/lib/unit/caller.js +++ /dev/null @@ -1,30 +0,0 @@ -const { isPromise } = require('../../util'); - -const caller = (test, state) => { - - let value, error, errored; - try { - value = test(state); - } catch (e) { - errored = true; - error = e; - } - - const promise = isPromise(value); - - if (promise) { - return value - .then(res => ({ status: 'ok', resolve: res, promise: true })) - .catch(rej => ({ status: 'notOk', rejection: rej, promise: true })); - } else { - return Promise.resolve({ - status: errored ? 'notOk' : 'ok', - ...(!errored && { value }), - ...(errored && { error }), - promise: false, - }); - } - -}; - -module.exports = caller; From 88c6744562d8b6346f3117b11eb8718708ead18f Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 09:02:50 +0530 Subject: [PATCH 11/13] [sample] Added updated test --- sample/sample7.test.js | 102 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 sample/sample7.test.js diff --git a/sample/sample7.test.js b/sample/sample7.test.js new file mode 100644 index 0000000..da4d5ff --- /dev/null +++ b/sample/sample7.test.js @@ -0,0 +1,102 @@ +/** + * This file contains random tests + * used during development + */ + +const Gunner = require('../index.js'); +const expect = Gunner.expect; +const expectMany = Gunner.expectMany; +const gunner = new Gunner({ name: 'sample tests' }); +const a = 1; + +gunner.before(Gunner.Start, () => console.log('Started tests!')); +gunner.before(Gunner.End, () => console.log('Ended tests!')); +let runCount = 1; +gunner.before('*', () => console.log(`Running test ${runCount++}`)); + +gunner.test('should automatically pass', () => expect().done()); +gunner.test(`should be equal`, () => expect(1).equal(1)); +gunner.test(`objects are deep equal`, () => expect({ a: 1 }).deepEqual({ a: 1 })); +gunner.test('expression should be true', () => expect(a === 1).isTrue()); + +gunner.test('should be a Promise (resolved)', () => + expect(Promise.resolve()).isPromise()); + +gunner.test('should be a Promise (rejected)', () => + expect(Promise.reject()).isPromise()); + +gunner.test('wait and resolve', () => { + return new Promise(r => { + setTimeout( + () => r('ok'), + 50 + ); + }); +}); + +gunner.test('should resolve to 5', () => + expect(Promise.resolve(5)).resolvesTo(5)); + +gunner.before( + 'file must have hello as content', + () => console.log('>> starting test! file must have hello as content'), + 'helloContentBefore', +); + +gunner.after( + 'file must have hello as content', + () => console.log('>> finished test! file must have hello as content'), + 'helloContentAfter', +); + +gunner.test('file must have hello as content', async () => { + const { readFile } = require('fs').promises; + const file = await readFile(__dirname + '/hello.txt', { encoding: 'utf8' }); + return [ + expect(file).equal('hello'), + expect(file.length).equal(5), + ]; +}); + +gunner.test('(should fail) Should automatically fail', () => + expect().fail()); + +gunner.test('(should fail) Value is not a Promise', () => + expect(5).isPromise()); + +gunner.test('(should fail) Error is not a Promise', () => + expect(flamethrower()).isPromise()); + +gunner.test(`(should fail) objects aren't deeply equal`, () => expect({a : 1}).deepEqual({ a: 2 })); + +gunner.test('(should fail) promise must reject', () => + expect(Promise.reject(new Error('Promise Rejected'))).equal('no rejection')); + +gunner.test('(should fail) multiple expect', () => { + + const a = { }; + a.b = 1; + a.c = 2; + + return expectMany([ + expect(a).hasProp('b'), + expect(a).hasPair('c', 3), + ]); + +}); + +const flamethrower = () => { + throw new Error('This burns!'); +}; + +gunner.test('(should fail) should catch error', () => { + return expect(flamethrower, []).equal(5); +}); + +gunner.test('(should fail) should not resolve to 5', () => + expect(Promise.resolve()).resolvesTo(5)); + +const trace = process.argv.slice(2).indexOf('--trace') !== -1; +const log = process.argv.slice(2).indexOf('--log') !== -1; + +gunner.run({ trace, log }).then(console.log); From d3fb1a27e306f9c47ee8c797df5346d6fb4397c6 Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 09:03:09 +0530 Subject: [PATCH 12/13] [version] Bump to 0.8.5 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f769dbd..8ce1e8d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@klenty/gunner", - "version": "0.8.1", + "version": "0.8.5", "description": "Zero magic, fast test-runner and assertion framework. No magic globals.", "main": "index.js", "repository": { From eeab27dd24bf1d4fb76afa4622da8d8cd213577e Mon Sep 17 00:00:00 2001 From: Muthu Kumar Date: Fri, 14 Sep 2018 09:11:36 +0530 Subject: [PATCH 13/13] [sample] Minor fixes and updated samples --- package.json | 2 +- sample/sample.test.js | 98 -------------------------------------------------- sample/sample2.test.js | 34 ++++++++++-------- src/gunner.js | 2 +- src/lib/caller.js | 2 +- src/lib/expect.js | 2 -- 6 files changed, 22 insertions(+), 118 deletions(-) delete mode 100644 sample/sample.test.js diff --git a/package.json b/package.json index 8ce1e8d..de8b87e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@klenty/gunner", - "version": "0.8.5", + "version": "0.8.6", "description": "Zero magic, fast test-runner and assertion framework. No magic globals.", "main": "index.js", "repository": { diff --git a/sample/sample.test.js b/sample/sample.test.js deleted file mode 100644 index b7efe11..0000000 --- a/sample/sample.test.js +++ /dev/null @@ -1,98 +0,0 @@ -/** - * This file contains random tests - * used during development - */ - -const Gunner = require('../index.js'); -const gunner = new Gunner({ name: 'sample tests' }); -const a = 1; - -// gunner.before(Gunner.Start, () => console.log('Started tests!')); -// gunner.before(Gunner.End, () => console.log('Ended tests!')); -// let runCount = 1; -// gunner.before('*', () => console.log(`Running test ${runCount++}`)); - -gunner.test('should automatically pass', expect => expect().done()); -gunner.test(`should be equal`, expect => expect(1).equal(1)); -gunner.test(`objects are deep equal`, expect => expect({ a: 1 }).deepEqual({ a: 1 })); -gunner.test('expression should be true', expect => expect(a === 1).isTrue()); - -gunner.test('should be a Promise (resolved)', expect => - expect(Promise.resolve()).isPromise()); - -gunner.test('should be a Promise (rejected)', expect => - expect(Promise.reject()).isPromise()); - -gunner.test('wait and resolve', () => { - return new Promise(r => { - setTimeout( - () => r('ok'), - 500 - ); - }); -}); - -gunner.test('should resolve to 5', expect => - expect(Promise.resolve(5)).resolvesTo(5)); - -// gunner.before( -// 'file must have hello as content', -// () => console.log('>> starting test! file must have hello as content'), -// ); - -// gunner.after( -// 'file must have hello as content', -// () => console.log('>> finished test! file must have hello as content'), -// ); - -gunner.test('file must have hello as content', async expect => { - const { readFile } = require('fs').promises; - const file = await readFile(__dirname + '/hello.txt', { encoding: 'utf8' }); - return [ - expect(file).equal('hello'), - expect(file.length).equal(5), - ]; -}); - -gunner.test('(should fail) Should automatically fail', expect => - expect().fail()); - -gunner.test('(should fail) Value is not a Promise', expect => - expect(5).isPromise()); - -gunner.test('(should fail) Error is not a Promise', expect => - expect(flamethrower()).isPromise()); - -gunner.test(`(should fail) objects aren't deeply equal`, expect => expect({a : 1}).deepEqual({ a: 2 })); - -gunner.test('(should fail) promise must reject', expect => - expect(Promise.reject(new Error('Promise Rejected'))).equal('no rejection')); - -gunner.test('(should fail) multiple expect', expect => { - - const a = { }; - a.b = 1; - a.c = 2; - - return [ - expect(a).hasProp('b'), - expect(a).hasPair('c', 3), - ]; - -}); - -const flamethrower = () => { - throw new Error('This burns!'); -}; - -gunner.test('(should fail) should catch error', expect => { - return expect(flamethrower()).equal(5); -}); - -gunner.test('(should fail) should not resolve to 5', expect => - expect(Promise.resolve()).resolvesTo(5)); - -const trace = process.argv.slice(2).indexOf('--trace') !== -1; -const log = process.argv.slice(2).indexOf('--log') !== -1; - -gunner.run({ trace, log }); diff --git a/sample/sample2.test.js b/sample/sample2.test.js index 8ffb9c2..ee5d1af 100644 --- a/sample/sample2.test.js +++ b/sample/sample2.test.js @@ -3,23 +3,27 @@ * used during development */ -const Gunner = require('../index.js'); +const { Gunner, expect, expectMany } = require('..'); const gunner = new Gunner({ name: 'state tests' }); -gunner.before(Gunner.Start, () => 'hello'); -gunner.before(Gunner.Start, () => 'below'); -gunner.before(Gunner.Start, () => 'shallow'); -gunner.before('*', () => 'stars'); -gunner.before('Test 1', () => 'nope'); +gunner.before(Gunner.Start, () => 'world', 'hello'); +gunner.before(Gunner.Start, () => 'earth', 'below'); +gunner.before(Gunner.Start, () => 'waters', 'shallow'); +gunner.before('*', () => 'stars', 'stars'); +gunner.before('Test 1', () => 'nope', 'test1'); -gunner.test('Test 1', (expect, state) => - [ - expect(state['@start']).deepEquals([ 'hello', 'below', 'shallow' ]), - expect(state['@every']).deepEquals([ 'stars' ]), - expect(state['@this']).deepEquals([ 'nope' ]), - ]); +gunner.test('Test 1', state => + expectMany([ + expect(state['@start']).deepEquals({ + hello: 'world', + below: 'earth', + shallow: 'waters' + }), + expect(state['@every']).deepEquals({ stars: 'stars' }), + expect(state['@this']).deepEquals({ test1: 'nope' }), + ])); -gunner.test('(should fail) Test 2', (expect, state) => - expect(state['@start']).deepEquals([ 'hellno' ])); +gunner.test('(should fail) Test 2', state => + expect(state['@start']).deepEquals({ 'hellna': true })); -gunner.run({ log: true }); \ No newline at end of file +gunner.run({ log: true }).then(console.log); \ No newline at end of file diff --git a/src/gunner.js b/src/gunner.js index d52eff0..2470336 100644 --- a/src/gunner.js +++ b/src/gunner.js @@ -1,7 +1,7 @@ 'use strict'; const { arrayOrPush } = require('./util'); -const caller = require('./lib/unit/caller'); +const caller = require('./lib/caller'); const testrunner = require('./lib/testrunner'); const { expect, expectMany } = require('./lib/expect'); diff --git a/src/lib/caller.js b/src/lib/caller.js index 639e19f..012d9e3 100644 --- a/src/lib/caller.js +++ b/src/lib/caller.js @@ -1,4 +1,4 @@ -const { isPromise } = require('../../util'); +const { isPromise } = require('../util'); const caller = (test, state) => { diff --git a/src/lib/expect.js b/src/lib/expect.js index 5509a40..9d53073 100644 --- a/src/lib/expect.js +++ b/src/lib/expect.js @@ -58,7 +58,5 @@ const expect = (thing, args) => const expectMany = Promise.all.bind(Promise); -expect(5).notEquals(5).then(console.log).catch(console.log); - module.exports.expect = expect; module.exports.expectMany = expectMany;