enhancement(schematics): optimize formatting during codegen
This commit is contained in:
parent
9897fa1970
commit
d537476b0c
20
.github/ISSUE_TEMPLATE.md
vendored
20
.github/ISSUE_TEMPLATE.md
vendored
@ -5,10 +5,10 @@ _[Please make sure you have read the submission guidelines before posting an iss
|
|||||||
Please answer the following questions for yourself before submitting an issue.
|
Please answer the following questions for yourself before submitting an issue.
|
||||||
**YOU MAY DELETE THE PREREQUISITES SECTION.**
|
**YOU MAY DELETE THE PREREQUISITES SECTION.**
|
||||||
|
|
||||||
* [ ] I am running the latest version
|
- [ ] I am running the latest version
|
||||||
* [ ] I checked the documentation and found no answer
|
- [ ] I checked the documentation and found no answer
|
||||||
* [ ] I checked to make sure that this issue has not already been filed
|
- [ ] I checked to make sure that this issue has not already been filed
|
||||||
* [ ] I'm reporting the issue to the correct repository (not related to Angular, AngularCLI or any dependency)
|
- [ ] I'm reporting the issue to the correct repository (not related to Angular, AngularCLI or any dependency)
|
||||||
|
|
||||||
## Expected Behavior
|
## Expected Behavior
|
||||||
|
|
||||||
@ -34,12 +34,12 @@ Please provide detailed steps for reproducing the issue.
|
|||||||
|
|
||||||
Please provide any relevant information about your setup:
|
Please provide any relevant information about your setup:
|
||||||
|
|
||||||
* version of Nx used
|
- version of Nx used
|
||||||
* version of Angular CLI used
|
- version of Angular CLI used
|
||||||
* `angular.json` configuration
|
- `angular.json` configuration
|
||||||
* version of Angular DevKit used
|
- version of Angular DevKit used
|
||||||
* 3rd-party libraries and their versions
|
- 3rd-party libraries and their versions
|
||||||
* and most importantly - a use-case that fails
|
- and most importantly - a use-case that fails
|
||||||
|
|
||||||
**A minimal reproduce scenario using allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem.**
|
**A minimal reproduce scenario using allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem.**
|
||||||
|
|
||||||
|
|||||||
202
CHANGELOG.md
202
CHANGELOG.md
@ -6,58 +6,58 @@
|
|||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
* **schematic:** add a migration to add tsconfig.tools.json ([c18baf0](https://github.com/nrwl/nx/commit/c18baf0))
|
- **schematic:** add a migration to add tsconfig.tools.json ([c18baf0](https://github.com/nrwl/nx/commit/c18baf0))
|
||||||
|
|
||||||
# 1.0.0
|
# 1.0.0
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
* **schematics:** dep-graph visual style for affected lib ([8ca8548](https://github.com/nrwl/nx/commit/8ca8548))
|
- **schematics:** dep-graph visual style for affected lib ([8ca8548](https://github.com/nrwl/nx/commit/8ca8548))
|
||||||
* **schematics:** remove strict check for "file" option for dep-graph ([6aa6702](https://github.com/nrwl/nx/commit/6aa6702))
|
- **schematics:** remove strict check for "file" option for dep-graph ([6aa6702](https://github.com/nrwl/nx/commit/6aa6702))
|
||||||
* **schematics:** add nxmodule forroot if not existing when generating ngrx for root ([e748e81](https://github.com/nrwl/nx/commit/e748e81))
|
- **schematics:** add nxmodule forroot if not existing when generating ngrx for root ([e748e81](https://github.com/nrwl/nx/commit/e748e81))
|
||||||
* **schematics:** don't leak file descriptor in shared.ts/mtime ([aa1ff78](https://github.com/nrwl/nx/commit/aa1ff78)), closes [#403](https://github.com/nrwl/nx/issues/403)
|
- **schematics:** don't leak file descriptor in shared.ts/mtime ([aa1ff78](https://github.com/nrwl/nx/commit/aa1ff78)), closes [#403](https://github.com/nrwl/nx/issues/403)
|
||||||
* **schematics:** ignore errors when the tools directory already exists ([2a377fe](https://github.com/nrwl/nx/commit/2a377fe))
|
- **schematics:** ignore errors when the tools directory already exists ([2a377fe](https://github.com/nrwl/nx/commit/2a377fe))
|
||||||
|
|
||||||
# 0.11.0
|
# 0.11.0
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Support to generate visualization graph](https://github.com/nrwl/nx/commit/49525efe3e31ff93dccf68499300fe35deaac78f)
|
- [Support to generate visualization graph](https://github.com/nrwl/nx/commit/49525efe3e31ff93dccf68499300fe35deaac78f)
|
||||||
|
|
||||||
# 0.10.1
|
# 0.10.1
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Add support for workspace-specific schematics](https://github.com/nrwl/nx/commit/bc559575f524aacbe3d25eb97210101e60de4526)
|
- [Add support for workspace-specific schematics](https://github.com/nrwl/nx/commit/bc559575f524aacbe3d25eb97210101e60de4526)
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
* [Extend ngrx and Angular schematics](https://github.com/nrwl/nx/commit/0c2b01bda6904e09f0c4f997ef4a98818723b795)
|
- [Extend ngrx and Angular schematics](https://github.com/nrwl/nx/commit/0c2b01bda6904e09f0c4f997ef4a98818723b795)
|
||||||
|
|
||||||
# 0.10.0
|
# 0.10.0
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Use npm-run-all to run build in parallel](https://github.com/nrwl/nx/commit/7b63de662e3aa99a8688681f0e26518ca05ffcbc)
|
- [Use npm-run-all to run build in parallel](https://github.com/nrwl/nx/commit/7b63de662e3aa99a8688681f0e26518ca05ffcbc)
|
||||||
* [Enhance nxEnforceModuleBoundaries check to support projects tagged with multiple tags](https://github.com/nrwl/nx/commit/d416c580b5db181cedf45ed952d9b6db49bb084d)
|
- [Enhance nxEnforceModuleBoundaries check to support projects tagged with multiple tags](https://github.com/nrwl/nx/commit/d416c580b5db181cedf45ed952d9b6db49bb084d)
|
||||||
* [Add a usage information option to create-nx-workspace ](https://github.com/nrwl/nx/commit/2746f0399d0c729ff08420f46f2c2c6b4256f6a7)
|
- [Add a usage information option to create-nx-workspace ](https://github.com/nrwl/nx/commit/2746f0399d0c729ff08420f46f2c2c6b4256f6a7)
|
||||||
* [Add an option to pass a custom module name when creating libs](https://github.com/nrwl/nx/commit/c1ca7df014043d0e27517b26470067677c57efa3)
|
- [Add an option to pass a custom module name when creating libs](https://github.com/nrwl/nx/commit/c1ca7df014043d0e27517b26470067677c57efa3)
|
||||||
* [Affected support for uncommitted changes](https://github.com/nrwl/nx/commit/113b51bd330c2af058675386e482d38f170a6688)
|
- [Affected support for uncommitted changes](https://github.com/nrwl/nx/commit/113b51bd330c2af058675386e482d38f170a6688)
|
||||||
* [Extend circular dependency check](https://github.com/nrwl/nx/commit/fff9659c3a108b613c6db89bcca4072494fbe85f)
|
- [Extend circular dependency check](https://github.com/nrwl/nx/commit/fff9659c3a108b613c6db89bcca4072494fbe85f)
|
||||||
* [Add lint checks ensuring the integrity of the workspace](https://github.com/nrwl/nx/commit/ce553b732e8ca004e1ecf53cf54bcadb6ba1f7f3)
|
- [Add lint checks ensuring the integrity of the workspace](https://github.com/nrwl/nx/commit/ce553b732e8ca004e1ecf53cf54bcadb6ba1f7f3)
|
||||||
* [Add ability to create bazel workspace](https://github.com/nrwl/nx/commit/5a26f241b1e8b8b87e2ab4da941d3d3c4c480046)
|
- [Add ability to create bazel workspace](https://github.com/nrwl/nx/commit/5a26f241b1e8b8b87e2ab4da941d3d3c4c480046)
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
* [Fix the absolute import check](https://github.com/nrwl/nx/commit/de138bb26cb816b86afe6b8f14abb362cec2a20e)
|
- [Fix the absolute import check](https://github.com/nrwl/nx/commit/de138bb26cb816b86afe6b8f14abb362cec2a20e)
|
||||||
* [Use yargs-parser to allow more types of arguments](https://github.com/nrwl/nx/commit/c747a4a0a066975bdbbda10234b78e3c63c3b44d)
|
- [Use yargs-parser to allow more types of arguments](https://github.com/nrwl/nx/commit/c747a4a0a066975bdbbda10234b78e3c63c3b44d)
|
||||||
* [Fix e2e lint config in angular cli json](https://github.com/nrwl/nx/commit/fc0bec90805217d03bf2008e9b241025cad72c05)
|
- [Fix e2e lint config in angular cli json](https://github.com/nrwl/nx/commit/fc0bec90805217d03bf2008e9b241025cad72c05)
|
||||||
* [Handle undefined rulesDirectory](https://github.com/nrwl/nx/commit/8beae9fa3d6d905778dd24c5e6b27fe7c534be13)
|
- [Handle undefined rulesDirectory](https://github.com/nrwl/nx/commit/8beae9fa3d6d905778dd24c5e6b27fe7c534be13)
|
||||||
* [Add appRoot.path for filesystem reads/writes](https://github.com/nrwl/nx/commit/809bdd4c270baf7fd883980db8d7171ebf09508e)
|
- [Add appRoot.path for filesystem reads/writes](https://github.com/nrwl/nx/commit/809bdd4c270baf7fd883980db8d7171ebf09508e)
|
||||||
* [Correct docstring for affected](https://github.com/nrwl/nx/commit/6394f9e1edf5a0b1f219050dc8b1e8269d5e5c2b)
|
- [Correct docstring for affected](https://github.com/nrwl/nx/commit/6394f9e1edf5a0b1f219050dc8b1e8269d5e5c2b)
|
||||||
* [Update karma conf with app check](https://github.com/nrwl/nx/commit/fea4f48decdfa17feb5e020318abf2ac319d05da)
|
- [Update karma conf with app check](https://github.com/nrwl/nx/commit/fea4f48decdfa17feb5e020318abf2ac319d05da)
|
||||||
* [Fix typo in CONTIRBUTING.md](https://github.com/nrwl/nx/commit/bd50643d60b3c2a8e8ace6ceaab5834d897b4aa3)
|
- [Fix typo in CONTIRBUTING.md](https://github.com/nrwl/nx/commit/bd50643d60b3c2a8e8ace6ceaab5834d897b4aa3)
|
||||||
* [Match ng lib and update versions ](https://github.com/nrwl/nx/commit/8482177b7373844d833aaad55e15a2a10d4ae116)
|
- [Match ng lib and update versions ](https://github.com/nrwl/nx/commit/8482177b7373844d833aaad55e15a2a10d4ae116)
|
||||||
|
|
||||||
# 0.9.0
|
# 0.9.0
|
||||||
|
|
||||||
@ -92,10 +92,10 @@ You can then define constraints in `tslint.json`, like this:
|
|||||||
|
|
||||||
With this configuration in place:
|
With this configuration in place:
|
||||||
|
|
||||||
* `utilslib` can depend on no libs.
|
- `utilslib` can depend on no libs.
|
||||||
* `apilib` can depend on `utilslib`
|
- `apilib` can depend on `utilslib`
|
||||||
* `implib` can depend on both `utilslib` and `apilib`.
|
- `implib` can depend on both `utilslib` and `apilib`.
|
||||||
* `untaggedlib` can depend on no libs.
|
- `untaggedlib` can depend on no libs.
|
||||||
|
|
||||||
This gets really useful once you have multiple libs with the same tag.
|
This gets really useful once you have multiple libs with the same tag.
|
||||||
|
|
||||||
@ -127,27 +127,27 @@ If we change the configuration to the following:
|
|||||||
|
|
||||||
The following will be true.
|
The following will be true.
|
||||||
|
|
||||||
* `utilslib` can depend on no libs.
|
- `utilslib` can depend on no libs.
|
||||||
* `apilib` can depend on `utilslib`
|
- `apilib` can depend on `utilslib`
|
||||||
* `implib` can depend on both `utilslib` and `apilib`.
|
- `implib` can depend on both `utilslib` and `apilib`.
|
||||||
* `untaggedlib` can depend on **all** libs.
|
- `untaggedlib` can depend on **all** libs.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Cache the dependency graph to speed up "ng lint"](https://github.com/nrwl/nx/commit/93ecf24bdadfa7ae28cf802b4f3193390858db90)
|
- [Cache the dependency graph to speed up "ng lint"](https://github.com/nrwl/nx/commit/93ecf24bdadfa7ae28cf802b4f3193390858db90)
|
||||||
* [Add lint check for circular deps](https://github.com/nrwl/nx/commit/53175f925e804539aacba8323af159d69205ddac)
|
- [Add lint check for circular deps](https://github.com/nrwl/nx/commit/53175f925e804539aacba8323af159d69205ddac)
|
||||||
* [Add support for tagged libs](https://github.com/nrwl/nx/commit/2842cb9c387226c24c0a42a154f3c65059d730f3)
|
- [Add support for tagged libs](https://github.com/nrwl/nx/commit/2842cb9c387226c24c0a42a154f3c65059d730f3)
|
||||||
* [Show warnings about importing lazy loadable libraries](https://github.com/nrwl/nx/commit/56788ba3d1a8220455b03f0c766963ae8179ce81)
|
- [Show warnings about importing lazy loadable libraries](https://github.com/nrwl/nx/commit/56788ba3d1a8220455b03f0c766963ae8179ce81)
|
||||||
* [Allow users to set prettier config](https://github.com/nrwl/nx/commit/56a6611575fee7b111655d2223f3e30ea684d000)
|
- [Allow users to set prettier config](https://github.com/nrwl/nx/commit/56a6611575fee7b111655d2223f3e30ea684d000)
|
||||||
* [Add store-freeze support](https://github.com/nrwl/nx/commit/e21caa0143862059d4b1089ccf3a7e3799cef0f2)
|
- [Add store-freeze support](https://github.com/nrwl/nx/commit/e21caa0143862059d4b1089ccf3a7e3799cef0f2)
|
||||||
* [Extend the nrwl schematics from the angular cli schematics](https://github.com/nrwl/nx/commit/04f8e2fd4613aff4064123cacd8eb54e1da09a60)
|
- [Extend the nrwl schematics from the angular cli schematics](https://github.com/nrwl/nx/commit/04f8e2fd4613aff4064123cacd8eb54e1da09a60)
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
* [Improve windows compatibility](https://github.com/nrwl/nx/commit/4f052bb3e60f20d0d676f283de2e2faece0dcef8)
|
- [Improve windows compatibility](https://github.com/nrwl/nx/commit/4f052bb3e60f20d0d676f283de2e2faece0dcef8)
|
||||||
* [Dasherize the state folder](https://github.com/nrwl/nx/commit/b17b186186ea5617b1b953f1ddd4ab05ebfa7d92)
|
- [Dasherize the state folder](https://github.com/nrwl/nx/commit/b17b186186ea5617b1b953f1ddd4ab05ebfa7d92)
|
||||||
* [Fix create-nx-workspace to respect the --directory](https://github.com/nrwl/nx/commit/da9310e9dbb4eb3294200ca72bfa70b14faec2c2)
|
- [Fix create-nx-workspace to respect the --directory](https://github.com/nrwl/nx/commit/da9310e9dbb4eb3294200ca72bfa70b14faec2c2)
|
||||||
* [Fix protractor.conf.js schema](https://github.com/nrwl/nx/commit/37cabafb35980ce8e991abc1269387b3aaaf9f25)
|
- [Fix protractor.conf.js schema](https://github.com/nrwl/nx/commit/37cabafb35980ce8e991abc1269387b3aaaf9f25)
|
||||||
|
|
||||||
# 0.8.0
|
# 0.8.0
|
||||||
|
|
||||||
@ -155,85 +155,85 @@ The following will be true.
|
|||||||
|
|
||||||
Nx no longer uses a patched version of the CLI--we switched to using `@angular/cli@1.7.1`. We also renamed the nx-migrate command into `update` to align with the CLI.
|
Nx no longer uses a patched version of the CLI--we switched to using `@angular/cli@1.7.1`. We also renamed the nx-migrate command into `update` to align with the CLI.
|
||||||
|
|
||||||
* [Switch to @angular/cli 1.7](https://github.com/nrwl/nx/commit/acdeb1b71c14e3bc7e5bd2bc925640ad7d0aa24d)
|
- [Switch to @angular/cli 1.7](https://github.com/nrwl/nx/commit/acdeb1b71c14e3bc7e5bd2bc925640ad7d0aa24d)
|
||||||
* [Add update, update:skip, and update:check commands](https://github.com/nrwl/nx/commit/2fb62597514f1c82e4d80d75a7d60d11229d5aa3)
|
- [Add update, update:skip, and update:check commands](https://github.com/nrwl/nx/commit/2fb62597514f1c82e4d80d75a7d60d11229d5aa3)
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
* [Fix format:write --libs-and-apps](https://github.com/nrwl/nx/commit/feeaba1a4b8d827a71731d919740135464d6e049)
|
- [Fix format:write --libs-and-apps](https://github.com/nrwl/nx/commit/feeaba1a4b8d827a71731d919740135464d6e049)
|
||||||
* [Change format to default to format-all when no patterns are detected](https://github.com/nrwl/nx/commit/58e99ab04d8e9505285bdcf31014f3774a6f900a)
|
- [Change format to default to format-all when no patterns are detected](https://github.com/nrwl/nx/commit/58e99ab04d8e9505285bdcf31014f3774a6f900a)
|
||||||
|
|
||||||
## Cleanup
|
## Cleanup
|
||||||
|
|
||||||
* [Remove the version property](https://github.com/nrwl/nx/commit/24063f02464b6da38e003841e04820dcc347e876)
|
- [Remove the version property](https://github.com/nrwl/nx/commit/24063f02464b6da38e003841e04820dcc347e876)
|
||||||
* [Use schematic context to format the generated code](https://github.com/nrwl/nx/commit/e7481a790f5becffc46e794ec46c0835a2114319)
|
- [Use schematic context to format the generated code](https://github.com/nrwl/nx/commit/e7481a790f5becffc46e794ec46c0835a2114319)
|
||||||
|
|
||||||
# 0.7.4
|
# 0.7.4
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Change generate effect tests to use toBeObservable](https://github.com/nrwl/nx/commit/222efe2f2630b02f6fdb11f560c9158cd4f51d75)
|
- [Change generate effect tests to use toBeObservable](https://github.com/nrwl/nx/commit/222efe2f2630b02f6fdb11f560c9158cd4f51d75)
|
||||||
|
|
||||||
## Fixes
|
## Fixes
|
||||||
|
|
||||||
* [Base projectPath on the full path instead of the current working directory of the process](https://github.com/nrwl/nx/commit/545f2ff13902a635b9c26854e9687790adff0616)
|
- [Base projectPath on the full path instead of the current working directory of the process](https://github.com/nrwl/nx/commit/545f2ff13902a635b9c26854e9687790adff0616)
|
||||||
* [Ammend command in script errors](https://github.com/nrwl/nx/commit/9128fa8be1e31525acb6043ff87af73b6b884aaa)
|
- [Ammend command in script errors](https://github.com/nrwl/nx/commit/9128fa8be1e31525acb6043ff87af73b6b884aaa)
|
||||||
|
|
||||||
# 0.7.2
|
# 0.7.2
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Added a post install script that run nx-migrate:check](https://github.com/nrwl/nx/commit/93a6b4e94be4b1b591eb017e77b79c777bc23deb)
|
- [Added a post install script that run nx-migrate:check](https://github.com/nrwl/nx/commit/93a6b4e94be4b1b591eb017e77b79c777bc23deb)
|
||||||
* [Updated create-nx-workspace to support yarn](https://github.com/nrwl/nx/commit/e5b247b573cef0c1cf5cc5163d030dbf514f4dff)
|
- [Updated create-nx-workspace to support yarn](https://github.com/nrwl/nx/commit/e5b247b573cef0c1cf5cc5163d030dbf514f4dff)
|
||||||
|
|
||||||
## Cleanup
|
## Cleanup
|
||||||
|
|
||||||
* [Cleaned up the output of nx-migrate](https://github.com/nrwl/nx/commit/7ab14e3b26e0e91d660ad5bb454dccb21b9745cf)
|
- [Cleaned up the output of nx-migrate](https://github.com/nrwl/nx/commit/7ab14e3b26e0e91d660ad5bb454dccb21b9745cf)
|
||||||
|
|
||||||
# 0.7.0
|
# 0.7.0
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Add nx-migrate:check and nx-migrate:skip scripts](d7ba9fdc1b9f4208db6de32184e953d00f6f064f)
|
- [Add nx-migrate:check and nx-migrate:skip scripts](d7ba9fdc1b9f4208db6de32184e953d00f6f064f)
|
||||||
|
|
||||||
# 0.7.0-beta.1
|
# 0.7.0-beta.1
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Switch to Angular 5.2 and CLI 1.6.5](https://github.com/nrwl/nx/commit/172c18dc9b84f7ac3019694e4a0eeeb40dd1bc26)
|
- [Switch to Angular 5.2 and CLI 1.6.5](https://github.com/nrwl/nx/commit/172c18dc9b84f7ac3019694e4a0eeeb40dd1bc26)
|
||||||
|
|
||||||
# 0.6.18
|
# 0.6.18
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Fixed affected: commands. Continue traversing within irrelevant PropertyAssignment nodes](https://github.com/nrwl/nx/commit/2293e28bd031efa80566228dddc202bc437c2b03)
|
- [Fixed affected: commands. Continue traversing within irrelevant PropertyAssignment nodes](https://github.com/nrwl/nx/commit/2293e28bd031efa80566228dddc202bc437c2b03)
|
||||||
* [Make affected and format windows-friendly](https://github.com/nrwl/nx/commit/9609fc675031bd4dca285ceb942a71d995d1ee7b)
|
- [Make affected and format windows-friendly](https://github.com/nrwl/nx/commit/9609fc675031bd4dca285ceb942a71d995d1ee7b)
|
||||||
|
|
||||||
## Cleanup
|
## Cleanup
|
||||||
|
|
||||||
* [Clean up tslint configuration](https://github.com/nrwl/nx/commit/828e4fe75da66dc41790e55a7738192940a04cbf)
|
- [Clean up tslint configuration](https://github.com/nrwl/nx/commit/828e4fe75da66dc41790e55a7738192940a04cbf)
|
||||||
* [Add a migration updating the version of prettier](https://github.com/nrwl/nx/commit/847a249980c3505845a8c597de8e9a3d78766f8b)
|
- [Add a migration updating the version of prettier](https://github.com/nrwl/nx/commit/847a249980c3505845a8c597de8e9a3d78766f8b)
|
||||||
|
|
||||||
# 0.6.13
|
# 0.6.13
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Avoid relative paths to node modules](https://github.com/nrwl/nx/commit/2c49c3029535a9b98216d367e9c2b77a8d40a4a4)
|
- [Avoid relative paths to node modules](https://github.com/nrwl/nx/commit/2c49c3029535a9b98216d367e9c2b77a8d40a4a4)
|
||||||
* [Handle the case when libraries are placed in the directory with the same name as an app](https://github.com/nrwl/nx/commit/f862ed05d18e1474156779ad1dee2e7a7c785d1d)
|
- [Handle the case when libraries are placed in the directory with the same name as an app](https://github.com/nrwl/nx/commit/f862ed05d18e1474156779ad1dee2e7a7c785d1d)
|
||||||
|
|
||||||
# 0.6.10
|
# 0.6.10
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Improve error messages in the affected: and format: commands](https://github.com/nrwl/nx/commit/878784ae814ffea28796f458ff2f8b0b641996c0)
|
- [Improve error messages in the affected: and format: commands](https://github.com/nrwl/nx/commit/878784ae814ffea28796f458ff2f8b0b641996c0)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Handle circular deps between apps and libs](https://github.com/nrwl/nx/commit/3531323fb5210b995b1296a198c8e76ee8bf9a07)
|
- [Handle circular deps between apps and libs](https://github.com/nrwl/nx/commit/3531323fb5210b995b1296a198c8e76ee8bf9a07)
|
||||||
* [Handle projects that have similar names](https://github.com/nrwl/nx/commit/fe7032d29f4dcd66b51dbb889a1cf1751cd1d20a)
|
- [Handle projects that have similar names](https://github.com/nrwl/nx/commit/fe7032d29f4dcd66b51dbb889a1cf1751cd1d20a)
|
||||||
* [Update workspace to set $schema and app name](https://github.com/nrwl/nx/commit/df5bd089b6515ea747f891bf590b46a4e00d0a92)
|
- [Update workspace to set \$schema and app name](https://github.com/nrwl/nx/commit/df5bd089b6515ea747f891bf590b46a4e00d0a92)
|
||||||
* [Update workspace to copy the cli file](https://github.com/nrwl/nx/commit/ddd8de3813f374a752b0e6f47deaa58c2e9f40c8)
|
- [Update workspace to copy the cli file](https://github.com/nrwl/nx/commit/ddd8de3813f374a752b0e6f47deaa58c2e9f40c8)
|
||||||
* [Disallow importing apps](https://github.com/nrwl/nx/commit/912fc81708d381f49950255eeff746a2dfd46c7b)
|
- [Disallow importing apps](https://github.com/nrwl/nx/commit/912fc81708d381f49950255eeff746a2dfd46c7b)
|
||||||
|
|
||||||
# 0.6.5
|
# 0.6.5
|
||||||
|
|
||||||
@ -269,11 +269,11 @@ npm run format:write
|
|||||||
npm run format:check
|
npm run format:check
|
||||||
```
|
```
|
||||||
|
|
||||||
* [Add format:check and format:write commands](https://github.com/nrwl/nx/commit/826a0b1056f9000425e189bad5a5d63966c3a704)
|
- [Add format:check and format:write commands](https://github.com/nrwl/nx/commit/826a0b1056f9000425e189bad5a5d63966c3a704)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Only allow importing libs using the configured npm scope](https://github.com/nrwl/nx/commit/c836668541532e64db088ef9a984678022abb3bd)
|
- [Only allow importing libs using the configured npm scope](https://github.com/nrwl/nx/commit/c836668541532e64db088ef9a984678022abb3bd)
|
||||||
|
|
||||||
# 0.6.0
|
# 0.6.0
|
||||||
|
|
||||||
@ -299,11 +299,11 @@ npm run build:affected ----files="libs/mylib/index.ts,libs/mylib2/index.ts"
|
|||||||
npm run e2e:affected ----files="libs/mylib/index.ts,libs/mylib2/index.ts"
|
npm run e2e:affected ----files="libs/mylib/index.ts,libs/mylib2/index.ts"
|
||||||
```
|
```
|
||||||
|
|
||||||
* [Add support for building and testing only the apps affected by a commit](https://github.com/nrwl/nx/commit/428762664acc5fd155dd7be630dab09101d23542)
|
- [Add support for building and testing only the apps affected by a commit](https://github.com/nrwl/nx/commit/428762664acc5fd155dd7be630dab09101d23542)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Make deep import check work for libs with same prefix](https://github.com/nrwl/nx/commit/3c55f34ca12a4d5338099586ffe9455c81a3b199)
|
- [Make deep import check work for libs with same prefix](https://github.com/nrwl/nx/commit/3c55f34ca12a4d5338099586ffe9455c81a3b199)
|
||||||
|
|
||||||
# 0.5.3
|
# 0.5.3
|
||||||
|
|
||||||
@ -330,53 +330,53 @@ Some folks also reported having problems running Nx behind a firewall, in a corp
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Replace install.sh with a more robust way of creating projects](https://github.com/nrwl/nx/commit/f91b5309bdaf764e436bd544ec4f10c84b99cb08)
|
- [Replace install.sh with a more robust way of creating projects](https://github.com/nrwl/nx/commit/f91b5309bdaf764e436bd544ec4f10c84b99cb08)
|
||||||
* [Bump up the version of prettier](https://github.com/nrwl/nx/commit/1481d169bbb7f1fbe3df5af2bce51c4215776d93)
|
- [Bump up the version of prettier](https://github.com/nrwl/nx/commit/1481d169bbb7f1fbe3df5af2bce51c4215776d93)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Generate an angular-cli config without the apps array, so the CLI can error properly](https://github.com/nrwl/nx/commit/a7f06edf5914212bcefbafb1198d262e9692cfdb)
|
- [Generate an angular-cli config without the apps array, so the CLI can error properly](https://github.com/nrwl/nx/commit/a7f06edf5914212bcefbafb1198d262e9692cfdb)
|
||||||
|
|
||||||
# 0.5.2
|
# 0.5.2
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Remove default prop for viewEncapsulation option flag](https://github.com/nrwl/nx/commit/b46eb1c699dd509f4be103979a5938c3f7486fb1)
|
- [Remove default prop for viewEncapsulation option flag](https://github.com/nrwl/nx/commit/b46eb1c699dd509f4be103979a5938c3f7486fb1)
|
||||||
* [Fix NPM link in README](https://github.com/nrwl/nx/commit/4aa42e4772522a20df384ab9a48861a8d4f7ab0f)
|
- [Fix NPM link in README](https://github.com/nrwl/nx/commit/4aa42e4772522a20df384ab9a48861a8d4f7ab0f)
|
||||||
* [Change rxjs version to use hat](https://github.com/nrwl/nx/commit/3b1942ed830ea31269a1fb9e995efb93b182870a)
|
- [Change rxjs version to use hat](https://github.com/nrwl/nx/commit/3b1942ed830ea31269a1fb9e995efb93b182870a)
|
||||||
|
|
||||||
# 0.5.1
|
# 0.5.1
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Disable typescript mismatch warnings](https://github.com/nrwl/nx/commit/ecb87a0dcd08f0968d77508976ce43a84f049743)
|
- [Disable typescript mismatch warnings](https://github.com/nrwl/nx/commit/ecb87a0dcd08f0968d77508976ce43a84f049743)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* ["ng test" should not compile e2e tests](https://github.com/nrwl/nx/commit/ac53e9a624b01cf71f88eb412678ffc48125ff38)
|
- ["ng test" should not compile e2e tests](https://github.com/nrwl/nx/commit/ac53e9a624b01cf71f88eb412678ffc48125ff38)
|
||||||
* [Fix 'npm run format'](https://github.com/nrwl/nx/commit/670cd57dfa7d5bbf6b9af4e52f2c7d40081138cb)
|
- [Fix 'npm run format'](https://github.com/nrwl/nx/commit/670cd57dfa7d5bbf6b9af4e52f2c7d40081138cb)
|
||||||
|
|
||||||
# 0.5.0
|
# 0.5.0
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Update the workspace to use Angular 5.1 and CLI 1.6](https://github.com/nrwl/nx/commit/a477bb9fc953e3b44d696945cc259119f701fb78)
|
- [Update the workspace to use Angular 5.1 and CLI 1.6](https://github.com/nrwl/nx/commit/a477bb9fc953e3b44d696945cc259119f701fb78)
|
||||||
|
|
||||||
# 0.4.0
|
# 0.4.0
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [Add support for generating nested apps and libs](https://github.com/nrwl/nx/commit/013a828d1e31f55a9b3f7c69587316890ea834d4)
|
- [Add support for generating nested apps and libs](https://github.com/nrwl/nx/commit/013a828d1e31f55a9b3f7c69587316890ea834d4)
|
||||||
* [Update NgRx schematic to allow the customization of the state folder](https://github.com/nrwl/nx/commit/a2d02652665f497be8958efc403d7a44bd831088)
|
- [Update NgRx schematic to allow the customization of the state folder](https://github.com/nrwl/nx/commit/a2d02652665f497be8958efc403d7a44bd831088)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Only begin converting to workspace once files have been checked](https://github.com/nrwl/nx/commit/e7fd6b1e04f3f3387a91c53a7ac479fe72bdd72e)
|
- [Only begin converting to workspace once files have been checked](https://github.com/nrwl/nx/commit/e7fd6b1e04f3f3387a91c53a7ac479fe72bdd72e)
|
||||||
* ["ng build" should only recompile the selected app](https://github.com/nrwl/nx/commit/550de7bb80f4d3f306c23fac70db52c98dadcd05)
|
- ["ng build" should only recompile the selected app](https://github.com/nrwl/nx/commit/550de7bb80f4d3f306c23fac70db52c98dadcd05)
|
||||||
|
|
||||||
## Refactoring
|
## Refactoring
|
||||||
|
|
||||||
* [Eliminated single letter variable names in effects template](https://github.com/nrwl/nx/commit/996143cf60bac1a57629815d5756db9ce23193ab)
|
- [Eliminated single letter variable names in effects template](https://github.com/nrwl/nx/commit/996143cf60bac1a57629815d5756db9ce23193ab)
|
||||||
|
|
||||||
# 0.3.0
|
# 0.3.0
|
||||||
|
|
||||||
@ -384,33 +384,33 @@ We want to be able to add new features to Nx without breaking existing workspace
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* [add `allow` option to whitelist deep imports](https://github.com/nrwl/nx/commit/b3f67351fe8890e06402672e687b1789f279613b)
|
- [add `allow` option to whitelist deep imports](https://github.com/nrwl/nx/commit/b3f67351fe8890e06402672e687b1789f279613b)
|
||||||
* [Added the nx-migrate command](https://github.com/nrwl/nx/commit/d6e66b99316181b8b67805b91cc35457c3465029)
|
- [Added the nx-migrate command](https://github.com/nrwl/nx/commit/d6e66b99316181b8b67805b91cc35457c3465029)
|
||||||
* [Upgrade Prettier to 1.8.2](https://github.com/nrwl/nx/commit/cc2277e91be2ca49fb1588f1d8e29ef91fd12044)
|
- [Upgrade Prettier to 1.8.2](https://github.com/nrwl/nx/commit/cc2277e91be2ca49fb1588f1d8e29ef91fd12044)
|
||||||
* [Update readme to point to example apps using Nx](https://github.com/nrwl/nx/commit/3d53e31391d5d79a0724d099c7121edb53e8b163)
|
- [Update readme to point to example apps using Nx](https://github.com/nrwl/nx/commit/3d53e31391d5d79a0724d099c7121edb53e8b163)
|
||||||
|
|
||||||
# 0.2.2
|
# 0.2.2
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [Adds a schema file to allow custom properties that the default CLI distribution does not support](https://github.com/nrwl/nx/commit/7fd7594e673cf38af7668b891ed7c75b390b3330)
|
- [Adds a schema file to allow custom properties that the default CLI distribution does not support](https://github.com/nrwl/nx/commit/7fd7594e673cf38af7668b891ed7c75b390b3330)
|
||||||
* [Fix issue with generating a wrong full path on windows](https://github.com/nrwl/nx/commit/11e6c055ba1211a5bee1cc73d46663985645f08e)
|
- [Fix issue with generating a wrong full path on windows](https://github.com/nrwl/nx/commit/11e6c055ba1211a5bee1cc73d46663985645f08e)
|
||||||
|
|
||||||
# 0.2.1
|
# 0.2.1
|
||||||
|
|
||||||
## New Features
|
## New Features
|
||||||
|
|
||||||
* [Export jasmine-marbles getTestScheduler and time functions](https://github.com/nrwl/nx/commit/2e4613f475fc2673731540fb4724d6ba2af02aae)
|
- [Export jasmine-marbles getTestScheduler and time functions](https://github.com/nrwl/nx/commit/2e4613f475fc2673731540fb4724d6ba2af02aae)
|
||||||
* [Use fetch instead of optimisticUpdate in the generated effect classes](https://github.com/nrwl/nx/commit/c9759cc4427283422e906ed19a8a2dabcb2a656b)
|
- [Use fetch instead of optimisticUpdate in the generated effect classes](https://github.com/nrwl/nx/commit/c9759cc4427283422e906ed19a8a2dabcb2a656b)
|
||||||
|
|
||||||
## Bug Fixes
|
## Bug Fixes
|
||||||
|
|
||||||
* [--routing should add RouterTestingModule](https://github.com/nrwl/nx/commit/d7fc5b56054c9a4c1fbb12845bfc0803f9a9ff86)
|
- [--routing should add RouterTestingModule](https://github.com/nrwl/nx/commit/d7fc5b56054c9a4c1fbb12845bfc0803f9a9ff86)
|
||||||
* [Fix wording in the documentation](https://github.com/nrwl/nx/commit/058c8995f35a9e677f88404bc9c8a2b177487080)
|
- [Fix wording in the documentation](https://github.com/nrwl/nx/commit/058c8995f35a9e677f88404bc9c8a2b177487080)
|
||||||
|
|
||||||
## Refactorings
|
## Refactorings
|
||||||
|
|
||||||
* [Refactor Nx to use RxJS lettable operators](https://github.com/nrwl/nx/commit/715efa4b225b65be0052a1e6a88c5bdcd5a6cf38)
|
- [Refactor Nx to use RxJS lettable operators](https://github.com/nrwl/nx/commit/715efa4b225b65be0052a1e6a88c5bdcd5a6cf38)
|
||||||
|
|
||||||
# 0.2.0
|
# 0.2.0
|
||||||
|
|
||||||
|
|||||||
@ -56,12 +56,12 @@ Before you submit an issue, please search the issue tracker, maybe an issue for
|
|||||||
|
|
||||||
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. Having a reproducible scenario gives us wealth of important information without going back & forth to you with additional questions like:
|
We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. Having a reproducible scenario gives us wealth of important information without going back & forth to you with additional questions like:
|
||||||
|
|
||||||
* version of Nx used
|
- version of Nx used
|
||||||
* version of Angular CLI used
|
- version of Angular CLI used
|
||||||
* `angular.json` configuration
|
- `angular.json` configuration
|
||||||
* version of Angular DevKit used
|
- version of Angular DevKit used
|
||||||
* 3rd-party libraries and their versions
|
- 3rd-party libraries and their versions
|
||||||
* and most importantly - a use-case that fails
|
- and most importantly - a use-case that fails
|
||||||
|
|
||||||
A minimal reproduce scenario using allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem.
|
A minimal reproduce scenario using allows us to quickly confirm a bug (or point out coding problem) as well as confirm that we are fixing the right problem.
|
||||||
|
|
||||||
@ -73,10 +73,10 @@ You can file new issues by filling out our [issue form](https://github.com/nrwl/
|
|||||||
|
|
||||||
Please follow the following guidelines:
|
Please follow the following guidelines:
|
||||||
|
|
||||||
* Make sure unit tests pass
|
- Make sure unit tests pass
|
||||||
* Make sure e2e tests pass
|
- Make sure e2e tests pass
|
||||||
* Make sure you run `yarn format`
|
- Make sure you run `yarn format`
|
||||||
* Update your commit message to follow the guidelines below
|
- Update your commit message to follow the guidelines below
|
||||||
|
|
||||||
#### Commit Message Guidelines
|
#### Commit Message Guidelines
|
||||||
|
|
||||||
@ -92,21 +92,21 @@ body
|
|||||||
|
|
||||||
The type must be one of the following:
|
The type must be one of the following:
|
||||||
|
|
||||||
* build
|
- build
|
||||||
* feat
|
- feat
|
||||||
* fix
|
- fix
|
||||||
* refactor
|
- refactor
|
||||||
* style
|
- style
|
||||||
* docs
|
- docs
|
||||||
* test
|
- test
|
||||||
|
|
||||||
##### Scope
|
##### Scope
|
||||||
|
|
||||||
The scope must be one of the following:
|
The scope must be one of the following:
|
||||||
|
|
||||||
* bazel
|
- bazel
|
||||||
* nx
|
- nx
|
||||||
* schematics
|
- schematics
|
||||||
|
|
||||||
##### Subject
|
##### Subject
|
||||||
|
|
||||||
|
|||||||
50
README.md
50
README.md
@ -24,17 +24,17 @@ Nx is an extension for the the Angular CLI implementing the monorepo-style devel
|
|||||||
|
|
||||||
Because Nx is built on top of the Angular CLI, you get all the conventional and loved features plus:
|
Because Nx is built on top of the Angular CLI, you get all the conventional and loved features plus:
|
||||||
|
|
||||||
* Nx Workspace
|
- Nx Workspace
|
||||||
* Workspace-Specific Schematics
|
- Workspace-Specific Schematics
|
||||||
* Intelligent Builds and Unit Testing
|
- Intelligent Builds and Unit Testing
|
||||||
* State Management
|
- State Management
|
||||||
* NgRx
|
- NgRx
|
||||||
* Data Persistence
|
- Data Persistence
|
||||||
* Linters
|
- Linters
|
||||||
* Code Formatter
|
- Code Formatter
|
||||||
* UpgradeModule and downgradeModule helpers
|
- UpgradeModule and downgradeModule helpers
|
||||||
* Jest unit tests integration
|
- Jest unit tests integration
|
||||||
* Node build tooling
|
- Node build tooling
|
||||||
|
|
||||||
# Why Nx?
|
# Why Nx?
|
||||||
|
|
||||||
@ -42,8 +42,8 @@ On the surface, large and small organizations care about the same things: consis
|
|||||||
|
|
||||||
What’s different about large organizations is that they have hundreds of Angular engineers building dozens of apps. So they have a lot of code, which changes everything.
|
What’s different about large organizations is that they have hundreds of Angular engineers building dozens of apps. So they have a lot of code, which changes everything.
|
||||||
|
|
||||||
* While ten (10) developers can reach a consensus on best practices by chatting over lunch, five hundred (500) developers cannot. You have to establish best practices, team standards, **and use tools to promote them**.
|
- While ten (10) developers can reach a consensus on best practices by chatting over lunch, five hundred (500) developers cannot. You have to establish best practices, team standards, **and use tools to promote them**.
|
||||||
* With three (3) projects developers will know what needs to be retested after making a change, with thirty (30) projects, however, this is no longer a simple process. Informal team rules to manage change will no longer work with large teams and multi-team, multi-project efforts. **You have to rely on the automated CI process instead.** …
|
- With three (3) projects developers will know what needs to be retested after making a change, with thirty (30) projects, however, this is no longer a simple process. Informal team rules to manage change will no longer work with large teams and multi-team, multi-project efforts. **You have to rely on the automated CI process instead.** …
|
||||||
|
|
||||||
In other words, small organizations can often get by with informal ad-hoc processes, whereas large organizations cannot. **Large organizations must rely on tooling to enable that. Nx is this tooling.**
|
In other words, small organizations can often get by with informal ad-hoc processes, whereas large organizations cannot. **Large organizations must rely on tooling to enable that. Nx is this tooling.**
|
||||||
|
|
||||||
@ -81,30 +81,30 @@ You are good to go!
|
|||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
* [Nx Documentation and Guides](https://nrwl.io/nx)
|
- [Nx Documentation and Guides](https://nrwl.io/nx)
|
||||||
* [Nx blog posts](https://blog.nrwl.io/nx/home)
|
- [Nx blog posts](https://blog.nrwl.io/nx/home)
|
||||||
|
|
||||||
### Videos
|
### Videos
|
||||||
|
|
||||||
* [5-minute video on how to get started with Nx.](http://nrwl.io/nx)
|
- [5-minute video on how to get started with Nx.](http://nrwl.io/nx)
|
||||||
* [Video course on using Nx Workspaces](https://angularplaybook.com/p/nx-workspaces)
|
- [Video course on using Nx Workspaces](https://angularplaybook.com/p/nx-workspaces)
|
||||||
|
|
||||||
### Talks
|
### Talks
|
||||||
|
|
||||||
* [Angular at Large Organizations](https://www.youtube.com/watch?v=piQ0EZhtus0)
|
- [Angular at Large Organizations](https://www.youtube.com/watch?v=piQ0EZhtus0)
|
||||||
* [Nx: The New Way to Build Enterprise Angular Apps](https://www.youtube.com/watch?v=xo-1SDmvM8Y)
|
- [Nx: The New Way to Build Enterprise Angular Apps](https://www.youtube.com/watch?v=xo-1SDmvM8Y)
|
||||||
* [Supercharging the Angular CLI](https://www.youtube.com/watch?v=bMkKz8AedHc)
|
- [Supercharging the Angular CLI](https://www.youtube.com/watch?v=bMkKz8AedHc)
|
||||||
* [Hands on Full Stack development with Nx and Bazel](https://www.youtube.com/watch?v=1KDDIhcQORM)
|
- [Hands on Full Stack development with Nx and Bazel](https://www.youtube.com/watch?v=1KDDIhcQORM)
|
||||||
|
|
||||||
### Podcasts and Shows
|
### Podcasts and Shows
|
||||||
|
|
||||||
* [ngAir 140: Nx for Enterprise Angular Development](https://www.youtube.com/watch?v=qYNiOKDno_I)
|
- [ngAir 140: Nx for Enterprise Angular Development](https://www.youtube.com/watch?v=qYNiOKDno_I)
|
||||||
* [ngHouston: NX Demo](https://www.youtube.com/watch?v=E_UlU2Yv4G0)
|
- [ngHouston: NX Demo](https://www.youtube.com/watch?v=E_UlU2Yv4G0)
|
||||||
|
|
||||||
## Misc
|
## Misc
|
||||||
|
|
||||||
* [nx-examples](https://github.com/nrwl/nx-examples) repo has branches for different nx comments to display expected behavior and example app and libraries. Check out the branch (workspace, ngrx...) to see what gets created for you. More info on readme.
|
- [nx-examples](https://github.com/nrwl/nx-examples) repo has branches for different nx comments to display expected behavior and example app and libraries. Check out the branch (workspace, ngrx...) to see what gets created for you. More info on readme.
|
||||||
* [xplat - Cross-platform tools for Nx workspaces](https://nstudio.io/xplat/)
|
- [xplat - Cross-platform tools for Nx workspaces](https://nstudio.io/xplat/)
|
||||||
|
|
||||||
## Want to help?
|
## Want to help?
|
||||||
|
|
||||||
|
|||||||
@ -10,9 +10,7 @@ import {
|
|||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
describe('Affected', () => {
|
describe('Affected', () => {
|
||||||
it(
|
it('should print, build, and test affected apps', () => {
|
||||||
'should print, build, and test affected apps',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myapp');
|
newApp('myapp');
|
||||||
newApp('myapp2');
|
newApp('myapp2');
|
||||||
@ -198,13 +196,9 @@ describe('Affected', () => {
|
|||||||
'npm run affected -- --target extract-i18n --files="libs/mylib/src/index.ts"'
|
'npm run affected -- --target extract-i18n --files="libs/mylib/src/index.ts"'
|
||||||
);
|
);
|
||||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('should print, build, and test all apps', () => {
|
||||||
'should print, build, and test all apps',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myapp');
|
newApp('myapp');
|
||||||
newApp('myapp2');
|
newApp('myapp2');
|
||||||
@ -238,12 +232,8 @@ describe('Affected', () => {
|
|||||||
expect(unitTests).toContain('Running test for myapp');
|
expect(unitTests).toContain('Running test for myapp');
|
||||||
expect(unitTests).toContain('Running test for mylib');
|
expect(unitTests).toContain('Running test for mylib');
|
||||||
|
|
||||||
const i18n = runCommand(
|
const i18n = runCommand('npm run affected -- --target extract-i18n --all');
|
||||||
'npm run affected -- --target extract-i18n --all'
|
|
||||||
);
|
|
||||||
expect(i18n).toContain('Running extract-i18n for myapp2');
|
expect(i18n).toContain('Running extract-i18n for myapp2');
|
||||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,17 +1,13 @@
|
|||||||
import { checkFilesExist, newApp, newBazelProject, newLib } from '../utils';
|
import { checkFilesExist, newApp, newBazelProject, newLib } from '../utils';
|
||||||
|
|
||||||
xdescribe('Nrwl Workspace (Bazel)', () => {
|
xdescribe('Nrwl Workspace (Bazel)', () => {
|
||||||
it(
|
it('should work', () => {
|
||||||
'should work',
|
|
||||||
() => {
|
|
||||||
newBazelProject();
|
newBazelProject();
|
||||||
newApp('myApp --directory=myDir');
|
newApp('myApp --directory=myDir');
|
||||||
newLib('myLib --directory=myDir');
|
newLib('myLib --directory=myDir');
|
||||||
|
|
||||||
checkFilesExist('WORKSPACE', 'BUILD.bazel');
|
checkFilesExist('WORKSPACE', 'BUILD.bazel');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// afterEach(() => {
|
// afterEach(() => {
|
||||||
|
|||||||
@ -12,9 +12,7 @@ import {
|
|||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
describe('Command line', () => {
|
describe('Command line', () => {
|
||||||
it(
|
it('lint should ensure module boundaries', () => {
|
||||||
'lint should ensure module boundaries',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myapp --tags=validtag');
|
newApp('myapp --tags=validtag');
|
||||||
newApp('myapp2');
|
newApp('myapp2');
|
||||||
@ -52,9 +50,7 @@ describe('Command line', () => {
|
|||||||
expect(out).toContain(
|
expect(out).toContain(
|
||||||
'A project tagged with "validtag" can only depend on libs tagged with "validtag"'
|
'A project tagged with "validtag" can only depend on libs tagged with "validtag"'
|
||||||
);
|
);
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it('should run nx lint', () => {
|
it('should run nx lint', () => {
|
||||||
newProject();
|
newProject();
|
||||||
@ -81,9 +77,7 @@ describe('Command line', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('format should check and reformat the code', () => {
|
||||||
'format should check and reformat the code',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myapp');
|
newApp('myapp');
|
||||||
newLib('mylib');
|
newLib('mylib');
|
||||||
@ -144,13 +138,9 @@ describe('Command line', () => {
|
|||||||
|
|
||||||
runCommand('npm run format:write');
|
runCommand('npm run format:write');
|
||||||
expect(runCommand('npm run -s format:check')).toEqual('');
|
expect(runCommand('npm run -s format:check')).toEqual('');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('should support workspace-specific schematics', () => {
|
||||||
'should support workspace-specific schematics',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
runCLI('g workspace-schematic custom');
|
runCLI('g workspace-schematic custom');
|
||||||
checkFilesExist(
|
checkFilesExist(
|
||||||
@ -193,9 +183,7 @@ describe('Command line', () => {
|
|||||||
);
|
);
|
||||||
expect(output).toContain('update angular.json');
|
expect(output).toContain('update angular.json');
|
||||||
expect(output).toContain('update nx.json');
|
expect(output).toContain('update nx.json');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
describe('dep-graph', () => {
|
describe('dep-graph', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
newProject();
|
newProject();
|
||||||
@ -225,9 +213,7 @@ describe('Command line', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('dep-graph should output json (without critical path) to file', () => {
|
||||||
'dep-graph should output json (without critical path) to file',
|
|
||||||
() => {
|
|
||||||
const file = 'dep-graph.json';
|
const file = 'dep-graph.json';
|
||||||
|
|
||||||
runCommand(`npm run dep-graph -- --file="${file}"`);
|
runCommand(`npm run dep-graph -- --file="${file}"`);
|
||||||
@ -283,13 +269,9 @@ describe('Command line', () => {
|
|||||||
},
|
},
|
||||||
criticalPath: []
|
criticalPath: []
|
||||||
});
|
});
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('dep-graph should output json with critical path to file', () => {
|
||||||
'dep-graph should output json with critical path to file',
|
|
||||||
() => {
|
|
||||||
const file = 'dep-graph.json';
|
const file = 'dep-graph.json';
|
||||||
|
|
||||||
runCommand(
|
runCommand(
|
||||||
@ -304,13 +286,9 @@ describe('Command line', () => {
|
|||||||
expect(jsonFileContents.criticalPath).toContain('myapp2');
|
expect(jsonFileContents.criticalPath).toContain('myapp2');
|
||||||
expect(jsonFileContents.criticalPath).toContain('mylib');
|
expect(jsonFileContents.criticalPath).toContain('mylib');
|
||||||
expect(jsonFileContents.criticalPath).not.toContain('mylib2');
|
expect(jsonFileContents.criticalPath).not.toContain('mylib2');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('dep-graph should output dot to file', () => {
|
||||||
'dep-graph should output dot to file',
|
|
||||||
() => {
|
|
||||||
const file = 'dep-graph.dot';
|
const file = 'dep-graph.dot';
|
||||||
|
|
||||||
runCommand(
|
runCommand(
|
||||||
@ -323,13 +301,9 @@ describe('Command line', () => {
|
|||||||
expect(fileContents).toContain('"myapp" -> "mylib"');
|
expect(fileContents).toContain('"myapp" -> "mylib"');
|
||||||
expect(fileContents).toContain('"myapp2" -> "mylib"');
|
expect(fileContents).toContain('"myapp2" -> "mylib"');
|
||||||
expect(fileContents).toContain('"mylib" -> "mylib2"');
|
expect(fileContents).toContain('"mylib" -> "mylib2"');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('dep-graph should output html to file', () => {
|
||||||
'dep-graph should output html to file',
|
|
||||||
() => {
|
|
||||||
const file = 'dep-graph.html';
|
const file = 'dep-graph.html';
|
||||||
runCommand(
|
runCommand(
|
||||||
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
|
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
|
||||||
@ -342,8 +316,6 @@ describe('Command line', () => {
|
|||||||
expect(fileContents).toContain('<title>myapp->mylib</title>');
|
expect(fileContents).toContain('<title>myapp->mylib</title>');
|
||||||
expect(fileContents).toContain('<title>myapp->mylib2</title>');
|
expect(fileContents).toContain('<title>myapp->mylib2</title>');
|
||||||
expect(fileContents).toContain('<title>mylib->mylib2</title>');
|
expect(fileContents).toContain('<title>mylib->mylib2</title>');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -11,9 +11,7 @@ import {
|
|||||||
|
|
||||||
describe('Cypress E2E Test runner', () => {
|
describe('Cypress E2E Test runner', () => {
|
||||||
describe('project scaffolding', () => {
|
describe('project scaffolding', () => {
|
||||||
it(
|
it('should generate an app with the Cypress as e2e test runner', () => {
|
||||||
'should generate an app with the Cypress as e2e test runner',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myApp --e2eTestRunner=cypress');
|
newApp('myApp --e2eTestRunner=cypress');
|
||||||
copyMissingPackages();
|
copyMissingPackages();
|
||||||
@ -32,15 +30,11 @@ describe('Cypress E2E Test runner', () => {
|
|||||||
checkFilesExist('apps/my-app-e2e/src/support/app.po.ts');
|
checkFilesExist('apps/my-app-e2e/src/support/app.po.ts');
|
||||||
checkFilesExist('apps/my-app-e2e/src/support/index.ts');
|
checkFilesExist('apps/my-app-e2e/src/support/index.ts');
|
||||||
checkFilesExist('apps/my-app-e2e/src/support/commands.ts');
|
checkFilesExist('apps/my-app-e2e/src/support/commands.ts');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('running Cypress', () => {
|
describe('running Cypress', () => {
|
||||||
it(
|
it('should execute e2e tests using Cypress', () => {
|
||||||
'should execute e2e tests using Cypress',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myApp --e2eTestRunner=cypress');
|
newApp('myApp --e2eTestRunner=cypress');
|
||||||
copyMissingPackages();
|
copyMissingPackages();
|
||||||
@ -61,8 +55,6 @@ describe('Cypress E2E Test runner', () => {
|
|||||||
expect(
|
expect(
|
||||||
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
||||||
).toContain('All specs passed!');
|
).toContain('All specs passed!');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
||||||
|
|
||||||
describe('DowngradeModule', () => {
|
describe('DowngradeModule', () => {
|
||||||
it(
|
it('should generate a downgradeModule setup', () => {
|
||||||
'should generate a downgradeModule setup',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myapp');
|
newApp('myapp');
|
||||||
|
|
||||||
@ -18,7 +16,5 @@ describe('DowngradeModule', () => {
|
|||||||
|
|
||||||
runCLI('build');
|
runCLI('build');
|
||||||
expect(runCLI('test --no-watch')).toContain('Executed 3 of 3 SUCCESS');
|
expect(runCLI('test --no-watch')).toContain('Executed 3 of 3 SUCCESS');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -12,9 +12,7 @@ describe('Jest', () => {
|
|||||||
newProject();
|
newProject();
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('should be able to generate a testable library using jest', async done => {
|
||||||
'should be able to generate a testable library using jest',
|
|
||||||
async done => {
|
|
||||||
newLib('jestlib --unit-test-runner jest');
|
newLib('jestlib --unit-test-runner jest');
|
||||||
copyMissingPackages();
|
copyMissingPackages();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -24,13 +22,9 @@ describe('Jest', () => {
|
|||||||
const jestResult = await runCLIAsync('test jestlib');
|
const jestResult = await runCLIAsync('test jestlib');
|
||||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||||
done();
|
done();
|
||||||
},
|
}, 10000);
|
||||||
10000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('should be able to generate a testable application using jest', async () => {
|
||||||
'should be able to generate a testable application using jest',
|
|
||||||
async () => {
|
|
||||||
newApp('jestapp --unit-test-runner jest');
|
newApp('jestapp --unit-test-runner jest');
|
||||||
copyMissingPackages();
|
copyMissingPackages();
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
@ -39,7 +33,5 @@ describe('Jest', () => {
|
|||||||
]);
|
]);
|
||||||
const jestResult = await runCLIAsync('test jestapp');
|
const jestResult = await runCLIAsync('test jestapp');
|
||||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||||
},
|
}, 10000);
|
||||||
10000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -13,9 +13,7 @@ import {
|
|||||||
} from '../utils';
|
} from '../utils';
|
||||||
|
|
||||||
describe('Nrwl Workspace', () => {
|
describe('Nrwl Workspace', () => {
|
||||||
it(
|
it('should work', () => {
|
||||||
'should work',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myApp --directory=myDir');
|
newApp('myApp --directory=myDir');
|
||||||
newLib('myLib --directory=myDir');
|
newLib('myLib --directory=myDir');
|
||||||
@ -37,9 +35,7 @@ describe('Nrwl Workspace', () => {
|
|||||||
`
|
`
|
||||||
);
|
);
|
||||||
runCLI('build --prod --project=my-dir-my-app --output-hashing none');
|
runCLI('build --prod --project=my-dir-my-app --output-hashing none');
|
||||||
expect(exists('./tmp/proj/dist/apps/my-dir/my-app/main.js')).toEqual(
|
expect(exists('./tmp/proj/dist/apps/my-dir/my-app/main.js')).toEqual(true);
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
// This is a loose requirement because there are a lot of
|
// This is a loose requirement because there are a lot of
|
||||||
// influences external from this project that affect this.
|
// influences external from this project that affect this.
|
||||||
@ -61,13 +57,9 @@ describe('Nrwl Workspace', () => {
|
|||||||
expect(runCLI('e2e --project=my-dir-my-app-e2e')).toContain(
|
expect(runCLI('e2e --project=my-dir-my-app-e2e')).toContain(
|
||||||
'Executed 1 of 1 spec SUCCESS'
|
'Executed 1 of 1 spec SUCCESS'
|
||||||
);
|
);
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('should support router config generation (lazy)', () => {
|
||||||
'should support router config generation (lazy)',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myApp --directory=myDir --routing');
|
newApp('myApp --directory=myDir --routing');
|
||||||
newLib(
|
newLib(
|
||||||
@ -78,13 +70,9 @@ describe('Nrwl Workspace', () => {
|
|||||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||||
'Executed 3 of 3 SUCCESS'
|
'Executed 3 of 3 SUCCESS'
|
||||||
);
|
);
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('should support router config generation (eager)', () => {
|
||||||
'should support router config generation (eager)',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myApp --directory=myDir --routing');
|
newApp('myApp --directory=myDir --routing');
|
||||||
newLib(
|
newLib(
|
||||||
@ -95,9 +83,7 @@ describe('Nrwl Workspace', () => {
|
|||||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||||
'Executed 3 of 3 SUCCESS'
|
'Executed 3 of 3 SUCCESS'
|
||||||
);
|
);
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
|
|
||||||
it('should support scss for styles', () => {
|
it('should support scss for styles', () => {
|
||||||
cleanup();
|
cleanup();
|
||||||
@ -119,9 +105,7 @@ describe('Nrwl Workspace', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// TODO: Fix this test. This test was incorrect before.. and fails after fixing it.
|
// TODO: Fix this test. This test was incorrect before.. and fails after fixing it.
|
||||||
xit(
|
xit('should not generate e2e configuration', () => {
|
||||||
'should not generate e2e configuration',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myApp --e2eTestRunner=none');
|
newApp('myApp --e2eTestRunner=none');
|
||||||
|
|
||||||
@ -135,7 +119,5 @@ describe('Nrwl Workspace', () => {
|
|||||||
|
|
||||||
// Making sure the e2e folder is not created
|
// Making sure the e2e folder is not created
|
||||||
expect(exists('./tmp/proj/apps/my-app-e2e')).toBeFalsy();
|
expect(exists('./tmp/proj/apps/my-app-e2e')).toBeFalsy();
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import { newApp, newProject, runCLI, copyMissingPackages } from '../utils';
|
import { newApp, newProject, runCLI, copyMissingPackages } from '../utils';
|
||||||
|
|
||||||
describe('ngrx', () => {
|
describe('ngrx', () => {
|
||||||
it(
|
it('should work', () => {
|
||||||
'should work',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myapp');
|
newApp('myapp');
|
||||||
|
|
||||||
@ -28,7 +26,5 @@ describe('ngrx', () => {
|
|||||||
expect(runCLI('test feature-flights --no-watch')).toContain(
|
expect(runCLI('test feature-flights --no-watch')).toContain(
|
||||||
'Executed 10 of 10 SUCCESS'
|
'Executed 10 of 10 SUCCESS'
|
||||||
);
|
);
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -18,9 +18,7 @@ describe('Node Applications', () => {
|
|||||||
copyMissingPackages();
|
copyMissingPackages();
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('should be able to generate a node application', async done => {
|
||||||
'should be able to generate a node application',
|
|
||||||
async done => {
|
|
||||||
runCLI('generate node-app node-app1');
|
runCLI('generate node-app node-app1');
|
||||||
copyMissingPackages();
|
copyMissingPackages();
|
||||||
|
|
||||||
@ -78,9 +76,7 @@ describe('Node Applications', () => {
|
|||||||
|
|
||||||
await new Promise(resolve => {
|
await new Promise(resolve => {
|
||||||
server.stdout.once('data', async data => {
|
server.stdout.once('data', async data => {
|
||||||
expect(data.toString()).toContain(
|
expect(data.toString()).toContain('Listening at http://localhost:3333');
|
||||||
'Listening at http://localhost:3333'
|
|
||||||
);
|
|
||||||
const result = await getData();
|
const result = await getData();
|
||||||
|
|
||||||
expect(result).toEqual('Welcome to node-app1!');
|
expect(result).toEqual('Welcome to node-app1!');
|
||||||
@ -110,13 +106,9 @@ describe('Node Applications', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
}, 30000);
|
||||||
30000
|
|
||||||
);
|
|
||||||
|
|
||||||
it(
|
it('should be able to generate an empty application', async () => {
|
||||||
'should be able to generate an empty application',
|
|
||||||
async () => {
|
|
||||||
runCLI('generate node-app node-app2 --framework none');
|
runCLI('generate node-app node-app2 --framework none');
|
||||||
updateFile('apps/node-app2/src/main.ts', `console.log('Hello World!');`);
|
updateFile('apps/node-app2/src/main.ts', `console.log('Hello World!');`);
|
||||||
await runCLIAsync('build node-app2');
|
await runCLIAsync('build node-app2');
|
||||||
@ -125,7 +117,5 @@ describe('Node Applications', () => {
|
|||||||
cwd: './tmp/proj'
|
cwd: './tmp/proj'
|
||||||
}).toString();
|
}).toString();
|
||||||
expect(result).toContain('Hello World!');
|
expect(result).toContain('Hello World!');
|
||||||
},
|
}, 30000);
|
||||||
30000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
||||||
|
|
||||||
describe('Upgrade', () => {
|
describe('Upgrade', () => {
|
||||||
it(
|
it('should generate an UpgradeModule setup', () => {
|
||||||
'should generate an UpgradeModule setup',
|
|
||||||
() => {
|
|
||||||
newProject();
|
newProject();
|
||||||
newApp('myapp');
|
newApp('myapp');
|
||||||
|
|
||||||
@ -35,7 +33,5 @@ describe('Upgrade', () => {
|
|||||||
|
|
||||||
runCLI('build');
|
runCLI('build');
|
||||||
runCLI('test --no-watch');
|
runCLI('test --no-watch');
|
||||||
},
|
}, 1000000);
|
||||||
1000000
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|||||||
@ -74,7 +74,7 @@
|
|||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"opn": "^5.3.0",
|
"opn": "^5.3.0",
|
||||||
"precise-commits": "1.0.2",
|
"precise-commits": "1.0.2",
|
||||||
"prettier": "1.10.2",
|
"prettier": "1.15.3",
|
||||||
"release-it": "^7.4.0",
|
"release-it": "^7.4.0",
|
||||||
"rxjs": "6.3.3",
|
"rxjs": "6.3.3",
|
||||||
"semver": "5.4.1",
|
"semver": "5.4.1",
|
||||||
|
|||||||
@ -12,7 +12,7 @@ node_modules/.bin/ng generate component [name] --directory=[dir]
|
|||||||
|
|
||||||
Example: node_modules/.bin/ng generate component friends --directory=myDir
|
Example: node_modules/.bin/ng generate component friends --directory=myDir
|
||||||
|
|
||||||
* must manually import the component's Bazel rule in the consuming Bazel rule
|
- must manually import the component's Bazel rule in the consuming Bazel rule
|
||||||
|
|
||||||
## Add new lib
|
## Add new lib
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ node_modules/.bin/ng generate lib [name]
|
|||||||
|
|
||||||
Example: node_modules/.bin/ng generate lib mylib
|
Example: node_modules/.bin/ng generate lib mylib
|
||||||
|
|
||||||
* must manually import the lib's Bazel rule in the consuming Bazel rule
|
- must manually import the lib's Bazel rule in the consuming Bazel rule
|
||||||
|
|
||||||
## Run dev server
|
## Run dev server
|
||||||
|
|
||||||
@ -38,4 +38,4 @@ Example: bazel run apps/my-dir/my-app/src:prodserver
|
|||||||
|
|
||||||
ibazel test //libs/mylib/src:test
|
ibazel test //libs/mylib/src:test
|
||||||
|
|
||||||
* currently works for libs
|
- currently works for libs
|
||||||
|
|||||||
@ -30,13 +30,11 @@
|
|||||||
"lazy": {
|
"lazy": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Add RouterModule.forChild when set to true, and a simple array of routes when set to false."
|
||||||
"Add RouterModule.forChild when set to true, and a simple array of routes when set to false."
|
|
||||||
},
|
},
|
||||||
"parentModule": {
|
"parentModule": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to."
|
||||||
"Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to."
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["name"]
|
"required": ["name"]
|
||||||
|
|||||||
@ -28,8 +28,7 @@
|
|||||||
"additionalProperties": false
|
"additionalProperties": false
|
||||||
},
|
},
|
||||||
"apps": {
|
"apps": {
|
||||||
"description":
|
"description": "Properties of the different applications in this project.",
|
||||||
"Properties of the different applications in this project.",
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
@ -102,8 +101,7 @@
|
|||||||
},
|
},
|
||||||
"allowOutsideOutDir": {
|
"allowOutsideOutDir": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Allow assets to be copied outside the outDir.",
|
||||||
"Allow assets to be copied outside the outDir.",
|
|
||||||
"default": false
|
"default": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -141,33 +139,27 @@
|
|||||||
},
|
},
|
||||||
"maximumWarning": {
|
"maximumWarning": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The maximum threshold for warning relative to the baseline."
|
||||||
"The maximum threshold for warning relative to the baseline."
|
|
||||||
},
|
},
|
||||||
"maximumError": {
|
"maximumError": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The maximum threshold for error relative to the baseline."
|
||||||
"The maximum threshold for error relative to the baseline."
|
|
||||||
},
|
},
|
||||||
"minimumWarning": {
|
"minimumWarning": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The minimum threshold for warning relative to the baseline."
|
||||||
"The minimum threshold for warning relative to the baseline."
|
|
||||||
},
|
},
|
||||||
"minimumError": {
|
"minimumError": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The minimum threshold for error relative to the baseline."
|
||||||
"The minimum threshold for error relative to the baseline."
|
|
||||||
},
|
},
|
||||||
"warning": {
|
"warning": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The threshold for warning relative to the baseline (min & max)."
|
||||||
"The threshold for warning relative to the baseline (min & max)."
|
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The threshold for error relative to the baseline (min & max)."
|
||||||
"The threshold for error relative to the baseline (min & max)."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -211,16 +203,14 @@
|
|||||||
},
|
},
|
||||||
"testTsconfig": {
|
"testTsconfig": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The name of the TypeScript configuration file for unit tests."
|
||||||
"The name of the TypeScript configuration file for unit tests."
|
|
||||||
},
|
},
|
||||||
"prefix": {
|
"prefix": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "The prefix to apply to generated selectors."
|
"description": "The prefix to apply to generated selectors."
|
||||||
},
|
},
|
||||||
"serviceWorker": {
|
"serviceWorker": {
|
||||||
"description":
|
"description": "Experimental support for a service worker from @angular/service-worker.",
|
||||||
"Experimental support for a service worker from @angular/service-worker.",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
@ -250,8 +240,7 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"includePaths": {
|
"includePaths": {
|
||||||
"description":
|
"description": "Paths to include. Paths will be resolved to project root.",
|
||||||
"Paths to include. Paths will be resolved to project root.",
|
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -288,8 +277,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"environments": {
|
"environments": {
|
||||||
"description":
|
"description": "Name and corresponding file for environment config.",
|
||||||
"Name and corresponding file for environment config.",
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true
|
"additionalProperties": true
|
||||||
}
|
}
|
||||||
@ -337,8 +325,7 @@
|
|||||||
"default": []
|
"default": []
|
||||||
},
|
},
|
||||||
"project": {
|
"project": {
|
||||||
"description":
|
"description": "Location of the tsconfig.json project file. Will also use as files to lint if 'files' property not present.",
|
||||||
"Location of the tsconfig.json project file. Will also use as files to lint if 'files' property not present.",
|
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"tslintConfig": {
|
"tslintConfig": {
|
||||||
@ -444,8 +431,7 @@
|
|||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"inlineTemplate": {
|
"inlineTemplate": {
|
||||||
"description":
|
"description": "Specifies if the template will be in the ts file.",
|
||||||
"Specifies if the template will be in the ts file.",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
@ -569,8 +555,7 @@
|
|||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
"poll": {
|
"poll": {
|
||||||
"description":
|
"description": "Enable and define the file watching poll time period (milliseconds).",
|
||||||
"Enable and define the file watching poll time period (milliseconds).",
|
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"deleteOutputPath": {
|
"deleteOutputPath": {
|
||||||
@ -589,8 +574,7 @@
|
|||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"commonChunk": {
|
"commonChunk": {
|
||||||
"description":
|
"description": "Use a separate bundle containing code used across multiple bundles.",
|
||||||
"Use a separate bundle containing code used across multiple bundles.",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
@ -666,14 +650,12 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"hmrWarning": {
|
"hmrWarning": {
|
||||||
"description":
|
"description": "Show a warning when the user enabled the --hmr option.",
|
||||||
"Show a warning when the user enabled the --hmr option.",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"nodeDeprecation": {
|
"nodeDeprecation": {
|
||||||
"description":
|
"description": "Show a warning when the node version is incompatible.",
|
||||||
"Show a warning when the node version is incompatible.",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
@ -683,20 +665,17 @@
|
|||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"versionMismatch": {
|
"versionMismatch": {
|
||||||
"description":
|
"description": "Show a warning when the global version is newer than the local one.",
|
||||||
"Show a warning when the global version is newer than the local one.",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"typescriptMismatch": {
|
"typescriptMismatch": {
|
||||||
"description":
|
"description": "Show a warning when the TypeScript version is incompatible",
|
||||||
"Show a warning when the TypeScript version is incompatible",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
},
|
},
|
||||||
"servePathDefault": {
|
"servePathDefault": {
|
||||||
"description":
|
"description": "Show a warning when deploy-url/base-href use unsupported serve path values.",
|
||||||
"Show a warning when deploy-url/base-href use unsupported serve path values.",
|
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": true
|
"default": true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -232,11 +232,13 @@ function findClass(
|
|||||||
): ts.ClassDeclaration {
|
): ts.ClassDeclaration {
|
||||||
const nodes = getSourceNodes(source);
|
const nodes = getSourceNodes(source);
|
||||||
|
|
||||||
const clazz = <any>nodes.filter(
|
const clazz = <any>(
|
||||||
|
nodes.filter(
|
||||||
n =>
|
n =>
|
||||||
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
||||||
(<any>n).name.text === className
|
(<any>n).name.text === className
|
||||||
)[0];
|
)[0]
|
||||||
|
);
|
||||||
|
|
||||||
if (!clazz) {
|
if (!clazz) {
|
||||||
throw new Error(`Cannot find class '${className}'`);
|
throw new Error(`Cannot find class '${className}'`);
|
||||||
@ -283,9 +285,8 @@ export function addImportToTestBed(
|
|||||||
specPath: string,
|
specPath: string,
|
||||||
symbolName: string
|
symbolName: string
|
||||||
): Change[] {
|
): Change[] {
|
||||||
const allCalls: ts.CallExpression[] = <any>findNodes(
|
const allCalls: ts.CallExpression[] = <any>(
|
||||||
source,
|
findNodes(source, ts.SyntaxKind.CallExpression)
|
||||||
ts.SyntaxKind.CallExpression
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const configureTestingModuleObjectLiterals = allCalls
|
const configureTestingModuleObjectLiterals = allCalls
|
||||||
@ -293,8 +294,7 @@ export function addImportToTestBed(
|
|||||||
.filter(
|
.filter(
|
||||||
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
|
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
|
||||||
)
|
)
|
||||||
.map(
|
.map(c =>
|
||||||
c =>
|
|
||||||
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
||||||
? c.arguments[0]
|
? c.arguments[0]
|
||||||
: null
|
: null
|
||||||
|
|||||||
@ -13,9 +13,8 @@ export function toClassName(str: string): string {
|
|||||||
|
|
||||||
export function toPropertyName(s: string): string {
|
export function toPropertyName(s: string): string {
|
||||||
return s
|
return s
|
||||||
.replace(
|
.replace(/(-|_|\.|\s)+(.)?/g, (_, __, chr) =>
|
||||||
/(-|_|\.|\s)+(.)?/g,
|
chr ? chr.toUpperCase() : ''
|
||||||
(_, __, chr) => (chr ? chr.toUpperCase() : '')
|
|
||||||
)
|
)
|
||||||
.replace(/^([A-Z])/, m => m.toLowerCase());
|
.replace(/^([A-Z])/, m => m.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -83,8 +83,7 @@ export default class CypressBuilder implements Builder<CypressBuilderOptions> {
|
|||||||
tap(() =>
|
tap(() =>
|
||||||
this.copyCypressFixtures(options.tsConfig, options.cypressConfig)
|
this.copyCypressFixtures(options.tsConfig, options.cypressConfig)
|
||||||
),
|
),
|
||||||
concatMap(
|
concatMap(() =>
|
||||||
() =>
|
|
||||||
!options.baseUrl && options.devServerTarget
|
!options.baseUrl && options.devServerTarget
|
||||||
? this.startDevServer(options.devServerTarget, options.watch)
|
? this.startDevServer(options.devServerTarget, options.watch)
|
||||||
: of(null)
|
: of(null)
|
||||||
|
|||||||
@ -22,14 +22,12 @@
|
|||||||
},
|
},
|
||||||
"headless": {
|
"headless": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Whether or not the open the Cypress application to run the tests. If set to 'true', will run in headless mode",
|
||||||
"Whether or not the open the Cypress application to run the tests. If set to 'true', will run in headless mode",
|
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"baseUrl": {
|
"baseUrl": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "Use this to pass directly the address of your distant server address with the port running your application"
|
||||||
"Use this to pass directly the address of your distant server address with the port running your application"
|
|
||||||
},
|
},
|
||||||
"browser": {
|
"browser": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|||||||
@ -5,8 +5,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"jestConfig": {
|
"jestConfig": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The path of the Jest configuration. (https://jestjs.io/docs/en/configuration.html)"
|
||||||
"The path of the Jest configuration. (https://jestjs.io/docs/en/configuration.html)"
|
|
||||||
},
|
},
|
||||||
"tsConfig": {
|
"tsConfig": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -14,67 +13,55 @@
|
|||||||
},
|
},
|
||||||
"setupFile": {
|
"setupFile": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration.html#setuptestframeworkscriptfile-string)"
|
||||||
"The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration.html#setuptestframeworkscriptfile-string)"
|
|
||||||
},
|
},
|
||||||
"watch": {
|
"watch": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Run tests when files change. (https://jestjs.io/docs/en/cli#watch)",
|
||||||
"Run tests when files change. (https://jestjs.io/docs/en/cli#watch)",
|
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"onlyChanged": {
|
"onlyChanged": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"alias": "o",
|
"alias": "o",
|
||||||
"description":
|
"description": "Isolate tests affected by uncommitted changes. (https://jestjs.io/docs/en/cli#onlychanged)"
|
||||||
"Isolate tests affected by uncommitted changes. (https://jestjs.io/docs/en/cli#onlychanged)"
|
|
||||||
},
|
},
|
||||||
"passWithNoTests": {
|
"passWithNoTests": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Allow test suite to pass when no test files are found. (https://jestjs.io/docs/en/cli#passwithnotests)"
|
||||||
"Allow test suite to pass when no test files are found. (https://jestjs.io/docs/en/cli#passwithnotests)"
|
|
||||||
},
|
},
|
||||||
"codeCoverage": {
|
"codeCoverage": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Export a code coverage report. (https://jestjs.io/docs/en/cli#coverage)"
|
||||||
"Export a code coverage report. (https://jestjs.io/docs/en/cli#coverage)"
|
|
||||||
},
|
},
|
||||||
"updateSnapshot": {
|
"updateSnapshot": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"alias": "u",
|
"alias": "u",
|
||||||
"description":
|
"description": "Re-record all failing snapshots. (https://jestjs.io/docs/en/cli#updatesnapshot)"
|
||||||
"Re-record all failing snapshots. (https://jestjs.io/docs/en/cli#updatesnapshot)"
|
|
||||||
},
|
},
|
||||||
"ci": {
|
"ci": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Fail on missing snapshots. (https://jestjs.io/docs/en/cli#ci)"
|
||||||
"Fail on missing snapshots. (https://jestjs.io/docs/en/cli#ci)"
|
|
||||||
},
|
},
|
||||||
"bail": {
|
"bail": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Exit the test suite immediately upon the first failing test suite. (https://jestjs.io/docs/en/cli#bail)"
|
||||||
"Exit the test suite immediately upon the first failing test suite. (https://jestjs.io/docs/en/cli#bail)"
|
|
||||||
},
|
},
|
||||||
"silent": {
|
"silent": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Prevent tests from printing messages through the console. (https://jestjs.io/docs/en/cli#silent)"
|
||||||
"Prevent tests from printing messages through the console. (https://jestjs.io/docs/en/cli#silent)"
|
|
||||||
},
|
},
|
||||||
"runInBand": {
|
"runInBand": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Run tests in a single process as opposed to multiple workers. Useful for CI. (https://jestjs.io/docs/en/cli.html#runinband)"
|
||||||
"Run tests in a single process as opposed to multiple workers. Useful for CI. (https://jestjs.io/docs/en/cli.html#runinband)"
|
|
||||||
},
|
},
|
||||||
"maxWorkers": {
|
"maxWorkers": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"description":
|
"description": "Max number of workers to run tests across. Useful for CI. (https://jestjs.io/docs/en/cli.html#maxworkers-num)"
|
||||||
"Max number of workers to run tests across. Useful for CI. (https://jestjs.io/docs/en/cli.html#maxworkers-num)"
|
|
||||||
},
|
},
|
||||||
"testNamePattern": {
|
"testNamePattern": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"alias": "t",
|
"alias": "t",
|
||||||
"description":
|
"description": "Run only tests with a name that matches the regex. (https://jestjs.io/docs/en/cli.html#testnamepattern-regex)"
|
||||||
"Run only tests with a name that matches the regex. (https://jestjs.io/docs/en/cli.html#testnamepattern-regex)"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["jestConfig", "tsConfig"]
|
"required": ["jestConfig", "tsConfig"]
|
||||||
|
|||||||
@ -47,20 +47,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description":
|
"description": "Dependencies to keep external to the bundle. (\"all\" (default), \"none\", or an array of module names)",
|
||||||
"Dependencies to keep external to the bundle. (\"all\" (default), \"none\", or an array of module names)",
|
|
||||||
"default": "all"
|
"default": "all"
|
||||||
},
|
},
|
||||||
"statsJson": {
|
"statsJson": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Generates a 'stats.json' file which can be analyzed using tools such as: #webpack-bundle-analyzer' or https: //webpack.github.io/analyse.",
|
||||||
"Generates a 'stats.json' file which can be analyzed using tools such as: #webpack-bundle-analyzer' or https: //webpack.github.io/analyse.",
|
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"extractLicenses": {
|
"extractLicenses": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description":
|
"description": "Extract all licenses in a separate file, in the case of production builds only.",
|
||||||
"Extract all licenses in a separate file, in the case of production builds only.",
|
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"optimization": {
|
"optimization": {
|
||||||
@ -75,8 +72,7 @@
|
|||||||
},
|
},
|
||||||
"maxWorkers": {
|
"maxWorkers": {
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"description":
|
"description": "Number of workers to use for type checking. (defaults to # of CPUS - 2)"
|
||||||
"Number of workers to use for type checking. (defaults to # of CPUS - 2)"
|
|
||||||
},
|
},
|
||||||
"fileReplacements": {
|
"fileReplacements": {
|
||||||
"description": "Replace files with other files in the build.",
|
"description": "Replace files with other files in the build.",
|
||||||
@ -111,8 +107,7 @@
|
|||||||
},
|
},
|
||||||
"input": {
|
"input": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The input directory path in which to apply 'glob'. Defaults to the project root."
|
||||||
"The input directory path in which to apply 'glob'. Defaults to the project root."
|
|
||||||
},
|
},
|
||||||
"ignore": {
|
"ignore": {
|
||||||
"description": "An array of globs to ignore.",
|
"description": "An array of globs to ignore.",
|
||||||
|
|||||||
@ -56,16 +56,17 @@ function userReducer(state: string, action: Action): string {
|
|||||||
return 'bob';
|
return 'bob';
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({ template: `ROOT[<router-outlet></router-outlet>]` })
|
@Component({
|
||||||
|
template: `
|
||||||
|
ROOT[<router-outlet></router-outlet>]
|
||||||
|
`
|
||||||
|
})
|
||||||
class RootCmp {}
|
class RootCmp {}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
template: `
|
template: `
|
||||||
Todo [
|
Todo [
|
||||||
<div *ngIf="(todo|async) as t">
|
<div *ngIf="(todo | async) as t">ID {{ t.id }} User {{ t.user }}</div>
|
||||||
ID {{t.id}}
|
|
||||||
User {{t.user}}
|
|
||||||
</div>
|
|
||||||
]
|
]
|
||||||
`
|
`
|
||||||
})
|
})
|
||||||
@ -113,9 +114,7 @@ describe('DataPersistence', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('should work', fakeAsync(() => {
|
||||||
'should work',
|
|
||||||
fakeAsync(() => {
|
|
||||||
const root = TestBed.createComponent(RootCmp);
|
const root = TestBed.createComponent(RootCmp);
|
||||||
|
|
||||||
const router: Router = TestBed.get(Router);
|
const router: Router = TestBed.get(Router);
|
||||||
@ -125,8 +124,7 @@ describe('DataPersistence', () => {
|
|||||||
|
|
||||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 123');
|
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 123');
|
||||||
expect(root.elementRef.nativeElement.innerHTML).toContain('User bob');
|
expect(root.elementRef.nativeElement.innerHTML).toContain('User bob');
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('`run` throwing an error', () => {
|
describe('`run` throwing an error', () => {
|
||||||
@ -155,9 +153,7 @@ describe('DataPersistence', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('should work', fakeAsync(() => {
|
||||||
'should work',
|
|
||||||
fakeAsync(() => {
|
|
||||||
const root = TestBed.createComponent(RootCmp);
|
const root = TestBed.createComponent(RootCmp);
|
||||||
|
|
||||||
const router: Router = TestBed.get(Router);
|
const router: Router = TestBed.get(Router);
|
||||||
@ -167,9 +163,7 @@ describe('DataPersistence', () => {
|
|||||||
router.navigateByUrl('/todo/123');
|
router.navigateByUrl('/todo/123');
|
||||||
tick(0);
|
tick(0);
|
||||||
root.detectChanges(false);
|
root.detectChanges(false);
|
||||||
expect(root.elementRef.nativeElement.innerHTML).not.toContain(
|
expect(root.elementRef.nativeElement.innerHTML).not.toContain('ID 123');
|
||||||
'ID 123'
|
|
||||||
);
|
|
||||||
expect(action.type).toEqual('ERROR');
|
expect(action.type).toEqual('ERROR');
|
||||||
expect(action.payload.error.message).toEqual('boom');
|
expect(action.payload.error.message).toEqual('boom');
|
||||||
|
|
||||||
@ -178,8 +172,7 @@ describe('DataPersistence', () => {
|
|||||||
tick(0);
|
tick(0);
|
||||||
root.detectChanges(false);
|
root.detectChanges(false);
|
||||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('`run` returning an error observable', () => {
|
describe('`run` returning an error observable', () => {
|
||||||
@ -208,9 +201,7 @@ describe('DataPersistence', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it(
|
it('should work', fakeAsync(() => {
|
||||||
'should work',
|
|
||||||
fakeAsync(() => {
|
|
||||||
const root = TestBed.createComponent(RootCmp);
|
const root = TestBed.createComponent(RootCmp);
|
||||||
|
|
||||||
const router: Router = TestBed.get(Router);
|
const router: Router = TestBed.get(Router);
|
||||||
@ -220,9 +211,7 @@ describe('DataPersistence', () => {
|
|||||||
router.navigateByUrl('/todo/123');
|
router.navigateByUrl('/todo/123');
|
||||||
tick(0);
|
tick(0);
|
||||||
root.detectChanges(false);
|
root.detectChanges(false);
|
||||||
expect(root.elementRef.nativeElement.innerHTML).not.toContain(
|
expect(root.elementRef.nativeElement.innerHTML).not.toContain('ID 123');
|
||||||
'ID 123'
|
|
||||||
);
|
|
||||||
expect(action.type).toEqual('ERROR');
|
expect(action.type).toEqual('ERROR');
|
||||||
expect(action.payload.error).toEqual('boom');
|
expect(action.payload.error).toEqual('boom');
|
||||||
|
|
||||||
@ -230,8 +219,7 @@ describe('DataPersistence', () => {
|
|||||||
tick(0);
|
tick(0);
|
||||||
root.detectChanges(false);
|
root.detectChanges(false);
|
||||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
||||||
})
|
}));
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -29,7 +29,11 @@
|
|||||||
"schematics": "./src/collection.json",
|
"schematics": "./src/collection.json",
|
||||||
"ng-update": {
|
"ng-update": {
|
||||||
"requirements": {},
|
"requirements": {},
|
||||||
"packageGroup": ["@nrwl/nx", "@nrwl/schematics", "@nrwl/builders"],
|
"packageGroup": [
|
||||||
|
"@nrwl/nx",
|
||||||
|
"@nrwl/schematics",
|
||||||
|
"@nrwl/builders"
|
||||||
|
],
|
||||||
"migrations": "./migrations/migrations.json"
|
"migrations": "./migrations/migrations.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@ -21,12 +21,10 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('not nested', () => {
|
describe('not nested', () => {
|
||||||
it('should update angular.json', () => {
|
it('should update angular.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||||
{ name: 'myApp' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||||
|
|
||||||
expect(angularJson.projects['my-app'].root).toEqual('apps/my-app/');
|
expect(angularJson.projects['my-app'].root).toEqual('apps/my-app/');
|
||||||
@ -35,12 +33,10 @@ describe('app', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update nx.json', () => {
|
it('should update nx.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp', tags: 'one,two' }, appTree)
|
||||||
{ name: 'myApp', tags: 'one,two' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||||
expect(nxJson).toEqual({
|
expect(nxJson).toEqual({
|
||||||
npmScope: 'proj',
|
npmScope: 'proj',
|
||||||
@ -55,12 +51,10 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||||
{ name: 'myApp' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(tree.exists(`apps/my-app/karma.conf.js`)).toBeTruthy();
|
expect(tree.exists(`apps/my-app/karma.conf.js`)).toBeTruthy();
|
||||||
expect(tree.exists('apps/my-app/src/main.ts')).toBeTruthy();
|
expect(tree.exists('apps/my-app/src/main.ts')).toBeTruthy();
|
||||||
expect(tree.exists('apps/my-app/src/app/app.module.ts')).toBeTruthy();
|
expect(tree.exists('apps/my-app/src/app/app.module.ts')).toBeTruthy();
|
||||||
@ -98,17 +92,13 @@ describe('app', () => {
|
|||||||
expect(tsconfigE2E.extends).toEqual('./tsconfig.json');
|
expect(tsconfigE2E.extends).toEqual('./tsconfig.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should default the prefix to npmScope', () => {
|
it('should default the prefix to npmScope', async () => {
|
||||||
const noPrefix = schematicRunner.runSchematic(
|
const noPrefix = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||||
{ name: 'myApp' },
|
.toPromise();
|
||||||
appTree
|
const withPrefix = await schematicRunner
|
||||||
);
|
.runSchematicAsync('app', { name: 'myApp', prefix: 'custom' }, appTree)
|
||||||
const withPrefix = schematicRunner.runSchematic(
|
.toPromise();
|
||||||
'app',
|
|
||||||
{ name: 'myApp', prefix: 'custom' },
|
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
// Testing without prefix
|
// Testing without prefix
|
||||||
|
|
||||||
@ -144,11 +134,9 @@ describe('app', () => {
|
|||||||
)
|
)
|
||||||
.toPromise();
|
.toPromise();
|
||||||
|
|
||||||
const result = schematicRunner.runSchematic(
|
const result = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||||
{ name: 'myApp' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(result.exists('apps/my-app/src/main.ts')).toEqual(true);
|
expect(result.exists('apps/my-app/src/main.ts')).toEqual(true);
|
||||||
expect(result.exists('apps/my-app-e2e/protractor.conf.js')).toEqual(true);
|
expect(result.exists('apps/my-app-e2e/protractor.conf.js')).toEqual(true);
|
||||||
@ -156,12 +144,14 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('nested', () => {
|
describe('nested', () => {
|
||||||
it('should update angular.json', () => {
|
it('should update angular.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', directory: 'myDir' },
|
{ name: 'myApp', directory: 'myDir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||||
|
|
||||||
expect(angularJson.projects['my-dir-my-app'].root).toEqual(
|
expect(angularJson.projects['my-dir-my-app'].root).toEqual(
|
||||||
@ -172,12 +162,14 @@ describe('app', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update nx.json', () => {
|
it('should update nx.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', directory: 'myDir', tags: 'one,two' },
|
{ name: 'myApp', directory: 'myDir', tags: 'one,two' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||||
expect(nxJson).toEqual({
|
expect(nxJson).toEqual({
|
||||||
npmScope: 'proj',
|
npmScope: 'proj',
|
||||||
@ -192,18 +184,20 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', async () => {
|
||||||
const hasJsonValue = ({ path, expectedValue, lookupFn }) => {
|
const hasJsonValue = ({ path, expectedValue, lookupFn }) => {
|
||||||
const content = getFileContent(tree, path);
|
const content = getFileContent(tree, path);
|
||||||
const config = JSON.parse(stripJsonComments(content));
|
const config = JSON.parse(stripJsonComments(content));
|
||||||
|
|
||||||
expect(lookupFn(config)).toEqual(expectedValue);
|
expect(lookupFn(config)).toEqual(expectedValue);
|
||||||
};
|
};
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', directory: 'myDir' },
|
{ name: 'myApp', directory: 'myDir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const appModulePath = 'apps/my-dir/my-app/src/app/app.module.ts';
|
const appModulePath = 'apps/my-dir/my-app/src/app/app.module.ts';
|
||||||
expect(getFileContent(tree, appModulePath)).toContain('class AppModule');
|
expect(getFileContent(tree, appModulePath)).toContain('class AppModule');
|
||||||
@ -250,24 +244,24 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should import NgModule', () => {
|
it('should import NgModule', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp', directory: 'myDir' }, appTree)
|
||||||
{ name: 'myApp', directory: 'myDir' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(
|
expect(
|
||||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
|
||||||
).toContain('NxModule.forRoot()');
|
).toContain('NxModule.forRoot()');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('routing', () => {
|
describe('routing', () => {
|
||||||
it('should include RouterTestingModule', () => {
|
it('should include RouterTestingModule', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', directory: 'myDir', routing: true },
|
{ name: 'myApp', directory: 'myDir', routing: true },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
|
||||||
).toContain('RouterModule.forRoot');
|
).toContain('RouterModule.forRoot');
|
||||||
@ -276,12 +270,14 @@ describe('app', () => {
|
|||||||
).toContain('imports: [RouterTestingModule]');
|
).toContain('imports: [RouterTestingModule]');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not modify tests when --skip-tests is set', () => {
|
it('should not modify tests when --skip-tests is set', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', directory: 'myDir', routing: true, skipTests: true },
|
{ name: 'myApp', directory: 'myDir', routing: true, skipTests: true },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
tree.exists('apps/my-dir/my-app/src/app/app.component.spec.ts')
|
tree.exists('apps/my-dir/my-app/src/app/app.component.spec.ts')
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
@ -289,12 +285,14 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('template generation mode', () => {
|
describe('template generation mode', () => {
|
||||||
it('should create Nx specific `app.component.html` template', () => {
|
it('should create Nx specific `app.component.html` template', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', directory: 'myDir' },
|
{ name: 'myApp', directory: 'myDir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.html')
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.html')
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
@ -303,12 +301,14 @@ describe('app', () => {
|
|||||||
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should update `template`'s property of AppComponent with Nx content", () => {
|
it("should update `template`'s property of AppComponent with Nx content", async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', directory: 'myDir', inlineTemplate: true },
|
{ name: 'myApp', directory: 'myDir', inlineTemplate: true },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.ts')
|
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.ts')
|
||||||
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
||||||
@ -316,23 +316,19 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('--style scss', () => {
|
describe('--style scss', () => {
|
||||||
it('should generate scss styles', () => {
|
it('should generate scss styles', async () => {
|
||||||
const result = schematicRunner.runSchematic(
|
const result = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp', style: 'scss' }, appTree)
|
||||||
{ name: 'myApp', style: 'scss' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(result.exists('apps/my-app/src/app/app.component.scss')).toEqual(
|
expect(result.exists('apps/my-app/src/app/app.component.scss')).toEqual(
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set it as default', () => {
|
it('should set it as default', async () => {
|
||||||
const result = schematicRunner.runSchematic(
|
const result = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'myApp', style: 'scss' }, appTree)
|
||||||
{ name: 'myApp', style: 'scss' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
const angularJson = readJsonInTree(result, 'angular.json');
|
const angularJson = readJsonInTree(result, 'angular.json');
|
||||||
|
|
||||||
@ -345,12 +341,14 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('--unit-test-runner jest', () => {
|
describe('--unit-test-runner jest', () => {
|
||||||
it('should generate a jest config', () => {
|
it('should generate a jest config', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', unitTestRunner: 'jest' },
|
{ name: 'myApp', unitTestRunner: 'jest' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(tree.exists('apps/my-app/src/test.ts')).toBeFalsy();
|
expect(tree.exists('apps/my-app/src/test.ts')).toBeFalsy();
|
||||||
expect(tree.exists('apps/my-app/src/test-setup.ts')).toBeTruthy();
|
expect(tree.exists('apps/my-app/src/test-setup.ts')).toBeTruthy();
|
||||||
expect(tree.exists('apps/my-app/tsconfig.spec.json')).toBeTruthy();
|
expect(tree.exists('apps/my-app/tsconfig.spec.json')).toBeTruthy();
|
||||||
@ -380,12 +378,14 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('--unit-test-runner none', () => {
|
describe('--unit-test-runner none', () => {
|
||||||
it('should not generate test configuration', () => {
|
it('should not generate test configuration', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', unitTestRunner: 'none' },
|
{ name: 'myApp', unitTestRunner: 'none' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(tree.exists('apps/my-app/src/test-setup.ts')).toBeFalsy();
|
expect(tree.exists('apps/my-app/src/test-setup.ts')).toBeFalsy();
|
||||||
expect(tree.exists('apps/my-app/src/test.ts')).toBeFalsy();
|
expect(tree.exists('apps/my-app/src/test.ts')).toBeFalsy();
|
||||||
expect(tree.exists('apps/my-app/tsconfig.spec.json')).toBeFalsy();
|
expect(tree.exists('apps/my-app/tsconfig.spec.json')).toBeFalsy();
|
||||||
@ -400,12 +400,14 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('--e2e-test-runner none', () => {
|
describe('--e2e-test-runner none', () => {
|
||||||
it('should not generate test configuration', () => {
|
it('should not generate test configuration', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'app',
|
'app',
|
||||||
{ name: 'myApp', e2eTestRunner: 'none' },
|
{ name: 'myApp', e2eTestRunner: 'none' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
|
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
|
||||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||||
expect(angularJson.projects['my-app-e2e']).toBeUndefined();
|
expect(angularJson.projects['my-app-e2e']).toBeUndefined();
|
||||||
@ -413,8 +415,10 @@ describe('app', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('replaceAppNameWithPath', () => {
|
describe('replaceAppNameWithPath', () => {
|
||||||
it('should protect `angular.json` commands and properties', () => {
|
it('should protect `angular.json` commands and properties', async () => {
|
||||||
const tree = schematicRunner.runSchematic('app', { name: 'ui' }, appTree);
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync('app', { name: 'ui' }, appTree)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||||
expect(angularJson.projects['ui']).toBeDefined();
|
expect(angularJson.projects['ui']).toBeDefined();
|
||||||
@ -423,12 +427,10 @@ describe('app', () => {
|
|||||||
).toEqual('@angular-devkit/build-angular:browser');
|
).toEqual('@angular-devkit/build-angular:browser');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should protect `angular.json` sensible properties value to be renamed', () => {
|
it('should protect `angular.json` sensible properties value to be renamed', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('app', { name: 'ui', prefix: 'ui' }, appTree)
|
||||||
{ name: 'ui', prefix: 'ui' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||||
expect(angularJson.projects['ui'].prefix).toEqual('ui');
|
expect(angularJson.projects['ui'].prefix).toEqual('ui');
|
||||||
|
|||||||
@ -84,9 +84,9 @@ function addRouterRootConfiguration(options: NormalizedSchema): Rule {
|
|||||||
const componentSpecPath = `${
|
const componentSpecPath = `${
|
||||||
options.appProjectRoot
|
options.appProjectRoot
|
||||||
}/src/app/app.component.spec.ts`;
|
}/src/app/app.component.spec.ts`;
|
||||||
const componentSpecSource = host.read(componentSpecPath)!.toString(
|
const componentSpecSource = host
|
||||||
'utf-8'
|
.read(componentSpecPath)!
|
||||||
);
|
.toString('utf-8');
|
||||||
const componentSpecSourceFile = ts.createSourceFile(
|
const componentSpecSourceFile = ts.createSourceFile(
|
||||||
componentSpecPath,
|
componentSpecPath,
|
||||||
componentSpecSource,
|
componentSpecSource,
|
||||||
|
|||||||
@ -85,8 +85,7 @@
|
|||||||
"description": "Test runner to use for unit tests",
|
"description": "Test runner to use for unit tests",
|
||||||
"default": "karma",
|
"default": "karma",
|
||||||
"x-prompt": {
|
"x-prompt": {
|
||||||
"message":
|
"message": "Which Unit Test Runner would you like to use for the application?",
|
||||||
"Which Unit Test Runner would you like to use for the application?",
|
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
@ -103,8 +102,7 @@
|
|||||||
"description": "Test runner to use for end to end (e2e) tests",
|
"description": "Test runner to use for end to end (e2e) tests",
|
||||||
"default": "protractor",
|
"default": "protractor",
|
||||||
"x-prompt": {
|
"x-prompt": {
|
||||||
"message":
|
"message": "Which E2E Test Runner would you like to use for the application?",
|
||||||
"Which E2E Test Runner would you like to use for the application?",
|
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
@ -121,8 +119,7 @@
|
|||||||
"tags": {
|
"tags": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Add tags to the application (used for linting)",
|
"description": "Add tags to the application (used for linting)",
|
||||||
"x-prompt":
|
"x-prompt": "Which tags would you like to add to the application? (used for linting)"
|
||||||
"Which tags would you like to add to the application? (used for linting)"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
|
|||||||
@ -18,12 +18,14 @@ describe('schematic:cypress-project', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('generate app --e2e-test-runner=cypress', () => {
|
describe('generate app --e2e-test-runner=cypress', () => {
|
||||||
it('should not contain any protractor files', () => {
|
it('should not contain any protractor files', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.exists('apps/my-app-e2e/protractor.e2e.json')
|
tree.exists('apps/my-app-e2e/protractor.e2e.json')
|
||||||
@ -38,12 +40,14 @@ describe('schematic:cypress-project', () => {
|
|||||||
expect(tree.exists('apps/my-app-e2e/src/app.po.ts')).not.toBeTruthy();
|
expect(tree.exists('apps/my-app-e2e/src/app.po.ts')).not.toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
expect(tree.exists('apps/my-app-e2e/cypress.json')).toBeTruthy();
|
expect(tree.exists('apps/my-app-e2e/cypress.json')).toBeTruthy();
|
||||||
expect(tree.exists('apps/my-app-e2e/tsconfig.e2e.json')).toBeTruthy();
|
expect(tree.exists('apps/my-app-e2e/tsconfig.e2e.json')).toBeTruthy();
|
||||||
@ -62,24 +66,28 @@ describe('schematic:cypress-project', () => {
|
|||||||
expect(tree.exists('apps/my-app-e2e/src/support/index.ts')).toBeTruthy();
|
expect(tree.exists('apps/my-app-e2e/src/support/index.ts')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add dependencies into `package.json` file', () => {
|
it('should add dependencies into `package.json` file', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const packageJson = readJsonInTree(tree, 'package.json');
|
const packageJson = readJsonInTree(tree, 'package.json');
|
||||||
|
|
||||||
expect(packageJson.devDependencies.cypress).toBeDefined();
|
expect(packageJson.devDependencies.cypress).toBeDefined();
|
||||||
expect(packageJson.devDependencies['@nrwl/builders']).toBeDefined();
|
expect(packageJson.devDependencies['@nrwl/builders']).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add update `angular.json` file', () => {
|
it('should add update `angular.json` file', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||||
const project = angularJson.projects['my-app-e2e'];
|
const project = angularJson.projects['my-app-e2e'];
|
||||||
|
|
||||||
@ -91,12 +99,14 @@ describe('schematic:cypress-project', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set right path names in `cypress.json`', () => {
|
it('should set right path names in `cypress.json`', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const cypressJson = readJsonInTree(tree, 'apps/my-app-e2e/cypress.json');
|
const cypressJson = readJsonInTree(tree, 'apps/my-app-e2e/cypress.json');
|
||||||
|
|
||||||
expect(cypressJson).toEqual({
|
expect(cypressJson).toEqual({
|
||||||
@ -112,12 +122,14 @@ describe('schematic:cypress-project', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set right path names in `tsconfig.e2e.json`', () => {
|
it('should set right path names in `tsconfig.e2e.json`', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const tsconfigJson = readJsonInTree(
|
const tsconfigJson = readJsonInTree(
|
||||||
tree,
|
tree,
|
||||||
'apps/my-app-e2e/tsconfig.e2e.json'
|
'apps/my-app-e2e/tsconfig.e2e.json'
|
||||||
@ -131,12 +143,14 @@ describe('schematic:cypress-project', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('generate app --e2e-test-runner=cypress --directory=my-dir', () => {
|
describe('generate app --e2e-test-runner=cypress --directory=my-dir', () => {
|
||||||
it('should set right path names in `cypress.json`', () => {
|
it('should set right path names in `cypress.json`', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const cypressJson = readJsonInTree(
|
const cypressJson = readJsonInTree(
|
||||||
tree,
|
tree,
|
||||||
'apps/my-dir/my-app-e2e/cypress.json'
|
'apps/my-dir/my-app-e2e/cypress.json'
|
||||||
@ -159,12 +173,14 @@ describe('schematic:cypress-project', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set right path names in `tsconfig.e2e.json`', () => {
|
it('should set right path names in `tsconfig.e2e.json`', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'application',
|
'application',
|
||||||
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const tsconfigJson = readJsonInTree(
|
const tsconfigJson = readJsonInTree(
|
||||||
tree,
|
tree,
|
||||||
'apps/my-dir/my-app-e2e/tsconfig.e2e.json'
|
'apps/my-dir/my-app-e2e/tsconfig.e2e.json'
|
||||||
|
|||||||
@ -19,15 +19,17 @@ describe('downgrade-module', () => {
|
|||||||
appTree = createApp(appTree, 'myapp');
|
appTree = createApp(appTree, 'myapp');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update main.ts', () => {
|
it('should update main.ts', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'downgrade-module',
|
'downgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const main = getFileContent(tree, '/apps/myapp/src/main.ts');
|
const main = getFileContent(tree, '/apps/myapp/src/main.ts');
|
||||||
expect(main).toContain('downgradeModule(bootstrapAngular)');
|
expect(main).toContain('downgradeModule(bootstrapAngular)');
|
||||||
@ -37,15 +39,17 @@ describe('downgrade-module', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update module', () => {
|
it('should update module', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'downgrade-module',
|
'downgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const appModule = getFileContent(tree, 'apps/myapp/src/app/app.module.ts');
|
const appModule = getFileContent(tree, 'apps/myapp/src/app/app.module.ts');
|
||||||
expect(appModule).not.toContain('bootstrap:');
|
expect(appModule).not.toContain('bootstrap:');
|
||||||
@ -53,7 +57,7 @@ describe('downgrade-module', () => {
|
|||||||
expect(appModule).toContain('ngDoBootstrap');
|
expect(appModule).toContain('ngDoBootstrap');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update package.json by default', () => {
|
it('should update package.json by default', async () => {
|
||||||
appTree.overwrite(
|
appTree.overwrite(
|
||||||
`/package.json`,
|
`/package.json`,
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@ -63,21 +67,23 @@ describe('downgrade-module', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'downgrade-module',
|
'downgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const packageJson = readJsonInTree(tree, '/package.json');
|
const packageJson = readJsonInTree(tree, '/package.json');
|
||||||
expect(packageJson.dependencies['@angular/upgrade']).toEqual('4.4.4');
|
expect(packageJson.dependencies['@angular/upgrade']).toEqual('4.4.4');
|
||||||
expect(packageJson.dependencies['angular']).toBeDefined();
|
expect(packageJson.dependencies['angular']).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not package.json when --skipPackageJson=true', () => {
|
it('should not package.json when --skipPackageJson=true', async () => {
|
||||||
appTree.overwrite(
|
appTree.overwrite(
|
||||||
`/package.json`,
|
`/package.json`,
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@ -87,7 +93,8 @@ describe('downgrade-module', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'downgrade-module',
|
'downgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
@ -95,14 +102,16 @@ describe('downgrade-module', () => {
|
|||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const packageJson = readJsonInTree(tree, 'package.json');
|
const packageJson = readJsonInTree(tree, 'package.json');
|
||||||
expect(packageJson.dependencies['@angular/upgrade']).not.toBeDefined();
|
expect(packageJson.dependencies['@angular/upgrade']).not.toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support custom angularJsImport', () => {
|
it('should support custom angularJsImport', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'downgrade-module',
|
'downgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
@ -110,7 +119,8 @@ describe('downgrade-module', () => {
|
|||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const main = getFileContent(tree, '/apps/myapp/src/main.ts');
|
const main = getFileContent(tree, '/apps/myapp/src/main.ts');
|
||||||
expect(main).toContain(`import 'legacy-app';`);
|
expect(main).toContain(`import 'legacy-app';`);
|
||||||
|
|||||||
@ -18,8 +18,7 @@
|
|||||||
},
|
},
|
||||||
"angularJsImport": {
|
"angularJsImport": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
||||||
"Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
|
||||||
},
|
},
|
||||||
"skipFormat": {
|
"skipFormat": {
|
||||||
"description": "Skip formatting files",
|
"description": "Skip formatting files",
|
||||||
@ -29,8 +28,7 @@
|
|||||||
"skipPackageJson": {
|
"skipPackageJson": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
||||||
"Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["project"]
|
"required": ["project"]
|
||||||
|
|||||||
@ -12,40 +12,46 @@ describe('lib', () => {
|
|||||||
|
|
||||||
let appTree: Tree;
|
let appTree: Tree;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(async () => {
|
||||||
appTree = new VirtualTree();
|
appTree = new VirtualTree();
|
||||||
appTree = createEmptyWorkspace(appTree);
|
appTree = createEmptyWorkspace(appTree);
|
||||||
appTree = schematicRunner.runSchematic(
|
appTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'lib1',
|
name: 'lib1',
|
||||||
unitTestRunner: 'none'
|
unitTestRunner: 'none'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1'
|
project: 'lib1'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(resultTree.exists('/libs/lib1/src/test-setup.ts')).toBeTruthy();
|
expect(resultTree.exists('/libs/lib1/src/test-setup.ts')).toBeTruthy();
|
||||||
expect(resultTree.exists('/libs/lib1/jest.config.js')).toBeTruthy();
|
expect(resultTree.exists('/libs/lib1/jest.config.js')).toBeTruthy();
|
||||||
expect(resultTree.exists('/libs/lib1/tsconfig.spec.json')).toBeTruthy();
|
expect(resultTree.exists('/libs/lib1/tsconfig.spec.json')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should alter angular.json', () => {
|
it('should alter angular.json', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1'
|
project: 'lib1'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||||
expect(angularJson.projects.lib1.architect.test).toEqual({
|
expect(angularJson.projects.lib1.architect.test).toEqual({
|
||||||
builder: '@nrwl/builders:jest',
|
builder: '@nrwl/builders:jest',
|
||||||
@ -60,14 +66,16 @@ describe('lib', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a jest.config.js', () => {
|
it('should create a jest.config.js', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1'
|
project: 'lib1'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(resultTree.readContent('libs/lib1/jest.config.js'))
|
expect(resultTree.readContent('libs/lib1/jest.config.js'))
|
||||||
.toBe(`module.exports = {
|
.toBe(`module.exports = {
|
||||||
name: 'lib1',
|
name: 'lib1',
|
||||||
@ -77,27 +85,31 @@ describe('lib', () => {
|
|||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the local tsconfig.json', () => {
|
it('should update the local tsconfig.json', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1'
|
project: 'lib1'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const tsConfig = readJsonInTree(resultTree, 'libs/lib1/tsconfig.json');
|
const tsConfig = readJsonInTree(resultTree, 'libs/lib1/tsconfig.json');
|
||||||
expect(tsConfig.compilerOptions.types).toContain('jest');
|
expect(tsConfig.compilerOptions.types).toContain('jest');
|
||||||
expect(tsConfig.compilerOptions.types).toContain('node');
|
expect(tsConfig.compilerOptions.types).toContain('node');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a tsconfig.spec.json', () => {
|
it('should create a tsconfig.spec.json', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1'
|
project: 'lib1'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const tsConfig = readJsonInTree(resultTree, 'libs/lib1/tsconfig.spec.json');
|
const tsConfig = readJsonInTree(resultTree, 'libs/lib1/tsconfig.spec.json');
|
||||||
expect(tsConfig).toEqual({
|
expect(tsConfig).toEqual({
|
||||||
extends: './tsconfig.json',
|
extends: './tsconfig.json',
|
||||||
@ -112,42 +124,48 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('--skip-setup-file', () => {
|
describe('--skip-setup-file', () => {
|
||||||
it('should generate src/test-setup.ts', () => {
|
it('should generate src/test-setup.ts', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1',
|
project: 'lib1',
|
||||||
skipSetupFile: true
|
skipSetupFile: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(resultTree.exists('src/test-setup.ts')).toBeFalsy();
|
expect(resultTree.exists('src/test-setup.ts')).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not list the setup file in angular.json', () => {
|
it('should not list the setup file in angular.json', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1',
|
project: 'lib1',
|
||||||
skipSetupFile: true
|
skipSetupFile: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||||
expect(
|
expect(
|
||||||
angularJson.projects.lib1.architect.test.options.setupFile
|
angularJson.projects.lib1.architect.test.options.setupFile
|
||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not list the setup file in tsconfig.spec.json', () => {
|
it('should not list the setup file in tsconfig.spec.json', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'jest-project',
|
'jest-project',
|
||||||
{
|
{
|
||||||
project: 'lib1',
|
project: 'lib1',
|
||||||
skipSetupFile: true
|
skipSetupFile: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const tsConfig = readJsonInTree(
|
const tsConfig = readJsonInTree(
|
||||||
resultTree,
|
resultTree,
|
||||||
'libs/lib1/tsconfig.spec.json'
|
'libs/lib1/tsconfig.spec.json'
|
||||||
|
|||||||
@ -21,12 +21,10 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('not nested', () => {
|
describe('not nested', () => {
|
||||||
it('should update ng-package.json', () => {
|
it('should update ng-package.json', async () => {
|
||||||
const publishableTree = schematicRunner.runSchematic(
|
const publishableTree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||||
{ name: 'myLib', publishable: true },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
let ngPackage = readJsonInTree(
|
let ngPackage = readJsonInTree(
|
||||||
publishableTree,
|
publishableTree,
|
||||||
'libs/my-lib/ng-package.json'
|
'libs/my-lib/ng-package.json'
|
||||||
@ -35,76 +33,70 @@ describe('lib', () => {
|
|||||||
expect(ngPackage.dest).toEqual('../../dist/libs/my-lib');
|
expect(ngPackage.dest).toEqual('../../dist/libs/my-lib');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not update package.json by default', () => {
|
it('should not update package.json by default', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||||
{ name: 'myLib' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const packageJson = readJsonInTree(tree, '/package.json');
|
const packageJson = readJsonInTree(tree, '/package.json');
|
||||||
expect(packageJson.devDependencies['ng-packagr']).toBeUndefined();
|
expect(packageJson.devDependencies['ng-packagr']).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update package.json when publishable', () => {
|
it('should update package.json when publishable', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||||
{ name: 'myLib', publishable: true },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const packageJson = readJsonInTree(tree, '/package.json');
|
const packageJson = readJsonInTree(tree, '/package.json');
|
||||||
expect(packageJson.devDependencies['ng-packagr']).toBeDefined();
|
expect(packageJson.devDependencies['ng-packagr']).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should update npmScope of lib's package.json when publishable", () => {
|
it("should update npmScope of lib's package.json when publishable", async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||||
{ name: 'myLib', publishable: true },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const packageJson = readJsonInTree(tree, '/libs/my-lib/package.json');
|
const packageJson = readJsonInTree(tree, '/libs/my-lib/package.json');
|
||||||
expect(packageJson.name).toEqual('@proj/my-lib');
|
expect(packageJson.name).toEqual('@proj/my-lib');
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should update npmScope of lib's package.json when publishable", () => {
|
it("should update npmScope of lib's package.json when publishable", async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', publishable: true, prefix: 'lib' },
|
{ name: 'myLib', publishable: true, prefix: 'lib' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const packageJson = readJsonInTree(tree, '/libs/my-lib/package.json');
|
const packageJson = readJsonInTree(tree, '/libs/my-lib/package.json');
|
||||||
expect(packageJson.name).toEqual('@proj/my-lib');
|
expect(packageJson.name).toEqual('@proj/my-lib');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update angular.json', () => {
|
it('should update angular.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||||
{ name: 'myLib', publishable: true },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||||
|
|
||||||
expect(angularJson.projects['my-lib'].root).toEqual('libs/my-lib');
|
expect(angularJson.projects['my-lib'].root).toEqual('libs/my-lib');
|
||||||
expect(angularJson.projects['my-lib'].architect.build).toBeDefined();
|
expect(angularJson.projects['my-lib'].architect.build).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove "build" target from angular.json when a library is not publishable', () => {
|
it('should remove "build" target from angular.json when a library is not publishable', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', publishable: false },
|
{ name: 'myLib', publishable: false },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||||
|
|
||||||
expect(angularJson.projects['my-lib'].root).toEqual('libs/my-lib');
|
expect(angularJson.projects['my-lib'].root).toEqual('libs/my-lib');
|
||||||
expect(angularJson.projects['my-lib'].architect.build).not.toBeDefined();
|
expect(angularJson.projects['my-lib'].architect.build).not.toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update nx.json', () => {
|
it('should update nx.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', tags: 'one,two' }, appTree)
|
||||||
{ name: 'myLib', tags: 'one,two' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||||
expect(nxJson).toEqual({
|
expect(nxJson).toEqual({
|
||||||
npmScope: 'proj',
|
npmScope: 'proj',
|
||||||
@ -116,24 +108,20 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update root tsconfig.json', () => {
|
it('should update root tsconfig.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||||
{ name: 'myLib' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
||||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
||||||
'libs/my-lib/src/index.ts'
|
'libs/my-lib/src/index.ts'
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a local tsconfig.json', () => {
|
it('should create a local tsconfig.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||||
{ name: 'myLib' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
const tsconfigJson = readJsonInTree(tree, 'libs/my-lib/tsconfig.json');
|
const tsconfigJson = readJsonInTree(tree, 'libs/my-lib/tsconfig.json');
|
||||||
expect(tsconfigJson).toEqual({
|
expect(tsconfigJson).toEqual({
|
||||||
@ -145,12 +133,10 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extend the local tsconfig.json with tsconfig.spec.json', () => {
|
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||||
{ name: 'myLib' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
const tsconfigJson = readJsonInTree(
|
const tsconfigJson = readJsonInTree(
|
||||||
tree,
|
tree,
|
||||||
@ -159,12 +145,10 @@ describe('lib', () => {
|
|||||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should extend the local tsconfig.json with tsconfig.lib.json', () => {
|
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||||
{ name: 'myLib' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
const tsconfigJson = readJsonInTree(
|
const tsconfigJson = readJsonInTree(
|
||||||
tree,
|
tree,
|
||||||
@ -173,12 +157,10 @@ describe('lib', () => {
|
|||||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||||
{ name: 'myLib' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(tree.exists(`libs/my-lib/karma.conf.js`)).toBeTruthy();
|
expect(tree.exists(`libs/my-lib/karma.conf.js`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy();
|
expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.module.ts')).toBeTruthy();
|
expect(tree.exists('libs/my-lib/src/lib/my-lib.module.ts')).toBeTruthy();
|
||||||
@ -194,11 +176,13 @@ describe('lib', () => {
|
|||||||
tree.exists('libs/my-lib/src/lib/my-lib.service.spec.ts')
|
tree.exists('libs/my-lib/src/lib/my-lib.service.spec.ts')
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
|
|
||||||
const tree2 = schematicRunner.runSchematic(
|
const tree2 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib2', simpleModuleName: true },
|
{ name: 'myLib2', simpleModuleName: true },
|
||||||
tree
|
tree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(tree2.exists(`libs/my-lib2/karma.conf.js`)).toBeTruthy();
|
expect(tree2.exists(`libs/my-lib2/karma.conf.js`)).toBeTruthy();
|
||||||
expect(tree2.exists('libs/my-lib2/src/index.ts')).toBeTruthy();
|
expect(tree2.exists('libs/my-lib2/src/index.ts')).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
@ -219,12 +203,10 @@ describe('lib', () => {
|
|||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not generate a module for --module false', () => {
|
it('should not generate a module for --module false', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', module: false }, appTree)
|
||||||
{ name: 'myLib', module: false },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.module.ts')).toEqual(
|
expect(tree.exists('libs/my-lib/src/lib/my-lib.module.ts')).toEqual(
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
@ -234,22 +216,18 @@ describe('lib', () => {
|
|||||||
expect(tree.exists('libs/my-lib/src/lib/.gitkeep')).toEqual(true);
|
expect(tree.exists('libs/my-lib/src/lib/.gitkeep')).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should default the prefix to npmScope', () => {
|
it('should default the prefix to npmScope', async () => {
|
||||||
const noPrefix = schematicRunner.runSchematic(
|
const noPrefix = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||||
{ name: 'myLib' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(
|
expect(
|
||||||
JSON.parse(noPrefix.read('angular.json').toString()).projects['my-lib']
|
JSON.parse(noPrefix.read('angular.json').toString()).projects['my-lib']
|
||||||
.prefix
|
.prefix
|
||||||
).toEqual('proj');
|
).toEqual('proj');
|
||||||
|
|
||||||
const withPrefix = schematicRunner.runSchematic(
|
const withPrefix = await schematicRunner
|
||||||
'app',
|
.runSchematicAsync('lib', { name: 'myLib', prefix: 'custom' }, appTree)
|
||||||
{ name: 'myLib', prefix: 'custom' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(
|
expect(
|
||||||
JSON.parse(withPrefix.read('angular.json').toString()).projects[
|
JSON.parse(withPrefix.read('angular.json').toString()).projects[
|
||||||
'my-lib'
|
'my-lib'
|
||||||
@ -259,12 +237,14 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('nested', () => {
|
describe('nested', () => {
|
||||||
it('should update nx.json', () => {
|
it('should update nx.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir', tags: 'one' },
|
{ name: 'myLib', directory: 'myDir', tags: 'one' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||||
expect(nxJson).toEqual({
|
expect(nxJson).toEqual({
|
||||||
npmScope: 'proj',
|
npmScope: 'proj',
|
||||||
@ -275,7 +255,8 @@ describe('lib', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const tree2 = schematicRunner.runSchematic(
|
const tree2 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib2',
|
name: 'myLib2',
|
||||||
@ -284,7 +265,8 @@ describe('lib', () => {
|
|||||||
simpleModuleName: true
|
simpleModuleName: true
|
||||||
},
|
},
|
||||||
tree
|
tree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const nxJson2 = readJsonInTree<NxJson>(tree2, '/nx.json');
|
const nxJson2 = readJsonInTree<NxJson>(tree2, '/nx.json');
|
||||||
expect(nxJson2).toEqual({
|
expect(nxJson2).toEqual({
|
||||||
npmScope: 'proj',
|
npmScope: 'proj',
|
||||||
@ -299,12 +281,14 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir' },
|
{ name: 'myLib', directory: 'myDir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(tree.exists(`libs/my-dir/my-lib/karma.conf.js`)).toBeTruthy();
|
expect(tree.exists(`libs/my-dir/my-lib/karma.conf.js`)).toBeTruthy();
|
||||||
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
|
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
@ -324,11 +308,13 @@ describe('lib', () => {
|
|||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-lib.service.spec.ts')
|
tree.exists('libs/my-dir/my-lib/src/lib/my-lib.service.spec.ts')
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
|
|
||||||
const tree2 = schematicRunner.runSchematic(
|
const tree2 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib2', directory: 'myDir', simpleModuleName: true },
|
{ name: 'myLib2', directory: 'myDir', simpleModuleName: true },
|
||||||
tree
|
tree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(tree2.exists(`libs/my-dir/my-lib2/karma.conf.js`)).toBeTruthy();
|
expect(tree2.exists(`libs/my-dir/my-lib2/karma.conf.js`)).toBeTruthy();
|
||||||
expect(tree2.exists('libs/my-dir/my-lib2/src/index.ts')).toBeTruthy();
|
expect(tree2.exists('libs/my-dir/my-lib2/src/index.ts')).toBeTruthy();
|
||||||
expect(
|
expect(
|
||||||
@ -349,12 +335,14 @@ describe('lib', () => {
|
|||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update ng-package.json', () => {
|
it('should update ng-package.json', async () => {
|
||||||
const publishableTree = schematicRunner.runSchematic(
|
const publishableTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir', publishable: true },
|
{ name: 'myLib', directory: 'myDir', publishable: true },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
let ngPackage = readJsonInTree(
|
let ngPackage = readJsonInTree(
|
||||||
publishableTree,
|
publishableTree,
|
||||||
@ -363,12 +351,14 @@ describe('lib', () => {
|
|||||||
expect(ngPackage.dest).toEqual('../../../dist/libs/my-dir/my-lib');
|
expect(ngPackage.dest).toEqual('../../../dist/libs/my-dir/my-lib');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update angular.json', () => {
|
it('should update angular.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir' },
|
{ name: 'myLib', directory: 'myDir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||||
|
|
||||||
expect(angularJson.projects['my-dir-my-lib'].root).toEqual(
|
expect(angularJson.projects['my-dir-my-lib'].root).toEqual(
|
||||||
@ -376,12 +366,14 @@ describe('lib', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update tsconfig.json', () => {
|
it('should update tsconfig.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir' },
|
{ name: 'myLib', directory: 'myDir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
||||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual(
|
expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual(
|
||||||
['libs/my-dir/my-lib/src/index.ts']
|
['libs/my-dir/my-lib/src/index.ts']
|
||||||
@ -391,12 +383,14 @@ describe('lib', () => {
|
|||||||
).toBeUndefined();
|
).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create a local tsconfig.json', () => {
|
it('should create a local tsconfig.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir' },
|
{ name: 'myLib', directory: 'myDir' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const tsconfigJson = readJsonInTree(
|
const tsconfigJson = readJsonInTree(
|
||||||
tree,
|
tree,
|
||||||
@ -411,12 +405,14 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not generate a module for --module false', () => {
|
it('should not generate a module for --module false', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir', module: false },
|
{ name: 'myLib', directory: 'myDir', module: false },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
||||||
).toEqual(false);
|
).toEqual(false);
|
||||||
@ -428,23 +424,26 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('router', () => {
|
describe('router', () => {
|
||||||
it('should error when lazy is set without routing', () => {
|
it('should error when lazy is set without routing', async () => {
|
||||||
expect(() =>
|
try {
|
||||||
schematicRunner.runSchematic(
|
await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', lazy: true }, appTree)
|
||||||
{ name: 'myLib', lazy: true },
|
.toPromise();
|
||||||
appTree
|
fail();
|
||||||
)
|
} catch (e) {
|
||||||
).toThrow('routing must be set');
|
expect(e.message).toEqual('routing must be set');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('lazy', () => {
|
describe('lazy', () => {
|
||||||
it('should add RouterModule.forChild', () => {
|
it('should add RouterModule.forChild', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir', routing: true, lazy: true },
|
{ name: 'myLib', directory: 'myDir', routing: true, lazy: true },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
||||||
@ -456,7 +455,8 @@ describe('lib', () => {
|
|||||||
)
|
)
|
||||||
).toContain('RouterModule.forChild');
|
).toContain('RouterModule.forChild');
|
||||||
|
|
||||||
const tree2 = schematicRunner.runSchematic(
|
const tree2 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib2',
|
name: 'myLib2',
|
||||||
@ -466,7 +466,8 @@ describe('lib', () => {
|
|||||||
simpleModuleName: true
|
simpleModuleName: true
|
||||||
},
|
},
|
||||||
tree
|
tree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree2.exists('libs/my-dir/my-lib2/src/lib/my-lib2.module.ts')
|
tree2.exists('libs/my-dir/my-lib2/src/lib/my-lib2.module.ts')
|
||||||
@ -476,9 +477,10 @@ describe('lib', () => {
|
|||||||
).toContain('RouterModule.forChild');
|
).toContain('RouterModule.forChild');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the parent module', () => {
|
it('should update the parent module', async () => {
|
||||||
appTree = createApp(appTree, 'myapp');
|
appTree = createApp(appTree, 'myapp');
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib',
|
name: 'myLib',
|
||||||
@ -488,12 +490,17 @@ describe('lib', () => {
|
|||||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
const moduleContents = getFileContent(
|
||||||
|
tree,
|
||||||
|
'apps/myapp/src/app/app.module.ts'
|
||||||
);
|
);
|
||||||
expect(
|
expect(moduleContents).toContain('RouterModule.forRoot([');
|
||||||
getFileContent(tree, 'apps/myapp/src/app/app.module.ts')
|
expect(moduleContents).toContain(`{
|
||||||
).toContain(
|
path: 'my-dir-my-lib',
|
||||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'}])`
|
loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'
|
||||||
);
|
}`);
|
||||||
|
|
||||||
const tsConfigAppJson = JSON.parse(
|
const tsConfigAppJson = JSON.parse(
|
||||||
stripJsonComments(
|
stripJsonComments(
|
||||||
@ -505,7 +512,8 @@ describe('lib', () => {
|
|||||||
'../../libs/my-dir/my-lib/src/index.ts'
|
'../../libs/my-dir/my-lib/src/index.ts'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const tree2 = schematicRunner.runSchematic(
|
const tree2 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib2',
|
name: 'myLib2',
|
||||||
@ -515,12 +523,21 @@ describe('lib', () => {
|
|||||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||||
},
|
},
|
||||||
tree
|
tree
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
const moduleContents2 = getFileContent(
|
||||||
|
tree2,
|
||||||
|
'apps/myapp/src/app/app.module.ts'
|
||||||
);
|
);
|
||||||
expect(
|
expect(moduleContents2).toContain('RouterModule.forRoot([');
|
||||||
getFileContent(tree2, 'apps/myapp/src/app/app.module.ts')
|
expect(moduleContents2).toContain(`{
|
||||||
).toContain(
|
path: 'my-dir-my-lib',
|
||||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'}, {path: 'my-dir-my-lib2', loadChildren: '@proj/my-dir/my-lib2#MyDirMyLib2Module'}])`
|
loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'
|
||||||
);
|
}`);
|
||||||
|
expect(moduleContents2).toContain(`{
|
||||||
|
path: 'my-dir-my-lib2',
|
||||||
|
loadChildren: '@proj/my-dir/my-lib2#MyDirMyLib2Module'
|
||||||
|
}`);
|
||||||
|
|
||||||
const tsConfigAppJson2 = JSON.parse(
|
const tsConfigAppJson2 = JSON.parse(
|
||||||
stripJsonComments(
|
stripJsonComments(
|
||||||
@ -533,7 +550,8 @@ describe('lib', () => {
|
|||||||
'../../libs/my-dir/my-lib2/src/index.ts'
|
'../../libs/my-dir/my-lib2/src/index.ts'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const tree3 = schematicRunner.runSchematic(
|
const tree3 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib3',
|
name: 'myLib3',
|
||||||
@ -544,11 +562,23 @@ describe('lib', () => {
|
|||||||
simpleModuleName: true
|
simpleModuleName: true
|
||||||
},
|
},
|
||||||
tree2
|
tree2
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
const moduleContents3 = getFileContent(
|
||||||
|
tree3,
|
||||||
|
'apps/myapp/src/app/app.module.ts'
|
||||||
);
|
);
|
||||||
expect(
|
expect(moduleContents3).toContain('RouterModule.forRoot([');
|
||||||
getFileContent(tree3, 'apps/myapp/src/app/app.module.ts')
|
expect(moduleContents3).toContain(`{
|
||||||
).toContain(
|
path: 'my-dir-my-lib',
|
||||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'}, {path: 'my-dir-my-lib2', loadChildren: '@proj/my-dir/my-lib2#MyDirMyLib2Module'}, {path: 'my-lib3', loadChildren: '@proj/my-dir/my-lib3#MyLib3Module'}])`
|
loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'
|
||||||
|
}`);
|
||||||
|
expect(moduleContents3).toContain(`{
|
||||||
|
path: 'my-dir-my-lib2',
|
||||||
|
loadChildren: '@proj/my-dir/my-lib2#MyDirMyLib2Module'
|
||||||
|
}`);
|
||||||
|
expect(moduleContents3).toContain(
|
||||||
|
`{ path: 'my-lib3', loadChildren: '@proj/my-dir/my-lib3#MyLib3Module' }`
|
||||||
);
|
);
|
||||||
|
|
||||||
const tsConfigAppJson3 = JSON.parse(
|
const tsConfigAppJson3 = JSON.parse(
|
||||||
@ -566,12 +596,14 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('eager', () => {
|
describe('eager', () => {
|
||||||
it('should add RouterModule and define an array of routes', () => {
|
it('should add RouterModule and define an array of routes', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', directory: 'myDir', routing: true },
|
{ name: 'myLib', directory: 'myDir', routing: true },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
@ -588,7 +620,8 @@ describe('lib', () => {
|
|||||||
)
|
)
|
||||||
).toContain('const myDirMyLibRoutes: Route[] = ');
|
).toContain('const myDirMyLibRoutes: Route[] = ');
|
||||||
|
|
||||||
const tree2 = schematicRunner.runSchematic(
|
const tree2 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib2',
|
name: 'myLib2',
|
||||||
@ -597,7 +630,8 @@ describe('lib', () => {
|
|||||||
simpleModuleName: true
|
simpleModuleName: true
|
||||||
},
|
},
|
||||||
tree
|
tree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
tree2.exists('libs/my-dir/my-lib2/src/lib/my-lib2.module.ts')
|
tree2.exists('libs/my-dir/my-lib2/src/lib/my-lib2.module.ts')
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
@ -609,9 +643,10 @@ describe('lib', () => {
|
|||||||
).toContain('const myLib2Routes: Route[] = ');
|
).toContain('const myLib2Routes: Route[] = ');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the parent module', () => {
|
it('should update the parent module', async () => {
|
||||||
appTree = createApp(appTree, 'myapp');
|
appTree = createApp(appTree, 'myapp');
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib',
|
name: 'myLib',
|
||||||
@ -620,14 +655,19 @@ describe('lib', () => {
|
|||||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
const moduleContents = getFileContent(
|
||||||
|
tree,
|
||||||
|
'apps/myapp/src/app/app.module.ts'
|
||||||
);
|
);
|
||||||
expect(
|
expect(moduleContents).toContain('RouterModule.forRoot([');
|
||||||
getFileContent(tree, 'apps/myapp/src/app/app.module.ts')
|
expect(moduleContents).toContain(
|
||||||
).toContain(
|
"{ path: 'my-dir-my-lib', children: myDirMyLibRoutes }"
|
||||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', children: myDirMyLibRoutes}])`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const tree2 = schematicRunner.runSchematic(
|
const tree2 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib2',
|
name: 'myLib2',
|
||||||
@ -636,14 +676,22 @@ describe('lib', () => {
|
|||||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||||
},
|
},
|
||||||
tree
|
tree
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
const moduleContents2 = getFileContent(
|
||||||
|
tree2,
|
||||||
|
'apps/myapp/src/app/app.module.ts'
|
||||||
);
|
);
|
||||||
expect(
|
expect(moduleContents2).toContain('RouterModule.forRoot([');
|
||||||
getFileContent(tree2, 'apps/myapp/src/app/app.module.ts')
|
expect(moduleContents2).toContain(
|
||||||
).toContain(
|
"{ path: 'my-dir-my-lib', children: myDirMyLibRoutes }"
|
||||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', children: myDirMyLibRoutes}, {path: 'my-dir-my-lib2', children: myDirMyLib2Routes}])`
|
);
|
||||||
|
expect(moduleContents2).toContain(
|
||||||
|
"{ path: 'my-dir-my-lib2', children: myDirMyLib2Routes }"
|
||||||
);
|
);
|
||||||
|
|
||||||
const tree3 = schematicRunner.runSchematic(
|
const tree3 = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{
|
{
|
||||||
name: 'myLib3',
|
name: 'myLib3',
|
||||||
@ -653,23 +701,31 @@ describe('lib', () => {
|
|||||||
simpleModuleName: true
|
simpleModuleName: true
|
||||||
},
|
},
|
||||||
tree2
|
tree2
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
const moduleContents3 = getFileContent(
|
||||||
|
tree3,
|
||||||
|
'apps/myapp/src/app/app.module.ts'
|
||||||
);
|
);
|
||||||
expect(
|
expect(moduleContents3).toContain('RouterModule.forRoot([');
|
||||||
getFileContent(tree3, 'apps/myapp/src/app/app.module.ts')
|
expect(moduleContents3).toContain(
|
||||||
).toContain(
|
"{ path: 'my-dir-my-lib', children: myDirMyLibRoutes }"
|
||||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', children: myDirMyLibRoutes}, {path: 'my-dir-my-lib2', children: myDirMyLib2Routes}, {path: 'my-lib3', children: myLib3Routes}])`
|
);
|
||||||
|
expect(moduleContents3).toContain(
|
||||||
|
"{ path: 'my-dir-my-lib2', children: myDirMyLib2Routes }"
|
||||||
|
);
|
||||||
|
expect(moduleContents3).toContain(
|
||||||
|
"{ path: 'my-lib3', children: myLib3Routes }"
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('--style scss', () => {
|
describe('--style scss', () => {
|
||||||
it('should set it as default', () => {
|
it('should set it as default', async () => {
|
||||||
const result = schematicRunner.runSchematic(
|
const result = await schematicRunner
|
||||||
'lib',
|
.runSchematicAsync('lib', { name: 'myLib', style: 'scss' }, appTree)
|
||||||
{ name: 'myLib', style: 'scss' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
|
|
||||||
const angularJson = readJsonInTree(result, 'angular.json');
|
const angularJson = readJsonInTree(result, 'angular.json');
|
||||||
|
|
||||||
@ -682,12 +738,14 @@ describe('lib', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('--unit-test-runner jest', () => {
|
describe('--unit-test-runner jest', () => {
|
||||||
it('should generate jest configuration', () => {
|
it('should generate jest configuration', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', unitTestRunner: 'jest' },
|
{ name: 'myLib', unitTestRunner: 'jest' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(resultTree.exists('libs/my-lib/src/test.ts')).toBeFalsy();
|
expect(resultTree.exists('libs/my-lib/src/test.ts')).toBeFalsy();
|
||||||
expect(resultTree.exists('libs/my-lib/src/test-setup.ts')).toBeTruthy();
|
expect(resultTree.exists('libs/my-lib/src/test-setup.ts')).toBeTruthy();
|
||||||
expect(resultTree.exists('libs/my-lib/tsconfig.spec.json')).toBeTruthy();
|
expect(resultTree.exists('libs/my-lib/tsconfig.spec.json')).toBeTruthy();
|
||||||
@ -704,23 +762,27 @@ describe('lib', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should skip the setup file if no module is generated', () => {
|
it('should skip the setup file if no module is generated', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', unitTestRunner: 'jest', module: false },
|
{ name: 'myLib', unitTestRunner: 'jest', module: false },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(resultTree.exists('libs/my-lib/src/test-setup.ts')).toBeFalsy();
|
expect(resultTree.exists('libs/my-lib/src/test-setup.ts')).toBeFalsy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('--unit-test-runner none', () => {
|
describe('--unit-test-runner none', () => {
|
||||||
it('should not generate test configuration', () => {
|
it('should not generate test configuration', async () => {
|
||||||
const resultTree = schematicRunner.runSchematic(
|
const resultTree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'lib',
|
'lib',
|
||||||
{ name: 'myLib', unitTestRunner: 'none' },
|
{ name: 'myLib', unitTestRunner: 'none' },
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
expect(
|
expect(
|
||||||
resultTree.exists('libs/my-lib/src/lib/my-lib.module.spec.ts')
|
resultTree.exists('libs/my-lib/src/lib/my-lib.module.spec.ts')
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
|
|||||||
@ -51,8 +51,7 @@
|
|||||||
},
|
},
|
||||||
"parentModule": {
|
"parentModule": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to.",
|
||||||
"Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to.",
|
|
||||||
"x-prompt": "Which module should import the library?"
|
"x-prompt": "Which module should import the library?"
|
||||||
},
|
},
|
||||||
"style": {
|
"style": {
|
||||||
@ -75,14 +74,12 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "Add router configuration. See lazy for more information.",
|
"description": "Add router configuration. See lazy for more information.",
|
||||||
"x-prompt":
|
"x-prompt": "Would you like to add a routing configuration to the library?"
|
||||||
"Would you like to add a routing configuration to the library?"
|
|
||||||
},
|
},
|
||||||
"lazy": {
|
"lazy": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Add RouterModule.forChild when set to true, and a simple array of routes when set to false.",
|
||||||
"Add RouterModule.forChild when set to true, and a simple array of routes when set to false.",
|
|
||||||
"x-prompt": "Will this library be lazy loaded?"
|
"x-prompt": "Will this library be lazy loaded?"
|
||||||
},
|
},
|
||||||
"module": {
|
"module": {
|
||||||
@ -94,8 +91,7 @@
|
|||||||
"tags": {
|
"tags": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Add tags to the library (used for linting)",
|
"description": "Add tags to the library (used for linting)",
|
||||||
"x-prompt":
|
"x-prompt": "Which tags would you like to add to the library? (used for linting)"
|
||||||
"Which tags would you like to add to the library? (used for linting)"
|
|
||||||
},
|
},
|
||||||
"unitTestRunner": {
|
"unitTestRunner": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
@ -103,8 +99,7 @@
|
|||||||
"description": "Test runner to use for unit tests",
|
"description": "Test runner to use for unit tests",
|
||||||
"default": "karma",
|
"default": "karma",
|
||||||
"x-prompt": {
|
"x-prompt": {
|
||||||
"message":
|
"message": "Which Unit Test Runner would you like to use for the library?",
|
||||||
"Which Unit Test Runner would you like to use for the library?",
|
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"items": [
|
"items": [
|
||||||
{ "value": "karma", "label": "Karma" },
|
{ "value": "karma", "label": "Karma" },
|
||||||
|
|||||||
@ -8,8 +8,7 @@
|
|||||||
"npmScope": {
|
"npmScope": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Npm scope for importing libs.",
|
"description": "Npm scope for importing libs.",
|
||||||
"x-prompt":
|
"x-prompt": "What is the npm scope you would like to use for your Nx Workspace?"
|
||||||
"What is the npm scope you would like to use for your Nx Workspace?"
|
|
||||||
},
|
},
|
||||||
"skipInstall": {
|
"skipInstall": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@ -62,7 +62,9 @@ function addTasks(options: Schema, context: SchematicContext) {
|
|||||||
const commit =
|
const commit =
|
||||||
typeof options.commit == 'object'
|
typeof options.commit == 'object'
|
||||||
? options.commit
|
? options.commit
|
||||||
: !!options.commit ? {} : false;
|
: !!options.commit
|
||||||
|
? {}
|
||||||
|
: false;
|
||||||
context.addTask(
|
context.addTask(
|
||||||
new RepositoryInitializerTask(options.directory, commit),
|
new RepositoryInitializerTask(options.directory, commit),
|
||||||
packageTask ? [packageTask] : []
|
packageTask ? [packageTask] : []
|
||||||
|
|||||||
@ -39,8 +39,7 @@
|
|||||||
"npmScope": {
|
"npmScope": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Npm scope for importing libs.",
|
"description": "Npm scope for importing libs.",
|
||||||
"x-prompt":
|
"x-prompt": "What is the npm scope you would like to use for your Nx Workspace?"
|
||||||
"What is the npm scope you would like to use for your Nx Workspace?"
|
|
||||||
},
|
},
|
||||||
"skipInstall": {
|
"skipInstall": {
|
||||||
"description": "Skip installing dependency packages.",
|
"description": "Skip installing dependency packages.",
|
||||||
@ -57,8 +56,7 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Package manager used in the project.",
|
"description": "Package manager used in the project.",
|
||||||
"x-prompt": {
|
"x-prompt": {
|
||||||
"message":
|
"message": "Which Package Manager would you like to use for your workspace?",
|
||||||
"Which Package Manager would you like to use for your workspace?",
|
|
||||||
"type": "list",
|
"type": "list",
|
||||||
"items": [
|
"items": [
|
||||||
{ "value": "npm", "label": "" },
|
{ "value": "npm", "label": "" },
|
||||||
|
|||||||
@ -31,8 +31,9 @@ describe('ngrx', () => {
|
|||||||
appTree = createApp(appTree, 'myapp');
|
appTree = createApp(appTree, 'myapp');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add empty root', () => {
|
it('should add empty root', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
@ -40,21 +41,24 @@ describe('ngrx', () => {
|
|||||||
onlyEmptyRoot: true
|
onlyEmptyRoot: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
tree.exists('apps/myapp/src/app/+state/state.actions.ts')
|
tree.exists('apps/myapp/src/app/+state/state.actions.ts')
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
|
|
||||||
|
expect(appModule).toContain('StoreModule.forRoot(');
|
||||||
expect(appModule).toContain(
|
expect(appModule).toContain(
|
||||||
'StoreModule.forRoot({},{ metaReducers : !environment.production ? [storeFreeze] : [] })'
|
'{ metaReducers: !environment.production ? [storeFreeze] : [] }'
|
||||||
);
|
);
|
||||||
expect(appModule).toContain('EffectsModule.forRoot');
|
expect(appModule).toContain('EffectsModule.forRoot');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add root', () => {
|
it('should add root', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'app',
|
name: 'app',
|
||||||
@ -62,7 +66,8 @@ describe('ngrx', () => {
|
|||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
[
|
[
|
||||||
'/apps/myapp/src/app/+state/app.actions.ts',
|
'/apps/myapp/src/app/+state/app.actions.ts',
|
||||||
@ -94,8 +99,9 @@ describe('ngrx', () => {
|
|||||||
expect(appModule).toContain('initialState: { app: appInitialState }');
|
expect(appModule).toContain('initialState: { app: appInitialState }');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add facade to root', () => {
|
it('should add facade to root', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'app',
|
name: 'app',
|
||||||
@ -104,7 +110,8 @@ describe('ngrx', () => {
|
|||||||
facade: true
|
facade: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||||
|
|
||||||
@ -135,9 +142,10 @@ describe('ngrx', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not add RouterStoreModule only if the module does not reference the router', () => {
|
it('should not add RouterStoreModule only if the module does not reference the router', async () => {
|
||||||
const newTree = createApp(appTree, 'myapp-norouter', false);
|
const newTree = createApp(appTree, 'myapp-norouter', false);
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'app',
|
name: 'app',
|
||||||
@ -145,7 +153,8 @@ describe('ngrx', () => {
|
|||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
newTree
|
newTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const appModule = getFileContent(
|
const appModule = getFileContent(
|
||||||
tree,
|
tree,
|
||||||
'/apps/myapp-norouter/src/app/app.module.ts'
|
'/apps/myapp-norouter/src/app/app.module.ts'
|
||||||
@ -153,21 +162,23 @@ describe('ngrx', () => {
|
|||||||
expect(appModule).not.toContain('StoreRouterConnectingModule');
|
expect(appModule).not.toContain('StoreRouterConnectingModule');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add feature', () => {
|
it('should add feature', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
module: 'apps/myapp/src/app/app.module.ts'
|
module: 'apps/myapp/src/app/app.module.ts'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||||
expect(appModule).toContain('StoreModule.forFeature');
|
expect(appModule).toContain('StoreModule.forFeature');
|
||||||
expect(appModule).toContain('EffectsModule.forFeature');
|
expect(appModule).toContain('EffectsModule.forFeature');
|
||||||
expect(appModule).toContain('STATE_FEATURE_KEY, stateReducer');
|
expect(appModule).toContain('STATE_FEATURE_KEY, stateReducer');
|
||||||
expect(appModule).toContain('{ initialState: stateInitialState }');
|
expect(appModule).toContain('initialState: stateInitialState');
|
||||||
expect(appModule).not.toContain(
|
expect(appModule).not.toContain(
|
||||||
'!environment.production ? [storeFreeze] : []'
|
'!environment.production ? [storeFreeze] : []'
|
||||||
);
|
);
|
||||||
@ -177,8 +188,9 @@ describe('ngrx', () => {
|
|||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add with custom directoryName', () => {
|
it('should add with custom directoryName', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
@ -186,7 +198,8 @@ describe('ngrx', () => {
|
|||||||
directory: 'myCustomState'
|
directory: 'myCustomState'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||||
expect(appModule).toContain('StoreModule.forFeature');
|
expect(appModule).toContain('StoreModule.forFeature');
|
||||||
@ -200,8 +213,9 @@ describe('ngrx', () => {
|
|||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only add files', () => {
|
it('should only add files', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
@ -210,7 +224,8 @@ describe('ngrx', () => {
|
|||||||
facade: true
|
facade: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||||
expect(appModule).not.toContain('StoreModule');
|
expect(appModule).not.toContain('StoreModule');
|
||||||
@ -231,15 +246,17 @@ describe('ngrx', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update package.json', () => {
|
it('should update package.json', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
module: 'apps/myapp/src/app/app.module.ts'
|
module: 'apps/myapp/src/app/app.module.ts'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
const packageJson = readJsonInTree(tree, 'package.json');
|
const packageJson = readJsonInTree(tree, 'package.json');
|
||||||
|
|
||||||
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||||
@ -249,9 +266,10 @@ describe('ngrx', () => {
|
|||||||
expect(packageJson.devDependencies['ngrx-store-freeze']).toBeDefined();
|
expect(packageJson.devDependencies['ngrx-store-freeze']).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error when no module is provided', () => {
|
it('should error when no module is provided', async () => {
|
||||||
expect(() =>
|
try {
|
||||||
schematicRunner.runSchematic(
|
await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
@ -259,12 +277,17 @@ describe('ngrx', () => {
|
|||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
)
|
)
|
||||||
).toThrow('The required --module option must be passed');
|
.toPromise();
|
||||||
|
fail();
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toEqual('The required --module option must be passed');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should error the module could not be found', () => {
|
it('should error the module could not be found', async () => {
|
||||||
expect(() =>
|
try {
|
||||||
schematicRunner.runSchematic(
|
await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'state',
|
name: 'state',
|
||||||
@ -272,17 +295,20 @@ describe('ngrx', () => {
|
|||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
)
|
)
|
||||||
).toThrow('Path does not exist: does-not-exist.ts');
|
.toPromise();
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toEqual('Path does not exist: does-not-exist.ts');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('code generation', () => {
|
describe('code generation', () => {
|
||||||
it('should scaffold the ngrx "user" files without a facade', () => {
|
it('should scaffold the ngrx "user" files without a facade', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const hasFile = file => expect(tree.exists(file)).toBeTruthy();
|
const hasFile = file => expect(tree.exists(file)).toBeTruthy();
|
||||||
const missingFile = file => expect(tree.exists(file)).not.toBeTruthy();
|
const missingFile = file => expect(tree.exists(file)).not.toBeTruthy();
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
|
|
||||||
const tree = buildNgrxTree(appConfig);
|
const tree = await buildNgrxTree(appConfig);
|
||||||
|
|
||||||
hasFile(`${statePath}/user.actions.ts`);
|
hasFile(`${statePath}/user.actions.ts`);
|
||||||
hasFile(`${statePath}/user.effects.ts`);
|
hasFile(`${statePath}/user.effects.ts`);
|
||||||
@ -294,10 +320,10 @@ describe('ngrx', () => {
|
|||||||
hasFile(`${statePath}/user.selectors.ts`);
|
hasFile(`${statePath}/user.selectors.ts`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scaffold the ngrx "user" files WITH a facade', () => {
|
it('should scaffold the ngrx "user" files WITH a facade', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const hasFile = file => expect(tree.exists(file)).toBeTruthy();
|
const hasFile = file => expect(tree.exists(file)).toBeTruthy();
|
||||||
const tree = buildNgrxTree(appConfig, 'user', true);
|
const tree = await buildNgrxTree(appConfig, 'user', true);
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
|
|
||||||
hasFile(`${statePath}/user.actions.ts`);
|
hasFile(`${statePath}/user.actions.ts`);
|
||||||
@ -312,18 +338,18 @@ describe('ngrx', () => {
|
|||||||
hasFile(`${statePath}/user.facade.spec.ts`);
|
hasFile(`${statePath}/user.facade.spec.ts`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build the ngrx actions', () => {
|
it('should build the ngrx actions', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const tree = buildNgrxTree(appConfig, 'users');
|
const tree = await buildNgrxTree(appConfig, 'users');
|
||||||
|
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
const content = getFileContent(tree, `${statePath}/users.actions.ts`);
|
const content = getFileContent(tree, `${statePath}/users.actions.ts`);
|
||||||
|
|
||||||
expect(content).toContain('UsersActionTypes');
|
expect(content).toContain('UsersActionTypes');
|
||||||
|
|
||||||
expect(content).toContain('LoadUsers = "[Users] Load Users"');
|
expect(content).toContain("LoadUsers = '[Users] Load Users'");
|
||||||
expect(content).toContain('UsersLoaded = "[Users] Users Loaded"');
|
expect(content).toContain("UsersLoaded = '[Users] Users Loaded'");
|
||||||
expect(content).toContain('UsersLoadError = "[Users] Users Load Error"');
|
expect(content).toContain("UsersLoadError = '[Users] Users Load Error'");
|
||||||
|
|
||||||
expect(content).toContain('class LoadUsers implements Action');
|
expect(content).toContain('class LoadUsers implements Action');
|
||||||
expect(content).toContain('class UsersLoaded implements Action');
|
expect(content).toContain('class UsersLoaded implements Action');
|
||||||
@ -333,9 +359,9 @@ describe('ngrx', () => {
|
|||||||
expect(content).toContain('export const fromUsersActions');
|
expect(content).toContain('export const fromUsersActions');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build the ngrx selectors', () => {
|
it('should build the ngrx selectors', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const tree = buildNgrxTree(appConfig, 'users');
|
const tree = await buildNgrxTree(appConfig, 'users');
|
||||||
|
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
const content = getFileContent(tree, `${statePath}/users.selectors.ts`);
|
const content = getFileContent(tree, `${statePath}/users.selectors.ts`);
|
||||||
@ -348,10 +374,10 @@ describe('ngrx', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build the ngrx facade', () => {
|
it('should build the ngrx facade', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const includeFacade = true;
|
const includeFacade = true;
|
||||||
const tree = buildNgrxTree(appConfig, 'users', includeFacade);
|
const tree = await buildNgrxTree(appConfig, 'users', includeFacade);
|
||||||
|
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
const content = getFileContent(tree, `${statePath}/users.facade.ts`);
|
const content = getFileContent(tree, `${statePath}/users.facade.ts`);
|
||||||
@ -365,9 +391,9 @@ describe('ngrx', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build the ngrx reducer', () => {
|
it('should build the ngrx reducer', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const tree = buildNgrxTree(appConfig, 'user');
|
const tree = await buildNgrxTree(appConfig, 'user');
|
||||||
|
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
const content = getFileContent(tree, `${statePath}/user.reducer.ts`);
|
const content = getFileContent(tree, `${statePath}/user.reducer.ts`);
|
||||||
@ -380,28 +406,34 @@ describe('ngrx', () => {
|
|||||||
`export interface UserState`,
|
`export interface UserState`,
|
||||||
'export function userReducer',
|
'export function userReducer',
|
||||||
'state: UserState = initialState',
|
'state: UserState = initialState',
|
||||||
'action: UserAction): UserState',
|
'action: UserAction',
|
||||||
|
'): UserState',
|
||||||
'case UserActionTypes.UserLoaded'
|
'case UserActionTypes.UserLoaded'
|
||||||
].forEach(text => {
|
].forEach(text => {
|
||||||
expect(content).toContain(text);
|
expect(content).toContain(text);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build the ngrx effects', () => {
|
it('should build the ngrx effects', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const tree = buildNgrxTree(appConfig, 'users');
|
const tree = await buildNgrxTree(appConfig, 'users');
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
const content = getFileContent(tree, `${statePath}/users.effects.ts`);
|
const content = getFileContent(tree, `${statePath}/users.effects.ts`);
|
||||||
|
|
||||||
[
|
[
|
||||||
`import { DataPersistence } from \'@nrwl/nx\'`,
|
`import { DataPersistence } from \'@nrwl/nx\'`,
|
||||||
`import { LoadUsers, UsersLoaded, UsersLoadError, UsersActionTypes } from \'./users.actions\'`,
|
`import {
|
||||||
|
LoadUsers,
|
||||||
|
UsersLoaded,
|
||||||
|
UsersLoadError,
|
||||||
|
UsersActionTypes
|
||||||
|
} from \'./users.actions\';`,
|
||||||
`loadUsers$`,
|
`loadUsers$`,
|
||||||
`run: (action: LoadUsers, state: UsersPartialState)`,
|
`run: (action: LoadUsers, state: UsersPartialState)`,
|
||||||
`return new UsersLoaded([])`,
|
`return new UsersLoaded([])`,
|
||||||
`return new UsersLoadError(error)`,
|
`return new UsersLoadError(error)`,
|
||||||
'private actions$: Actions',
|
'private actions$: Actions',
|
||||||
'private dataPersistence: DataPersistence<UsersPartialState>)'
|
'private dataPersistence: DataPersistence<UsersPartialState>'
|
||||||
].forEach(text => {
|
].forEach(text => {
|
||||||
expect(content).toContain(text);
|
expect(content).toContain(text);
|
||||||
});
|
});
|
||||||
@ -409,9 +441,9 @@ describe('ngrx', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('unit tests', () => {
|
describe('unit tests', () => {
|
||||||
it('should produce proper specs for the ngrx reducer', () => {
|
it('should produce proper specs for the ngrx reducer', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const tree = buildNgrxTree(appConfig);
|
const tree = await buildNgrxTree(appConfig);
|
||||||
|
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
const contents = tree.readContent(`${statePath}/user.reducer.spec.ts`);
|
const contents = tree.readContent(`${statePath}/user.reducer.spec.ts`);
|
||||||
@ -422,10 +454,11 @@ describe('ngrx', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the barrel API with exports for ngrx facade, selector, and reducer', () => {
|
it('should update the barrel API with exports for ngrx facade, selector, and reducer', async () => {
|
||||||
appTree = createLib(appTree, 'flights');
|
appTree = createLib(appTree, 'flights');
|
||||||
let libConfig = getLibConfig();
|
let libConfig = getLibConfig();
|
||||||
let tree = schematicRunner.runSchematic(
|
let tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'super-users',
|
name: 'super-users',
|
||||||
@ -433,7 +466,8 @@ describe('ngrx', () => {
|
|||||||
facade: true
|
facade: true
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const barrel = tree.readContent(libConfig.barrel);
|
const barrel = tree.readContent(libConfig.barrel);
|
||||||
expect(barrel).toContain(
|
expect(barrel).toContain(
|
||||||
@ -441,10 +475,11 @@ describe('ngrx', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not update the barrel API with a facade', () => {
|
it('should not update the barrel API with a facade', async () => {
|
||||||
appTree = createLib(appTree, 'flights');
|
appTree = createLib(appTree, 'flights');
|
||||||
let libConfig = getLibConfig();
|
let libConfig = getLibConfig();
|
||||||
let tree = schematicRunner.runSchematic(
|
let tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'super-users',
|
name: 'super-users',
|
||||||
@ -452,7 +487,8 @@ describe('ngrx', () => {
|
|||||||
facade: false
|
facade: false
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const barrel = tree.readContent(libConfig.barrel);
|
const barrel = tree.readContent(libConfig.barrel);
|
||||||
expect(barrel).not.toContain(
|
expect(barrel).not.toContain(
|
||||||
@ -460,16 +496,18 @@ describe('ngrx', () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should produce proper tests for the ngrx reducer for a name with a dash', () => {
|
it('should produce proper tests for the ngrx reducer for a name with a dash', async () => {
|
||||||
const appConfig = getAppConfig();
|
const appConfig = getAppConfig();
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: 'super-users',
|
name: 'super-users',
|
||||||
module: appConfig.appModule
|
module: appConfig.appModule
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||||
const contents = tree.readContent(
|
const contents = tree.readContent(
|
||||||
@ -483,12 +521,13 @@ describe('ngrx', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function buildNgrxTree(
|
async function buildNgrxTree(
|
||||||
appConfig: AppConfig,
|
appConfig: AppConfig,
|
||||||
featureName: string = 'user',
|
featureName: string = 'user',
|
||||||
withFacade = false
|
withFacade = false
|
||||||
): UnitTestTree {
|
): Promise<UnitTestTree> {
|
||||||
return schematicRunner.runSchematic(
|
return await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'ngrx',
|
'ngrx',
|
||||||
{
|
{
|
||||||
name: featureName,
|
name: featureName,
|
||||||
@ -496,6 +535,7 @@ describe('ngrx', () => {
|
|||||||
facade: withFacade
|
facade: withFacade
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@ -6,8 +6,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "Name of the NgRx feature (e.g., Products, Users, etc.). Recommended to use plural form for name.",
|
||||||
"Name of the NgRx feature (e.g., Products, Users, etc.). Recommended to use plural form for name.",
|
|
||||||
"$default": {
|
"$default": {
|
||||||
"$source": "argv",
|
"$source": "argv",
|
||||||
"index": 0
|
"index": 0
|
||||||
@ -16,42 +15,35 @@
|
|||||||
},
|
},
|
||||||
"module": {
|
"module": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "Path to ngModule; host directory will contain the new '+state' directory (e.g., libs/comments/src/lib/comments-state.module.ts).",
|
||||||
"Path to ngModule; host directory will contain the new '+state' directory (e.g., libs/comments/src/lib/comments-state.module.ts).",
|
"x-prompt": "What is the path to the module where this ngrx state should be added to?"
|
||||||
"x-prompt":
|
|
||||||
"What is the path to the module where this ngrx state should be added to?"
|
|
||||||
},
|
},
|
||||||
"directory": {
|
"directory": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"default": "+state",
|
"default": "+state",
|
||||||
"description":
|
"description": "Override the name of the folder used to contain/group the NgRx files: contains actions, effects, reducers. selectors. (e.g., +state)"
|
||||||
"Override the name of the folder used to contain/group the NgRx files: contains actions, effects, reducers. selectors. (e.g., +state)"
|
|
||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Add StoreModule.forRoot and EffectsModule.forRoot() instead of forFeature (e.g., --root).",
|
||||||
"Add StoreModule.forRoot and EffectsModule.forRoot() instead of forFeature (e.g., --root).",
|
|
||||||
"x-prompt": "Is this the root state of the application?"
|
"x-prompt": "Is this the root state of the application?"
|
||||||
},
|
},
|
||||||
"facade": {
|
"facade": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Create a Facade class for the the Feature (e.g., --facade).",
|
||||||
"Create a Facade class for the the Feature (e.g., --facade).",
|
|
||||||
"x-prompt": "Would you like to add a Facade to your ngrx state"
|
"x-prompt": "Would you like to add a Facade to your ngrx state"
|
||||||
},
|
},
|
||||||
"onlyAddFiles": {
|
"onlyAddFiles": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Only add new NgRx files, without changing the module file (e.g., --onlyAddFiles)."
|
||||||
"Only add new NgRx files, without changing the module file (e.g., --onlyAddFiles)."
|
|
||||||
},
|
},
|
||||||
"onlyEmptyRoot": {
|
"onlyEmptyRoot": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Do not generate any files. Only generate StoreModule.forRoot and EffectsModule.forRoot (e.g., --onlyEmptyRoot)."
|
||||||
"Do not generate any files. Only generate StoreModule.forRoot and EffectsModule.forRoot (e.g., --onlyEmptyRoot)."
|
|
||||||
},
|
},
|
||||||
"skipFormat": {
|
"skipFormat": {
|
||||||
"description": "Skip formatting files",
|
"description": "Skip formatting files",
|
||||||
@ -61,8 +53,7 @@
|
|||||||
"skipPackageJson": {
|
"skipPackageJson": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Do not add NgRx dependencies to package.json (e.g., --skipPackageJson)"
|
||||||
"Do not add NgRx dependencies to package.json (e.g., --skipPackageJson)"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["module"]
|
"required": ["module"]
|
||||||
|
|||||||
@ -43,8 +43,7 @@
|
|||||||
"tags": {
|
"tags": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "Add tags to the application (used for linting)",
|
"description": "Add tags to the application (used for linting)",
|
||||||
"x-prompt":
|
"x-prompt": "Which tags would you like to add to the node application? (used for linting)"
|
||||||
"Which tags would you like to add to the node application? (used for linting)"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": []
|
"required": []
|
||||||
|
|||||||
@ -18,13 +18,11 @@
|
|||||||
},
|
},
|
||||||
"angularJsImport": {
|
"angularJsImport": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
||||||
"Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
|
||||||
},
|
},
|
||||||
"angularJsCmpSelector": {
|
"angularJsCmpSelector": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description":
|
"description": "The selector of an AngularJS component (e.g., --angularJsCmpSelector=myComponent)"
|
||||||
"The selector of an AngularJS component (e.g., --angularJsCmpSelector=myComponent)"
|
|
||||||
},
|
},
|
||||||
"skipFormat": {
|
"skipFormat": {
|
||||||
"description": "Skip formatting files",
|
"description": "Skip formatting files",
|
||||||
@ -34,8 +32,7 @@
|
|||||||
"skipPackageJson": {
|
"skipPackageJson": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description":
|
"description": "Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
||||||
"Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
|
||||||
},
|
},
|
||||||
"router": {
|
"router": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
|
|||||||
@ -19,15 +19,17 @@ describe('upgrade-module', () => {
|
|||||||
appTree = createApp(appTree, 'myapp');
|
appTree = createApp(appTree, 'myapp');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update the bootstrap logic', () => {
|
it('should update the bootstrap logic', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'upgrade-module',
|
'upgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||||
expect(appModule).toContain(
|
expect(appModule).toContain(
|
||||||
@ -41,7 +43,7 @@ describe('upgrade-module', () => {
|
|||||||
expect(tree.exists('/apps/myapp/src/hybrid.spec.ts')).toBeTruthy();
|
expect(tree.exists('/apps/myapp/src/hybrid.spec.ts')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should update package.json by default', () => {
|
it('should update package.json by default', async () => {
|
||||||
appTree.overwrite(
|
appTree.overwrite(
|
||||||
`/package.json`,
|
`/package.json`,
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@ -51,21 +53,23 @@ describe('upgrade-module', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'upgrade-module',
|
'upgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const packageJson = readJsonInTree(tree, '/package.json');
|
const packageJson = readJsonInTree(tree, '/package.json');
|
||||||
expect(packageJson.dependencies['@angular/upgrade']).toEqual('4.4.4');
|
expect(packageJson.dependencies['@angular/upgrade']).toEqual('4.4.4');
|
||||||
expect(packageJson.dependencies['angular']).toBeDefined();
|
expect(packageJson.dependencies['angular']).toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not package.json when --skipPackageJson=true', () => {
|
it('should not package.json when --skipPackageJson=true', async () => {
|
||||||
appTree.overwrite(
|
appTree.overwrite(
|
||||||
`/package.json`,
|
`/package.json`,
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
@ -75,7 +79,8 @@ describe('upgrade-module', () => {
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'upgrade-module',
|
'upgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
@ -83,14 +88,16 @@ describe('upgrade-module', () => {
|
|||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const packageJson = readJsonInTree(tree, '/package.json');
|
const packageJson = readJsonInTree(tree, '/package.json');
|
||||||
expect(packageJson.dependencies['@angular/upgrade']).not.toBeDefined();
|
expect(packageJson.dependencies['@angular/upgrade']).not.toBeDefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add router configuration when --router=true', () => {
|
it('should add router configuration when --router=true', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'upgrade-module',
|
'upgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
@ -98,14 +105,16 @@ describe('upgrade-module', () => {
|
|||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const legacySetup = getFileContent(tree, '/apps/myapp/src/legacy-setup.ts');
|
const legacySetup = getFileContent(tree, '/apps/myapp/src/legacy-setup.ts');
|
||||||
expect(legacySetup).toContain(`setUpLocationSync`);
|
expect(legacySetup).toContain(`setUpLocationSync`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should support custom angularJsImport', () => {
|
it('should support custom angularJsImport', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
|
.runSchematicAsync(
|
||||||
'upgrade-module',
|
'upgrade-module',
|
||||||
{
|
{
|
||||||
name: 'legacy',
|
name: 'legacy',
|
||||||
@ -113,7 +122,8 @@ describe('upgrade-module', () => {
|
|||||||
project: 'myapp'
|
project: 'myapp'
|
||||||
},
|
},
|
||||||
appTree
|
appTree
|
||||||
);
|
)
|
||||||
|
.toPromise();
|
||||||
|
|
||||||
const legacySetup = getFileContent(tree, '/apps/myapp/src/legacy-setup.ts');
|
const legacySetup = getFileContent(tree, '/apps/myapp/src/legacy-setup.ts');
|
||||||
expect(legacySetup).toContain(`import 'legacy-app';`);
|
expect(legacySetup).toContain(`import 'legacy-app';`);
|
||||||
|
|||||||
@ -16,12 +16,10 @@ describe('workspace-schematic', () => {
|
|||||||
appTree = createEmptyWorkspace(appTree);
|
appTree = createEmptyWorkspace(appTree);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate files', () => {
|
it('should generate files', async () => {
|
||||||
const tree = schematicRunner.runSchematic(
|
const tree = await schematicRunner
|
||||||
'workspace-schematic',
|
.runSchematicAsync('workspace-schematic', { name: 'custom' }, appTree)
|
||||||
{ name: 'custom' },
|
.toPromise();
|
||||||
appTree
|
|
||||||
);
|
|
||||||
expect(tree.exists('tools/schematics/custom/index.ts')).toBeTruthy();
|
expect(tree.exists('tools/schematics/custom/index.ts')).toBeTruthy();
|
||||||
expect(tree.exists('tools/schematics/custom/schema.json')).toBeTruthy();
|
expect(tree.exists('tools/schematics/custom/schema.json')).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|||||||
@ -91,12 +91,10 @@ function hasDependencyOnTouchedProjects(
|
|||||||
deps[project]
|
deps[project]
|
||||||
.map(d => d.projectName)
|
.map(d => d.projectName)
|
||||||
.filter(k =>
|
.filter(k =>
|
||||||
hasDependencyOnTouchedProjects(
|
hasDependencyOnTouchedProjects(k, touchedProjects, deps, [
|
||||||
k,
|
...visisted,
|
||||||
touchedProjects,
|
project
|
||||||
deps,
|
])
|
||||||
[...visisted, project]
|
|
||||||
)
|
|
||||||
).length > 0
|
).length > 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -208,7 +208,9 @@ function withDepGraphOptions(yargs: yargs.Argv): yargs.Argv {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function parseCSV(args: string[]) {
|
function parseCSV(args: string[]) {
|
||||||
return args.map(arg => arg.split(',')).reduce(
|
return args
|
||||||
|
.map(arg => arg.split(','))
|
||||||
|
.reduce(
|
||||||
(acc, value) => {
|
(acc, value) => {
|
||||||
return [...acc, ...value];
|
return [...acc, ...value];
|
||||||
},
|
},
|
||||||
|
|||||||
@ -267,7 +267,9 @@ export function getProjectNodes(angularJson, nxJson): ProjectNode[] {
|
|||||||
|
|
||||||
const projectType =
|
const projectType =
|
||||||
p.projectType === 'application'
|
p.projectType === 'application'
|
||||||
? key.endsWith('-e2e') ? ProjectType.e2e : ProjectType.app
|
? key.endsWith('-e2e')
|
||||||
|
? ProjectType.e2e
|
||||||
|
: ProjectType.app
|
||||||
: ProjectType.lib;
|
: ProjectType.lib;
|
||||||
|
|
||||||
let implicitDependencies = nxJson.projects[key].implicitDependencies || [];
|
let implicitDependencies = nxJson.projects[key].implicitDependencies || [];
|
||||||
|
|||||||
@ -224,8 +224,7 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker {
|
|||||||
if (done[sourceProjectName]) return false;
|
if (done[sourceProjectName]) return false;
|
||||||
if (!this.deps[sourceProjectName]) return false;
|
if (!this.deps[sourceProjectName]) return false;
|
||||||
return this.deps[sourceProjectName]
|
return this.deps[sourceProjectName]
|
||||||
.map(
|
.map(dep =>
|
||||||
dep =>
|
|
||||||
dep.projectName === targetProjectName
|
dep.projectName === targetProjectName
|
||||||
? true
|
? true
|
||||||
: this.isDependingOn(dep.projectName, targetProjectName, {
|
: this.isDependingOn(dep.projectName, targetProjectName, {
|
||||||
|
|||||||
@ -264,11 +264,13 @@ export function findClass(
|
|||||||
): ts.ClassDeclaration {
|
): ts.ClassDeclaration {
|
||||||
const nodes = getSourceNodes(source);
|
const nodes = getSourceNodes(source);
|
||||||
|
|
||||||
const clazz = <any>nodes.filter(
|
const clazz = <any>(
|
||||||
|
nodes.filter(
|
||||||
n =>
|
n =>
|
||||||
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
||||||
(<any>n).name.text === className
|
(<any>n).name.text === className
|
||||||
)[0];
|
)[0]
|
||||||
|
);
|
||||||
|
|
||||||
if (!clazz && !silent) {
|
if (!clazz && !silent) {
|
||||||
throw new Error(`Cannot find class '${className}'`);
|
throw new Error(`Cannot find class '${className}'`);
|
||||||
@ -315,9 +317,8 @@ export function addImportToTestBed(
|
|||||||
specPath: string,
|
specPath: string,
|
||||||
symbolName: string
|
symbolName: string
|
||||||
): Change[] {
|
): Change[] {
|
||||||
const allCalls: ts.CallExpression[] = <any>findNodes(
|
const allCalls: ts.CallExpression[] = <any>(
|
||||||
source,
|
findNodes(source, ts.SyntaxKind.CallExpression)
|
||||||
ts.SyntaxKind.CallExpression
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const configureTestingModuleObjectLiterals = allCalls
|
const configureTestingModuleObjectLiterals = allCalls
|
||||||
@ -325,8 +326,7 @@ export function addImportToTestBed(
|
|||||||
.filter(
|
.filter(
|
||||||
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
|
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
|
||||||
)
|
)
|
||||||
.map(
|
.map(c =>
|
||||||
c =>
|
|
||||||
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
||||||
? c.arguments[0]
|
? c.arguments[0]
|
||||||
: null
|
: null
|
||||||
|
|||||||
@ -24,9 +24,8 @@ export function toClassName(str: string): string {
|
|||||||
*/
|
*/
|
||||||
export function toPropertyName(s: string): string {
|
export function toPropertyName(s: string): string {
|
||||||
return s
|
return s
|
||||||
.replace(
|
.replace(/(-|_|\.|\s)+(.)?/g, (_, __, chr) =>
|
||||||
/(-|_|\.|\s)+(.)?/g,
|
chr ? chr.toUpperCase() : ''
|
||||||
(_, __, chr) => (chr ? chr.toUpperCase() : '')
|
|
||||||
)
|
)
|
||||||
.replace(/^([A-Z])/, m => m.toLowerCase());
|
.replace(/^([A-Z])/, m => m.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,9 @@ import { forEach, FileEntry, Rule } from '@angular-devkit/schematics';
|
|||||||
* Remove a file from the Virtual Schematic Tree
|
* Remove a file from the Virtual Schematic Tree
|
||||||
*/
|
*/
|
||||||
export function deleteFile(from: string): Rule {
|
export function deleteFile(from: string): Rule {
|
||||||
return forEach((entry: FileEntry): FileEntry | null => {
|
return forEach(
|
||||||
|
(entry: FileEntry): FileEntry | null => {
|
||||||
return entry.path === from ? null : entry;
|
return entry.path === from ? null : entry;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
||||||
import { Tree } from '@angular-devkit/schematics';
|
import { Tree } from '@angular-devkit/schematics';
|
||||||
|
|
||||||
|
import * as prettier from 'prettier';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
|
||||||
import { createEmptyWorkspace } from '../testing-utils';
|
import { createEmptyWorkspace } from '../testing-utils';
|
||||||
import { formatFiles } from './format-files';
|
import { formatFiles } from './format-files';
|
||||||
import { serializeJson } from '../fileutils';
|
import { serializeJson } from '../fileutils';
|
||||||
|
import * as appRoot from 'app-root-path';
|
||||||
|
|
||||||
describe('formatFiles', () => {
|
describe('formatFiles', () => {
|
||||||
let tree: Tree;
|
let tree: Tree;
|
||||||
@ -15,52 +17,89 @@ describe('formatFiles', () => {
|
|||||||
'@nrwl/schematics',
|
'@nrwl/schematics',
|
||||||
path.join(__dirname, '../../collection.json')
|
path.join(__dirname, '../../collection.json')
|
||||||
);
|
);
|
||||||
tree = createEmptyWorkspace(Tree.empty());
|
spyOn(prettier, 'format').and.callFake(input => 'formated :: ' + input);
|
||||||
tree.overwrite(
|
tree = Tree.empty();
|
||||||
'package.json',
|
});
|
||||||
serializeJson({
|
|
||||||
scripts: {
|
it('should format created files', async () => {
|
||||||
format: 'prettier'
|
spyOn(prettier, 'resolveConfig').and.returnValue(
|
||||||
}
|
Promise.resolve({
|
||||||
|
printWidth: 80
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
tree.create('a.ts', 'const a=a');
|
||||||
|
const result = await schematicRunner
|
||||||
|
.callRule(formatFiles(), tree)
|
||||||
|
.toPromise();
|
||||||
|
expect(prettier.format).toHaveBeenCalledWith('const a=a', {
|
||||||
|
printWidth: 80,
|
||||||
|
filepath: appRoot.resolve('a.ts')
|
||||||
|
});
|
||||||
|
expect(result.read('a.ts').toString()).toEqual('formated :: const a=a');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not format deleted files', async () => {
|
||||||
|
spyOn(prettier, 'resolveConfig').and.returnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
printWidth: 80
|
||||||
|
})
|
||||||
|
);
|
||||||
|
tree.create('b.ts', '');
|
||||||
|
tree.delete('b.ts');
|
||||||
|
await schematicRunner.callRule(formatFiles(), tree).toPromise();
|
||||||
|
expect(prettier.format).not.toHaveBeenCalledWith(
|
||||||
|
'const b=b',
|
||||||
|
jasmine.anything()
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should format files', done => {
|
it('should format overwritten files', async () => {
|
||||||
schematicRunner.callRule(formatFiles(), tree).subscribe(result => {
|
spyOn(prettier, 'resolveConfig').and.returnValue(Promise.resolve(null));
|
||||||
expect(schematicRunner.tasks.length).toBe(1);
|
tree.create('a.ts', 'const a=a');
|
||||||
expect(schematicRunner.tasks[0]).toEqual({
|
tree.overwrite('a.ts', 'const a=b');
|
||||||
name: 'node-package',
|
const result = await schematicRunner
|
||||||
options: {
|
.callRule(formatFiles(), tree)
|
||||||
packageName: 'run format -- --untracked',
|
.toPromise();
|
||||||
quiet: true
|
expect(prettier.format).toHaveBeenCalledWith('const a=b', {
|
||||||
}
|
filepath: appRoot.resolve('a.ts')
|
||||||
});
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
|
expect(result.read('a.ts').toString()).toEqual('formated :: const a=b');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not format files if there is no format npm script', done => {
|
it('should not format renamed files', async () => {
|
||||||
tree.overwrite(
|
spyOn(prettier, 'resolveConfig').and.returnValue(Promise.resolve(null));
|
||||||
'package.json',
|
tree.create('a.ts', 'const a=a');
|
||||||
serializeJson({
|
tree.rename('a.ts', 'b.ts');
|
||||||
scripts: {}
|
const result = await schematicRunner
|
||||||
|
.callRule(formatFiles(), tree)
|
||||||
|
.toPromise();
|
||||||
|
expect(prettier.format).toHaveBeenCalledWith('const a=a', {
|
||||||
|
filepath: appRoot.resolve('b.ts')
|
||||||
|
});
|
||||||
|
expect(result.read('b.ts').toString()).toEqual('formated :: const a=a');
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('--skip-format', () => {
|
||||||
|
it('should not format created files', async () => {
|
||||||
|
spyOn(prettier, 'resolveConfig').and.returnValue(
|
||||||
|
Promise.resolve({
|
||||||
|
printWidth: 80
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
schematicRunner.callRule(formatFiles(), tree).subscribe(result => {
|
tree.create('a.ts', 'const a=a');
|
||||||
expect(schematicRunner.tasks.length).toBe(0);
|
const result = await schematicRunner
|
||||||
//TODO: test that a warning is emitted.
|
.callRule(
|
||||||
done();
|
formatFiles({
|
||||||
|
skipFormat: true
|
||||||
|
}),
|
||||||
|
tree
|
||||||
|
)
|
||||||
|
.toPromise();
|
||||||
|
expect(prettier.format).not.toHaveBeenCalledWith('const a=a', {
|
||||||
|
printWidth: 80,
|
||||||
|
filepath: appRoot.resolve('a.ts')
|
||||||
});
|
});
|
||||||
});
|
expect(result.read('a.ts').toString()).toEqual('const a=a');
|
||||||
|
|
||||||
it('should not format files if skipFormat is passed', done => {
|
|
||||||
schematicRunner
|
|
||||||
.callRule(formatFiles({ skipFormat: true }), tree)
|
|
||||||
.subscribe(result => {
|
|
||||||
expect(schematicRunner.tasks.length).toBe(0);
|
|
||||||
//TODO: test that a warning is not emitted.
|
|
||||||
done();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,25 +1,15 @@
|
|||||||
import { readJsonInTree } from '../ast-utils';
|
|
||||||
import {
|
import {
|
||||||
TaskConfigurationGenerator,
|
|
||||||
TaskConfiguration,
|
|
||||||
Tree,
|
Tree,
|
||||||
SchematicContext,
|
SchematicContext,
|
||||||
Rule,
|
Rule,
|
||||||
noop
|
noop,
|
||||||
|
OverwriteFileAction,
|
||||||
|
CreateFileAction
|
||||||
} from '@angular-devkit/schematics';
|
} from '@angular-devkit/schematics';
|
||||||
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
import { format, resolveConfig, getFileInfo } from 'prettier';
|
||||||
|
import * as appRoot from 'app-root-path';
|
||||||
class FormatFiles implements TaskConfigurationGenerator<any> {
|
import { from } from 'rxjs';
|
||||||
toConfiguration(): TaskConfiguration<any> {
|
import { filter, map, mergeMap } from 'rxjs/operators';
|
||||||
return {
|
|
||||||
name: 'node-package',
|
|
||||||
options: {
|
|
||||||
packageName: 'run format -- --untracked', // workaround. we should define a custom task executor.
|
|
||||||
quiet: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function formatFiles(
|
export function formatFiles(
|
||||||
options: { skipFormat: boolean } = { skipFormat: false }
|
options: { skipFormat: boolean } = { skipFormat: false }
|
||||||
@ -28,15 +18,45 @@ export function formatFiles(
|
|||||||
return noop();
|
return noop();
|
||||||
}
|
}
|
||||||
return (host: Tree, context: SchematicContext) => {
|
return (host: Tree, context: SchematicContext) => {
|
||||||
const packageJson = readJsonInTree(host, 'package.json');
|
const files = new Set(
|
||||||
if (packageJson.scripts && packageJson.scripts.format) {
|
host.actions
|
||||||
context.addTask(new FormatFiles());
|
.filter(action => action.kind !== 'd' && action.kind !== 'r')
|
||||||
} else {
|
.map((action: OverwriteFileAction | CreateFileAction) => ({
|
||||||
context.logger.warn(stripIndents`
|
path: action.path,
|
||||||
Files were not formated during this code generation.
|
content: action.content.toString()
|
||||||
The "format" npm script is missing in your package.json.
|
}))
|
||||||
Please either add a format script or pass --skip-format.
|
);
|
||||||
`);
|
if (files.size === 0) {
|
||||||
|
return host;
|
||||||
}
|
}
|
||||||
|
return from(files).pipe(
|
||||||
|
filter(file => host.exists(file.path)),
|
||||||
|
mergeMap(async file => {
|
||||||
|
const systemPath = appRoot.resolve(file.path);
|
||||||
|
let options: any = {
|
||||||
|
filepath: systemPath
|
||||||
|
};
|
||||||
|
const resolvedOptions = await resolveConfig(systemPath);
|
||||||
|
if (resolvedOptions) {
|
||||||
|
options = {
|
||||||
|
...options,
|
||||||
|
...resolvedOptions
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const support = await getFileInfo(systemPath, options);
|
||||||
|
if (support.ignored || !support.inferredParser) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
host.overwrite(file.path, format(file.content, options));
|
||||||
|
} catch (e) {
|
||||||
|
context.logger.warn(
|
||||||
|
`Could not format ${file.path} because ${e.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
map(() => host)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9151,10 +9151,10 @@ preserve@^0.2.0:
|
|||||||
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b"
|
||||||
integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
|
integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
|
||||||
|
|
||||||
prettier@1.10.2:
|
prettier@1.15.3:
|
||||||
version "1.10.2"
|
version "1.15.3"
|
||||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93"
|
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a"
|
||||||
integrity sha512-TcdNoQIWFoHblurqqU6d1ysopjq7UX0oRcT/hJ8qvBAELiYWn+Ugf0AXdnzISEJ7vuhNnQ98N8jR8Sh53x4IZg==
|
integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==
|
||||||
|
|
||||||
pretty-format@^23.6.0:
|
pretty-format@^23.6.0:
|
||||||
version "23.6.0"
|
version "23.6.0"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user