├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .hound.yml ├── .travis.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── README.md ├── contributing.md ├── gulpfile.js ├── package.json ├── src └── wizard.js └── test ├── fixtures ├── module_and_root │ ├── foo.js │ └── model │ │ └── bar.js ├── module_es6 │ └── service.js ├── module_files │ ├── controller │ │ ├── module1.js │ │ └── module2.js │ └── model │ │ ├── module1.js │ │ └── module2.js └── root_files │ └── foo.js ├── setup ├── .globals.json ├── node.js └── setup.js └── unit └── wizard.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"], 3 | "plugins": [ 4 | "syntax-async-functions", 5 | "transform-async-to-generator", 6 | "transform-runtime" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # This file is for unifying the coding style for different editors and IDEs 2 | # See editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | indent_style = space 8 | indent_size = 2 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | package.json -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["eslint:recommended", "google"], 3 | "parserOptions": { 4 | "ecmaVersion": 2017, 5 | "sourceType": "module" 6 | }, 7 | "globals": { 8 | "expect": false, 9 | "sinon": false, 10 | "stub": false 11 | }, 12 | "env": { 13 | "node": true, 14 | "mocha": true, 15 | "es6": true, 16 | }, 17 | "rules": { 18 | "no-process-env": 0 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | npm-debug.log 3 | node_modules 4 | dist 5 | .DS_Store 6 | .env 7 | coverage 8 | -------------------------------------------------------------------------------- /.hound.yml: -------------------------------------------------------------------------------- 1 | eslint: 2 | enabled: true 3 | config_file: .eslintrc 4 | ignore_file: .eslintignore 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '6' 4 | - '7.5' 5 | after_success: 6 | - npm run test:coverage:travis 7 | deploy: 8 | provider: npm 9 | email: pragmaticivan@gmail.com 10 | on: 11 | tags: true 12 | api_key: 13 | secure: jgv6kF0H++8+l87mzBgKQ8F9B9VapMSAf7fDsJNL+A7rNygWfEaP7jTOOxGPAVHDFjOiCMDztB/veoAQ+JsX2EMMLdxFky4NKpwQg3lNR5psbc1szaMl+xuzgp4fFjsBlXZoXyoRdFjqK2kjYtz40ntoNvVAV4PhkRIQoLLcbkbrASuY4RlU6n6lcbkidfdn4IG0q8R9MjSJHWIDd1rh1ccuR0nErgXilSuNxt8iz9quex/HcQKCWTtMVqGeTzTrETyJaTnGHr3bGES3Y2HQtDanYZaVUzZ4gVUAYpEXujgyZiryVJ3h6YpZtYsqKqNIQfKildvYMS9gwuk3emT1D/B4fNZ/v3kQaT6src7KN5L36pRSM+y5rzJI2ORYCD+SlnmvFMbPQrxdhH+88A6Eq0C/NtAlvtZPUCUlcteFLrT9Z9o2Y5Mprq1mbr4XvKenTCRTmem4iLFfkzx4j53wJmO3J5V4DsdoecYIxc10GfrNTRD9hFwjg0S3lOVcCPwEQloNzq2HJqp1WF9RMyCLrI/XgiK0kVkNiH15djLsO1bqqDywZQWaXE5YZp4TBu+M54HerzuHUnWwA9cfcy6pKerE4cZVUEvOW1W72gnAmciXet5E1eLG24AkIGQphlj7bEa6BcN23kYrT3wrGfFgt389szaDVvly4BWE34GEl3g= 14 | addons: 15 | jwt: 16 | secure: jYmHfSa1TSbul63+xbcZl59hYlYGH6yIp5z0NAwaGJ2w8hJtRZa5B26BVu4iiimErnIO4syfgaqBlytzrNTQUV/IVHAHQBr/dKeRY/W2Nv/I/aMZGrNLLFf/7HkTTRKzU0Xs9dohENAtFTp1BXWmWdnTI5VAH333BURhiOBoy+ISw1+mZ8NM4kMLu2TU9EZWzHzcC/3MFBaZvEgbjuOxJTHqK53miXYyiWYSYXMExy+NI7c2f2arDq26IUA6hSnOJQ8hj6oLvpE8pBfRZWPXF72opqG6PNQSh2QWKljigHjgVi4S8+xp5szJxzP43GVG8vnTzf9kaIgxVPjdCuUJUOJvkSyPwXNP5oHB+z22DSS0HDFH3oVRpvU/OsbM6d9r27fr8OrCy0tdIRGanv6PJXjISiQYrjkdhXcdg3dkdPSOpXWOub8nG0aFbSaqG4opJDCwya97jmq3S3NmZMpHsUwOxeSFpttIvcIh+N1M0CrgrP74wWxdCSvy7nfaDqu9efylqQqGwKejUhLH8uklgdtqB5lgAn3dA6pRPN3Yare2TLOyoXlfxWxZ1EdW+pW4DKI/nNKhQQCbigXOfARSO4D0g3cegCY0++4TvSjml53/XztzFZM8dfFBI5afDjvMjaqsR68fLnHLN2nTK0GM69jGexQrgGZAXfE2OnFQdCg= 17 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). 3 | 4 | Generated by [auto-changelog](https://github.com/CookPete/auto-changelog) 5 | 6 | 7 | ## [Unreleased](https://github.com/pragmaticivan/wizard/compare/v1.1.0...HEAD) 8 | 9 | ### Commits 10 | * Applies refactoring and getter for defaultProcessorFn. [`04d7010`](https://github.com/pragmaticivan/wizard/commit/04d7010e50649c466663ea4e9271c3220fb66bce) 11 | 12 | 13 | ## [v1.1.0](https://github.com/pragmaticivan/wizard/compare/v1.0.5...v1.1.0) - 2017-02-16 14 | 15 | ### Commits 16 | * Adds support to external function to process module actions [`d304520`](https://github.com/pragmaticivan/wizard/commit/d3045203e75c55f557285a14de6a22edfa086996) 17 | 18 | 19 | ## [v1.0.5](https://github.com/pragmaticivan/wizard/compare/v1.0.4...v1.0.5) - 2017-02-14 20 | 21 | ### Commits 22 | * Fixes auto changelog [`3e7e47e`](https://github.com/pragmaticivan/wizard/commit/3e7e47edaaaaccb7cea865a77507288d14be7744) 23 | 24 | 25 | ## [v1.0.4](https://github.com/pragmaticivan/wizard/compare/v1.0.3...v1.0.4) - 2017-02-14 26 | 27 | ### Commits 28 | * Replaces changelog lib [`39b1627`](https://github.com/pragmaticivan/wizard/commit/39b1627a646c83a0cbe9f4337fa1ceca543f6b51) 29 | 30 | 31 | ## [v1.0.3](https://github.com/pragmaticivan/wizard/compare/v1.0.2...v1.0.3) - 2017-02-14 32 | 33 | ### Commits 34 | * Removes unused dependency [`caddc21`](https://github.com/pragmaticivan/wizard/commit/caddc21a68e88b42826ab793cf9cda46d3e6d8a4) 35 | 36 | 37 | ## [v1.0.2](https://github.com/pragmaticivan/wizard/compare/v1.0.1...v1.0.2) - 2017-02-14 38 | 39 | ### Commits 40 | * Updates version hook to accept only pulls [`d14d207`](https://github.com/pragmaticivan/wizard/commit/d14d207a26d287874905879d17d5f07bd1b90293) 41 | 42 | 43 | ## [v1.0.1](https://github.com/pragmaticivan/wizard/compare/v1.0.0...v1.0.1) - 2017-02-14 44 | 45 | ### Commits 46 | * Adds hook for postversion [`ac49392`](https://github.com/pragmaticivan/wizard/commit/ac493920c31010625a049e18b9adbd56179f997d) 47 | 48 | 49 | ## [v1.0.0](https://github.com/pragmaticivan/wizard/compare/v0.2.14...v1.0.0) - 2017-02-14 50 | 51 | ### Commits 52 | * Removes yarn due to maturity [`9e8aecd`](https://github.com/pragmaticivan/wizard/commit/9e8aecda80a11fb76a5628f120f05511acd38bd5) 53 | 54 | 55 | ## [v0.2.14](https://github.com/pragmaticivan/wizard/compare/v0.2.13...v0.2.14) - 2017-02-13 56 | 57 | ### Commits 58 | * Removes some of the async code [`65ca13d`](https://github.com/pragmaticivan/wizard/commit/65ca13d870c71e0bcfe9bad326da831e4a9e321b) 59 | 60 | 61 | ## [v0.2.13](https://github.com/pragmaticivan/wizard/compare/v0.2.12...v0.2.13) - 2017-02-13 62 | 63 | ### Commits 64 | * Removes bluebird from babel register [`2e31b11`](https://github.com/pragmaticivan/wizard/commit/2e31b11549cd474243eeb7ccd8e8e585f9aeae1d) 65 | 66 | 67 | ## [v0.2.12](https://github.com/pragmaticivan/wizard/compare/v0.2.11...v0.2.12) - 2017-02-13 68 | 69 | ### Commits 70 | * Updates structure of Promise on into function [`47c6c65`](https://github.com/pragmaticivan/wizard/commit/47c6c65ff98e11ad9d35d4c874cba0ed03de626f) 71 | 72 | 73 | ## [v0.2.11](https://github.com/pragmaticivan/wizard/compare/v0.2.10...v0.2.11) - 2017-02-13 74 | 75 | ### Commits 76 | * Controls rejection on getFiles function [`323b74c`](https://github.com/pragmaticivan/wizard/commit/323b74c96c6a4b6e78f241739ae4583471bd13dd) 77 | 78 | 79 | ## [v0.2.10](https://github.com/pragmaticivan/wizard/compare/v0.2.9...v0.2.10) - 2017-02-13 80 | 81 | ### Commits 82 | * Moves promise resolve to outside the loop [`80222af`](https://github.com/pragmaticivan/wizard/commit/80222af2b3c76188bdb730e837603fbf73316acd) 83 | 84 | 85 | ## [v0.2.9](https://github.com/pragmaticivan/wizard/compare/v0.2.8...v0.2.9) - 2017-02-13 86 | 87 | ### Commits 88 | * Improves reject catch [`718012b`](https://github.com/pragmaticivan/wizard/commit/718012b5b497a35ba26fc6b2cff51f8a3ee8a0be) 89 | 90 | 91 | ## [v0.2.8](https://github.com/pragmaticivan/wizard/compare/v0.2.7...v0.2.8) - 2017-02-13 92 | 93 | ### Commits 94 | * Adds files field on package.json [`8ac5051`](https://github.com/pragmaticivan/wizard/commit/8ac5051786a9a20e52ce870690d79fcf882021a0) 95 | 96 | 97 | ## [v0.2.7](https://github.com/pragmaticivan/wizard/compare/v0.2.6...v0.2.7) - 2017-02-13 98 | 99 | ### Commits 100 | * Adds jsnext support [`99359b2`](https://github.com/pragmaticivan/wizard/commit/99359b23f75d28c717fb9063d1458a5714384bbd) 101 | 102 | 103 | ## [v0.2.6](https://github.com/pragmaticivan/wizard/compare/v0.2.5...v0.2.6) - 2017-02-13 104 | 105 | ### Commits 106 | * Fixes lint [`e6c37db`](https://github.com/pragmaticivan/wizard/commit/e6c37dba1a39f46c51b2a2ab3d0a167a1fd5533d) 107 | 108 | 109 | ## [v0.2.5](https://github.com/pragmaticivan/wizard/compare/v0.2.4...v0.2.5) - 2017-02-12 110 | 111 | ### Commits 112 | * Check if file exist [`df4b3d1`](https://github.com/pragmaticivan/wizard/commit/df4b3d1131c056b70e40d8ac2bdb5533762ddeb9) 113 | 114 | 115 | ## [v0.2.4](https://github.com/pragmaticivan/wizard/compare/v0.2.3...v0.2.4) - 2017-02-10 116 | 117 | ### Commits 118 | * Fixes bluebird support [`4b2ebdd`](https://github.com/pragmaticivan/wizard/commit/4b2ebddc1459a446ea6f2d24b092af59d3321044) 119 | 120 | 121 | ## [v0.2.3](https://github.com/pragmaticivan/wizard/compare/v0.2.2...v0.2.3) - 2017-02-10 122 | 123 | ### Commits 124 | * Adds bluebird to replace native promises [`c0e8cb8`](https://github.com/pragmaticivan/wizard/commit/c0e8cb89e40a232b9226d567e0579d3b8e95a325) 125 | 126 | 127 | ## [v0.2.2](https://github.com/pragmaticivan/wizard/compare/v0.2.1...v0.2.2) - 2017-02-08 128 | 129 | ### Commits 130 | * Improves code spacing on readme [`9c64e69`](https://github.com/pragmaticivan/wizard/commit/9c64e69b35d4cfd107950573a0d2332224d5d2fb) 131 | 132 | 133 | ## [v0.2.1](https://github.com/pragmaticivan/wizard/compare/v0.2.0...v0.2.1) - 2017-02-08 134 | 135 | ### Commits 136 | * Improves readme [`0546695`](https://github.com/pragmaticivan/wizard/commit/0546695b9c7f80cfdb9eca8efec67de0a13b5045) 137 | 138 | 139 | ## [v0.2.0](https://github.com/pragmaticivan/wizard/compare/v0.1.2...v0.2.0) - 2017-02-08 140 | 141 | ### Commits 142 | * Adds custom log support [`1e06a26`](https://github.com/pragmaticivan/wizard/commit/1e06a2656d081998e72ca29edf073e47e4c93a51) 143 | 144 | 145 | ## [v0.1.2](https://github.com/pragmaticivan/wizard/compare/v0.1.1...v0.1.2) - 2017-02-08 146 | 147 | ### Commits 148 | * Fixes eslint [`00934d6`](https://github.com/pragmaticivan/wizard/commit/00934d6aa0d22388937932f116415fe4e7620d5a) 149 | 150 | 151 | ## [v0.1.1](https://github.com/pragmaticivan/wizard/compare/v0.1.0...v0.1.1) - 2017-02-08 152 | 153 | ### Commits 154 | * Adds full coverage for all specs [`8a4cd87`](https://github.com/pragmaticivan/wizard/commit/8a4cd87b6ff66078d63cd4f86e2ae34dbb3e5c5e) 155 | 156 | 157 | ## [v0.1.0](https://github.com/pragmaticivan/wizard/compare/v0.0.23...v0.1.0) - 2017-02-07 158 | 159 | ### Merged 160 | * Performs glob loading in parallel injecting the files by group [`#2`](https://github.com/pragmaticivan/wizard/pull/2) 161 | 162 | ### Fixed 163 | * Performs glob loading in parallel injecting the files by group [`#1`](https://github.com/pragmaticivan/wizard/issues/1) 164 | 165 | 166 | ## [v0.0.23](https://github.com/pragmaticivan/wizard/compare/v0.0.22...v0.0.23) - 2017-02-03 167 | 168 | ### Commits 169 | * Fixes doc and removes appveyor.com support [`1f08d8a`](https://github.com/pragmaticivan/wizard/commit/1f08d8a18751be1fc04f2780285396bae5d67c00) 170 | 171 | 172 | ## [v0.0.22](https://github.com/pragmaticivan/wizard/compare/v0.0.21...v0.0.22) - 2017-02-03 173 | 174 | ### Commits 175 | * Updates doc and clean contructor [`eba11a3`](https://github.com/pragmaticivan/wizard/commit/eba11a34b905eb2503b5703b2d6fbca766623671) 176 | 177 | 178 | ## [v0.0.21](https://github.com/pragmaticivan/wizard/compare/v0.0.20...v0.0.21) - 2017-02-01 179 | 180 | ### Commits 181 | * Adds build watch task [`358d244`](https://github.com/pragmaticivan/wizard/commit/358d2443c8df1b66b2c6eaad78bb674a99edbdcb) 182 | 183 | 184 | ## [v0.0.20](https://github.com/pragmaticivan/wizard/compare/v0.0.19...v0.0.20) - 2017-02-01 185 | 186 | ### Commits 187 | * Fixes return for eslint [`904c7dd`](https://github.com/pragmaticivan/wizard/commit/904c7dd1d00f6430f6f36fd6edf0cb96bea8b732) 188 | 189 | 190 | ## [v0.0.19](https://github.com/pragmaticivan/wizard/compare/v0.0.18...v0.0.19) - 2017-02-01 191 | 192 | ### Commits 193 | * Makes 'into' function always return a promise. [`8c8f591`](https://github.com/pragmaticivan/wizard/commit/8c8f59136c4e9665c8aa89d7119ddbf352f706d3) 194 | 195 | 196 | ## [v0.0.18](https://github.com/pragmaticivan/wizard/compare/v0.0.16...v0.0.18) - 2017-01-31 197 | 198 | ### Commits 199 | * Adds appveyor support [`5c6546f`](https://github.com/pragmaticivan/wizard/commit/5c6546f83b53109a131dcabce5d99461399ef06e) 200 | 201 | 202 | ## [v0.0.16](https://github.com/pragmaticivan/wizard/compare/v0.0.15...v0.0.16) - 2017-01-31 203 | 204 | ### Commits 205 | * Updates order of changelog by semver [`10d9c18`](https://github.com/pragmaticivan/wizard/commit/10d9c18106dbee8e875ad21a93cb9019d4e52e87) 206 | 207 | 208 | ## [v0.0.15](https://github.com/pragmaticivan/wizard/compare/v0.0.14...v0.0.15) - 2017-01-31 209 | 210 | ### Commits 211 | * Adds tests for exclusion [`d7d5d0f`](https://github.com/pragmaticivan/wizard/commit/d7d5d0fe008effaf6e446613b639efab4599a7c5) 212 | 213 | 214 | ## [v0.0.14](https://github.com/pragmaticivan/wizard/compare/v0.0.12...v0.0.14) - 2017-01-31 215 | 216 | ### Commits 217 | * Fixes changelog [`4d61f32`](https://github.com/pragmaticivan/wizard/commit/4d61f3208e9b888cef4708964556a4065c54debc) 218 | 219 | 220 | ## [v0.0.12](https://github.com/pragmaticivan/wizard/compare/v0.0.11...v0.0.12) - 2017-01-31 221 | 222 | ### Commits 223 | * Adds npm version and npm link to README [`fa2e562`](https://github.com/pragmaticivan/wizard/commit/fa2e56212260580e8395de16249ca2c48ecb9d10) 224 | 225 | 226 | ## [v0.0.11](https://github.com/pragmaticivan/wizard/compare/v0.0.10...v0.0.11) - 2017-01-31 227 | 228 | ### Commits 229 | * Adds code of conduct and contributing guide [`896144c`](https://github.com/pragmaticivan/wizard/commit/896144c27ba64eb62134f61e53f02aca3ddb0405) 230 | 231 | 232 | ## [v0.0.10](https://github.com/pragmaticivan/wizard/compare/v0.0.9...v0.0.10) - 2017-01-31 233 | 234 | ### Commits 235 | * Cleans babelrc [`e92bf6e`](https://github.com/pragmaticivan/wizard/commit/e92bf6ea5764a0a4251700712c2a584bfe9738ee) 236 | 237 | 238 | ## [v0.0.9](https://github.com/pragmaticivan/wizard/compare/v0.0.8...v0.0.9) - 2017-01-30 239 | 240 | ### Commits 241 | * Extracts file injection code [`095f665`](https://github.com/pragmaticivan/wizard/commit/095f6659cc0dfe5166ff004b2b3d9523b322f8ab) 242 | 243 | 244 | ## [v0.0.8](https://github.com/pragmaticivan/wizard/compare/v0.0.7...v0.0.8) - 2017-01-30 245 | 246 | ### Commits 247 | * Starts using async/await [`70bfc83`](https://github.com/pragmaticivan/wizard/commit/70bfc8329783042b7d34196a49031c86524b3084) 248 | 249 | 250 | ## [v0.0.7](https://github.com/pragmaticivan/wizard/compare/v0.0.6...v0.0.7) - 2017-01-30 251 | 252 | ### Commits 253 | * Test with specified npm version [`efb4469`](https://github.com/pragmaticivan/wizard/commit/efb4469cc0fdd0b199463d9c0fd33648e08a5954) 254 | 255 | 256 | ## [v0.0.6](https://github.com/pragmaticivan/wizard/compare/v0.0.5...v0.0.6) - 2017-01-30 257 | 258 | ### Commits 259 | * Enables auto deployment only on tags [`6e3ac04`](https://github.com/pragmaticivan/wizard/commit/6e3ac049dbd2e4f881ca489fdd334cfd71bab23a) 260 | 261 | 262 | ## [v0.0.5](https://github.com/pragmaticivan/wizard/compare/v0.0.4...v0.0.5) - 2017-01-30 263 | 264 | ### Commits 265 | * Fix github changelog releases [`eaf9bec`](https://github.com/pragmaticivan/wizard/commit/eaf9bec581f292c96de1faafb6c1077a682d49e1) 266 | 267 | 268 | ## [v0.0.4](https://github.com/pragmaticivan/wizard/compare/v0.0.3...v0.0.4) - 2017-01-30 269 | 270 | ### Commits 271 | * Adds travis npm auto publish [`1d69c65`](https://github.com/pragmaticivan/wizard/commit/1d69c65765e5edae922af0b74675d2a3e3221801) 272 | 273 | 274 | ## [v0.0.3](https://github.com/pragmaticivan/wizard/compare/v0.0.2...v0.0.3) - 2017-01-30 275 | 276 | ### Commits 277 | * Improves package.json [`fb060c9`](https://github.com/pragmaticivan/wizard/commit/fb060c9447969f48cab110c653130f5432fb380c) 278 | 279 | 280 | ## [v0.0.2](https://github.com/pragmaticivan/wizard/compare/v0.0.1...v0.0.2) - 2017-01-30 281 | 282 | ### Commits 283 | * Adds build tasks [`c94dd92`](https://github.com/pragmaticivan/wizard/commit/c94dd9298e9d7449691f09c0112de8e2fc95ea1a) 284 | 285 | 286 | ## v0.0.1 - 2017-01-30 287 | 288 | ### Commits 289 | * 🎩 ✨ [`2679412`](https://github.com/pragmaticivan/wizard/commit/2679412f33bdad1b98cfe6d6fbc64324d3ab26e5) 290 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at pragmaticivan@gmail.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

wizard

2 | 3 |
Fast, flexible autoload for express dependencies using the power of glob.
4 | 5 |
6 | 7 | Travis CI 8 | 9 | 10 | 11 | Coverage 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | Npm 20 | 21 | 22 | License 23 |
24 | 25 | ## Why 26 | 27 | Loading dependencies and including them into express shouldn't be hard. Sometimes you need a clean and powerful interface like the one provide by the glob package to do the job. 28 | 29 | That's why express-wizard exists. 30 | 31 | ## Install 32 | 33 | You can get it on npm. 34 | 35 | ```bash 36 | $ npm install express-wizard --save 37 | 38 | // or 39 | 40 | $ yarn add express-wizard 41 | ``` 42 | ## Usage 43 | ```js 44 | var Wizard = require('express-wizard'); 45 | 46 | var instance = new Wizard() 47 | .inject('model/**/*.js') 48 | .inject(['controller/**/*.js', 'service/**/*.js']) 49 | .inject('stop.js') 50 | .exclude('middleware/**/*.js') 51 | .exclude('start.js') 52 | .into(app); 53 | // app.model.foo 54 | // app.model.bar 55 | // app.controller.foo 56 | // app.controller.bar 57 | // app.service.foo 58 | // app.service.bar 59 | // app.stop 60 | 61 | ``` 62 | 63 | ## Options 64 | 65 | #### Defaults 66 | 67 | ```js 68 | new Wizard({ 69 | cwd: process.cwd(), 70 | logger: console, 71 | verbose: true, 72 | loggingType: 'info', 73 | defaultExclusion: [] 74 | }); 75 | ``` 76 | ### Logging 77 | 78 | `logger` - Defaults to console, this can be switched out. 79 | `verbose` - On by default, set to `false` for no logging 80 | `loggingType` - Set the type of logging, defaults to `info` 81 | 82 | ### Base Directory (cwd) 83 | 84 | Wizard will simply use a relative path from your current working directory, however sometimes you don't want heavily nested files included in the object chain, so you can set the cwd: 85 | 86 | ```js 87 | new Wizard() 88 | .include('project/model/**/*.js') // ./project/model/foo.js 89 | .into(app); 90 | ``` 91 | 92 | would result in: 93 | 94 | ```js 95 | app.project.model.foo 96 | ``` 97 | 98 | so using the `cwd` option: 99 | 100 | ```js 101 | new Wizard({cwd: 'project'}) 102 | .include('model/**/*.js') // ./project/model/foo.js 103 | .into(app); 104 | ``` 105 | would give us: 106 | 107 | ```js 108 | app.model.foo 109 | ``` 110 | 111 | 112 | ## Semver 113 | 114 | Until wizard reaches a `1.0` release, breaking changes will be released with a new minor version. For example `0.6.1`, and `0.6.4` will have the same API, but `0.7.0` will have breaking changes. 115 | 116 | ## Tests 117 | 118 | To run the test suite, first install the dependencies, then run `npm test`: 119 | 120 | ```bash 121 | $ npm install 122 | or 123 | $ yarn install 124 | 125 | $ npm test 126 | ``` 127 | ## Resources 128 | 129 | * [Changelog](https://github.com/pragmaticivan/wizard/blob/master/CHANGELOG.md) 130 | * [Contributing Guide](https://github.com/pragmaticivan/wizard/blob/master/CONTRIBUTING.md) 131 | * [Code of Conduct](https://github.com/pragmaticivan/wizard/blob/master/CODE_OF_CONDUCT.md) 132 | 133 | ## License 134 | 135 | [MIT License](http://pragmaticivan.mit-license.org/) © Ivan Santos 136 | -------------------------------------------------------------------------------- /contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | We are open to, and grateful for, any contributions made by the community. By contributing to wizard, you agree to abide by the [code of conduct](https://github.com/pragmaticivan/wizard/blob/master/CODE_OF_CONDUCT.md). 4 | 5 | ### Code Style 6 | 7 | Please follow the [Google javascript style guide](http://google.github.io/styleguide/jsguide.html). 8 | 9 | ### Commit Messages 10 | 11 | Commit messages should be verb based, using the following pattern: 12 | 13 | - `Fixes ...` 14 | - `Adds ...` 15 | - `Updates ...` 16 | - `Removes ...` 17 | 18 | ### Testing 19 | 20 | Please update the tests to reflect your code changes. Pull requests will not be accepted if they are failing on [Travis CI](https://travis-ci.com/pragmaticivan/wizard). 21 | 22 | ### Documentation 23 | 24 | Please update the docs accordingly so that there are no discrepencies between the API and the documentation. 25 | 26 | ### Developing 27 | 28 | - `npm run test` run the mocha tests for browser environment 29 | - `npm run test:watch` watch for changes and run `test` 30 | - `npm run build` bundle the source 31 | 32 | 33 | ### Releasing 34 | 35 | Releasing a new version is mostly automated. Once this has been done run the commands below. Versions should follow [semantic versioning](http://semver.org/). 36 | 37 | - `npm version [ | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]` 38 | - `npm publish` 39 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const eslint = require('gulp-eslint'); 3 | const del = require('del'); 4 | const runSequence = require('run-sequence'); 5 | const babel = require('gulp-babel'); 6 | const sourcemaps = require('gulp-sourcemaps'); 7 | const isparta = require('isparta'); 8 | const loadPlugins = require('gulp-load-plugins'); 9 | const concat = require('gulp-concat'); 10 | const codecov = require('gulp-codecov'); 11 | const mochaGlobals = require('./test/setup/.globals'); 12 | const Instrumenter = isparta.Instrumenter; 13 | 14 | // Load all of our Gulp plugins 15 | const $ = loadPlugins(); 16 | const watchFiles = ['src/**/*', 'test/**/*']; 17 | const destinationFolder = 'dist'; 18 | 19 | /** 20 | * Require register babel. 21 | */ 22 | function registerBabel_() { 23 | require('babel-register'); 24 | } 25 | 26 | /** 27 | * Mocha helper. 28 | * @return {gulp} 29 | */ 30 | function mocha_() { 31 | return gulp.src(['test/setup/node.js', 'test/unit/**/*.js'], {read: false}) 32 | .pipe($.mocha({ 33 | reporter: 'spec', 34 | globals: Object.keys(mochaGlobals.globals), 35 | ignoreLeaks: false, 36 | })); 37 | } 38 | 39 | /** 40 | * Test helper. 41 | * @return {gulp} 42 | */ 43 | function test() { 44 | registerBabel_(); 45 | return mocha_(); 46 | } 47 | 48 | /** 49 | * Build helper. 50 | * @param {Function} done 51 | */ 52 | function build(done) { 53 | runSequence( 54 | 'clean', 55 | 'build-src', 56 | ['lint'], 57 | done 58 | ); 59 | } 60 | 61 | /** 62 | * Clean distribution folder. 63 | * @param {Function} done [description] 64 | */ 65 | function cleanDist(done) { 66 | del([destinationFolder]).then(() => done()); 67 | } 68 | 69 | /** 70 | * Coverage helper. 71 | * @param {Function} done 72 | */ 73 | function coverage(done) { 74 | registerBabel_(); 75 | gulp.src(['src/**/*.js']) 76 | .pipe($.istanbul({ 77 | instrumenter: Instrumenter, 78 | includeUntested: true, 79 | })) 80 | .pipe($.istanbul.hookRequire()) 81 | .on('finish', () => { 82 | return test() 83 | .pipe($.istanbul.writeReports()) 84 | .on('end', done); 85 | }); 86 | } 87 | 88 | /** 89 | * CodeCov helper. 90 | */ 91 | function codeCoverageServer() { 92 | gulp.src('./coverage/lcov.info') 93 | .pipe(codecov()); 94 | } 95 | 96 | /** 97 | * Test watch helper. 98 | */ 99 | function testWatch() { 100 | gulp.watch(watchFiles, ['test']); 101 | } 102 | 103 | 104 | // General build 105 | gulp.task('build', build); 106 | 107 | 108 | // Build the src files 109 | gulp.task('build-src', () => { 110 | return gulp.src('src/**/*.js') 111 | .pipe(sourcemaps.init()) 112 | .pipe(babel()) 113 | .pipe(concat('all.js')) 114 | .pipe(sourcemaps.write('.')) 115 | .pipe(gulp.dest('dist')); 116 | }); 117 | 118 | gulp.task('watch-src', () => { 119 | return gulp.watch('src/**/*.js', [ 120 | 'build-src', 121 | ]); 122 | }); 123 | 124 | gulp.task('watch', ['watch-src']); 125 | 126 | 127 | // Performs eslint functions 128 | 129 | const lintWatchFiles = ['**/*.js', 130 | '!node_modules/**', 131 | '!coverage/**', 132 | '!dist/**']; 133 | gulp.task('lint', () => { 134 | return gulp.src(lintWatchFiles) 135 | .pipe(eslint()) 136 | .pipe(eslint.format()) 137 | .pipe(eslint.failAfterError()); 138 | }); 139 | 140 | gulp.task('lint:watch', () => { 141 | gulp.watch(lintWatchFiles, ['lint']); 142 | }); 143 | 144 | // Remove the built files 145 | gulp.task('clean', cleanDist); 146 | 147 | // Set up coverage and run tests 148 | gulp.task('coverage', coverage); 149 | 150 | // Run our tests 151 | gulp.task('test', test); 152 | gulp.task('test:watch', testWatch); 153 | gulp.task('test:coverage:travis', codeCoverageServer); 154 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-wizard", 3 | "version": "1.2.0", 4 | "description": "Autoload your express dependencies using the power of glob", 5 | "main": "dist/all.js", 6 | "jsnext:main": "src/wizard.js", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/pragmaticivan/wizard.git" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/pragmaticivan/wizard/issues" 13 | }, 14 | "files": [ 15 | "dist", 16 | "src" 17 | ], 18 | "scripts": { 19 | "build": "node ./node_modules/.bin/gulp build", 20 | "lint": "node ./node_modules/.bin/gulp lint", 21 | "release": "node NODE_ENV=production ./node_modules/.bin/gulp build", 22 | "test": "node ./node_modules/.bin/gulp coverage", 23 | "test:watch": "node ./node_modules/.bin/gulp test:watch", 24 | "test:coverage:travis": "node ./node_modules/.bin/gulp test:coverage:travis", 25 | "generate-changelog": "node ./node_modules/.bin/auto-changelog", 26 | "preversion": "npm test", 27 | "postversion": "git push && git push --tags && rm -rf dist", 28 | "version": "npm run generate-changelog && git add CHANGELOG.md", 29 | "prepublish": "npm run build" 30 | }, 31 | "author": "Ivan Santos", 32 | "license": "MIT", 33 | "devDependencies": { 34 | "auto-changelog": "^0.3.1", 35 | "babel-core": "^6.22.1", 36 | "babel-plugin-syntax-async-functions": "^6.13.0", 37 | "babel-plugin-transform-async-to-generator": "^6.22.0", 38 | "babel-plugin-transform-runtime": "^6.22.0", 39 | "babel-preset-es2015": "^6.22.0", 40 | "chai": "^3.5.0", 41 | "del": "^2.2.2", 42 | "eslint": "^3.13.1", 43 | "eslint-config-google": "^0.7.1", 44 | "eslint-loader": "^1.6.1", 45 | "gulp": "^3.9.1", 46 | "gulp-babel": "^6.1.2", 47 | "gulp-codecov": "^2.0.2", 48 | "gulp-concat": "^2.6.1", 49 | "gulp-eslint": "^3.0.1", 50 | "gulp-istanbul": "^1.1.1", 51 | "gulp-load-plugins": "^1.4.0", 52 | "gulp-mocha": "^3.0.1", 53 | "gulp-sourcemaps": "^2.4.0", 54 | "isparta": "^4.0.0", 55 | "mocha": "^3.2.0", 56 | "run-sequence": "^1.2.2", 57 | "sinon": "^1.17.7", 58 | "sinon-chai": "^2.8.0" 59 | }, 60 | "dependencies": { 61 | "multi-glob": "^1.0.1" 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/wizard.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | const glob = require('multi-glob').glob; 3 | 4 | /** 5 | * Wizard lib 6 | */ 7 | class Wizard { 8 | 9 | /** 10 | * Constructor. 11 | * @param {!Object} optConfig 12 | */ 13 | constructor(optConfig = {}) { 14 | /** 15 | * Holds the configuration options. 16 | * @type {?Object} 17 | * @protected 18 | */ 19 | this.options = { 20 | cwd: process.cwd(), 21 | logger: console, 22 | verbose: true, 23 | loggingType: 'info', 24 | defaultExclusion: [], 25 | }; 26 | 27 | this.options = Object.assign(this.options, optConfig); 28 | 29 | /** 30 | * Holds the injection globs. 31 | * @type {?Array} 32 | * @default {[]} 33 | * @protected 34 | */ 35 | this.injectionGlobs = []; 36 | 37 | /** 38 | * Holds the injection globs. 39 | * @type {?Array} 40 | * @default {[]} 41 | * @protected 42 | */ 43 | this.exclusionGlobs = []; 44 | 45 | /** 46 | * Holds the default processor function. 47 | * @type {?Function} 48 | * @default {defaultProcessorFn_} 49 | * @protected 50 | */ 51 | this.processorFn = this.defaultProcessorFn_; 52 | 53 | 54 | this.loadDefaultExclusion_(); 55 | 56 | this.log_(['Initialized in', this.getOptions().cwd]); 57 | } 58 | 59 | /** 60 | * Asserts value is defined and not null. 61 | * @param {Object} value Value to be checked. 62 | * @param {string} errorMessage Error message 63 | * @private 64 | */ 65 | assertNotNull_(value, errorMessage) { 66 | if((value === undefined) || (value === null)) { 67 | throw new Error(errorMessage); 68 | } 69 | } 70 | 71 | /** 72 | * Creates namespace inside parent object. 73 | * @param {!Object} parent Target object where to insert the nested values. 74 | * @param {!Array} parts Namespace representation key. 75 | * @param {Function|Object} mod Function or object to be 76 | * inserted into the namespace. 77 | * @return {Object} parent Returns a parent after recursive 78 | * namespace creation. 79 | * @private 80 | */ 81 | createNamespace_(parent, parts, mod) { 82 | let part = parts.shift(); 83 | 84 | if (!parent[part]) { 85 | parent[this.getKeyName_(part)] = parts.length ? {} : mod; 86 | } 87 | 88 | if (parts.length) { 89 | parent = this.createNamespace_(parent[part], parts, mod); 90 | } 91 | 92 | return parent; 93 | } 94 | 95 | /** 96 | * Default processor to perform call of args in a function. It checks if 97 | * the module has a default attribute in case of es6 exports module. 98 | * @param {Function|Object} module Module to be processed. 99 | * @param {Array=} optArgs Arguments to be applyed to the module function. 100 | * @return {Function|Object} Processed module. 101 | * @private 102 | */ 103 | defaultProcessorFn_(module, optArgs) { 104 | if (module.default) { 105 | module = module.default; 106 | } 107 | 108 | if (typeof module === 'function') { 109 | module = module.apply(module, optArgs); 110 | } 111 | return module; 112 | } 113 | 114 | /** 115 | * Accumulates glob pattern to be excluded from the main object. 116 | * @param {string|string[]} glob 117 | * @return {Wizard} 118 | */ 119 | exclude(glob) { 120 | this.assertNotNull_(glob, 'Glob is required.'); 121 | 122 | if (Array.isArray(glob)) { 123 | Array.prototype.push.apply(this.getExclusionGlobs(), glob); 124 | } else { 125 | this.getExclusionGlobs().push(glob); 126 | } 127 | return this; 128 | } 129 | 130 | /** 131 | * Gets default processor function. 132 | * @return {Function} Default processor function. 133 | */ 134 | getDefaultProcessorFn() { 135 | return this.defaultProcessorFn_; 136 | } 137 | 138 | /** 139 | * Returns module manipulation processor. 140 | * @return {Function} Processor function 141 | */ 142 | getProcessorFn() { 143 | return this.processorFn; 144 | } 145 | 146 | /** 147 | * Accumulate glob pattern to be inserted into the main object. 148 | * @param {string} glob 149 | * @return {Wizard} 150 | */ 151 | inject(glob) { 152 | if (!glob) { 153 | throw new Error('Glob is required.'); 154 | } 155 | 156 | if (Array.isArray(glob)) { 157 | this.getInjectionGlobs().push(glob); 158 | } else { 159 | this.getInjectionGlobs().push([glob]); 160 | } 161 | 162 | return this; 163 | } 164 | 165 | /** 166 | * Target where the files are going to be injected. 167 | * @param {Object} obj 168 | * @param {[]} optArgs 169 | * @return {Promise} 170 | */ 171 | async into(obj, ...optArgs) { 172 | let files = await this.getFiles(); 173 | 174 | if (files.length === 0) { 175 | return []; 176 | } 177 | 178 | files.forEach(( 179 | fileGroup) => this.processInjection_(fileGroup, obj, optArgs)); 180 | 181 | return files; 182 | } 183 | 184 | /** 185 | * Load default glob for exclusion. 186 | * @return {Wizard} 187 | */ 188 | loadDefaultExclusion_() { 189 | const defaultExclusion = this.getOptions().defaultExclusion; 190 | 191 | if (defaultExclusion.length > 0) { 192 | return this.exclude(defaultExclusion); 193 | } 194 | 195 | return this; 196 | } 197 | 198 | /** 199 | * Logs using default logger 200 | * @param {string} message 201 | * @param {string} type 202 | * @return {Wizard} 203 | */ 204 | log_(message, type) { 205 | if (this.getOptions().verbose) { 206 | this.getOptions() 207 | .logger[type || this.getOptions().loggingType](message.join(' ')); 208 | } 209 | 210 | return this; 211 | } 212 | 213 | /** 214 | * Process file injection. 215 | * @param {string[]} fileGroup 216 | * @param {Object} obj 217 | * @param {string[]} optArgs 218 | */ 219 | processInjection_(fileGroup, obj, optArgs) { 220 | fileGroup.forEach((loopFile) => { 221 | delete require.cache[this.getFullPath_(loopFile)]; 222 | 223 | let parts = this.getRelativePath_(loopFile).split(path.sep).slice(1); 224 | let mod = require(this.getFullPath_(loopFile)); 225 | 226 | if(this.getProcessorFn()) { 227 | let processor = this.getProcessorFn(); 228 | mod = processor(mod, optArgs); 229 | } 230 | 231 | this.log_(['+', this.getRelativePath_(loopFile)], 'info'); 232 | 233 | this.createNamespace_(obj, parts, mod); 234 | }); 235 | } 236 | 237 | /** 238 | * Sets module manipulation processor. 239 | * @param {Function} processorFn 240 | */ 241 | setProcessorFn(processorFn) { 242 | this.processorFn = processorFn; 243 | } 244 | 245 | /** 246 | * Gets keyname removing excension if required. 247 | * @param {string} name 248 | * @return {string} 249 | */ 250 | getKeyName_(name) { 251 | return path.basename(name, path.extname(name)); 252 | } 253 | 254 | /** 255 | * Get exclusion globs. 256 | * @return {Array} Exclusion globs. 257 | */ 258 | getExclusionGlobs() { 259 | return this.exclusionGlobs; 260 | } 261 | 262 | /** 263 | * Get files. 264 | * @return {Promise} Returns a promise with the grouped files. 265 | */ 266 | async getFiles() { 267 | let groupedFiles = []; 268 | 269 | for (let globPattern of this.getInjectionGlobs()) { 270 | let files = await this.getGlobFile(globPattern); 271 | groupedFiles.push(files); 272 | } 273 | 274 | return groupedFiles; 275 | } 276 | 277 | /** 278 | * Concatenates cwd directory from options with the file name. 279 | * @param {string} file Target file. 280 | * @return {string} Returns full patch. 281 | */ 282 | getFullPath_(file) { 283 | return `${this.getOptions().cwd}/${file}`; 284 | } 285 | 286 | /** 287 | * Get files based on provided glob. 288 | * @param {Array|string} pattern Pattern used to locate 289 | * files using glob module. 290 | * @return {Promise} Returns promise with the files found in the processing. 291 | */ 292 | getGlobFile(pattern) { 293 | return new Promise((resolve, reject) => { 294 | const options = { 295 | ignore: this.getExclusionGlobs(), 296 | cwd: this.getOptions().cwd, 297 | }; 298 | 299 | glob(pattern, options, (err, files) => { 300 | if (err) { 301 | reject(err); 302 | } 303 | resolve(files); 304 | }); 305 | }); 306 | } 307 | 308 | /** 309 | * Get files to be inject. 310 | * @return {Array} 311 | */ 312 | getInjectionGlobs() { 313 | return this.injectionGlobs; 314 | } 315 | 316 | /** 317 | * Get options. 318 | * @return {Object} 319 | */ 320 | getOptions() { 321 | return this.options; 322 | } 323 | 324 | /** 325 | * Get relative path. 326 | * @param {string} file Target file to concatenate with relative path. 327 | * @return {string} Relative path. 328 | * @private 329 | */ 330 | getRelativePath_(file) { 331 | return '.' + this.getFullPath_(file).split(this.getOptions().cwd).pop(); 332 | } 333 | } 334 | 335 | export default Wizard; 336 | -------------------------------------------------------------------------------- /test/fixtures/module_and_root/foo.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | return this; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/module_and_root/model/bar.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | return this; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/module_es6/service.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Service using default 3 | * @return {Function} 4 | */ 5 | export default function() { 6 | return this; // eslint-disable-line no-invalid-this 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/module_files/controller/module1.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app, modify) { 2 | if (modify) { 3 | this.execute = true; 4 | } 5 | this.foo = 'bar'; 6 | return this; 7 | }; 8 | -------------------------------------------------------------------------------- /test/fixtures/module_files/controller/module2.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | return this; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/module_files/model/module1.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | return this; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/module_files/model/module2.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | return this; 3 | }; 4 | -------------------------------------------------------------------------------- /test/fixtures/root_files/foo.js: -------------------------------------------------------------------------------- 1 | module.exports = function(app) { 2 | return this; 3 | }; 4 | -------------------------------------------------------------------------------- /test/setup/.globals.json: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | "expect": true, 4 | "mock": true, 5 | "sandbox": true, 6 | "spy": true, 7 | "stub": true, 8 | "useFakeServer": true, 9 | "useFakeTimers": true, 10 | "useFakeXMLHttpRequest": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/setup/node.js: -------------------------------------------------------------------------------- 1 | import chai from 'chai'; 2 | import sinon from 'sinon'; 3 | import sinonChai from 'sinon-chai'; 4 | 5 | global.chai = chai; 6 | global.sinon = sinon; 7 | global.chai.use(sinonChai); 8 | 9 | require('babel-core/register'); 10 | require('./setup')(); 11 | -------------------------------------------------------------------------------- /test/setup/setup.js: -------------------------------------------------------------------------------- 1 | module.exports = function(root) { 2 | root = root ? root : global; 3 | root.expect = root.chai.expect; 4 | 5 | beforeEach(() => { 6 | // Using these globally-available Sinon features is preferrable, as they're 7 | // automatically restored for you in the subsequent `afterEach` 8 | root.sandbox = root.sinon.sandbox.create(); 9 | root.stub = root.sandbox.stub.bind(root.sandbox); 10 | root.spy = root.sandbox.spy.bind(root.sandbox); 11 | root.mock = root.sandbox.mock.bind(root.sandbox); 12 | root.useFakeTimers = root.sandbox 13 | .useFakeTimers 14 | .bind(root.sandbox); 15 | root.useFakeXMLHttpRequest = root.sandbox 16 | .useFakeXMLHttpRequest 17 | .bind(root.sandbox); 18 | root.useFakeServer = root.sandbox 19 | .useFakeServer 20 | .bind(root.sandbox); 21 | }); 22 | 23 | afterEach(() => { 24 | delete root.stub; 25 | delete root.spy; 26 | root.sandbox.restore(); 27 | }); 28 | }; 29 | -------------------------------------------------------------------------------- /test/unit/wizard.js: -------------------------------------------------------------------------------- 1 | import Wizard from '../../src/wizard'; 2 | import path from 'path'; 3 | 4 | describe('Wizard', function() { 5 | describe('config', function() { 6 | let cwd = path.resolve('test/fixtures/module_files'); 7 | let verbose = false; 8 | 9 | it('should set verbose to false', function() { 10 | const optParams = { 11 | verbose: false, 12 | }; 13 | 14 | const wizard = new Wizard(optParams); 15 | 16 | expect(wizard.getOptions().verbose).to.equal(false); 17 | }); 18 | 19 | it('should set a custom logger', function() { 20 | const logger = {foo: true, info: function() {}}; 21 | const instance = new Wizard({logger: logger, verbose: verbose}); 22 | return 'foo' in instance.getOptions().logger; 23 | }); 24 | 25 | it('should set the working directory to `'+ cwd +'`', function() { 26 | const instance = new Wizard({cwd: cwd, verbose: verbose}); 27 | expect(instance.getOptions().cwd).to.equal(cwd); 28 | }); 29 | 30 | it('should load default exclusion into exclusion list', function() { 31 | const instance = new Wizard({cwd: cwd, 32 | verbose: verbose, 33 | defaultExclusion: ['foo.js']}); 34 | expect(instance.getExclusionGlobs()).to.deep.equal(['foo.js']); 35 | }); 36 | }); 37 | 38 | describe('logging', function() { 39 | it('should log when verbose is true', function() { 40 | const cwd = path.resolve('test/fixtures/module_files'); 41 | stub(console, 'info'); 42 | new Wizard({cwd: cwd, verbose: true}); 43 | const calledWith = console.info // eslint-disable-line no-console 44 | .calledWith(`Initialized in ${cwd}`); // eslint-disable-line max-len 45 | expect(calledWith).to.be.true; 46 | }); 47 | }); 48 | 49 | describe('#getDefaultProcessorFn', () => { 50 | it('should return a function', () => { 51 | const verbose = false; 52 | const instance = new Wizard({verbose: verbose}); 53 | expect(instance.getDefaultProcessorFn()).to.be.a('function'); 54 | }); 55 | }); 56 | 57 | describe('#inject', function() { 58 | it('should add a glob pattern to inject one file', function() { 59 | const verbose = false; 60 | const instance = new Wizard({verbose: verbose}); 61 | const file = ['test/fixtures/root_files/foo.js']; 62 | 63 | instance.inject('test/fixtures/root_files/foo.js'); 64 | 65 | expect([file]).to.deep.equal(instance.getInjectionGlobs()); 66 | }); 67 | 68 | it('should add a glob pattern to inject one file using array', function() { 69 | const verbose = false; 70 | const instance = new Wizard({verbose: verbose}); 71 | const file = ['test/fixtures/root_files/foo.js']; 72 | 73 | instance.inject(['test/fixtures/root_files/foo.js']); 74 | 75 | expect([file]).to.deep.equal(instance.getInjectionGlobs()); 76 | }); 77 | 78 | it('should inject all the files in the module_files app', function() { 79 | const verbose = false; 80 | const instance = new Wizard({verbose: verbose}); 81 | const files = [ 82 | ['test/fixtures/module_files/model/**/*.js'], 83 | ['test/fixtures/module_files/controller/**/*.js'], 84 | ]; 85 | 86 | instance.inject('test/fixtures/module_files/model/**/*.js') 87 | .inject('test/fixtures/module_files/controller/**/*.js'); 88 | 89 | expect(files).to.deep.equal(instance.getInjectionGlobs()); 90 | }); 91 | 92 | it('should thrown an error if glob is not provided', function() { 93 | const verbose = false; 94 | const instance = new Wizard({verbose: verbose}); 95 | 96 | expect(function() { 97 | instance.inject(); 98 | }).to.throw('Glob is required.'); 99 | }); 100 | }); 101 | 102 | describe('#exclude', function() { 103 | it('should add a glob pattern to exclude one file', function() { 104 | const verbose = false; 105 | const instance = new Wizard({verbose: verbose}); 106 | const file = 'test/fixtures/root_files/foo.js'; 107 | 108 | instance.exclude('test/fixtures/root_files/foo.js'); 109 | 110 | expect([file]).to.deep.equal(instance.getExclusionGlobs()); 111 | }); 112 | 113 | it('should add a glob pattern to exclude one file using array', function() { 114 | const verbose = false; 115 | const instance = new Wizard({verbose: verbose}); 116 | const file = 'test/fixtures/root_files/foo.js'; 117 | 118 | instance.exclude(['test/fixtures/root_files/foo.js']); 119 | 120 | expect([file]).to.deep.equal(instance.getExclusionGlobs()); 121 | }); 122 | 123 | it('should exclude all the files in the module_files app', function() { 124 | const verbose = false; 125 | const instance = new Wizard({verbose: verbose}); 126 | const files = [ 127 | 'test/fixtures/module_files/model/**/*.js', 128 | 'test/fixtures/module_files/controller/**/*.js', 129 | ]; 130 | 131 | instance.exclude('test/fixtures/module_files/model/**/*.js') 132 | .exclude('test/fixtures/module_files/controller/**/*.js'); 133 | 134 | expect(files).to.deep.equal(instance.getExclusionGlobs()); 135 | }); 136 | 137 | it('should thrown an error if glob is not provided', function() { 138 | const verbose = false; 139 | const instance = new Wizard({verbose: verbose}); 140 | 141 | expect(function() { 142 | instance.exclude(); 143 | }).to.throw('Glob is required.'); 144 | }); 145 | }); 146 | 147 | describe('#into', function() { 148 | let cwd = path.resolve('test/fixtures/module_files'); 149 | const verbose = false; 150 | 151 | it('should load the module_files app files', async () => { 152 | const instance = new Wizard({verbose: verbose, cwd: cwd}); 153 | let app = {}; 154 | 155 | await instance.inject('model/**/*.js') 156 | .inject('controller/**/*.js') 157 | .into(app); 158 | 159 | ['module1', 'module2'].map((file) => { 160 | expect(typeof app.model[file]).to.equal('function'); 161 | expect(typeof app.controller[file]).to.equal('function'); 162 | }); 163 | }); 164 | 165 | it('should load the files inside the model folder', async () => { 166 | const instance = new Wizard({verbose: verbose, cwd: cwd}); 167 | let app = {}; 168 | 169 | await instance.inject('model/**/*.js') 170 | .into(app); 171 | 172 | ['module1', 'module2'].map((file) => { 173 | expect(typeof app.model[file]).to.equal('function'); 174 | }); 175 | 176 | expect(app.controllers).to.equal(undefined); 177 | }); 178 | 179 | it('should be able to perform a script', async () => { 180 | const instance = new Wizard({verbose: verbose, cwd: cwd}); 181 | let app = {}; 182 | 183 | await instance.inject('controller/**/*.js') 184 | .into(app, app, true); 185 | 186 | expect(app.controller.module1.execute).to.equal(true); 187 | }); 188 | 189 | it('should not update fake app if there\'s no injected files', async () => { 190 | const instance = new Wizard({verbose: verbose, cwd: cwd}); 191 | let app = {}; 192 | 193 | await instance.into(app); 194 | 195 | expect(app).to.deep.equal({}); 196 | }); 197 | 198 | it('should be able to load a file using export default', async () => { 199 | const customCwd = path.resolve('test/fixtures/module_es6'); 200 | const instance = new Wizard({verbose: verbose, cwd: customCwd}); 201 | let app = {}; 202 | 203 | await instance.inject('service.js').into(app); 204 | 205 | expect(typeof app['service']).to.equal('function'); 206 | }); 207 | }); 208 | 209 | describe('#setProcessor', () => { 210 | let cwd = path.resolve('test/fixtures/module_files'); 211 | const verbose = false; 212 | 213 | it('it should replace the default processor and create custom actions for each module', async() => { // eslint-disable-line max-len 214 | const instance = new Wizard({verbose: verbose, cwd: cwd}); 215 | let app = {}; 216 | 217 | stub(console, 'info'); 218 | 219 | let customFunction = (mod, optArgs) => { 220 | console.info(optArgs);// eslint-disable-line no-console 221 | }; 222 | 223 | instance.setProcessorFn(customFunction); 224 | 225 | await instance.inject('controller/**/*.js').into(app, app); 226 | 227 | expect(console.info.calledTwice) // eslint-disable-line no-console 228 | .to.be.true; 229 | }); 230 | }); 231 | }); 232 | --------------------------------------------------------------------------------