From 5a12989105ce5362ccffc13d670756c1c3afc9cb Mon Sep 17 00:00:00 2001 From: k1r0s Date: Tue, 20 Nov 2018 17:36:46 +0100 Subject: [PATCH] feat: methods decorated with async advices now return a promise which wraps the original task fix #118 --- docs/api.md | 2 - docs/faq.md | 8 - package-lock.json | 216 ++++++++++++------------ package.json | 4 +- test/promise-wrap-async-adivces.spec.ts | 50 ++++++ 5 files changed, 160 insertions(+), 120 deletions(-) create mode 100644 test/promise-wrap-async-adivces.spec.ts diff --git a/docs/api.md b/docs/api.md index 20005b60..230b9020 100644 --- a/docs/api.md +++ b/docs/api.md @@ -149,5 +149,3 @@ class View { setPermission () { ... } } ``` - -Be careful, since decorated methods with **async Advices** return `undefined` diff --git a/docs/faq.md b/docs/faq.md index fba2fd6c..31a97ea8 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -35,10 +35,6 @@ This is the minimal `tsconfig.json`. kaop-ts uses metadata properties inside methods or classes. If you alter that references by reasignment you'll mess Advice call stack. -### Avoid async Advices with some frameworks functions (i.e.: React `render` function) - -Careful when adding async Advices to some frameworks functions, let's say `render` method of React component. In this case, the method will be evaluated as `undefined` messing up React rendering. - ### Useful Tips > Join points decorators can be stacked and used sync or asynchronously. @@ -48,7 +44,3 @@ Careful when adding async Advices to some frameworks functions, let's say `rende > You can prevent main method execution by calling `meta.prevent`. > Some contexts or metadata may be accessible in several cases. For example: trying to modify method arguments at `after` join point doesn't have any sense. *Maybe for communication purposes between advices*. - -> You should not perform async calls during `beforeInstance` join points because you will mess up instantiation of that class. - -> Async advices return 'undefined' diff --git a/package-lock.json b/package-lock.json index 651b994a..244b95d1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1284,7 +1284,7 @@ "integrity": "sha512-uFLE0LFMxrH8Z5Hd9QgivvRbrl/NFkOTHzGhlqQxsnmx5JBLrp4bc249afLL+GccyY/8hkcGi2LpVaOzaEY0nQ==", "dev": true, "requires": { - "fast-json-stable-stringify": "^2.0.0" + "fast-json-stable-stringify": "2.0.0" } }, "bser": { @@ -1459,7 +1459,7 @@ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", "dev": true, "requires": { - "restore-cursor": "^1.0.1" + "restore-cursor": "1.0.1" } }, "cli-table": { @@ -1588,10 +1588,10 @@ "cachedir": "2.1.0", "cz-conventional-changelog": "2.1.0", "dedent": "0.7.0", - "detect-indent": "^5.0.0", + "detect-indent": "5.0.0", "find-node-modules": "1.0.4", "find-root": "1.1.0", - "fs-extra": "^7.0.0", + "fs-extra": "7.0.0", "glob": "7.1.3", "inquirer": "1.2.3", "lodash": "4.17.11", @@ -1612,12 +1612,12 @@ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" } }, "lodash": { @@ -1656,10 +1656,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "buffer-from": "1.1.1", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" } }, "conventional-changelog-angular": { @@ -2032,7 +2032,7 @@ "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=", "dev": true, "requires": { - "fs-exists-sync": "^0.1.0" + "fs-exists-sync": "0.1.0" } }, "detect-indent": { @@ -2369,7 +2369,7 @@ "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=", "dev": true, "requires": { - "os-homedir": "^1.0.1" + "os-homedir": "1.0.2" } }, "expect": { @@ -2430,9 +2430,9 @@ "integrity": "sha1-Etew24UPf/fnCBuvQAVwAGDEYAs=", "dev": true, "requires": { - "extend": "^3.0.0", - "spawn-sync": "^1.0.15", - "tmp": "^0.0.29" + "extend": "3.0.2", + "spawn-sync": "1.0.15", + "tmp": "0.0.29" } }, "extglob": { @@ -2809,8 +2809,8 @@ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" } }, "filename-regex": { @@ -2849,7 +2849,7 @@ "dev": true, "requires": { "findup-sync": "0.4.2", - "merge": "^1.2.0" + "merge": "1.2.0" } }, "find-parent-dir": { @@ -2913,10 +2913,10 @@ "integrity": "sha1-qBF9D3MST1pFRoOVef5S1xKfteU=", "dev": true, "requires": { - "detect-file": "^0.1.0", - "is-glob": "^2.0.1", - "micromatch": "^2.3.7", - "resolve-dir": "^0.1.0" + "detect-file": "0.1.0", + "is-glob": "2.0.1", + "micromatch": "2.3.11", + "resolve-dir": "0.1.1" } }, "for-in": { @@ -2993,9 +2993,9 @@ "integrity": "sha512-EglNDLRpmaTWiD/qraZn6HREAEAHJcJOmxNEYwq6xeMKnVMAy3GUcFB+wXt2C6k4CNvB/mP1y/U3dzvKKj5OtQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" + "graceful-fs": "4.1.11", + "jsonfile": "4.0.0", + "universalify": "0.1.2" } }, "fs.realpath": { @@ -3680,8 +3680,8 @@ "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=", "dev": true, "requires": { - "global-prefix": "^0.1.4", - "is-windows": "^0.2.0" + "global-prefix": "0.1.5", + "is-windows": "0.2.0" } }, "global-prefix": { @@ -3690,10 +3690,10 @@ "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=", "dev": true, "requires": { - "homedir-polyfill": "^1.0.0", - "ini": "^1.3.4", - "is-windows": "^0.2.0", - "which": "^1.2.12" + "homedir-polyfill": "1.0.1", + "ini": "1.3.5", + "is-windows": "0.2.0", + "which": "1.3.1" } }, "globals": { @@ -3899,7 +3899,7 @@ "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", "dev": true, "requires": { - "parse-passwd": "^1.0.0" + "parse-passwd": "1.0.0" } }, "hook-std": { @@ -3988,16 +3988,16 @@ "integrity": "sha512-jnUD0PK3xGLB5Jc3f3UEwl8qOZeLd0WiWABhVyHPS5R298HOccGZJMOMBSk3gFksAa1BeK9FQYYEfPNlqkfBxg==", "dev": true, "requires": { - "cosmiconfig": "^5.0.6", - "execa": "^0.9.0", - "find-up": "^3.0.0", - "get-stdin": "^6.0.0", - "is-ci": "^1.2.1", - "pkg-dir": "^3.0.0", - "please-upgrade-node": "^3.1.1", - "read-pkg": "^4.0.1", - "run-node": "^1.0.0", - "slash": "^2.0.0" + "cosmiconfig": "5.0.6", + "execa": "0.9.0", + "find-up": "3.0.0", + "get-stdin": "6.0.0", + "is-ci": "1.2.1", + "pkg-dir": "3.0.0", + "please-upgrade-node": "3.1.1", + "read-pkg": "4.0.1", + "run-node": "1.0.0", + "slash": "2.0.0" }, "dependencies": { "cross-spawn": { @@ -4006,9 +4006,9 @@ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", "dev": true, "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "lru-cache": "4.1.3", + "shebang-command": "1.2.0", + "which": "1.3.1" } }, "execa": { @@ -4017,13 +4017,13 @@ "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==", "dev": true, "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" + "cross-spawn": "5.1.0", + "get-stream": "3.0.0", + "is-stream": "1.1.0", + "npm-run-path": "2.0.2", + "p-finally": "1.0.0", + "signal-exit": "3.0.2", + "strip-eof": "1.0.0" } }, "find-up": { @@ -4032,7 +4032,7 @@ "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { - "locate-path": "^3.0.0" + "locate-path": "3.0.0" } }, "locate-path": { @@ -4041,8 +4041,8 @@ "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "p-locate": "3.0.0", + "path-exists": "3.0.0" } }, "p-limit": { @@ -4051,7 +4051,7 @@ "integrity": "sha512-fl5s52lI5ahKCernzzIyAP0QAZbGIovtVHGwpcu1Jr/EpzLVDI2myISHwGqK7m8uQFugVWSrbxH7XnhGtvEc+A==", "dev": true, "requires": { - "p-try": "^2.0.0" + "p-try": "2.0.0" } }, "p-locate": { @@ -4060,7 +4060,7 @@ "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { - "p-limit": "^2.0.0" + "p-limit": "2.0.0" } }, "p-try": { @@ -4075,8 +4075,8 @@ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "error-ex": "1.3.2", + "json-parse-better-errors": "1.0.2" } }, "path-exists": { @@ -4097,7 +4097,7 @@ "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { - "find-up": "^3.0.0" + "find-up": "3.0.0" } }, "read-pkg": { @@ -4106,9 +4106,9 @@ "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", "dev": true, "requires": { - "normalize-package-data": "^2.3.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0" + "normalize-package-data": "2.4.0", + "parse-json": "4.0.0", + "pify": "3.0.0" } }, "slash": { @@ -4184,20 +4184,20 @@ "integrity": "sha1-TexvMvN+97sLLtPx0aXD9UUHSRg=", "dev": true, "requires": { - "ansi-escapes": "^1.1.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^2.0.0", - "external-editor": "^1.1.0", - "figures": "^1.3.5", - "lodash": "^4.3.0", + "ansi-escapes": "1.4.0", + "chalk": "1.1.3", + "cli-cursor": "1.0.2", + "cli-width": "2.2.0", + "external-editor": "1.1.1", + "figures": "1.7.0", + "lodash": "4.17.5", "mute-stream": "0.0.6", - "pinkie-promise": "^2.0.0", - "run-async": "^2.2.0", - "rx": "^4.1.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", - "through": "^2.3.6" + "pinkie-promise": "2.0.1", + "run-async": "2.3.0", + "rx": "4.1.0", + "string-width": "1.0.2", + "strip-ansi": "3.0.1", + "through": "2.3.8" } }, "interpret": { @@ -5493,7 +5493,7 @@ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "jsonify": { @@ -5521,9 +5521,9 @@ } }, "kaop": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/kaop/-/kaop-4.3.0.tgz", - "integrity": "sha512-6dXt5HsP3xTjrxHD3Y95y4SWjObm3Zk+V0gteGfRvEcUorof8Y85AKQbfOYIJOcAG50fP+8dc9+/gMN53/ytXA==" + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/kaop/-/kaop-4.4.1.tgz", + "integrity": "sha512-/yDs7J3UeVJdsLcL52mAA08W1zdPtG65ejMrNf8sVDRX29sUBRmLYefXjt2O1ofPEcYlUKR0kChBmRp7iydv8Q==" }, "kind-of": { "version": "3.2.2", @@ -9736,7 +9736,7 @@ "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", "dev": true, "requires": { - "semver-compare": "^1.0.0" + "semver-compare": "1.0.0" } }, "pn": { @@ -9954,7 +9954,7 @@ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", "dev": true, "requires": { - "resolve": "^1.1.6" + "resolve": "1.8.1" } }, "redent": { @@ -10121,8 +10121,8 @@ "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", "dev": true, "requires": { - "expand-tilde": "^1.2.2", - "global-modules": "^0.2.3" + "expand-tilde": "1.2.2", + "global-modules": "0.2.3" } }, "resolve-from": { @@ -10143,8 +10143,8 @@ "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", "dev": true, "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "exit-hook": "1.1.1", + "onetime": "1.1.0" } }, "ret": { @@ -10181,7 +10181,7 @@ "dev": true, "requires": { "@types/estree": "0.0.39", - "@types/node": "*" + "@types/node": "10.11.4" } }, "rollup-plugin-commonjs": { @@ -10237,7 +10237,7 @@ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { - "is-promise": "^2.1.0" + "is-promise": "2.1.0" } }, "run-node": { @@ -10973,9 +10973,9 @@ "integrity": "sha1-N5zM+1a5HIYB5HkzVutTgpJN6a0=", "dev": true, "requires": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" + "glob": "7.1.1", + "interpret": "1.1.0", + "rechoir": "0.6.2" } }, "shellwords": { @@ -11210,8 +11210,8 @@ "integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=", "dev": true, "requires": { - "concat-stream": "^1.4.7", - "os-shim": "^0.1.2" + "concat-stream": "1.6.2", + "os-shim": "0.1.3" } }, "spdx-correct": { @@ -11481,7 +11481,7 @@ "integrity": "sha1-8lEl/w3Z2jzLDC3Tce4SiLuRKMA=", "dev": true, "requires": { - "os-tmpdir": "~1.0.1" + "os-tmpdir": "1.0.2" } }, "tmpl": { @@ -11595,14 +11595,14 @@ "integrity": "sha512-oV/wBwGUS7olSk/9yWMiSIJWbz5xO4zhftnY3gwv6s4SMg6WHF1m8XZNBvQOKQRiTAexZ9754Z13dxBq3Zgssw==", "dev": true, "requires": { - "bs-logger": "0.x", - "buffer-from": "1.x", - "fast-json-stable-stringify": "2.x", - "json5": "2.x", - "make-error": "1.x", - "mkdirp": "0.x", - "semver": "^5.5", - "yargs-parser": "10.x" + "bs-logger": "0.2.5", + "buffer-from": "1.1.1", + "fast-json-stable-stringify": "2.0.0", + "json5": "2.1.0", + "make-error": "1.3.5", + "mkdirp": "0.5.1", + "semver": "5.5.1", + "yargs-parser": "10.1.0" }, "dependencies": { "json5": { @@ -11611,7 +11611,7 @@ "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "1.2.0" } }, "yargs-parser": { @@ -11620,7 +11620,7 @@ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "4.1.0" } } } diff --git a/package.json b/package.json index a85c4831..5ca37841 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,7 @@ "jest": { "testEnvironment": "node", "transform": { - ".(ts|tsx)": "/node_modules/ts-jest/preprocessor.js" + ".(ts|tsx)": "ts-jest" }, "testRegex": "(/__tests__/.*|\\.(test|spec))\\.ts$", "moduleFileExtensions": [ @@ -87,7 +87,7 @@ "validate-commit-msg": "^2.10.1" }, "dependencies": { - "kaop": "^4.3.0", + "kaop": "^4.4.1", "reflect-metadata": "^0.1.12" } } diff --git a/test/promise-wrap-async-adivces.spec.ts b/test/promise-wrap-async-adivces.spec.ts new file mode 100644 index 00000000..adcd49b2 --- /dev/null +++ b/test/promise-wrap-async-adivces.spec.ts @@ -0,0 +1,50 @@ +import { beforeMethod, afterMethod } from "../src" + +const delay = beforeMethod(meta => setTimeout(meta.commit, 10)) +const handleError = afterMethod(meta => meta.handle()) + +class Dummy { + + @delay + do1 () { + return Promise.resolve(10) + } + + do2 () { + return Promise.resolve(10) + } + + @delay + do3 () { + throw new Error("lmaooo") + } + + @delay + @handleError + do4 () { + throw new Error("lmaooo") + } +} + +let instance +describe("promise based advice", () => { + beforeAll(() => { + instance = new Dummy() + }) + + it("decorator should be able to return original value despite being wrapped by an asynchronous advice", () => { + return instance.do1().then(num => expect(num).toBe(10)) + }) + + it("method should be independent from advices", () => { + return instance.do2().then(num => expect(num).toBe(10)) + }) + + it("method should return a promise that rejects", () => { + return instance.do3().catch(err => expect(err.message).toBe("lmaooo")) + }) + + it("should be able to work as spected when handling exceptions", () => { + return instance.do4() + }) +})