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.
|
||||
**YOU MAY DELETE THE PREREQUISITES SECTION.**
|
||||
|
||||
* [ ] I am running the latest version
|
||||
* [ ] I checked the documentation and found no answer
|
||||
* [ ] 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 am running the latest version
|
||||
- [ ] I checked the documentation and found no answer
|
||||
- [ ] 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)
|
||||
|
||||
## Expected Behavior
|
||||
|
||||
@ -34,12 +34,12 @@ Please provide detailed steps for reproducing the issue.
|
||||
|
||||
Please provide any relevant information about your setup:
|
||||
|
||||
* version of Nx used
|
||||
* version of Angular CLI used
|
||||
* `angular.json` configuration
|
||||
* version of Angular DevKit used
|
||||
* 3rd-party libraries and their versions
|
||||
* and most importantly - a use-case that fails
|
||||
- version of Nx used
|
||||
- version of Angular CLI used
|
||||
- `angular.json` configuration
|
||||
- version of Angular DevKit used
|
||||
- 3rd-party libraries and their versions
|
||||
- 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.**
|
||||
|
||||
|
||||
202
CHANGELOG.md
202
CHANGELOG.md
@ -6,58 +6,58 @@
|
||||
|
||||
## 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
|
||||
|
||||
## Fixes
|
||||
|
||||
* **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:** 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:** ignore errors when the tools directory already exists ([2a377fe](https://github.com/nrwl/nx/commit/2a377fe))
|
||||
- **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:** 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:** ignore errors when the tools directory already exists ([2a377fe](https://github.com/nrwl/nx/commit/2a377fe))
|
||||
|
||||
# 0.11.0
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
|
||||
* [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
|
||||
|
||||
## Features
|
||||
|
||||
* [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)
|
||||
* [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)
|
||||
* [Affected support for uncommitted changes](https://github.com/nrwl/nx/commit/113b51bd330c2af058675386e482d38f170a6688)
|
||||
* [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 ability to create bazel workspace](https://github.com/nrwl/nx/commit/5a26f241b1e8b8b87e2ab4da941d3d3c4c480046)
|
||||
- [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)
|
||||
- [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)
|
||||
- [Affected support for uncommitted changes](https://github.com/nrwl/nx/commit/113b51bd330c2af058675386e482d38f170a6688)
|
||||
- [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 ability to create bazel workspace](https://github.com/nrwl/nx/commit/5a26f241b1e8b8b87e2ab4da941d3d3c4c480046)
|
||||
|
||||
## Fixes
|
||||
|
||||
* [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)
|
||||
* [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)
|
||||
* [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)
|
||||
* [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)
|
||||
* [Match ng lib and update versions ](https://github.com/nrwl/nx/commit/8482177b7373844d833aaad55e15a2a10d4ae116)
|
||||
- [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)
|
||||
- [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)
|
||||
- [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)
|
||||
- [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)
|
||||
- [Match ng lib and update versions ](https://github.com/nrwl/nx/commit/8482177b7373844d833aaad55e15a2a10d4ae116)
|
||||
|
||||
# 0.9.0
|
||||
|
||||
@ -92,10 +92,10 @@ You can then define constraints in `tslint.json`, like this:
|
||||
|
||||
With this configuration in place:
|
||||
|
||||
* `utilslib` can depend on no libs.
|
||||
* `apilib` can depend on `utilslib`
|
||||
* `implib` can depend on both `utilslib` and `apilib`.
|
||||
* `untaggedlib` can depend on no libs.
|
||||
- `utilslib` can depend on no libs.
|
||||
- `apilib` can depend on `utilslib`
|
||||
- `implib` can depend on both `utilslib` and `apilib`.
|
||||
- `untaggedlib` can depend on no libs.
|
||||
|
||||
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.
|
||||
|
||||
* `utilslib` can depend on no libs.
|
||||
* `apilib` can depend on `utilslib`
|
||||
* `implib` can depend on both `utilslib` and `apilib`.
|
||||
* `untaggedlib` can depend on **all** libs.
|
||||
- `utilslib` can depend on no libs.
|
||||
- `apilib` can depend on `utilslib`
|
||||
- `implib` can depend on both `utilslib` and `apilib`.
|
||||
- `untaggedlib` can depend on **all** libs.
|
||||
|
||||
## Features
|
||||
|
||||
* [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 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)
|
||||
* [Allow users to set prettier config](https://github.com/nrwl/nx/commit/56a6611575fee7b111655d2223f3e30ea684d000)
|
||||
* [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)
|
||||
- [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 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)
|
||||
- [Allow users to set prettier config](https://github.com/nrwl/nx/commit/56a6611575fee7b111655d2223f3e30ea684d000)
|
||||
- [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)
|
||||
|
||||
## Fixes
|
||||
|
||||
* [Improve windows compatibility](https://github.com/nrwl/nx/commit/4f052bb3e60f20d0d676f283de2e2faece0dcef8)
|
||||
* [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 protractor.conf.js schema](https://github.com/nrwl/nx/commit/37cabafb35980ce8e991abc1269387b3aaaf9f25)
|
||||
- [Improve windows compatibility](https://github.com/nrwl/nx/commit/4f052bb3e60f20d0d676f283de2e2faece0dcef8)
|
||||
- [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 protractor.conf.js schema](https://github.com/nrwl/nx/commit/37cabafb35980ce8e991abc1269387b3aaaf9f25)
|
||||
|
||||
# 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.
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## Fixes
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## Cleanup
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
# 0.7.4
|
||||
|
||||
## 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
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
# 0.7.2
|
||||
|
||||
## Features
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
|
||||
## 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
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## Cleanup
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
# 0.6.13
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
# 0.6.10
|
||||
|
||||
## 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
|
||||
|
||||
* [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)
|
||||
* [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)
|
||||
* [Disallow importing apps](https://github.com/nrwl/nx/commit/912fc81708d381f49950255eeff746a2dfd46c7b)
|
||||
- [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)
|
||||
- [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)
|
||||
- [Disallow importing apps](https://github.com/nrwl/nx/commit/912fc81708d381f49950255eeff746a2dfd46c7b)
|
||||
|
||||
# 0.6.5
|
||||
|
||||
@ -269,11 +269,11 @@ npm run format:write
|
||||
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
|
||||
|
||||
* [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
|
||||
|
||||
@ -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"
|
||||
```
|
||||
|
||||
* [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
|
||||
|
||||
* [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
|
||||
|
||||
@ -330,53 +330,53 @@ Some folks also reported having problems running Nx behind a firewall, in a corp
|
||||
|
||||
## Features
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## 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
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* [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)
|
||||
* [Change rxjs version to use hat](https://github.com/nrwl/nx/commit/3b1942ed830ea31269a1fb9e995efb93b182870a)
|
||||
- [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)
|
||||
- [Change rxjs version to use hat](https://github.com/nrwl/nx/commit/3b1942ed830ea31269a1fb9e995efb93b182870a)
|
||||
|
||||
# 0.5.1
|
||||
|
||||
## 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
|
||||
|
||||
* ["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)
|
||||
- ["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)
|
||||
|
||||
# 0.5.0
|
||||
|
||||
## 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
|
||||
|
||||
## Features
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## 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
|
||||
|
||||
@ -384,33 +384,33 @@ We want to be able to add new features to Nx without breaking existing workspace
|
||||
|
||||
## Features
|
||||
|
||||
* [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)
|
||||
* [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)
|
||||
- [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)
|
||||
- [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)
|
||||
|
||||
# 0.2.2
|
||||
|
||||
## 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)
|
||||
* [Fix issue with generating a wrong full path on windows](https://github.com/nrwl/nx/commit/11e6c055ba1211a5bee1cc73d46663985645f08e)
|
||||
- [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)
|
||||
|
||||
# 0.2.1
|
||||
|
||||
## New Features
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## Bug Fixes
|
||||
|
||||
* [--routing should add RouterTestingModule](https://github.com/nrwl/nx/commit/d7fc5b56054c9a4c1fbb12845bfc0803f9a9ff86)
|
||||
* [Fix wording in the documentation](https://github.com/nrwl/nx/commit/058c8995f35a9e677f88404bc9c8a2b177487080)
|
||||
- [--routing should add RouterTestingModule](https://github.com/nrwl/nx/commit/d7fc5b56054c9a4c1fbb12845bfc0803f9a9ff86)
|
||||
- [Fix wording in the documentation](https://github.com/nrwl/nx/commit/058c8995f35a9e677f88404bc9c8a2b177487080)
|
||||
|
||||
## 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
|
||||
|
||||
|
||||
@ -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:
|
||||
|
||||
* version of Nx used
|
||||
* version of Angular CLI used
|
||||
* `angular.json` configuration
|
||||
* version of Angular DevKit used
|
||||
* 3rd-party libraries and their versions
|
||||
* and most importantly - a use-case that fails
|
||||
- version of Nx used
|
||||
- version of Angular CLI used
|
||||
- `angular.json` configuration
|
||||
- version of Angular DevKit used
|
||||
- 3rd-party libraries and their versions
|
||||
- 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.
|
||||
|
||||
@ -73,10 +73,10 @@ You can file new issues by filling out our [issue form](https://github.com/nrwl/
|
||||
|
||||
Please follow the following guidelines:
|
||||
|
||||
* Make sure unit tests pass
|
||||
* Make sure e2e tests pass
|
||||
* Make sure you run `yarn format`
|
||||
* Update your commit message to follow the guidelines below
|
||||
- Make sure unit tests pass
|
||||
- Make sure e2e tests pass
|
||||
- Make sure you run `yarn format`
|
||||
- Update your commit message to follow the guidelines below
|
||||
|
||||
#### Commit Message Guidelines
|
||||
|
||||
@ -92,21 +92,21 @@ body
|
||||
|
||||
The type must be one of the following:
|
||||
|
||||
* build
|
||||
* feat
|
||||
* fix
|
||||
* refactor
|
||||
* style
|
||||
* docs
|
||||
* test
|
||||
- build
|
||||
- feat
|
||||
- fix
|
||||
- refactor
|
||||
- style
|
||||
- docs
|
||||
- test
|
||||
|
||||
##### Scope
|
||||
|
||||
The scope must be one of the following:
|
||||
|
||||
* bazel
|
||||
* nx
|
||||
* schematics
|
||||
- bazel
|
||||
- nx
|
||||
- schematics
|
||||
|
||||
##### 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:
|
||||
|
||||
* Nx Workspace
|
||||
* Workspace-Specific Schematics
|
||||
* Intelligent Builds and Unit Testing
|
||||
* State Management
|
||||
* NgRx
|
||||
* Data Persistence
|
||||
* Linters
|
||||
* Code Formatter
|
||||
* UpgradeModule and downgradeModule helpers
|
||||
* Jest unit tests integration
|
||||
* Node build tooling
|
||||
- Nx Workspace
|
||||
- Workspace-Specific Schematics
|
||||
- Intelligent Builds and Unit Testing
|
||||
- State Management
|
||||
- NgRx
|
||||
- Data Persistence
|
||||
- Linters
|
||||
- Code Formatter
|
||||
- UpgradeModule and downgradeModule helpers
|
||||
- Jest unit tests integration
|
||||
- Node build tooling
|
||||
|
||||
# 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.
|
||||
|
||||
* 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.** …
|
||||
- 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.** …
|
||||
|
||||
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
|
||||
|
||||
* [Nx Documentation and Guides](https://nrwl.io/nx)
|
||||
* [Nx blog posts](https://blog.nrwl.io/nx/home)
|
||||
- [Nx Documentation and Guides](https://nrwl.io/nx)
|
||||
- [Nx blog posts](https://blog.nrwl.io/nx/home)
|
||||
|
||||
### Videos
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
### Talks
|
||||
|
||||
* [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)
|
||||
* [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)
|
||||
- [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)
|
||||
- [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)
|
||||
|
||||
### Podcasts and Shows
|
||||
|
||||
* [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)
|
||||
- [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)
|
||||
|
||||
## 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.
|
||||
* [xplat - Cross-platform tools for Nx workspaces](https://nstudio.io/xplat/)
|
||||
- [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/)
|
||||
|
||||
## Want to help?
|
||||
|
||||
|
||||
@ -10,20 +10,18 @@ import {
|
||||
} from '../utils';
|
||||
|
||||
describe('Affected', () => {
|
||||
it(
|
||||
'should print, build, and test affected apps',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('mylib2');
|
||||
newLib('mypublishablelib --publishable');
|
||||
copyMissingPackages();
|
||||
it('should print, build, and test affected apps', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('mylib2');
|
||||
newLib('mypublishablelib --publishable');
|
||||
copyMissingPackages();
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
`
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
`
|
||||
import '@proj/mylib';
|
||||
describe('sample test', () => {
|
||||
it('should test', () => {
|
||||
@ -31,10 +29,10 @@ describe('Affected', () => {
|
||||
});
|
||||
});
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
'libs/mypublishablelib/src/lib/mypublishablelib.module.spec.ts',
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
'libs/mypublishablelib/src/lib/mypublishablelib.module.spec.ts',
|
||||
`
|
||||
import '@proj/mylib';
|
||||
describe('sample test', () => {
|
||||
it('should test', () => {
|
||||
@ -42,208 +40,200 @@ describe('Affected', () => {
|
||||
});
|
||||
});
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
const affectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(affectedApps).toContain('myapp');
|
||||
expect(affectedApps).not.toContain('myapp2');
|
||||
expect(affectedApps).not.toContain('myapp-e2e');
|
||||
const affectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(affectedApps).toContain('myapp');
|
||||
expect(affectedApps).not.toContain('myapp2');
|
||||
expect(affectedApps).not.toContain('myapp-e2e');
|
||||
|
||||
const implicitlyAffectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="package.json"'
|
||||
);
|
||||
expect(implicitlyAffectedApps).toContain('myapp');
|
||||
expect(implicitlyAffectedApps).toContain('myapp2');
|
||||
const implicitlyAffectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="package.json"'
|
||||
);
|
||||
expect(implicitlyAffectedApps).toContain('myapp');
|
||||
expect(implicitlyAffectedApps).toContain('myapp2');
|
||||
|
||||
const noAffectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="README.md"'
|
||||
);
|
||||
expect(noAffectedApps).not.toContain('myapp');
|
||||
expect(noAffectedApps).not.toContain('myapp2');
|
||||
const noAffectedApps = runCommand(
|
||||
'npm run affected:apps -- --files="README.md"'
|
||||
);
|
||||
expect(noAffectedApps).not.toContain('myapp');
|
||||
expect(noAffectedApps).not.toContain('myapp2');
|
||||
|
||||
const affectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(affectedLibs).toContain('mypublishablelib');
|
||||
expect(affectedLibs).toContain('mylib');
|
||||
expect(affectedLibs).not.toContain('mylib2');
|
||||
const affectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(affectedLibs).toContain('mypublishablelib');
|
||||
expect(affectedLibs).toContain('mylib');
|
||||
expect(affectedLibs).not.toContain('mylib2');
|
||||
|
||||
const implicitlyAffectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="package.json"'
|
||||
);
|
||||
expect(implicitlyAffectedLibs).toContain('mypublishablelib');
|
||||
expect(implicitlyAffectedLibs).toContain('mylib');
|
||||
expect(implicitlyAffectedLibs).toContain('mylib2');
|
||||
const implicitlyAffectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="package.json"'
|
||||
);
|
||||
expect(implicitlyAffectedLibs).toContain('mypublishablelib');
|
||||
expect(implicitlyAffectedLibs).toContain('mylib');
|
||||
expect(implicitlyAffectedLibs).toContain('mylib2');
|
||||
|
||||
const noAffectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="README.md"'
|
||||
);
|
||||
expect(noAffectedLibs).not.toContain('mypublishablelib');
|
||||
expect(noAffectedLibs).not.toContain('mylib');
|
||||
expect(noAffectedLibs).not.toContain('mylib2');
|
||||
const noAffectedLibs = runCommand(
|
||||
'npm run affected:libs -- --files="README.md"'
|
||||
);
|
||||
expect(noAffectedLibs).not.toContain('mypublishablelib');
|
||||
expect(noAffectedLibs).not.toContain('mylib');
|
||||
expect(noAffectedLibs).not.toContain('mylib2');
|
||||
|
||||
const build = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(build).toContain('Running build for mypublishablelib');
|
||||
expect(build).toContain('Running build for myapp');
|
||||
expect(build).not.toContain('is not registered with the build command');
|
||||
expect(build).not.toContain('with flags:');
|
||||
const build = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(build).toContain('Running build for mypublishablelib');
|
||||
expect(build).toContain('Running build for myapp');
|
||||
expect(build).not.toContain('is not registered with the build command');
|
||||
expect(build).not.toContain('with flags:');
|
||||
|
||||
// Should work in parallel
|
||||
const buildParallel = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --parallel'
|
||||
);
|
||||
expect(buildParallel).toContain(
|
||||
'Running build for projects:\n myapp,\n mypublishablelib'
|
||||
);
|
||||
expect(buildParallel).toContain(
|
||||
'Running build for affected projects succeeded.'
|
||||
);
|
||||
// Should work in parallel
|
||||
const buildParallel = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --parallel'
|
||||
);
|
||||
expect(buildParallel).toContain(
|
||||
'Running build for projects:\n myapp,\n mypublishablelib'
|
||||
);
|
||||
expect(buildParallel).toContain(
|
||||
'Running build for affected projects succeeded.'
|
||||
);
|
||||
|
||||
const buildExcluded = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --exclude myapp'
|
||||
);
|
||||
expect(buildExcluded).toContain('Running build for mypublishablelib');
|
||||
const buildExcluded = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --exclude myapp'
|
||||
);
|
||||
expect(buildExcluded).toContain('Running build for mypublishablelib');
|
||||
|
||||
const buildExcludedCsv = runCommand(
|
||||
'npm run affected:build -- --files="package.json" --exclude myapp,myapp2,mypublishablelib'
|
||||
);
|
||||
expect(buildExcludedCsv).toContain('No projects to run build');
|
||||
const buildExcludedCsv = runCommand(
|
||||
'npm run affected:build -- --files="package.json" --exclude myapp,myapp2,mypublishablelib'
|
||||
);
|
||||
expect(buildExcludedCsv).toContain('No projects to run build');
|
||||
|
||||
// affected:build should pass non-nx flags to the CLI
|
||||
const buildWithFlags = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --stats-json'
|
||||
);
|
||||
expect(buildWithFlags).toContain('Running build for mypublishablelib');
|
||||
expect(buildWithFlags).toContain('Running build for myapp');
|
||||
expect(buildWithFlags).toContain('With flags: --stats-json=true');
|
||||
// affected:build should pass non-nx flags to the CLI
|
||||
const buildWithFlags = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --stats-json'
|
||||
);
|
||||
expect(buildWithFlags).toContain('Running build for mypublishablelib');
|
||||
expect(buildWithFlags).toContain('Running build for myapp');
|
||||
expect(buildWithFlags).toContain('With flags: --stats-json=true');
|
||||
|
||||
const e2e = runCommand(
|
||||
'npm run affected:e2e -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(e2e).toContain('should display welcome message');
|
||||
const e2e = runCommand(
|
||||
'npm run affected:e2e -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(e2e).toContain('should display welcome message');
|
||||
|
||||
const unitTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(unitTests).toContain('Running test for mylib');
|
||||
expect(unitTests).toContain('Running test for mypublishablelib');
|
||||
expect(unitTests).toContain('Running test for myapp');
|
||||
const unitTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(unitTests).toContain('Running test for mylib');
|
||||
expect(unitTests).toContain('Running test for mypublishablelib');
|
||||
expect(unitTests).toContain('Running test for myapp');
|
||||
|
||||
// Fail a Unit Test
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
readFile('apps/myapp/src/app/app.component.spec.ts').replace(
|
||||
'.toEqual(1)',
|
||||
'.toEqual(2)'
|
||||
)
|
||||
);
|
||||
// Fail a Unit Test
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
readFile('apps/myapp/src/app/app.component.spec.ts').replace(
|
||||
'.toEqual(1)',
|
||||
'.toEqual(2)'
|
||||
)
|
||||
);
|
||||
|
||||
const failedTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
const failedTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
|
||||
expect(failedTests).toContain('Running test for mylib');
|
||||
expect(failedTests).toContain('Running test for mypublishablelib');
|
||||
expect(failedTests).toContain('Running test for myapp');
|
||||
expect(failedTests).toContain('Failed projects: myapp');
|
||||
expect(failedTests).toContain(
|
||||
'You can isolate the above projects by passing --only-failed'
|
||||
);
|
||||
expect(readJson('dist/.nx-results')).toEqual({
|
||||
command: 'test',
|
||||
results: {
|
||||
myapp: false,
|
||||
mylib: true,
|
||||
mypublishablelib: true
|
||||
}
|
||||
});
|
||||
expect(failedTests).toContain('Running test for mylib');
|
||||
expect(failedTests).toContain('Running test for mypublishablelib');
|
||||
expect(failedTests).toContain('Running test for myapp');
|
||||
expect(failedTests).toContain('Failed projects: myapp');
|
||||
expect(failedTests).toContain(
|
||||
'You can isolate the above projects by passing --only-failed'
|
||||
);
|
||||
expect(readJson('dist/.nx-results')).toEqual({
|
||||
command: 'test',
|
||||
results: {
|
||||
myapp: false,
|
||||
mylib: true,
|
||||
mypublishablelib: true
|
||||
}
|
||||
});
|
||||
|
||||
// Fix failing Unit Test
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
readFile('apps/myapp/src/app/app.component.spec.ts').replace(
|
||||
'.toEqual(2)',
|
||||
'.toEqual(1)'
|
||||
)
|
||||
);
|
||||
// Fix failing Unit Test
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.spec.ts',
|
||||
readFile('apps/myapp/src/app/app.component.spec.ts').replace(
|
||||
'.toEqual(2)',
|
||||
'.toEqual(1)'
|
||||
)
|
||||
);
|
||||
|
||||
const isolatedTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts" --only-failed'
|
||||
);
|
||||
expect(isolatedTests).toContain('Running test for myapp');
|
||||
const isolatedTests = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts" --only-failed'
|
||||
);
|
||||
expect(isolatedTests).toContain('Running test for myapp');
|
||||
|
||||
const linting = runCommand(
|
||||
'npm run affected:lint -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(linting).toContain('Running lint for mylib');
|
||||
expect(linting).toContain('Running lint for myapp');
|
||||
expect(linting).toContain('Running lint for myapp-e2e');
|
||||
expect(linting).toContain('Running lint for mypublishablelib');
|
||||
const linting = runCommand(
|
||||
'npm run affected:lint -- --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(linting).toContain('Running lint for mylib');
|
||||
expect(linting).toContain('Running lint for myapp');
|
||||
expect(linting).toContain('Running lint for myapp-e2e');
|
||||
expect(linting).toContain('Running lint for mypublishablelib');
|
||||
|
||||
const lintWithJsonFormating = runCommand(
|
||||
'npm run affected:lint -- --files="libs/mylib/src/index.ts" -- --format json'
|
||||
);
|
||||
expect(lintWithJsonFormating).toContain('With flags: --format json');
|
||||
const lintWithJsonFormating = runCommand(
|
||||
'npm run affected:lint -- --files="libs/mylib/src/index.ts" -- --format json'
|
||||
);
|
||||
expect(lintWithJsonFormating).toContain('With flags: --format json');
|
||||
|
||||
const unitTestsExcluded = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts" --exclude=myapp,mypublishablelib'
|
||||
);
|
||||
expect(unitTestsExcluded).toContain('Running test for mylib');
|
||||
const unitTestsExcluded = runCommand(
|
||||
'npm run affected:test -- --files="libs/mylib/src/index.ts" --exclude=myapp,mypublishablelib'
|
||||
);
|
||||
expect(unitTestsExcluded).toContain('Running test for mylib');
|
||||
|
||||
const i18n = runCommand(
|
||||
'npm run affected -- --target extract-i18n --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
const i18n = runCommand(
|
||||
'npm run affected -- --target extract-i18n --files="libs/mylib/src/index.ts"'
|
||||
);
|
||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||
}, 1000000);
|
||||
|
||||
it(
|
||||
'should print, build, and test all apps',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('mypublishablelib --publishable');
|
||||
copyMissingPackages();
|
||||
it('should print, build, and test all apps', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('mypublishablelib --publishable');
|
||||
copyMissingPackages();
|
||||
|
||||
const affectedApps = runCommand('npm run affected:apps -- --all');
|
||||
expect(affectedApps).toContain('myapp');
|
||||
expect(affectedApps).toContain('myapp2');
|
||||
expect(affectedApps).not.toContain('myapp-e2e');
|
||||
const affectedApps = runCommand('npm run affected:apps -- --all');
|
||||
expect(affectedApps).toContain('myapp');
|
||||
expect(affectedApps).toContain('myapp2');
|
||||
expect(affectedApps).not.toContain('myapp-e2e');
|
||||
|
||||
const build = runCommand('npm run affected:build -- --all');
|
||||
expect(build).toContain('Running build for myapp');
|
||||
expect(build).toContain('Running build for myapp2');
|
||||
expect(build).toContain('Running build for mypublishablelib');
|
||||
expect(build).not.toContain('is not registered with the build command');
|
||||
const build = runCommand('npm run affected:build -- --all');
|
||||
expect(build).toContain('Running build for myapp');
|
||||
expect(build).toContain('Running build for myapp2');
|
||||
expect(build).toContain('Running build for mypublishablelib');
|
||||
expect(build).not.toContain('is not registered with the build command');
|
||||
|
||||
const buildExcluded = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --exclude myapp,myapp2,mypublishablelib'
|
||||
);
|
||||
expect(buildExcluded).toContain('No projects to run build');
|
||||
const buildExcluded = runCommand(
|
||||
'npm run affected:build -- --files="libs/mylib/src/index.ts" --exclude myapp,myapp2,mypublishablelib'
|
||||
);
|
||||
expect(buildExcluded).toContain('No projects to run build');
|
||||
|
||||
const e2e = runCommand('npm run affected:e2e -- --all');
|
||||
expect(e2e).toContain('Running e2e for myapp-e2e');
|
||||
expect(e2e).toContain('Running e2e for myapp2-e2e');
|
||||
const e2e = runCommand('npm run affected:e2e -- --all');
|
||||
expect(e2e).toContain('Running e2e for myapp-e2e');
|
||||
expect(e2e).toContain('Running e2e for myapp2-e2e');
|
||||
|
||||
const unitTests = runCommand('npm run affected:test -- --all');
|
||||
expect(unitTests).toContain('Running test for mypublishablelib');
|
||||
expect(unitTests).toContain('Running test for myapp2');
|
||||
expect(unitTests).toContain('Running test for myapp');
|
||||
expect(unitTests).toContain('Running test for mylib');
|
||||
const unitTests = runCommand('npm run affected:test -- --all');
|
||||
expect(unitTests).toContain('Running test for mypublishablelib');
|
||||
expect(unitTests).toContain('Running test for myapp2');
|
||||
expect(unitTests).toContain('Running test for myapp');
|
||||
expect(unitTests).toContain('Running test for mylib');
|
||||
|
||||
const i18n = runCommand(
|
||||
'npm run affected -- --target extract-i18n --all'
|
||||
);
|
||||
expect(i18n).toContain('Running extract-i18n for myapp2');
|
||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
const i18n = runCommand('npm run affected -- --target extract-i18n --all');
|
||||
expect(i18n).toContain('Running extract-i18n for myapp2');
|
||||
expect(i18n).toContain('Running extract-i18n for myapp');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -1,17 +1,13 @@
|
||||
import { checkFilesExist, newApp, newBazelProject, newLib } from '../utils';
|
||||
|
||||
xdescribe('Nrwl Workspace (Bazel)', () => {
|
||||
it(
|
||||
'should work',
|
||||
() => {
|
||||
newBazelProject();
|
||||
newApp('myApp --directory=myDir');
|
||||
newLib('myLib --directory=myDir');
|
||||
it('should work', () => {
|
||||
newBazelProject();
|
||||
newApp('myApp --directory=myDir');
|
||||
newLib('myLib --directory=myDir');
|
||||
|
||||
checkFilesExist('WORKSPACE', 'BUILD.bazel');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
checkFilesExist('WORKSPACE', 'BUILD.bazel');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
// afterEach(() => {
|
||||
|
||||
@ -12,27 +12,25 @@ import {
|
||||
} from '../utils';
|
||||
|
||||
describe('Command line', () => {
|
||||
it(
|
||||
'lint should ensure module boundaries',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myapp --tags=validtag');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('lazylib');
|
||||
newLib('invalidtaglib --tags=invalidtag');
|
||||
newLib('validtaglib --tags=validtag');
|
||||
it('lint should ensure module boundaries', () => {
|
||||
newProject();
|
||||
newApp('myapp --tags=validtag');
|
||||
newApp('myapp2');
|
||||
newLib('mylib');
|
||||
newLib('lazylib');
|
||||
newLib('invalidtaglib --tags=invalidtag');
|
||||
newLib('validtaglib --tags=validtag');
|
||||
|
||||
const tslint = readJson('tslint.json');
|
||||
tslint.rules['nx-enforce-module-boundaries'][1].depConstraints = [
|
||||
{ sourceTag: 'validtag', onlyDependOnLibsWithTags: ['validtag'] },
|
||||
...tslint.rules['nx-enforce-module-boundaries'][1].depConstraints
|
||||
];
|
||||
updateFile('tslint.json', JSON.stringify(tslint, null, 2));
|
||||
const tslint = readJson('tslint.json');
|
||||
tslint.rules['nx-enforce-module-boundaries'][1].depConstraints = [
|
||||
{ sourceTag: 'validtag', onlyDependOnLibsWithTags: ['validtag'] },
|
||||
...tslint.rules['nx-enforce-module-boundaries'][1].depConstraints
|
||||
];
|
||||
updateFile('tslint.json', JSON.stringify(tslint, null, 2));
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/main.ts',
|
||||
`
|
||||
updateFile(
|
||||
'apps/myapp/src/main.ts',
|
||||
`
|
||||
import '../../../libs/mylib';
|
||||
import '@proj/lazylib';
|
||||
import '@proj/mylib/deep';
|
||||
@ -42,19 +40,17 @@ describe('Command line', () => {
|
||||
|
||||
const s = {loadChildren: '@proj/lazylib'};
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
const out = runCLI('lint', { silenceError: true });
|
||||
expect(out).toContain('library imports must start with @proj/');
|
||||
expect(out).toContain('imports of lazy-loaded libraries are forbidden');
|
||||
expect(out).toContain('deep imports into libraries are forbidden');
|
||||
expect(out).toContain('imports of apps are forbidden');
|
||||
expect(out).toContain(
|
||||
'A project tagged with "validtag" can only depend on libs tagged with "validtag"'
|
||||
);
|
||||
},
|
||||
1000000
|
||||
);
|
||||
const out = runCLI('lint', { silenceError: true });
|
||||
expect(out).toContain('library imports must start with @proj/');
|
||||
expect(out).toContain('imports of lazy-loaded libraries are forbidden');
|
||||
expect(out).toContain('deep imports into libraries are forbidden');
|
||||
expect(out).toContain('imports of apps are forbidden');
|
||||
expect(out).toContain(
|
||||
'A project tagged with "validtag" can only depend on libs tagged with "validtag"'
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it('should run nx lint', () => {
|
||||
newProject();
|
||||
@ -81,121 +77,113 @@ describe('Command line', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
'format should check and reformat the code',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newLib('mylib');
|
||||
updateFile(
|
||||
'apps/myapp/src/main.ts',
|
||||
`
|
||||
it('format should check and reformat the code', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
newLib('mylib');
|
||||
updateFile(
|
||||
'apps/myapp/src/main.ts',
|
||||
`
|
||||
const x = 1111;
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.module.ts',
|
||||
`
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.module.ts',
|
||||
`
|
||||
const y = 1111;
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.ts',
|
||||
`
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.ts',
|
||||
`
|
||||
const z = 1111;
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'libs/mylib/index.ts',
|
||||
`
|
||||
updateFile(
|
||||
'libs/mylib/index.ts',
|
||||
`
|
||||
const x = 1111;
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
'libs/mylib/src/mylib.module.ts',
|
||||
`
|
||||
);
|
||||
updateFile(
|
||||
'libs/mylib/src/mylib.module.ts',
|
||||
`
|
||||
const y = 1111;
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
let stdout = runCommand(
|
||||
'npm run -s format:check -- --files="libs/mylib/index.ts" --libs-and-apps'
|
||||
);
|
||||
expect(stdout).toContain('libs/mylib/index.ts');
|
||||
expect(stdout).toContain('libs/mylib/src/mylib.module.ts');
|
||||
let stdout = runCommand(
|
||||
'npm run -s format:check -- --files="libs/mylib/index.ts" --libs-and-apps'
|
||||
);
|
||||
expect(stdout).toContain('libs/mylib/index.ts');
|
||||
expect(stdout).toContain('libs/mylib/src/mylib.module.ts');
|
||||
|
||||
stdout = runCommand('npm run -s format:check');
|
||||
expect(stdout).toContain('apps/myapp/src/main.ts');
|
||||
expect(stdout).toContain('apps/myapp/src/app/app.module.ts');
|
||||
expect(stdout).toContain('apps/myapp/src/app/app.component.ts');
|
||||
stdout = runCommand('npm run -s format:check');
|
||||
expect(stdout).toContain('apps/myapp/src/main.ts');
|
||||
expect(stdout).toContain('apps/myapp/src/app/app.module.ts');
|
||||
expect(stdout).toContain('apps/myapp/src/app/app.component.ts');
|
||||
|
||||
runCommand(
|
||||
'npm run format:write -- --files="apps/myapp/src/app/app.module.ts,apps/myapp/src/app/app.component.ts"'
|
||||
);
|
||||
runCommand(
|
||||
'npm run format:write -- --files="apps/myapp/src/app/app.module.ts,apps/myapp/src/app/app.component.ts"'
|
||||
);
|
||||
|
||||
stdout = runCommand('npm run -s format:check');
|
||||
stdout = runCommand('npm run -s format:check');
|
||||
|
||||
expect(stdout).toContain('apps/myapp/src/main.ts');
|
||||
expect(stdout).not.toContain('apps/myapp/src/app/app.module.ts');
|
||||
expect(stdout).not.toContain('apps/myapp/src/app/app.component.ts');
|
||||
expect(stdout).toContain('apps/myapp/src/main.ts');
|
||||
expect(stdout).not.toContain('apps/myapp/src/app/app.module.ts');
|
||||
expect(stdout).not.toContain('apps/myapp/src/app/app.component.ts');
|
||||
|
||||
runCommand('npm run format:write');
|
||||
expect(runCommand('npm run -s format:check')).toEqual('');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
runCommand('npm run format:write');
|
||||
expect(runCommand('npm run -s format:check')).toEqual('');
|
||||
}, 1000000);
|
||||
|
||||
it(
|
||||
'should support workspace-specific schematics',
|
||||
() => {
|
||||
newProject();
|
||||
runCLI('g workspace-schematic custom');
|
||||
checkFilesExist(
|
||||
'tools/schematics/custom/index.ts',
|
||||
'tools/schematics/custom/schema.json'
|
||||
);
|
||||
it('should support workspace-specific schematics', () => {
|
||||
newProject();
|
||||
runCLI('g workspace-schematic custom');
|
||||
checkFilesExist(
|
||||
'tools/schematics/custom/index.ts',
|
||||
'tools/schematics/custom/schema.json'
|
||||
);
|
||||
|
||||
const json = readJson('tools/schematics/custom/schema.json');
|
||||
json.properties['directory'] = {
|
||||
type: 'string',
|
||||
description: 'lib directory'
|
||||
};
|
||||
updateFile('tools/schematics/custom/schema.json', JSON.stringify(json));
|
||||
const json = readJson('tools/schematics/custom/schema.json');
|
||||
json.properties['directory'] = {
|
||||
type: 'string',
|
||||
description: 'lib directory'
|
||||
};
|
||||
updateFile('tools/schematics/custom/schema.json', JSON.stringify(json));
|
||||
|
||||
const indexFile = readFile('tools/schematics/custom/index.ts');
|
||||
updateFile(
|
||||
'tools/schematics/custom/index.ts',
|
||||
indexFile.replace(
|
||||
'name: schema.name',
|
||||
'name: schema.name, directory: schema.directory'
|
||||
)
|
||||
);
|
||||
const indexFile = readFile('tools/schematics/custom/index.ts');
|
||||
updateFile(
|
||||
'tools/schematics/custom/index.ts',
|
||||
indexFile.replace(
|
||||
'name: schema.name',
|
||||
'name: schema.name, directory: schema.directory'
|
||||
)
|
||||
);
|
||||
|
||||
const dryRunOutput = runCommand(
|
||||
'npm run workspace-schematic custom mylib -- --directory=dir -d'
|
||||
);
|
||||
expect(exists('libs/dir/mylib/src/index.ts')).toEqual(false);
|
||||
expect(dryRunOutput).toContain(
|
||||
'create libs/dir/mylib/src/lib/dir-mylib.module.ts'
|
||||
);
|
||||
expect(dryRunOutput).toContain('update angular.json');
|
||||
expect(dryRunOutput).toContain('update nx.json');
|
||||
const dryRunOutput = runCommand(
|
||||
'npm run workspace-schematic custom mylib -- --directory=dir -d'
|
||||
);
|
||||
expect(exists('libs/dir/mylib/src/index.ts')).toEqual(false);
|
||||
expect(dryRunOutput).toContain(
|
||||
'create libs/dir/mylib/src/lib/dir-mylib.module.ts'
|
||||
);
|
||||
expect(dryRunOutput).toContain('update angular.json');
|
||||
expect(dryRunOutput).toContain('update nx.json');
|
||||
|
||||
const output = runCommand(
|
||||
'npm run workspace-schematic custom mylib -- --directory=dir'
|
||||
);
|
||||
checkFilesExist('libs/dir/mylib/src/index.ts');
|
||||
expect(output).toContain(
|
||||
'create libs/dir/mylib/src/lib/dir-mylib.module.ts'
|
||||
);
|
||||
expect(output).toContain('update angular.json');
|
||||
expect(output).toContain('update nx.json');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
const output = runCommand(
|
||||
'npm run workspace-schematic custom mylib -- --directory=dir'
|
||||
);
|
||||
checkFilesExist('libs/dir/mylib/src/index.ts');
|
||||
expect(output).toContain(
|
||||
'create libs/dir/mylib/src/lib/dir-mylib.module.ts'
|
||||
);
|
||||
expect(output).toContain('update angular.json');
|
||||
expect(output).toContain('update nx.json');
|
||||
}, 1000000);
|
||||
describe('dep-graph', () => {
|
||||
beforeEach(() => {
|
||||
newProject();
|
||||
@ -225,125 +213,109 @@ describe('Command line', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
'dep-graph should output json (without critical path) to file',
|
||||
() => {
|
||||
const file = 'dep-graph.json';
|
||||
it('dep-graph should output json (without critical path) to file', () => {
|
||||
const file = 'dep-graph.json';
|
||||
|
||||
runCommand(`npm run dep-graph -- --file="${file}"`);
|
||||
runCommand(`npm run dep-graph -- --file="${file}"`);
|
||||
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
|
||||
const jsonFileContents = readJson(file);
|
||||
const jsonFileContents = readJson(file);
|
||||
|
||||
expect(jsonFileContents).toEqual({
|
||||
deps: {
|
||||
mylib2: [],
|
||||
myapp3: [],
|
||||
'myapp3-e2e': [
|
||||
{
|
||||
projectName: 'myapp3',
|
||||
type: 'implicit'
|
||||
}
|
||||
],
|
||||
myapp2: [
|
||||
{
|
||||
projectName: 'mylib',
|
||||
type: 'es6Import'
|
||||
}
|
||||
],
|
||||
'myapp2-e2e': [
|
||||
{
|
||||
projectName: 'myapp2',
|
||||
type: 'implicit'
|
||||
}
|
||||
],
|
||||
mylib: [
|
||||
{
|
||||
projectName: 'mylib2',
|
||||
type: 'es6Import'
|
||||
}
|
||||
],
|
||||
myapp: [
|
||||
{
|
||||
projectName: 'mylib',
|
||||
type: 'es6Import'
|
||||
},
|
||||
{
|
||||
projectName: 'mylib2',
|
||||
type: 'loadChildren'
|
||||
}
|
||||
],
|
||||
'myapp-e2e': [
|
||||
{
|
||||
projectName: 'myapp',
|
||||
type: 'implicit'
|
||||
}
|
||||
]
|
||||
},
|
||||
criticalPath: []
|
||||
});
|
||||
},
|
||||
1000000
|
||||
);
|
||||
expect(jsonFileContents).toEqual({
|
||||
deps: {
|
||||
mylib2: [],
|
||||
myapp3: [],
|
||||
'myapp3-e2e': [
|
||||
{
|
||||
projectName: 'myapp3',
|
||||
type: 'implicit'
|
||||
}
|
||||
],
|
||||
myapp2: [
|
||||
{
|
||||
projectName: 'mylib',
|
||||
type: 'es6Import'
|
||||
}
|
||||
],
|
||||
'myapp2-e2e': [
|
||||
{
|
||||
projectName: 'myapp2',
|
||||
type: 'implicit'
|
||||
}
|
||||
],
|
||||
mylib: [
|
||||
{
|
||||
projectName: 'mylib2',
|
||||
type: 'es6Import'
|
||||
}
|
||||
],
|
||||
myapp: [
|
||||
{
|
||||
projectName: 'mylib',
|
||||
type: 'es6Import'
|
||||
},
|
||||
{
|
||||
projectName: 'mylib2',
|
||||
type: 'loadChildren'
|
||||
}
|
||||
],
|
||||
'myapp-e2e': [
|
||||
{
|
||||
projectName: 'myapp',
|
||||
type: 'implicit'
|
||||
}
|
||||
]
|
||||
},
|
||||
criticalPath: []
|
||||
});
|
||||
}, 1000000);
|
||||
|
||||
it(
|
||||
'dep-graph should output json with critical path to file',
|
||||
() => {
|
||||
const file = 'dep-graph.json';
|
||||
it('dep-graph should output json with critical path to file', () => {
|
||||
const file = 'dep-graph.json';
|
||||
|
||||
runCommand(
|
||||
`npm run affected:dep-graph -- --files="libs/mylib/src/index.ts" --file="${file}"`
|
||||
);
|
||||
runCommand(
|
||||
`npm run affected:dep-graph -- --files="libs/mylib/src/index.ts" --file="${file}"`
|
||||
);
|
||||
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
|
||||
const jsonFileContents = readJson(file);
|
||||
const jsonFileContents = readJson(file);
|
||||
|
||||
expect(jsonFileContents.criticalPath).toContain('myapp');
|
||||
expect(jsonFileContents.criticalPath).toContain('myapp2');
|
||||
expect(jsonFileContents.criticalPath).toContain('mylib');
|
||||
expect(jsonFileContents.criticalPath).not.toContain('mylib2');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
expect(jsonFileContents.criticalPath).toContain('myapp');
|
||||
expect(jsonFileContents.criticalPath).toContain('myapp2');
|
||||
expect(jsonFileContents.criticalPath).toContain('mylib');
|
||||
expect(jsonFileContents.criticalPath).not.toContain('mylib2');
|
||||
}, 1000000);
|
||||
|
||||
it(
|
||||
'dep-graph should output dot to file',
|
||||
() => {
|
||||
const file = 'dep-graph.dot';
|
||||
it('dep-graph should output dot to file', () => {
|
||||
const file = 'dep-graph.dot';
|
||||
|
||||
runCommand(
|
||||
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
|
||||
);
|
||||
runCommand(
|
||||
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
|
||||
);
|
||||
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
|
||||
const fileContents = readFile(file);
|
||||
expect(fileContents).toContain('"myapp" -> "mylib"');
|
||||
expect(fileContents).toContain('"myapp2" -> "mylib"');
|
||||
expect(fileContents).toContain('"mylib" -> "mylib2"');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
const fileContents = readFile(file);
|
||||
expect(fileContents).toContain('"myapp" -> "mylib"');
|
||||
expect(fileContents).toContain('"myapp2" -> "mylib"');
|
||||
expect(fileContents).toContain('"mylib" -> "mylib2"');
|
||||
}, 1000000);
|
||||
|
||||
it(
|
||||
'dep-graph should output html to file',
|
||||
() => {
|
||||
const file = 'dep-graph.html';
|
||||
runCommand(
|
||||
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
|
||||
);
|
||||
it('dep-graph should output html to file', () => {
|
||||
const file = 'dep-graph.html';
|
||||
runCommand(
|
||||
`npm run dep-graph -- --files="libs/mylib/index.ts" --file="${file}"`
|
||||
);
|
||||
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
expect(() => checkFilesExist(file)).not.toThrow();
|
||||
|
||||
const fileContents = readFile(file);
|
||||
expect(fileContents).toContain('<html>');
|
||||
expect(fileContents).toContain('<title>myapp->mylib</title>');
|
||||
expect(fileContents).toContain('<title>myapp->mylib2</title>');
|
||||
expect(fileContents).toContain('<title>mylib->mylib2</title>');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
const fileContents = readFile(file);
|
||||
expect(fileContents).toContain('<html>');
|
||||
expect(fileContents).toContain('<title>myapp->mylib</title>');
|
||||
expect(fileContents).toContain('<title>myapp->mylib2</title>');
|
||||
expect(fileContents).toContain('<title>mylib->mylib2</title>');
|
||||
}, 1000000);
|
||||
});
|
||||
});
|
||||
|
||||
@ -11,58 +11,50 @@ import {
|
||||
|
||||
describe('Cypress E2E Test runner', () => {
|
||||
describe('project scaffolding', () => {
|
||||
it(
|
||||
'should generate an app with the Cypress as e2e test runner',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=cypress');
|
||||
copyMissingPackages();
|
||||
it('should generate an app with the Cypress as e2e test runner', () => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=cypress');
|
||||
copyMissingPackages();
|
||||
|
||||
// Making sure the package.json file contains the Cypress dependency
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.devDependencies['cypress']).toBeTruthy();
|
||||
// Making sure the package.json file contains the Cypress dependency
|
||||
const packageJson = readJson('package.json');
|
||||
expect(packageJson.devDependencies['cypress']).toBeTruthy();
|
||||
|
||||
// Making sure the cypress folders & files are created
|
||||
checkFilesExist('apps/my-app-e2e/cypress.json');
|
||||
checkFilesExist('apps/my-app-e2e/tsconfig.e2e.json');
|
||||
// Making sure the cypress folders & files are created
|
||||
checkFilesExist('apps/my-app-e2e/cypress.json');
|
||||
checkFilesExist('apps/my-app-e2e/tsconfig.e2e.json');
|
||||
|
||||
checkFilesExist('apps/my-app-e2e/src/fixtures/example.json');
|
||||
checkFilesExist('apps/my-app-e2e/src/integration/app.spec.ts');
|
||||
checkFilesExist('apps/my-app-e2e/src/plugins/index.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/commands.ts');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
checkFilesExist('apps/my-app-e2e/src/fixtures/example.json');
|
||||
checkFilesExist('apps/my-app-e2e/src/integration/app.spec.ts');
|
||||
checkFilesExist('apps/my-app-e2e/src/plugins/index.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/commands.ts');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
describe('running Cypress', () => {
|
||||
it(
|
||||
'should execute e2e tests using Cypress',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=cypress');
|
||||
copyMissingPackages();
|
||||
it('should execute e2e tests using Cypress', () => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=cypress');
|
||||
copyMissingPackages();
|
||||
|
||||
expect(
|
||||
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
||||
).toContain('All specs passed!');
|
||||
expect(
|
||||
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
||||
).toContain('All specs passed!');
|
||||
|
||||
const originalContents = JSON.parse(
|
||||
readFile('apps/my-app-e2e/cypress.json')
|
||||
);
|
||||
delete originalContents.fixtures;
|
||||
updateFile(
|
||||
'apps/my-app-e2e/cypress.json',
|
||||
JSON.stringify(originalContents)
|
||||
);
|
||||
const originalContents = JSON.parse(
|
||||
readFile('apps/my-app-e2e/cypress.json')
|
||||
);
|
||||
delete originalContents.fixtures;
|
||||
updateFile(
|
||||
'apps/my-app-e2e/cypress.json',
|
||||
JSON.stringify(originalContents)
|
||||
);
|
||||
|
||||
expect(
|
||||
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
||||
).toContain('All specs passed!');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
expect(
|
||||
runCLI('e2e --project=my-app-e2e --headless --watch=false')
|
||||
).toContain('All specs passed!');
|
||||
}, 1000000);
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,24 +1,20 @@
|
||||
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
||||
|
||||
describe('DowngradeModule', () => {
|
||||
it(
|
||||
'should generate a downgradeModule setup',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
it('should generate a downgradeModule setup', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/legacy.js',
|
||||
`window.angular.module('legacy', []);`
|
||||
);
|
||||
updateFile(
|
||||
'apps/myapp/src/legacy.js',
|
||||
`window.angular.module('legacy', []);`
|
||||
);
|
||||
|
||||
runCLI(
|
||||
'generate downgrade-module legacy --angularJsImport=./legacy --project=myapp'
|
||||
);
|
||||
runCLI(
|
||||
'generate downgrade-module legacy --angularJsImport=./legacy --project=myapp'
|
||||
);
|
||||
|
||||
runCLI('build');
|
||||
expect(runCLI('test --no-watch')).toContain('Executed 3 of 3 SUCCESS');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
runCLI('build');
|
||||
expect(runCLI('test --no-watch')).toContain('Executed 3 of 3 SUCCESS');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -12,34 +12,26 @@ describe('Jest', () => {
|
||||
newProject();
|
||||
});
|
||||
|
||||
it(
|
||||
'should be able to generate a testable library using jest',
|
||||
async done => {
|
||||
newLib('jestlib --unit-test-runner jest');
|
||||
copyMissingPackages();
|
||||
await Promise.all([
|
||||
runCLIAsync('generate service test --project jestlib'),
|
||||
runCLIAsync('generate component test --project jestlib')
|
||||
]);
|
||||
const jestResult = await runCLIAsync('test jestlib');
|
||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||
done();
|
||||
},
|
||||
10000
|
||||
);
|
||||
it('should be able to generate a testable library using jest', async done => {
|
||||
newLib('jestlib --unit-test-runner jest');
|
||||
copyMissingPackages();
|
||||
await Promise.all([
|
||||
runCLIAsync('generate service test --project jestlib'),
|
||||
runCLIAsync('generate component test --project jestlib')
|
||||
]);
|
||||
const jestResult = await runCLIAsync('test jestlib');
|
||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||
done();
|
||||
}, 10000);
|
||||
|
||||
it(
|
||||
'should be able to generate a testable application using jest',
|
||||
async () => {
|
||||
newApp('jestapp --unit-test-runner jest');
|
||||
copyMissingPackages();
|
||||
await Promise.all([
|
||||
runCLIAsync('generate service test --project jestapp'),
|
||||
runCLIAsync('generate component test --project jestapp')
|
||||
]);
|
||||
const jestResult = await runCLIAsync('test jestapp');
|
||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||
},
|
||||
10000
|
||||
);
|
||||
it('should be able to generate a testable application using jest', async () => {
|
||||
newApp('jestapp --unit-test-runner jest');
|
||||
copyMissingPackages();
|
||||
await Promise.all([
|
||||
runCLIAsync('generate service test --project jestapp'),
|
||||
runCLIAsync('generate component test --project jestapp')
|
||||
]);
|
||||
const jestResult = await runCLIAsync('test jestapp');
|
||||
expect(jestResult.stderr).toContain('Test Suites: 3 passed, 3 total');
|
||||
}, 10000);
|
||||
});
|
||||
|
||||
@ -13,16 +13,14 @@ import {
|
||||
} from '../utils';
|
||||
|
||||
describe('Nrwl Workspace', () => {
|
||||
it(
|
||||
'should work',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir');
|
||||
newLib('myLib --directory=myDir');
|
||||
it('should work', () => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir');
|
||||
newLib('myLib --directory=myDir');
|
||||
|
||||
updateFile(
|
||||
'apps/my-dir/my-app/src/app/app.module.ts',
|
||||
`
|
||||
updateFile(
|
||||
'apps/my-dir/my-app/src/app/app.module.ts',
|
||||
`
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { MyDirMyLibModule } from '@proj/my-dir/my-lib';
|
||||
@ -35,69 +33,57 @@ describe('Nrwl Workspace', () => {
|
||||
})
|
||||
export class AppModule {}
|
||||
`
|
||||
);
|
||||
runCLI('build --prod --project=my-dir-my-app --output-hashing none');
|
||||
expect(exists('./tmp/proj/dist/apps/my-dir/my-app/main.js')).toEqual(
|
||||
true
|
||||
);
|
||||
);
|
||||
runCLI('build --prod --project=my-dir-my-app --output-hashing none');
|
||||
expect(exists('./tmp/proj/dist/apps/my-dir/my-app/main.js')).toEqual(true);
|
||||
|
||||
// This is a loose requirement because there are a lot of
|
||||
// influences external from this project that affect this.
|
||||
const bundleSize = getSize('./tmp/proj/dist/apps/my-dir/my-app/main.js');
|
||||
console.log(`The current bundle size is ${bundleSize} KB`);
|
||||
expect(bundleSize).toBeLessThanOrEqual(200000);
|
||||
// This is a loose requirement because there are a lot of
|
||||
// influences external from this project that affect this.
|
||||
const bundleSize = getSize('./tmp/proj/dist/apps/my-dir/my-app/main.js');
|
||||
console.log(`The current bundle size is ${bundleSize} KB`);
|
||||
expect(bundleSize).toBeLessThanOrEqual(200000);
|
||||
|
||||
// running tests for the app
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
);
|
||||
// running tests for the app
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
);
|
||||
|
||||
// running tests for the lib
|
||||
expect(runCLI('test --project=my-dir-my-lib --no-watch')).toContain(
|
||||
'Executed 1 of 1 SUCCESS'
|
||||
);
|
||||
// running tests for the lib
|
||||
expect(runCLI('test --project=my-dir-my-lib --no-watch')).toContain(
|
||||
'Executed 1 of 1 SUCCESS'
|
||||
);
|
||||
|
||||
// e2e tests
|
||||
expect(runCLI('e2e --project=my-dir-my-app-e2e')).toContain(
|
||||
'Executed 1 of 1 spec SUCCESS'
|
||||
);
|
||||
},
|
||||
1000000
|
||||
);
|
||||
// e2e tests
|
||||
expect(runCLI('e2e --project=my-dir-my-app-e2e')).toContain(
|
||||
'Executed 1 of 1 spec SUCCESS'
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it(
|
||||
'should support router config generation (lazy)',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir --routing');
|
||||
newLib(
|
||||
'myLib --directory=myDir --routing --lazy --parentModule=apps/my-dir/my-app/src/app/app.module.ts'
|
||||
);
|
||||
it('should support router config generation (lazy)', () => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir --routing');
|
||||
newLib(
|
||||
'myLib --directory=myDir --routing --lazy --parentModule=apps/my-dir/my-app/src/app/app.module.ts'
|
||||
);
|
||||
|
||||
runCLI('build --aot --project=my-dir-my-app');
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
);
|
||||
},
|
||||
1000000
|
||||
);
|
||||
runCLI('build --aot --project=my-dir-my-app');
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it(
|
||||
'should support router config generation (eager)',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir --routing');
|
||||
newLib(
|
||||
'myLib --directory=myDir --routing --parentModule=apps/my-dir/my-app/src/app/app.module.ts'
|
||||
);
|
||||
it('should support router config generation (eager)', () => {
|
||||
newProject();
|
||||
newApp('myApp --directory=myDir --routing');
|
||||
newLib(
|
||||
'myLib --directory=myDir --routing --parentModule=apps/my-dir/my-app/src/app/app.module.ts'
|
||||
);
|
||||
|
||||
runCLI('build --aot --project=my-dir-my-app');
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
);
|
||||
},
|
||||
1000000
|
||||
);
|
||||
runCLI('build --aot --project=my-dir-my-app');
|
||||
expect(runCLI('test --project=my-dir-my-app --no-watch')).toContain(
|
||||
'Executed 3 of 3 SUCCESS'
|
||||
);
|
||||
}, 1000000);
|
||||
|
||||
it('should support scss for styles', () => {
|
||||
cleanup();
|
||||
@ -119,23 +105,19 @@ describe('Nrwl Workspace', () => {
|
||||
});
|
||||
|
||||
// TODO: Fix this test. This test was incorrect before.. and fails after fixing it.
|
||||
xit(
|
||||
'should not generate e2e configuration',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=none');
|
||||
xit('should not generate e2e configuration', () => {
|
||||
newProject();
|
||||
newApp('myApp --e2eTestRunner=none');
|
||||
|
||||
// Making sure the angular.json file doesn't contain e2e project
|
||||
const angularJson = readJson('angular.json');
|
||||
expect(angularJson.projects['my-app-e2e']).toBeUndefined();
|
||||
// Making sure the angular.json file doesn't contain e2e project
|
||||
const angularJson = readJson('angular.json');
|
||||
expect(angularJson.projects['my-app-e2e']).toBeUndefined();
|
||||
|
||||
// Making sure the nx.json file doesn't contain e2e project
|
||||
const nxJson = readJson('angular.json');
|
||||
expect(nxJson.projects['my-app-e2e']).toBeUndefined();
|
||||
// Making sure the nx.json file doesn't contain e2e project
|
||||
const nxJson = readJson('angular.json');
|
||||
expect(nxJson.projects['my-app-e2e']).toBeUndefined();
|
||||
|
||||
// Making sure the e2e folder is not created
|
||||
expect(exists('./tmp/proj/apps/my-app-e2e')).toBeFalsy();
|
||||
},
|
||||
1000000
|
||||
);
|
||||
// Making sure the e2e folder is not created
|
||||
expect(exists('./tmp/proj/apps/my-app-e2e')).toBeFalsy();
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -1,34 +1,30 @@
|
||||
import { newApp, newProject, runCLI, copyMissingPackages } from '../utils';
|
||||
|
||||
describe('ngrx', () => {
|
||||
it(
|
||||
'should work',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
it('should work', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
|
||||
// Generate root ngrx state management
|
||||
runCLI(
|
||||
'generate ngrx users --module=apps/myapp/src/app/app.module.ts --root --collection=@nrwl/schematics'
|
||||
);
|
||||
copyMissingPackages();
|
||||
// Generate root ngrx state management
|
||||
runCLI(
|
||||
'generate ngrx users --module=apps/myapp/src/app/app.module.ts --root --collection=@nrwl/schematics'
|
||||
);
|
||||
copyMissingPackages();
|
||||
|
||||
// Generate feature library and ngrx state within that library
|
||||
runCLI('g @nrwl/schematics:lib feature-flights --prefix=fl');
|
||||
runCLI(
|
||||
'generate ngrx flights --module=libs/feature-flights/src/lib/feature-flights.module.ts --facade --collection=@nrwl/schematics'
|
||||
);
|
||||
// Generate feature library and ngrx state within that library
|
||||
runCLI('g @nrwl/schematics:lib feature-flights --prefix=fl');
|
||||
runCLI(
|
||||
'generate ngrx flights --module=libs/feature-flights/src/lib/feature-flights.module.ts --facade --collection=@nrwl/schematics'
|
||||
);
|
||||
|
||||
expect(runCLI('lint', { silenceError: true })).not.toContain('ERROR');
|
||||
expect(runCLI('lint', { silenceError: true })).not.toContain('ERROR');
|
||||
|
||||
expect(runCLI('build')).toContain('chunk {main} main.js,');
|
||||
expect(runCLI('test myapp --no-watch')).toContain(
|
||||
'Executed 10 of 10 SUCCESS'
|
||||
);
|
||||
expect(runCLI('test feature-flights --no-watch')).toContain(
|
||||
'Executed 10 of 10 SUCCESS'
|
||||
);
|
||||
},
|
||||
1000000
|
||||
);
|
||||
expect(runCLI('build')).toContain('chunk {main} main.js,');
|
||||
expect(runCLI('test myapp --no-watch')).toContain(
|
||||
'Executed 10 of 10 SUCCESS'
|
||||
);
|
||||
expect(runCLI('test feature-flights --no-watch')).toContain(
|
||||
'Executed 10 of 10 SUCCESS'
|
||||
);
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -18,114 +18,104 @@ describe('Node Applications', () => {
|
||||
copyMissingPackages();
|
||||
});
|
||||
|
||||
it(
|
||||
'should be able to generate a node application',
|
||||
async done => {
|
||||
runCLI('generate node-app node-app1');
|
||||
copyMissingPackages();
|
||||
it('should be able to generate a node application', async done => {
|
||||
runCLI('generate node-app node-app1');
|
||||
copyMissingPackages();
|
||||
|
||||
updateFile(
|
||||
'apps/node-app1/src/app/test.spec.ts',
|
||||
`
|
||||
updateFile(
|
||||
'apps/node-app1/src/app/test.spec.ts',
|
||||
`
|
||||
describe('test', () => {
|
||||
it('should work', () => {
|
||||
expect(true).toEqual(true);
|
||||
})
|
||||
})
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
updateFile('apps/node-app1/src/assets/file.txt', ``);
|
||||
const jestResult = await runCLIAsync('test node-app1');
|
||||
expect(jestResult.stderr).toContain('Test Suites: 1 passed, 1 total');
|
||||
updateFile('apps/node-app1/src/assets/file.txt', ``);
|
||||
const jestResult = await runCLIAsync('test node-app1');
|
||||
expect(jestResult.stderr).toContain('Test Suites: 1 passed, 1 total');
|
||||
|
||||
function getData() {
|
||||
return new Promise(resolve => {
|
||||
http.get('http://localhost:3333', res => {
|
||||
expect(res.statusCode).toEqual(200);
|
||||
let data = '';
|
||||
res.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
res.once('end', () => {
|
||||
resolve(data);
|
||||
});
|
||||
function getData() {
|
||||
return new Promise(resolve => {
|
||||
http.get('http://localhost:3333', res => {
|
||||
expect(res.statusCode).toEqual(200);
|
||||
let data = '';
|
||||
res.on('data', chunk => {
|
||||
data += chunk;
|
||||
});
|
||||
res.once('end', () => {
|
||||
resolve(data);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
await runCLIAsync('build node-app1');
|
||||
|
||||
expect(exists('./tmp/proj/dist/apps/node-app1/main.js')).toBeTruthy();
|
||||
expect(
|
||||
exists('./tmp/proj/dist/apps/node-app1/assets/file.txt')
|
||||
).toBeTruthy();
|
||||
expect(exists('./tmp/proj/dist/apps/node-app1/main.js.map')).toBeTruthy();
|
||||
|
||||
const server = fork(
|
||||
path.join(
|
||||
__dirname,
|
||||
'../../../tmp/proj',
|
||||
`./dist/apps/node-app1/main.js`
|
||||
),
|
||||
[],
|
||||
{
|
||||
cwd: './tmp/proj',
|
||||
silent: true
|
||||
}
|
||||
);
|
||||
expect(server).toBeTruthy();
|
||||
|
||||
await runCLIAsync('build node-app1');
|
||||
|
||||
expect(exists('./tmp/proj/dist/apps/node-app1/main.js')).toBeTruthy();
|
||||
expect(
|
||||
exists('./tmp/proj/dist/apps/node-app1/assets/file.txt')
|
||||
).toBeTruthy();
|
||||
expect(exists('./tmp/proj/dist/apps/node-app1/main.js.map')).toBeTruthy();
|
||||
|
||||
const server = fork(
|
||||
path.join(
|
||||
__dirname,
|
||||
'../../../tmp/proj',
|
||||
`./dist/apps/node-app1/main.js`
|
||||
),
|
||||
[],
|
||||
{
|
||||
cwd: './tmp/proj',
|
||||
silent: true
|
||||
}
|
||||
);
|
||||
expect(server).toBeTruthy();
|
||||
|
||||
await new Promise(resolve => {
|
||||
server.stdout.once('data', async data => {
|
||||
expect(data.toString()).toContain(
|
||||
'Listening at http://localhost:3333'
|
||||
);
|
||||
const result = await getData();
|
||||
|
||||
expect(result).toEqual('Welcome to node-app1!');
|
||||
treeKill(server.pid, 'SIGTERM', err => {
|
||||
expect(err).toBeFalsy();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const process = spawn(
|
||||
'node',
|
||||
['./node_modules/.bin/ng', 'serve', 'node-app1'],
|
||||
{
|
||||
cwd: './tmp/proj'
|
||||
}
|
||||
);
|
||||
|
||||
process.stdout.on('data', async (data: Buffer) => {
|
||||
if (!data.toString().includes('Listening at http://localhost:3333')) {
|
||||
return;
|
||||
}
|
||||
await new Promise(resolve => {
|
||||
server.stdout.once('data', async data => {
|
||||
expect(data.toString()).toContain('Listening at http://localhost:3333');
|
||||
const result = await getData();
|
||||
|
||||
expect(result).toEqual('Welcome to node-app1!');
|
||||
treeKill(process.pid, 'SIGTERM', err => {
|
||||
treeKill(server.pid, 'SIGTERM', err => {
|
||||
expect(err).toBeFalsy();
|
||||
done();
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
},
|
||||
30000
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
'should be able to generate an empty application',
|
||||
async () => {
|
||||
runCLI('generate node-app node-app2 --framework none');
|
||||
updateFile('apps/node-app2/src/main.ts', `console.log('Hello World!');`);
|
||||
await runCLIAsync('build node-app2');
|
||||
expect(exists('./tmp/proj/dist/apps/node-app2/main.js')).toBeTruthy();
|
||||
const result = execSync('node dist/apps/node-app2/main.js', {
|
||||
const process = spawn(
|
||||
'node',
|
||||
['./node_modules/.bin/ng', 'serve', 'node-app1'],
|
||||
{
|
||||
cwd: './tmp/proj'
|
||||
}).toString();
|
||||
expect(result).toContain('Hello World!');
|
||||
},
|
||||
30000
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
process.stdout.on('data', async (data: Buffer) => {
|
||||
if (!data.toString().includes('Listening at http://localhost:3333')) {
|
||||
return;
|
||||
}
|
||||
const result = await getData();
|
||||
expect(result).toEqual('Welcome to node-app1!');
|
||||
treeKill(process.pid, 'SIGTERM', err => {
|
||||
expect(err).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
}, 30000);
|
||||
|
||||
it('should be able to generate an empty application', async () => {
|
||||
runCLI('generate node-app node-app2 --framework none');
|
||||
updateFile('apps/node-app2/src/main.ts', `console.log('Hello World!');`);
|
||||
await runCLIAsync('build node-app2');
|
||||
expect(exists('./tmp/proj/dist/apps/node-app2/main.js')).toBeTruthy();
|
||||
const result = execSync('node dist/apps/node-app2/main.js', {
|
||||
cwd: './tmp/proj'
|
||||
}).toString();
|
||||
expect(result).toContain('Hello World!');
|
||||
}, 30000);
|
||||
});
|
||||
|
||||
@ -1,41 +1,37 @@
|
||||
import { newApp, newProject, runCLI, updateFile } from '../utils';
|
||||
|
||||
describe('Upgrade', () => {
|
||||
it(
|
||||
'should generate an UpgradeModule setup',
|
||||
() => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
it('should generate an UpgradeModule setup', () => {
|
||||
newProject();
|
||||
newApp('myapp');
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/legacy.js',
|
||||
`
|
||||
updateFile(
|
||||
'apps/myapp/src/legacy.js',
|
||||
`
|
||||
const angular = window.angular.module('legacy', []);
|
||||
angular.component('proj-root-legacy', {
|
||||
template: 'Expected Value'
|
||||
});
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.html',
|
||||
`
|
||||
updateFile(
|
||||
'apps/myapp/src/app/app.component.html',
|
||||
`
|
||||
EXPECTED [<proj-root-legacy></proj-root-legacy>]
|
||||
`
|
||||
);
|
||||
);
|
||||
|
||||
updateFile('apps/myapp/src/app/app.component.spec.ts', ``);
|
||||
updateFile('apps/myapp/src/app/app.component.spec.ts', ``);
|
||||
|
||||
runCLI(
|
||||
'generate upgrade-module legacy --angularJsImport=./legacy ' +
|
||||
'--angularJsCmpSelector=proj-root-legacy --project=myapp'
|
||||
);
|
||||
runCLI(
|
||||
'generate upgrade-module legacy --angularJsImport=./legacy ' +
|
||||
'--angularJsCmpSelector=proj-root-legacy --project=myapp'
|
||||
);
|
||||
|
||||
expect(runCLI('lint', { silenceError: true })).not.toContain('ERROR');
|
||||
expect(runCLI('lint', { silenceError: true })).not.toContain('ERROR');
|
||||
|
||||
runCLI('build');
|
||||
runCLI('test --no-watch');
|
||||
},
|
||||
1000000
|
||||
);
|
||||
runCLI('build');
|
||||
runCLI('test --no-watch');
|
||||
}, 1000000);
|
||||
});
|
||||
|
||||
@ -74,7 +74,7 @@
|
||||
"npm-run-all": "^4.1.5",
|
||||
"opn": "^5.3.0",
|
||||
"precise-commits": "1.0.2",
|
||||
"prettier": "1.10.2",
|
||||
"prettier": "1.15.3",
|
||||
"release-it": "^7.4.0",
|
||||
"rxjs": "6.3.3",
|
||||
"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
|
||||
|
||||
* 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
|
||||
|
||||
@ -20,7 +20,7 @@ node_modules/.bin/ng generate lib [name]
|
||||
|
||||
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
|
||||
|
||||
@ -38,4 +38,4 @@ Example: bazel run apps/my-dir/my-app/src:prodserver
|
||||
|
||||
ibazel test //libs/mylib/src:test
|
||||
|
||||
* currently works for libs
|
||||
- currently works for libs
|
||||
|
||||
@ -30,13 +30,11 @@
|
||||
"lazy": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Add RouterModule.forChild when set to true, and a simple array of routes when set to false."
|
||||
"description": "Add RouterModule.forChild when set to true, and a simple array of routes when set to false."
|
||||
},
|
||||
"parentModule": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to."
|
||||
"description": "Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to."
|
||||
}
|
||||
},
|
||||
"required": ["name"]
|
||||
|
||||
@ -28,8 +28,7 @@
|
||||
"additionalProperties": false
|
||||
},
|
||||
"apps": {
|
||||
"description":
|
||||
"Properties of the different applications in this project.",
|
||||
"description": "Properties of the different applications in this project.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
@ -102,8 +101,7 @@
|
||||
},
|
||||
"allowOutsideOutDir": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Allow assets to be copied outside the outDir.",
|
||||
"description": "Allow assets to be copied outside the outDir.",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
@ -141,33 +139,27 @@
|
||||
},
|
||||
"maximumWarning": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The maximum threshold for warning relative to the baseline."
|
||||
"description": "The maximum threshold for warning relative to the baseline."
|
||||
},
|
||||
"maximumError": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The maximum threshold for error relative to the baseline."
|
||||
"description": "The maximum threshold for error relative to the baseline."
|
||||
},
|
||||
"minimumWarning": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The minimum threshold for warning relative to the baseline."
|
||||
"description": "The minimum threshold for warning relative to the baseline."
|
||||
},
|
||||
"minimumError": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The minimum threshold for error relative to the baseline."
|
||||
"description": "The minimum threshold for error relative to the baseline."
|
||||
},
|
||||
"warning": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The threshold for warning relative to the baseline (min & max)."
|
||||
"description": "The threshold for warning relative to the baseline (min & max)."
|
||||
},
|
||||
"error": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The threshold for error relative to the baseline (min & max)."
|
||||
"description": "The threshold for error relative to the baseline (min & max)."
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -211,16 +203,14 @@
|
||||
},
|
||||
"testTsconfig": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The name of the TypeScript configuration file for unit tests."
|
||||
"description": "The name of the TypeScript configuration file for unit tests."
|
||||
},
|
||||
"prefix": {
|
||||
"type": "string",
|
||||
"description": "The prefix to apply to generated selectors."
|
||||
},
|
||||
"serviceWorker": {
|
||||
"description":
|
||||
"Experimental support for a service worker from @angular/service-worker.",
|
||||
"description": "Experimental support for a service worker from @angular/service-worker.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
@ -250,8 +240,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"includePaths": {
|
||||
"description":
|
||||
"Paths to include. Paths will be resolved to project root.",
|
||||
"description": "Paths to include. Paths will be resolved to project root.",
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
@ -288,8 +277,7 @@
|
||||
"type": "string"
|
||||
},
|
||||
"environments": {
|
||||
"description":
|
||||
"Name and corresponding file for environment config.",
|
||||
"description": "Name and corresponding file for environment config.",
|
||||
"type": "object",
|
||||
"additionalProperties": true
|
||||
}
|
||||
@ -337,8 +325,7 @@
|
||||
"default": []
|
||||
},
|
||||
"project": {
|
||||
"description":
|
||||
"Location of the tsconfig.json project file. Will also use as files to lint if 'files' property not present.",
|
||||
"description": "Location of the tsconfig.json project file. Will also use as files to lint if 'files' property not present.",
|
||||
"type": "string"
|
||||
},
|
||||
"tslintConfig": {
|
||||
@ -444,8 +431,7 @@
|
||||
"default": false
|
||||
},
|
||||
"inlineTemplate": {
|
||||
"description":
|
||||
"Specifies if the template will be in the ts file.",
|
||||
"description": "Specifies if the template will be in the ts file.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
@ -569,8 +555,7 @@
|
||||
"type": "boolean"
|
||||
},
|
||||
"poll": {
|
||||
"description":
|
||||
"Enable and define the file watching poll time period (milliseconds).",
|
||||
"description": "Enable and define the file watching poll time period (milliseconds).",
|
||||
"type": "number"
|
||||
},
|
||||
"deleteOutputPath": {
|
||||
@ -589,8 +574,7 @@
|
||||
"default": true
|
||||
},
|
||||
"commonChunk": {
|
||||
"description":
|
||||
"Use a separate bundle containing code used across multiple bundles.",
|
||||
"description": "Use a separate bundle containing code used across multiple bundles.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
@ -666,14 +650,12 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"hmrWarning": {
|
||||
"description":
|
||||
"Show a warning when the user enabled the --hmr option.",
|
||||
"description": "Show a warning when the user enabled the --hmr option.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"nodeDeprecation": {
|
||||
"description":
|
||||
"Show a warning when the node version is incompatible.",
|
||||
"description": "Show a warning when the node version is incompatible.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
@ -683,20 +665,17 @@
|
||||
"default": true
|
||||
},
|
||||
"versionMismatch": {
|
||||
"description":
|
||||
"Show a warning when the global version is newer than the local one.",
|
||||
"description": "Show a warning when the global version is newer than the local one.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"typescriptMismatch": {
|
||||
"description":
|
||||
"Show a warning when the TypeScript version is incompatible",
|
||||
"description": "Show a warning when the TypeScript version is incompatible",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
},
|
||||
"servePathDefault": {
|
||||
"description":
|
||||
"Show a warning when deploy-url/base-href use unsupported serve path values.",
|
||||
"description": "Show a warning when deploy-url/base-href use unsupported serve path values.",
|
||||
"type": "boolean",
|
||||
"default": true
|
||||
}
|
||||
|
||||
@ -232,11 +232,13 @@ function findClass(
|
||||
): ts.ClassDeclaration {
|
||||
const nodes = getSourceNodes(source);
|
||||
|
||||
const clazz = <any>nodes.filter(
|
||||
n =>
|
||||
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
||||
(<any>n).name.text === className
|
||||
)[0];
|
||||
const clazz = <any>(
|
||||
nodes.filter(
|
||||
n =>
|
||||
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
||||
(<any>n).name.text === className
|
||||
)[0]
|
||||
);
|
||||
|
||||
if (!clazz) {
|
||||
throw new Error(`Cannot find class '${className}'`);
|
||||
@ -283,9 +285,8 @@ export function addImportToTestBed(
|
||||
specPath: string,
|
||||
symbolName: string
|
||||
): Change[] {
|
||||
const allCalls: ts.CallExpression[] = <any>findNodes(
|
||||
source,
|
||||
ts.SyntaxKind.CallExpression
|
||||
const allCalls: ts.CallExpression[] = <any>(
|
||||
findNodes(source, ts.SyntaxKind.CallExpression)
|
||||
);
|
||||
|
||||
const configureTestingModuleObjectLiterals = allCalls
|
||||
@ -293,11 +294,10 @@ export function addImportToTestBed(
|
||||
.filter(
|
||||
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
|
||||
)
|
||||
.map(
|
||||
c =>
|
||||
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
||||
? c.arguments[0]
|
||||
: null
|
||||
.map(c =>
|
||||
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
||||
? c.arguments[0]
|
||||
: null
|
||||
);
|
||||
|
||||
if (configureTestingModuleObjectLiterals.length > 0) {
|
||||
|
||||
@ -13,9 +13,8 @@ export function toClassName(str: string): string {
|
||||
|
||||
export function toPropertyName(s: string): string {
|
||||
return s
|
||||
.replace(
|
||||
/(-|_|\.|\s)+(.)?/g,
|
||||
(_, __, chr) => (chr ? chr.toUpperCase() : '')
|
||||
.replace(/(-|_|\.|\s)+(.)?/g, (_, __, chr) =>
|
||||
chr ? chr.toUpperCase() : ''
|
||||
)
|
||||
.replace(/^([A-Z])/, m => m.toLowerCase());
|
||||
}
|
||||
|
||||
@ -83,11 +83,10 @@ export default class CypressBuilder implements Builder<CypressBuilderOptions> {
|
||||
tap(() =>
|
||||
this.copyCypressFixtures(options.tsConfig, options.cypressConfig)
|
||||
),
|
||||
concatMap(
|
||||
() =>
|
||||
!options.baseUrl && options.devServerTarget
|
||||
? this.startDevServer(options.devServerTarget, options.watch)
|
||||
: of(null)
|
||||
concatMap(() =>
|
||||
!options.baseUrl && options.devServerTarget
|
||||
? this.startDevServer(options.devServerTarget, options.watch)
|
||||
: of(null)
|
||||
),
|
||||
concatMap(() =>
|
||||
this.initCypress(
|
||||
|
||||
@ -22,14 +22,12 @@
|
||||
},
|
||||
"headless": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Whether or not the open the Cypress application to run the tests. If set to 'true', will run in headless mode",
|
||||
"description": "Whether or not the open the Cypress application to run the tests. If set to 'true', will run in headless mode",
|
||||
"default": false
|
||||
},
|
||||
"baseUrl": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"Use this to pass directly the address of your distant server address with the port running your application"
|
||||
"description": "Use this to pass directly the address of your distant server address with the port running your application"
|
||||
},
|
||||
"browser": {
|
||||
"type": "string",
|
||||
|
||||
@ -5,8 +5,7 @@
|
||||
"properties": {
|
||||
"jestConfig": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The path of the Jest configuration. (https://jestjs.io/docs/en/configuration.html)"
|
||||
"description": "The path of the Jest configuration. (https://jestjs.io/docs/en/configuration.html)"
|
||||
},
|
||||
"tsConfig": {
|
||||
"type": "string",
|
||||
@ -14,67 +13,55 @@
|
||||
},
|
||||
"setupFile": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration.html#setuptestframeworkscriptfile-string)"
|
||||
"description": "The name of a setup file used by Jest. (https://jestjs.io/docs/en/configuration.html#setuptestframeworkscriptfile-string)"
|
||||
},
|
||||
"watch": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Run tests when files change. (https://jestjs.io/docs/en/cli#watch)",
|
||||
"description": "Run tests when files change. (https://jestjs.io/docs/en/cli#watch)",
|
||||
"default": false
|
||||
},
|
||||
"onlyChanged": {
|
||||
"type": "boolean",
|
||||
"alias": "o",
|
||||
"description":
|
||||
"Isolate tests affected by uncommitted changes. (https://jestjs.io/docs/en/cli#onlychanged)"
|
||||
"description": "Isolate tests affected by uncommitted changes. (https://jestjs.io/docs/en/cli#onlychanged)"
|
||||
},
|
||||
"passWithNoTests": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Allow test suite to pass when no test files are found. (https://jestjs.io/docs/en/cli#passwithnotests)"
|
||||
"description": "Allow test suite to pass when no test files are found. (https://jestjs.io/docs/en/cli#passwithnotests)"
|
||||
},
|
||||
"codeCoverage": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Export a code coverage report. (https://jestjs.io/docs/en/cli#coverage)"
|
||||
"description": "Export a code coverage report. (https://jestjs.io/docs/en/cli#coverage)"
|
||||
},
|
||||
"updateSnapshot": {
|
||||
"type": "boolean",
|
||||
"alias": "u",
|
||||
"description":
|
||||
"Re-record all failing snapshots. (https://jestjs.io/docs/en/cli#updatesnapshot)"
|
||||
"description": "Re-record all failing snapshots. (https://jestjs.io/docs/en/cli#updatesnapshot)"
|
||||
},
|
||||
"ci": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Fail on missing snapshots. (https://jestjs.io/docs/en/cli#ci)"
|
||||
"description": "Fail on missing snapshots. (https://jestjs.io/docs/en/cli#ci)"
|
||||
},
|
||||
"bail": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Exit the test suite immediately upon the first failing test suite. (https://jestjs.io/docs/en/cli#bail)"
|
||||
"description": "Exit the test suite immediately upon the first failing test suite. (https://jestjs.io/docs/en/cli#bail)"
|
||||
},
|
||||
"silent": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Prevent tests from printing messages through the console. (https://jestjs.io/docs/en/cli#silent)"
|
||||
"description": "Prevent tests from printing messages through the console. (https://jestjs.io/docs/en/cli#silent)"
|
||||
},
|
||||
"runInBand": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Run tests in a single process as opposed to multiple workers. Useful for CI. (https://jestjs.io/docs/en/cli.html#runinband)"
|
||||
"description": "Run tests in a single process as opposed to multiple workers. Useful for CI. (https://jestjs.io/docs/en/cli.html#runinband)"
|
||||
},
|
||||
"maxWorkers": {
|
||||
"type": "number",
|
||||
"description":
|
||||
"Max number of workers to run tests across. Useful for CI. (https://jestjs.io/docs/en/cli.html#maxworkers-num)"
|
||||
"description": "Max number of workers to run tests across. Useful for CI. (https://jestjs.io/docs/en/cli.html#maxworkers-num)"
|
||||
},
|
||||
"testNamePattern": {
|
||||
"type": "string",
|
||||
"alias": "t",
|
||||
"description":
|
||||
"Run only tests with a name that matches the regex. (https://jestjs.io/docs/en/cli.html#testnamepattern-regex)"
|
||||
"description": "Run only tests with a name that matches the regex. (https://jestjs.io/docs/en/cli.html#testnamepattern-regex)"
|
||||
}
|
||||
},
|
||||
"required": ["jestConfig", "tsConfig"]
|
||||
|
||||
@ -47,20 +47,17 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"description":
|
||||
"Dependencies to keep external to the bundle. (\"all\" (default), \"none\", or an array of module names)",
|
||||
"description": "Dependencies to keep external to the bundle. (\"all\" (default), \"none\", or an array of module names)",
|
||||
"default": "all"
|
||||
},
|
||||
"statsJson": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Generates a 'stats.json' file which can be analyzed using tools such as: #webpack-bundle-analyzer' or https: //webpack.github.io/analyse.",
|
||||
"description": "Generates a 'stats.json' file which can be analyzed using tools such as: #webpack-bundle-analyzer' or https: //webpack.github.io/analyse.",
|
||||
"default": false
|
||||
},
|
||||
"extractLicenses": {
|
||||
"type": "boolean",
|
||||
"description":
|
||||
"Extract all licenses in a separate file, in the case of production builds only.",
|
||||
"description": "Extract all licenses in a separate file, in the case of production builds only.",
|
||||
"default": false
|
||||
},
|
||||
"optimization": {
|
||||
@ -75,8 +72,7 @@
|
||||
},
|
||||
"maxWorkers": {
|
||||
"type": "number",
|
||||
"description":
|
||||
"Number of workers to use for type checking. (defaults to # of CPUS - 2)"
|
||||
"description": "Number of workers to use for type checking. (defaults to # of CPUS - 2)"
|
||||
},
|
||||
"fileReplacements": {
|
||||
"description": "Replace files with other files in the build.",
|
||||
@ -111,8 +107,7 @@
|
||||
},
|
||||
"input": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The input directory path in which to apply 'glob'. Defaults to the project root."
|
||||
"description": "The input directory path in which to apply 'glob'. Defaults to the project root."
|
||||
},
|
||||
"ignore": {
|
||||
"description": "An array of globs to ignore.",
|
||||
|
||||
@ -56,18 +56,19 @@ function userReducer(state: string, action: Action): string {
|
||||
return 'bob';
|
||||
}
|
||||
|
||||
@Component({ template: `ROOT[<router-outlet></router-outlet>]` })
|
||||
@Component({
|
||||
template: `
|
||||
ROOT[<router-outlet></router-outlet>]
|
||||
`
|
||||
})
|
||||
class RootCmp {}
|
||||
|
||||
@Component({
|
||||
template: `
|
||||
Todo [
|
||||
<div *ngIf="(todo|async) as t">
|
||||
ID {{t.id}}
|
||||
User {{t.user}}
|
||||
</div>
|
||||
]
|
||||
`
|
||||
Todo [
|
||||
<div *ngIf="(todo | async) as t">ID {{ t.id }} User {{ t.user }}</div>
|
||||
]
|
||||
`
|
||||
})
|
||||
class TodoComponent {
|
||||
todo = this.store.select('todos', 'selected');
|
||||
@ -113,20 +114,17 @@ describe('DataPersistence', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it(
|
||||
'should work',
|
||||
fakeAsync(() => {
|
||||
const root = TestBed.createComponent(RootCmp);
|
||||
it('should work', fakeAsync(() => {
|
||||
const root = TestBed.createComponent(RootCmp);
|
||||
|
||||
const router: Router = TestBed.get(Router);
|
||||
router.navigateByUrl('/todo/123');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
const router: Router = TestBed.get(Router);
|
||||
router.navigateByUrl('/todo/123');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 123');
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('User bob');
|
||||
})
|
||||
);
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 123');
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('User bob');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('`run` throwing an error', () => {
|
||||
@ -155,31 +153,26 @@ describe('DataPersistence', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it(
|
||||
'should work',
|
||||
fakeAsync(() => {
|
||||
const root = TestBed.createComponent(RootCmp);
|
||||
it('should work', fakeAsync(() => {
|
||||
const root = TestBed.createComponent(RootCmp);
|
||||
|
||||
const router: Router = TestBed.get(Router);
|
||||
let action;
|
||||
TestBed.get(Actions).subscribe(a => (action = a));
|
||||
const router: Router = TestBed.get(Router);
|
||||
let action;
|
||||
TestBed.get(Actions).subscribe(a => (action = a));
|
||||
|
||||
router.navigateByUrl('/todo/123');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).not.toContain(
|
||||
'ID 123'
|
||||
);
|
||||
expect(action.type).toEqual('ERROR');
|
||||
expect(action.payload.error.message).toEqual('boom');
|
||||
router.navigateByUrl('/todo/123');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).not.toContain('ID 123');
|
||||
expect(action.type).toEqual('ERROR');
|
||||
expect(action.payload.error.message).toEqual('boom');
|
||||
|
||||
// can recover after an error
|
||||
router.navigateByUrl('/todo/456');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
||||
})
|
||||
);
|
||||
// can recover after an error
|
||||
router.navigateByUrl('/todo/456');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
||||
}));
|
||||
});
|
||||
|
||||
describe('`run` returning an error observable', () => {
|
||||
@ -208,30 +201,25 @@ describe('DataPersistence', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it(
|
||||
'should work',
|
||||
fakeAsync(() => {
|
||||
const root = TestBed.createComponent(RootCmp);
|
||||
it('should work', fakeAsync(() => {
|
||||
const root = TestBed.createComponent(RootCmp);
|
||||
|
||||
const router: Router = TestBed.get(Router);
|
||||
let action;
|
||||
TestBed.get(Actions).subscribe(a => (action = a));
|
||||
const router: Router = TestBed.get(Router);
|
||||
let action;
|
||||
TestBed.get(Actions).subscribe(a => (action = a));
|
||||
|
||||
router.navigateByUrl('/todo/123');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).not.toContain(
|
||||
'ID 123'
|
||||
);
|
||||
expect(action.type).toEqual('ERROR');
|
||||
expect(action.payload.error).toEqual('boom');
|
||||
router.navigateByUrl('/todo/123');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).not.toContain('ID 123');
|
||||
expect(action.type).toEqual('ERROR');
|
||||
expect(action.payload.error).toEqual('boom');
|
||||
|
||||
router.navigateByUrl('/todo/456');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
||||
})
|
||||
);
|
||||
router.navigateByUrl('/todo/456');
|
||||
tick(0);
|
||||
root.detectChanges(false);
|
||||
expect(root.elementRef.nativeElement.innerHTML).toContain('ID 456');
|
||||
}));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -580,8 +580,8 @@ const updateAngularJson = updateJsonInTree('angular.json', json => {
|
||||
const type = !project.architect.build
|
||||
? 'e2e'
|
||||
: project.architect.build.options.main.startsWith('apps')
|
||||
? 'application'
|
||||
: 'library';
|
||||
? 'application'
|
||||
: 'library';
|
||||
if (type !== 'e2e') {
|
||||
project.projectType = type;
|
||||
}
|
||||
|
||||
@ -29,7 +29,11 @@
|
||||
"schematics": "./src/collection.json",
|
||||
"ng-update": {
|
||||
"requirements": {},
|
||||
"packageGroup": ["@nrwl/nx", "@nrwl/schematics", "@nrwl/builders"],
|
||||
"packageGroup": [
|
||||
"@nrwl/nx",
|
||||
"@nrwl/schematics",
|
||||
"@nrwl/builders"
|
||||
],
|
||||
"migrations": "./migrations/migrations.json"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@ -21,12 +21,10 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('not nested', () => {
|
||||
it('should update angular.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp' },
|
||||
appTree
|
||||
);
|
||||
it('should update angular.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||
|
||||
expect(angularJson.projects['my-app'].root).toEqual('apps/my-app/');
|
||||
@ -35,12 +33,10 @@ describe('app', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should update nx.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', tags: 'one,two' },
|
||||
appTree
|
||||
);
|
||||
it('should update nx.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp', tags: 'one,two' }, appTree)
|
||||
.toPromise();
|
||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'proj',
|
||||
@ -55,12 +51,10 @@ describe('app', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp' },
|
||||
appTree
|
||||
);
|
||||
it('should generate files', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||
.toPromise();
|
||||
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/app/app.module.ts')).toBeTruthy();
|
||||
@ -98,17 +92,13 @@ describe('app', () => {
|
||||
expect(tsconfigE2E.extends).toEqual('./tsconfig.json');
|
||||
});
|
||||
|
||||
it('should default the prefix to npmScope', () => {
|
||||
const noPrefix = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp' },
|
||||
appTree
|
||||
);
|
||||
const withPrefix = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', prefix: 'custom' },
|
||||
appTree
|
||||
);
|
||||
it('should default the prefix to npmScope', async () => {
|
||||
const noPrefix = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||
.toPromise();
|
||||
const withPrefix = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp', prefix: 'custom' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
// Testing without prefix
|
||||
|
||||
@ -144,11 +134,9 @@ describe('app', () => {
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const result = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp' },
|
||||
appTree
|
||||
);
|
||||
const result = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
expect(result.exists('apps/my-app/src/main.ts')).toEqual(true);
|
||||
expect(result.exists('apps/my-app-e2e/protractor.conf.js')).toEqual(true);
|
||||
@ -156,12 +144,14 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('nested', () => {
|
||||
it('should update angular.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
it('should update angular.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||
|
||||
expect(angularJson.projects['my-dir-my-app'].root).toEqual(
|
||||
@ -172,12 +162,14 @@ describe('app', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should update nx.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', tags: 'one,two' },
|
||||
appTree
|
||||
);
|
||||
it('should update nx.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', tags: 'one,two' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'proj',
|
||||
@ -192,18 +184,20 @@ describe('app', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate files', () => {
|
||||
it('should generate files', async () => {
|
||||
const hasJsonValue = ({ path, expectedValue, lookupFn }) => {
|
||||
const content = getFileContent(tree, path);
|
||||
const config = JSON.parse(stripJsonComments(content));
|
||||
|
||||
expect(lookupFn(config)).toEqual(expectedValue);
|
||||
};
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const appModulePath = 'apps/my-dir/my-app/src/app/app.module.ts';
|
||||
expect(getFileContent(tree, appModulePath)).toContain('class AppModule');
|
||||
@ -250,24 +244,24 @@ describe('app', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should import NgModule', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
it('should import NgModule', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp', directory: 'myDir' }, appTree)
|
||||
.toPromise();
|
||||
expect(
|
||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
|
||||
).toContain('NxModule.forRoot()');
|
||||
});
|
||||
|
||||
describe('routing', () => {
|
||||
it('should include RouterTestingModule', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', routing: true },
|
||||
appTree
|
||||
);
|
||||
it('should include RouterTestingModule', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', routing: true },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.module.ts')
|
||||
).toContain('RouterModule.forRoot');
|
||||
@ -276,12 +270,14 @@ describe('app', () => {
|
||||
).toContain('imports: [RouterTestingModule]');
|
||||
});
|
||||
|
||||
it('should not modify tests when --skip-tests is set', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', routing: true, skipTests: true },
|
||||
appTree
|
||||
);
|
||||
it('should not modify tests when --skip-tests is set', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', routing: true, skipTests: true },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
tree.exists('apps/my-dir/my-app/src/app/app.component.spec.ts')
|
||||
).toBeFalsy();
|
||||
@ -289,12 +285,14 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('template generation mode', () => {
|
||||
it('should create Nx specific `app.component.html` template', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
it('should create Nx specific `app.component.html` template', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.html')
|
||||
).toBeTruthy();
|
||||
@ -303,12 +301,14 @@ describe('app', () => {
|
||||
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
||||
});
|
||||
|
||||
it("should update `template`'s property of AppComponent with Nx content", () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', inlineTemplate: true },
|
||||
appTree
|
||||
);
|
||||
it("should update `template`'s property of AppComponent with Nx content", async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', directory: 'myDir', inlineTemplate: true },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
getFileContent(tree, 'apps/my-dir/my-app/src/app/app.component.ts')
|
||||
).toContain('This is an Angular CLI app built with Nrwl Nx!');
|
||||
@ -316,23 +316,19 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('--style scss', () => {
|
||||
it('should generate scss styles', () => {
|
||||
const result = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', style: 'scss' },
|
||||
appTree
|
||||
);
|
||||
it('should generate scss styles', async () => {
|
||||
const result = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp', style: 'scss' }, appTree)
|
||||
.toPromise();
|
||||
expect(result.exists('apps/my-app/src/app/app.component.scss')).toEqual(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it('should set it as default', () => {
|
||||
const result = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', style: 'scss' },
|
||||
appTree
|
||||
);
|
||||
it('should set it as default', async () => {
|
||||
const result = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'myApp', style: 'scss' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
const angularJson = readJsonInTree(result, 'angular.json');
|
||||
|
||||
@ -345,12 +341,14 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('--unit-test-runner jest', () => {
|
||||
it('should generate a jest config', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', unitTestRunner: 'jest' },
|
||||
appTree
|
||||
);
|
||||
it('should generate a jest config', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', unitTestRunner: 'jest' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
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/tsconfig.spec.json')).toBeTruthy();
|
||||
@ -380,12 +378,14 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('--unit-test-runner none', () => {
|
||||
it('should not generate test configuration', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', unitTestRunner: 'none' },
|
||||
appTree
|
||||
);
|
||||
it('should not generate test configuration', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', unitTestRunner: 'none' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
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/tsconfig.spec.json')).toBeFalsy();
|
||||
@ -400,12 +400,14 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('--e2e-test-runner none', () => {
|
||||
it('should not generate test configuration', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myApp', e2eTestRunner: 'none' },
|
||||
appTree
|
||||
);
|
||||
it('should not generate test configuration', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'app',
|
||||
{ name: 'myApp', e2eTestRunner: 'none' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
|
||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||
expect(angularJson.projects['my-app-e2e']).toBeUndefined();
|
||||
@ -413,8 +415,10 @@ describe('app', () => {
|
||||
});
|
||||
|
||||
describe('replaceAppNameWithPath', () => {
|
||||
it('should protect `angular.json` commands and properties', () => {
|
||||
const tree = schematicRunner.runSchematic('app', { name: 'ui' }, appTree);
|
||||
it('should protect `angular.json` commands and properties', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'ui' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||
expect(angularJson.projects['ui']).toBeDefined();
|
||||
@ -423,12 +427,10 @@ describe('app', () => {
|
||||
).toEqual('@angular-devkit/build-angular:browser');
|
||||
});
|
||||
|
||||
it('should protect `angular.json` sensible properties value to be renamed', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'ui', prefix: 'ui' },
|
||||
appTree
|
||||
);
|
||||
it('should protect `angular.json` sensible properties value to be renamed', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('app', { name: 'ui', prefix: 'ui' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||
expect(angularJson.projects['ui'].prefix).toEqual('ui');
|
||||
|
||||
@ -84,9 +84,9 @@ function addRouterRootConfiguration(options: NormalizedSchema): Rule {
|
||||
const componentSpecPath = `${
|
||||
options.appProjectRoot
|
||||
}/src/app/app.component.spec.ts`;
|
||||
const componentSpecSource = host.read(componentSpecPath)!.toString(
|
||||
'utf-8'
|
||||
);
|
||||
const componentSpecSource = host
|
||||
.read(componentSpecPath)!
|
||||
.toString('utf-8');
|
||||
const componentSpecSourceFile = ts.createSourceFile(
|
||||
componentSpecPath,
|
||||
componentSpecSource,
|
||||
|
||||
@ -85,8 +85,7 @@
|
||||
"description": "Test runner to use for unit tests",
|
||||
"default": "karma",
|
||||
"x-prompt": {
|
||||
"message":
|
||||
"Which Unit Test Runner would you like to use for the application?",
|
||||
"message": "Which Unit Test Runner would you like to use for the application?",
|
||||
"type": "list",
|
||||
"items": [
|
||||
{
|
||||
@ -103,8 +102,7 @@
|
||||
"description": "Test runner to use for end to end (e2e) tests",
|
||||
"default": "protractor",
|
||||
"x-prompt": {
|
||||
"message":
|
||||
"Which E2E Test Runner would you like to use for the application?",
|
||||
"message": "Which E2E Test Runner would you like to use for the application?",
|
||||
"type": "list",
|
||||
"items": [
|
||||
{
|
||||
@ -121,8 +119,7 @@
|
||||
"tags": {
|
||||
"type": "string",
|
||||
"description": "Add tags to the application (used for linting)",
|
||||
"x-prompt":
|
||||
"Which tags would you like to add to the application? (used for linting)"
|
||||
"x-prompt": "Which tags would you like to add to the application? (used for linting)"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
@ -18,12 +18,14 @@ describe('schematic:cypress-project', () => {
|
||||
});
|
||||
|
||||
describe('generate app --e2e-test-runner=cypress', () => {
|
||||
it('should not contain any protractor files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
);
|
||||
it('should not contain any protractor files', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
expect(
|
||||
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();
|
||||
});
|
||||
|
||||
it('should generate files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
);
|
||||
it('should generate files', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
expect(tree.exists('apps/my-app-e2e/cypress.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();
|
||||
});
|
||||
|
||||
it('should add dependencies into `package.json` file', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
);
|
||||
it('should add dependencies into `package.json` file', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const packageJson = readJsonInTree(tree, 'package.json');
|
||||
|
||||
expect(packageJson.devDependencies.cypress).toBeDefined();
|
||||
expect(packageJson.devDependencies['@nrwl/builders']).toBeDefined();
|
||||
});
|
||||
|
||||
it('should add update `angular.json` file', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
);
|
||||
it('should add update `angular.json` file', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(tree, 'angular.json');
|
||||
const project = angularJson.projects['my-app-e2e'];
|
||||
|
||||
@ -91,12 +99,14 @@ describe('schematic:cypress-project', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should set right path names in `cypress.json`', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
);
|
||||
it('should set right path names in `cypress.json`', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const cypressJson = readJsonInTree(tree, 'apps/my-app-e2e/cypress.json');
|
||||
|
||||
expect(cypressJson).toEqual({
|
||||
@ -112,12 +122,14 @@ describe('schematic:cypress-project', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should set right path names in `tsconfig.e2e.json`', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
);
|
||||
it('should set right path names in `tsconfig.e2e.json`', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
'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', () => {
|
||||
it('should set right path names in `cypress.json`', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
||||
appTree
|
||||
);
|
||||
it('should set right path names in `cypress.json`', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const cypressJson = readJsonInTree(
|
||||
tree,
|
||||
'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`', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
||||
appTree
|
||||
);
|
||||
it('should set right path names in `tsconfig.e2e.json`', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'application',
|
||||
{ name: 'myApp', e2eTestRunner: 'cypress', directory: 'my-dir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
'apps/my-dir/my-app-e2e/tsconfig.e2e.json'
|
||||
|
||||
@ -19,15 +19,17 @@ describe('downgrade-module', () => {
|
||||
appTree = createApp(appTree, 'myapp');
|
||||
});
|
||||
|
||||
it('should update main.ts', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should update main.ts', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const main = getFileContent(tree, '/apps/myapp/src/main.ts');
|
||||
expect(main).toContain('downgradeModule(bootstrapAngular)');
|
||||
@ -37,15 +39,17 @@ describe('downgrade-module', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should update module', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should update module', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const appModule = getFileContent(tree, 'apps/myapp/src/app/app.module.ts');
|
||||
expect(appModule).not.toContain('bootstrap:');
|
||||
@ -53,7 +57,7 @@ describe('downgrade-module', () => {
|
||||
expect(appModule).toContain('ngDoBootstrap');
|
||||
});
|
||||
|
||||
it('should update package.json by default', () => {
|
||||
it('should update package.json by default', async () => {
|
||||
appTree.overwrite(
|
||||
`/package.json`,
|
||||
JSON.stringify({
|
||||
@ -63,21 +67,23 @@ describe('downgrade-module', () => {
|
||||
})
|
||||
);
|
||||
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const packageJson = readJsonInTree(tree, '/package.json');
|
||||
expect(packageJson.dependencies['@angular/upgrade']).toEqual('4.4.4');
|
||||
expect(packageJson.dependencies['angular']).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not package.json when --skipPackageJson=true', () => {
|
||||
it('should not package.json when --skipPackageJson=true', async () => {
|
||||
appTree.overwrite(
|
||||
`/package.json`,
|
||||
JSON.stringify({
|
||||
@ -87,30 +93,34 @@ describe('downgrade-module', () => {
|
||||
})
|
||||
);
|
||||
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
skipPackageJson: true,
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
skipPackageJson: true,
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const packageJson = readJsonInTree(tree, 'package.json');
|
||||
expect(packageJson.dependencies['@angular/upgrade']).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should support custom angularJsImport', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
angularJsImport: 'legacy-app',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should support custom angularJsImport', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'downgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
angularJsImport: 'legacy-app',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const main = getFileContent(tree, '/apps/myapp/src/main.ts');
|
||||
expect(main).toContain(`import 'legacy-app';`);
|
||||
|
||||
@ -18,8 +18,7 @@
|
||||
},
|
||||
"angularJsImport": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
||||
"description": "Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files",
|
||||
@ -29,8 +28,7 @@
|
||||
"skipPackageJson": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
||||
"description": "Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
||||
}
|
||||
},
|
||||
"required": ["project"]
|
||||
|
||||
@ -12,40 +12,46 @@ describe('lib', () => {
|
||||
|
||||
let appTree: Tree;
|
||||
|
||||
beforeEach(() => {
|
||||
beforeEach(async () => {
|
||||
appTree = new VirtualTree();
|
||||
appTree = createEmptyWorkspace(appTree);
|
||||
appTree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'lib1',
|
||||
unitTestRunner: 'none'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
appTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'lib1',
|
||||
unitTestRunner: 'none'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
});
|
||||
|
||||
it('should generate files', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should generate files', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(resultTree.exists('/libs/lib1/src/test-setup.ts')).toBeTruthy();
|
||||
expect(resultTree.exists('/libs/lib1/jest.config.js')).toBeTruthy();
|
||||
expect(resultTree.exists('/libs/lib1/tsconfig.spec.json')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should alter angular.json', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should alter angular.json', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||
expect(angularJson.projects.lib1.architect.test).toEqual({
|
||||
builder: '@nrwl/builders:jest',
|
||||
@ -60,14 +66,16 @@ describe('lib', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should create a jest.config.js', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should create a jest.config.js', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(resultTree.readContent('libs/lib1/jest.config.js'))
|
||||
.toBe(`module.exports = {
|
||||
name: 'lib1',
|
||||
@ -77,27 +85,31 @@ describe('lib', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should update the local tsconfig.json', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should update the local tsconfig.json', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const tsConfig = readJsonInTree(resultTree, 'libs/lib1/tsconfig.json');
|
||||
expect(tsConfig.compilerOptions.types).toContain('jest');
|
||||
expect(tsConfig.compilerOptions.types).toContain('node');
|
||||
});
|
||||
|
||||
it('should create a tsconfig.spec.json', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should create a tsconfig.spec.json', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const tsConfig = readJsonInTree(resultTree, 'libs/lib1/tsconfig.spec.json');
|
||||
expect(tsConfig).toEqual({
|
||||
extends: './tsconfig.json',
|
||||
@ -112,42 +124,48 @@ describe('lib', () => {
|
||||
});
|
||||
|
||||
describe('--skip-setup-file', () => {
|
||||
it('should generate src/test-setup.ts', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1',
|
||||
skipSetupFile: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should generate src/test-setup.ts', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1',
|
||||
skipSetupFile: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(resultTree.exists('src/test-setup.ts')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not list the setup file in angular.json', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1',
|
||||
skipSetupFile: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should not list the setup file in angular.json', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1',
|
||||
skipSetupFile: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(resultTree, 'angular.json');
|
||||
expect(
|
||||
angularJson.projects.lib1.architect.test.options.setupFile
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should not list the setup file in tsconfig.spec.json', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1',
|
||||
skipSetupFile: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should not list the setup file in tsconfig.spec.json', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'jest-project',
|
||||
{
|
||||
project: 'lib1',
|
||||
skipSetupFile: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const tsConfig = readJsonInTree(
|
||||
resultTree,
|
||||
'libs/lib1/tsconfig.spec.json'
|
||||
|
||||
@ -21,12 +21,10 @@ describe('lib', () => {
|
||||
});
|
||||
|
||||
describe('not nested', () => {
|
||||
it('should update ng-package.json', () => {
|
||||
const publishableTree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: true },
|
||||
appTree
|
||||
);
|
||||
it('should update ng-package.json', async () => {
|
||||
const publishableTree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||
.toPromise();
|
||||
let ngPackage = readJsonInTree(
|
||||
publishableTree,
|
||||
'libs/my-lib/ng-package.json'
|
||||
@ -35,76 +33,70 @@ describe('lib', () => {
|
||||
expect(ngPackage.dest).toEqual('../../dist/libs/my-lib');
|
||||
});
|
||||
|
||||
it('should not update package.json by default', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib' },
|
||||
appTree
|
||||
);
|
||||
it('should not update package.json by default', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||
.toPromise();
|
||||
const packageJson = readJsonInTree(tree, '/package.json');
|
||||
expect(packageJson.devDependencies['ng-packagr']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should update package.json when publishable', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: true },
|
||||
appTree
|
||||
);
|
||||
it('should update package.json when publishable', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||
.toPromise();
|
||||
const packageJson = readJsonInTree(tree, '/package.json');
|
||||
expect(packageJson.devDependencies['ng-packagr']).toBeDefined();
|
||||
});
|
||||
|
||||
it("should update npmScope of lib's package.json when publishable", () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: true },
|
||||
appTree
|
||||
);
|
||||
it("should update npmScope of lib's package.json when publishable", async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||
.toPromise();
|
||||
const packageJson = readJsonInTree(tree, '/libs/my-lib/package.json');
|
||||
expect(packageJson.name).toEqual('@proj/my-lib');
|
||||
});
|
||||
|
||||
it("should update npmScope of lib's package.json when publishable", () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: true, prefix: 'lib' },
|
||||
appTree
|
||||
);
|
||||
it("should update npmScope of lib's package.json when publishable", async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: true, prefix: 'lib' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const packageJson = readJsonInTree(tree, '/libs/my-lib/package.json');
|
||||
expect(packageJson.name).toEqual('@proj/my-lib');
|
||||
});
|
||||
|
||||
it('should update angular.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: true },
|
||||
appTree
|
||||
);
|
||||
it('should update angular.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', publishable: true }, appTree)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||
|
||||
expect(angularJson.projects['my-lib'].root).toEqual('libs/my-lib');
|
||||
expect(angularJson.projects['my-lib'].architect.build).toBeDefined();
|
||||
});
|
||||
|
||||
it('should remove "build" target from angular.json when a library is not publishable', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: false },
|
||||
appTree
|
||||
);
|
||||
it('should remove "build" target from angular.json when a library is not publishable', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', publishable: false },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||
|
||||
expect(angularJson.projects['my-lib'].root).toEqual('libs/my-lib');
|
||||
expect(angularJson.projects['my-lib'].architect.build).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should update nx.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', tags: 'one,two' },
|
||||
appTree
|
||||
);
|
||||
it('should update nx.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', tags: 'one,two' }, appTree)
|
||||
.toPromise();
|
||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'proj',
|
||||
@ -116,24 +108,20 @@ describe('lib', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should update root tsconfig.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib' },
|
||||
appTree
|
||||
);
|
||||
it('should update root tsconfig.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||
.toPromise();
|
||||
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
|
||||
'libs/my-lib/src/index.ts'
|
||||
]);
|
||||
});
|
||||
|
||||
it('should create a local tsconfig.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib' },
|
||||
appTree
|
||||
);
|
||||
it('should create a local tsconfig.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
const tsconfigJson = readJsonInTree(tree, 'libs/my-lib/tsconfig.json');
|
||||
expect(tsconfigJson).toEqual({
|
||||
@ -145,12 +133,10 @@ describe('lib', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should extend the local tsconfig.json with tsconfig.spec.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib' },
|
||||
appTree
|
||||
);
|
||||
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
@ -159,12 +145,10 @@ describe('lib', () => {
|
||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||
});
|
||||
|
||||
it('should extend the local tsconfig.json with tsconfig.lib.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib' },
|
||||
appTree
|
||||
);
|
||||
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
@ -173,12 +157,10 @@ describe('lib', () => {
|
||||
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
|
||||
});
|
||||
|
||||
it('should generate files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib' },
|
||||
appTree
|
||||
);
|
||||
it('should generate files', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||
.toPromise();
|
||||
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/lib/my-lib.module.ts')).toBeTruthy();
|
||||
@ -194,11 +176,13 @@ describe('lib', () => {
|
||||
tree.exists('libs/my-lib/src/lib/my-lib.service.spec.ts')
|
||||
).toBeFalsy();
|
||||
|
||||
const tree2 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib2', simpleModuleName: true },
|
||||
tree
|
||||
);
|
||||
const tree2 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib2', simpleModuleName: true },
|
||||
tree
|
||||
)
|
||||
.toPromise();
|
||||
expect(tree2.exists(`libs/my-lib2/karma.conf.js`)).toBeTruthy();
|
||||
expect(tree2.exists('libs/my-lib2/src/index.ts')).toBeTruthy();
|
||||
expect(
|
||||
@ -219,12 +203,10 @@ describe('lib', () => {
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should not generate a module for --module false', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', module: false },
|
||||
appTree
|
||||
);
|
||||
it('should not generate a module for --module false', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', module: false }, appTree)
|
||||
.toPromise();
|
||||
expect(tree.exists('libs/my-lib/src/lib/my-lib.module.ts')).toEqual(
|
||||
false
|
||||
);
|
||||
@ -234,22 +216,18 @@ describe('lib', () => {
|
||||
expect(tree.exists('libs/my-lib/src/lib/.gitkeep')).toEqual(true);
|
||||
});
|
||||
|
||||
it('should default the prefix to npmScope', () => {
|
||||
const noPrefix = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib' },
|
||||
appTree
|
||||
);
|
||||
it('should default the prefix to npmScope', async () => {
|
||||
const noPrefix = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib' }, appTree)
|
||||
.toPromise();
|
||||
expect(
|
||||
JSON.parse(noPrefix.read('angular.json').toString()).projects['my-lib']
|
||||
.prefix
|
||||
).toEqual('proj');
|
||||
|
||||
const withPrefix = schematicRunner.runSchematic(
|
||||
'app',
|
||||
{ name: 'myLib', prefix: 'custom' },
|
||||
appTree
|
||||
);
|
||||
const withPrefix = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', prefix: 'custom' }, appTree)
|
||||
.toPromise();
|
||||
expect(
|
||||
JSON.parse(withPrefix.read('angular.json').toString()).projects[
|
||||
'my-lib'
|
||||
@ -259,12 +237,14 @@ describe('lib', () => {
|
||||
});
|
||||
|
||||
describe('nested', () => {
|
||||
it('should update nx.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', tags: 'one' },
|
||||
appTree
|
||||
);
|
||||
it('should update nx.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', tags: 'one' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const nxJson = readJsonInTree<NxJson>(tree, '/nx.json');
|
||||
expect(nxJson).toEqual({
|
||||
npmScope: 'proj',
|
||||
@ -275,16 +255,18 @@ describe('lib', () => {
|
||||
}
|
||||
});
|
||||
|
||||
const tree2 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
tags: 'one,two',
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree
|
||||
);
|
||||
const tree2 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
tags: 'one,two',
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree
|
||||
)
|
||||
.toPromise();
|
||||
const nxJson2 = readJsonInTree<NxJson>(tree2, '/nx.json');
|
||||
expect(nxJson2).toEqual({
|
||||
npmScope: 'proj',
|
||||
@ -299,12 +281,14 @@ describe('lib', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should generate files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
it('should generate files', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
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(
|
||||
@ -324,11 +308,13 @@ describe('lib', () => {
|
||||
tree.exists('libs/my-dir/my-lib/src/lib/my-lib.service.spec.ts')
|
||||
).toBeFalsy();
|
||||
|
||||
const tree2 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib2', directory: 'myDir', simpleModuleName: true },
|
||||
tree
|
||||
);
|
||||
const tree2 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib2', directory: 'myDir', simpleModuleName: true },
|
||||
tree
|
||||
)
|
||||
.toPromise();
|
||||
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(
|
||||
@ -349,12 +335,14 @@ describe('lib', () => {
|
||||
).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should update ng-package.json', () => {
|
||||
const publishableTree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', publishable: true },
|
||||
appTree
|
||||
);
|
||||
it('should update ng-package.json', async () => {
|
||||
const publishableTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', publishable: true },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
let ngPackage = readJsonInTree(
|
||||
publishableTree,
|
||||
@ -363,12 +351,14 @@ describe('lib', () => {
|
||||
expect(ngPackage.dest).toEqual('../../../dist/libs/my-dir/my-lib');
|
||||
});
|
||||
|
||||
it('should update angular.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
it('should update angular.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const angularJson = readJsonInTree(tree, '/angular.json');
|
||||
|
||||
expect(angularJson.projects['my-dir-my-lib'].root).toEqual(
|
||||
@ -376,12 +366,14 @@ describe('lib', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('should update tsconfig.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
it('should update tsconfig.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const tsconfigJson = readJsonInTree(tree, '/tsconfig.json');
|
||||
expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual(
|
||||
['libs/my-dir/my-lib/src/index.ts']
|
||||
@ -391,12 +383,14 @@ describe('lib', () => {
|
||||
).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should create a local tsconfig.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
);
|
||||
it('should create a local tsconfig.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const tsconfigJson = readJsonInTree(
|
||||
tree,
|
||||
@ -411,12 +405,14 @@ describe('lib', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should not generate a module for --module false', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', module: false },
|
||||
appTree
|
||||
);
|
||||
it('should not generate a module for --module false', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', module: false },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
||||
).toEqual(false);
|
||||
@ -428,23 +424,26 @@ describe('lib', () => {
|
||||
});
|
||||
|
||||
describe('router', () => {
|
||||
it('should error when lazy is set without routing', () => {
|
||||
expect(() =>
|
||||
schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', lazy: true },
|
||||
appTree
|
||||
)
|
||||
).toThrow('routing must be set');
|
||||
it('should error when lazy is set without routing', async () => {
|
||||
try {
|
||||
await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', lazy: true }, appTree)
|
||||
.toPromise();
|
||||
fail();
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('routing must be set');
|
||||
}
|
||||
});
|
||||
|
||||
describe('lazy', () => {
|
||||
it('should add RouterModule.forChild', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', routing: true, lazy: true },
|
||||
appTree
|
||||
);
|
||||
it('should add RouterModule.forChild', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', routing: true, lazy: true },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
expect(
|
||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
||||
@ -456,17 +455,19 @@ describe('lib', () => {
|
||||
)
|
||||
).toContain('RouterModule.forChild');
|
||||
|
||||
const tree2 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree
|
||||
);
|
||||
const tree2 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
expect(
|
||||
tree2.exists('libs/my-dir/my-lib2/src/lib/my-lib2.module.ts')
|
||||
@ -476,24 +477,30 @@ describe('lib', () => {
|
||||
).toContain('RouterModule.forChild');
|
||||
});
|
||||
|
||||
it('should update the parent module', () => {
|
||||
it('should update the parent module', async () => {
|
||||
appTree = createApp(appTree, 'myapp');
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree, 'apps/myapp/src/app/app.module.ts')
|
||||
).toContain(
|
||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'}])`
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const moduleContents = getFileContent(
|
||||
tree,
|
||||
'apps/myapp/src/app/app.module.ts'
|
||||
);
|
||||
expect(moduleContents).toContain('RouterModule.forRoot([');
|
||||
expect(moduleContents).toContain(`{
|
||||
path: 'my-dir-my-lib',
|
||||
loadChildren: '@proj/my-dir/my-lib#MyDirMyLibModule'
|
||||
}`);
|
||||
|
||||
const tsConfigAppJson = JSON.parse(
|
||||
stripJsonComments(
|
||||
@ -505,22 +512,32 @@ describe('lib', () => {
|
||||
'../../libs/my-dir/my-lib/src/index.ts'
|
||||
]);
|
||||
|
||||
const tree2 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
tree
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree2, 'apps/myapp/src/app/app.module.ts')
|
||||
).toContain(
|
||||
`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'}])`
|
||||
const tree2 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
tree
|
||||
)
|
||||
.toPromise();
|
||||
const moduleContents2 = getFileContent(
|
||||
tree2,
|
||||
'apps/myapp/src/app/app.module.ts'
|
||||
);
|
||||
expect(moduleContents2).toContain('RouterModule.forRoot([');
|
||||
expect(moduleContents2).toContain(`{
|
||||
path: 'my-dir-my-lib',
|
||||
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(
|
||||
stripJsonComments(
|
||||
@ -533,22 +550,35 @@ describe('lib', () => {
|
||||
'../../libs/my-dir/my-lib2/src/index.ts'
|
||||
]);
|
||||
|
||||
const tree3 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib3',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts',
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree2
|
||||
const tree3 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib3',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
lazy: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts',
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree2
|
||||
)
|
||||
.toPromise();
|
||||
const moduleContents3 = getFileContent(
|
||||
tree3,
|
||||
'apps/myapp/src/app/app.module.ts'
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree3, 'apps/myapp/src/app/app.module.ts')
|
||||
).toContain(
|
||||
`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'}])`
|
||||
expect(moduleContents3).toContain('RouterModule.forRoot([');
|
||||
expect(moduleContents3).toContain(`{
|
||||
path: 'my-dir-my-lib',
|
||||
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(
|
||||
@ -566,12 +596,14 @@ describe('lib', () => {
|
||||
});
|
||||
|
||||
describe('eager', () => {
|
||||
it('should add RouterModule and define an array of routes', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', routing: true },
|
||||
appTree
|
||||
);
|
||||
it('should add RouterModule and define an array of routes', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', directory: 'myDir', routing: true },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
tree.exists('libs/my-dir/my-lib/src/lib/my-dir-my-lib.module.ts')
|
||||
).toBeTruthy();
|
||||
@ -588,16 +620,18 @@ describe('lib', () => {
|
||||
)
|
||||
).toContain('const myDirMyLibRoutes: Route[] = ');
|
||||
|
||||
const tree2 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree
|
||||
);
|
||||
const tree2 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
tree2.exists('libs/my-dir/my-lib2/src/lib/my-lib2.module.ts')
|
||||
).toBeTruthy();
|
||||
@ -609,67 +643,89 @@ describe('lib', () => {
|
||||
).toContain('const myLib2Routes: Route[] = ');
|
||||
});
|
||||
|
||||
it('should update the parent module', () => {
|
||||
it('should update the parent module', async () => {
|
||||
appTree = createApp(appTree, 'myapp');
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const moduleContents = getFileContent(
|
||||
tree,
|
||||
'apps/myapp/src/app/app.module.ts'
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree, 'apps/myapp/src/app/app.module.ts')
|
||||
).toContain(
|
||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', children: myDirMyLibRoutes}])`
|
||||
expect(moduleContents).toContain('RouterModule.forRoot([');
|
||||
expect(moduleContents).toContain(
|
||||
"{ path: 'my-dir-my-lib', children: myDirMyLibRoutes }"
|
||||
);
|
||||
|
||||
const tree2 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
tree
|
||||
const tree2 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib2',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
tree
|
||||
)
|
||||
.toPromise();
|
||||
const moduleContents2 = getFileContent(
|
||||
tree2,
|
||||
'apps/myapp/src/app/app.module.ts'
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree2, 'apps/myapp/src/app/app.module.ts')
|
||||
).toContain(
|
||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', children: myDirMyLibRoutes}, {path: 'my-dir-my-lib2', children: myDirMyLib2Routes}])`
|
||||
expect(moduleContents2).toContain('RouterModule.forRoot([');
|
||||
expect(moduleContents2).toContain(
|
||||
"{ path: 'my-dir-my-lib', children: myDirMyLibRoutes }"
|
||||
);
|
||||
expect(moduleContents2).toContain(
|
||||
"{ path: 'my-dir-my-lib2', children: myDirMyLib2Routes }"
|
||||
);
|
||||
|
||||
const tree3 = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib3',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts',
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree2
|
||||
const tree3 = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{
|
||||
name: 'myLib3',
|
||||
directory: 'myDir',
|
||||
routing: true,
|
||||
parentModule: 'apps/myapp/src/app/app.module.ts',
|
||||
simpleModuleName: true
|
||||
},
|
||||
tree2
|
||||
)
|
||||
.toPromise();
|
||||
const moduleContents3 = getFileContent(
|
||||
tree3,
|
||||
'apps/myapp/src/app/app.module.ts'
|
||||
);
|
||||
expect(
|
||||
getFileContent(tree3, 'apps/myapp/src/app/app.module.ts')
|
||||
).toContain(
|
||||
`RouterModule.forRoot([{path: 'my-dir-my-lib', children: myDirMyLibRoutes}, {path: 'my-dir-my-lib2', children: myDirMyLib2Routes}, {path: 'my-lib3', children: myLib3Routes}])`
|
||||
expect(moduleContents3).toContain('RouterModule.forRoot([');
|
||||
expect(moduleContents3).toContain(
|
||||
"{ path: 'my-dir-my-lib', children: myDirMyLibRoutes }"
|
||||
);
|
||||
expect(moduleContents3).toContain(
|
||||
"{ path: 'my-dir-my-lib2', children: myDirMyLib2Routes }"
|
||||
);
|
||||
expect(moduleContents3).toContain(
|
||||
"{ path: 'my-lib3', children: myLib3Routes }"
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('--style scss', () => {
|
||||
it('should set it as default', () => {
|
||||
const result = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', style: 'scss' },
|
||||
appTree
|
||||
);
|
||||
it('should set it as default', async () => {
|
||||
const result = await schematicRunner
|
||||
.runSchematicAsync('lib', { name: 'myLib', style: 'scss' }, appTree)
|
||||
.toPromise();
|
||||
|
||||
const angularJson = readJsonInTree(result, 'angular.json');
|
||||
|
||||
@ -682,12 +738,14 @@ describe('lib', () => {
|
||||
});
|
||||
|
||||
describe('--unit-test-runner jest', () => {
|
||||
it('should generate jest configuration', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'jest' },
|
||||
appTree
|
||||
);
|
||||
it('should generate jest configuration', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'jest' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
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/tsconfig.spec.json')).toBeTruthy();
|
||||
@ -704,23 +762,27 @@ describe('lib', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('should skip the setup file if no module is generated', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'jest', module: false },
|
||||
appTree
|
||||
);
|
||||
it('should skip the setup file if no module is generated', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'jest', module: false },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(resultTree.exists('libs/my-lib/src/test-setup.ts')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('--unit-test-runner none', () => {
|
||||
it('should not generate test configuration', () => {
|
||||
const resultTree = schematicRunner.runSchematic(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'none' },
|
||||
appTree
|
||||
);
|
||||
it('should not generate test configuration', async () => {
|
||||
const resultTree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'lib',
|
||||
{ name: 'myLib', unitTestRunner: 'none' },
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
expect(
|
||||
resultTree.exists('libs/my-lib/src/lib/my-lib.module.spec.ts')
|
||||
).toBeFalsy();
|
||||
|
||||
@ -51,8 +51,7 @@
|
||||
},
|
||||
"parentModule": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"Update the router configuration of the parent module using loadChildren or children, depending on what `lazy` is set to.",
|
||||
"description": "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?"
|
||||
},
|
||||
"style": {
|
||||
@ -75,14 +74,12 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Add router configuration. See lazy for more information.",
|
||||
"x-prompt":
|
||||
"Would you like to add a routing configuration to the library?"
|
||||
"x-prompt": "Would you like to add a routing configuration to the library?"
|
||||
},
|
||||
"lazy": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Add RouterModule.forChild when set to true, and a simple array of routes when set to false.",
|
||||
"description": "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?"
|
||||
},
|
||||
"module": {
|
||||
@ -94,8 +91,7 @@
|
||||
"tags": {
|
||||
"type": "string",
|
||||
"description": "Add tags to the library (used for linting)",
|
||||
"x-prompt":
|
||||
"Which tags would you like to add to the library? (used for linting)"
|
||||
"x-prompt": "Which tags would you like to add to the library? (used for linting)"
|
||||
},
|
||||
"unitTestRunner": {
|
||||
"type": "string",
|
||||
@ -103,8 +99,7 @@
|
||||
"description": "Test runner to use for unit tests",
|
||||
"default": "karma",
|
||||
"x-prompt": {
|
||||
"message":
|
||||
"Which Unit Test Runner would you like to use for the library?",
|
||||
"message": "Which Unit Test Runner would you like to use for the library?",
|
||||
"type": "list",
|
||||
"items": [
|
||||
{ "value": "karma", "label": "Karma" },
|
||||
|
||||
@ -8,8 +8,7 @@
|
||||
"npmScope": {
|
||||
"type": "string",
|
||||
"description": "Npm scope for importing libs.",
|
||||
"x-prompt":
|
||||
"What is the npm scope you would like to use for your Nx Workspace?"
|
||||
"x-prompt": "What is the npm scope you would like to use for your Nx Workspace?"
|
||||
},
|
||||
"skipInstall": {
|
||||
"type": "boolean",
|
||||
|
||||
@ -62,7 +62,9 @@ function addTasks(options: Schema, context: SchematicContext) {
|
||||
const commit =
|
||||
typeof options.commit == 'object'
|
||||
? options.commit
|
||||
: !!options.commit ? {} : false;
|
||||
: !!options.commit
|
||||
? {}
|
||||
: false;
|
||||
context.addTask(
|
||||
new RepositoryInitializerTask(options.directory, commit),
|
||||
packageTask ? [packageTask] : []
|
||||
|
||||
@ -39,8 +39,7 @@
|
||||
"npmScope": {
|
||||
"type": "string",
|
||||
"description": "Npm scope for importing libs.",
|
||||
"x-prompt":
|
||||
"What is the npm scope you would like to use for your Nx Workspace?"
|
||||
"x-prompt": "What is the npm scope you would like to use for your Nx Workspace?"
|
||||
},
|
||||
"skipInstall": {
|
||||
"description": "Skip installing dependency packages.",
|
||||
@ -57,8 +56,7 @@
|
||||
"type": "string",
|
||||
"description": "Package manager used in the project.",
|
||||
"x-prompt": {
|
||||
"message":
|
||||
"Which Package Manager would you like to use for your workspace?",
|
||||
"message": "Which Package Manager would you like to use for your workspace?",
|
||||
"type": "list",
|
||||
"items": [
|
||||
{ "value": "npm", "label": "" },
|
||||
|
||||
@ -31,38 +31,43 @@ describe('ngrx', () => {
|
||||
appTree = createApp(appTree, 'myapp');
|
||||
});
|
||||
|
||||
it('should add empty root', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
onlyEmptyRoot: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should add empty root', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
onlyEmptyRoot: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||
|
||||
expect(
|
||||
tree.exists('apps/myapp/src/app/+state/state.actions.ts')
|
||||
).toBeFalsy();
|
||||
|
||||
expect(appModule).toContain('StoreModule.forRoot(');
|
||||
expect(appModule).toContain(
|
||||
'StoreModule.forRoot({},{ metaReducers : !environment.production ? [storeFreeze] : [] })'
|
||||
'{ metaReducers: !environment.production ? [storeFreeze] : [] }'
|
||||
);
|
||||
expect(appModule).toContain('EffectsModule.forRoot');
|
||||
});
|
||||
|
||||
it('should add root', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'app',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
root: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should add root', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'app',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
root: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
[
|
||||
'/apps/myapp/src/app/+state/app.actions.ts',
|
||||
@ -91,20 +96,22 @@ describe('ngrx', () => {
|
||||
expect(appModule).toContain('!environment.production ? [storeFreeze] : []');
|
||||
|
||||
expect(appModule).toContain('app: appReducer');
|
||||
expect(appModule).toContain('initialState : { app : appInitialState }');
|
||||
expect(appModule).toContain('initialState: { app: appInitialState }');
|
||||
});
|
||||
|
||||
it('should add facade to root', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'app',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
root: true,
|
||||
facade: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should add facade to root', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'app',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
root: true,
|
||||
facade: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||
|
||||
@ -118,7 +125,7 @@ describe('ngrx', () => {
|
||||
expect(appModule).toContain('providers: [AppFacade]');
|
||||
|
||||
expect(appModule).toContain('app: appReducer');
|
||||
expect(appModule).toContain('initialState : { app : appInitialState }');
|
||||
expect(appModule).toContain('initialState: { app: appInitialState }');
|
||||
|
||||
[
|
||||
'/apps/myapp/src/app/+state/app.actions.ts',
|
||||
@ -135,17 +142,19 @@ 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 tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'app',
|
||||
module: 'apps/myapp-norouter/src/app/app.module.ts',
|
||||
root: true
|
||||
},
|
||||
newTree
|
||||
);
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'app',
|
||||
module: 'apps/myapp-norouter/src/app/app.module.ts',
|
||||
root: true
|
||||
},
|
||||
newTree
|
||||
)
|
||||
.toPromise();
|
||||
const appModule = getFileContent(
|
||||
tree,
|
||||
'/apps/myapp-norouter/src/app/app.module.ts'
|
||||
@ -153,21 +162,23 @@ describe('ngrx', () => {
|
||||
expect(appModule).not.toContain('StoreRouterConnectingModule');
|
||||
});
|
||||
|
||||
it('should add feature', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should add feature', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||
expect(appModule).toContain('StoreModule.forFeature');
|
||||
expect(appModule).toContain('EffectsModule.forFeature');
|
||||
expect(appModule).toContain('STATE_FEATURE_KEY, stateReducer');
|
||||
expect(appModule).toContain('{ initialState: stateInitialState }');
|
||||
expect(appModule).toContain('initialState: stateInitialState');
|
||||
expect(appModule).not.toContain(
|
||||
'!environment.production ? [storeFreeze] : []'
|
||||
);
|
||||
@ -177,16 +188,18 @@ describe('ngrx', () => {
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should add with custom directoryName', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
directory: 'myCustomState'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should add with custom directoryName', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
directory: 'myCustomState'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||
expect(appModule).toContain('StoreModule.forFeature');
|
||||
@ -200,17 +213,19 @@ describe('ngrx', () => {
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should only add files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
onlyAddFiles: true,
|
||||
facade: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should only add files', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts',
|
||||
onlyAddFiles: true,
|
||||
facade: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||
expect(appModule).not.toContain('StoreModule');
|
||||
@ -231,15 +246,17 @@ describe('ngrx', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should update package.json', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should update package.json', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'apps/myapp/src/app/app.module.ts'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
const packageJson = readJsonInTree(tree, 'package.json');
|
||||
|
||||
expect(packageJson.dependencies['@ngrx/store']).toBeDefined();
|
||||
@ -249,40 +266,49 @@ describe('ngrx', () => {
|
||||
expect(packageJson.devDependencies['ngrx-store-freeze']).toBeDefined();
|
||||
});
|
||||
|
||||
it('should error when no module is provided', () => {
|
||||
expect(() =>
|
||||
schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: ''
|
||||
},
|
||||
appTree
|
||||
)
|
||||
).toThrow('The required --module option must be passed');
|
||||
it('should error when no module is provided', async () => {
|
||||
try {
|
||||
await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: ''
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
fail();
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('The required --module option must be passed');
|
||||
}
|
||||
});
|
||||
|
||||
it('should error the module could not be found', () => {
|
||||
expect(() =>
|
||||
schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'does-not-exist.ts'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
).toThrow('Path does not exist: does-not-exist.ts');
|
||||
it('should error the module could not be found', async () => {
|
||||
try {
|
||||
await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'state',
|
||||
module: 'does-not-exist.ts'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
} catch (e) {
|
||||
expect(e.message).toEqual('Path does not exist: does-not-exist.ts');
|
||||
}
|
||||
});
|
||||
|
||||
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 hasFile = file => expect(tree.exists(file)).toBeTruthy();
|
||||
const missingFile = file => expect(tree.exists(file)).not.toBeTruthy();
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
|
||||
const tree = buildNgrxTree(appConfig);
|
||||
const tree = await buildNgrxTree(appConfig);
|
||||
|
||||
hasFile(`${statePath}/user.actions.ts`);
|
||||
hasFile(`${statePath}/user.effects.ts`);
|
||||
@ -294,10 +320,10 @@ describe('ngrx', () => {
|
||||
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 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`;
|
||||
|
||||
hasFile(`${statePath}/user.actions.ts`);
|
||||
@ -312,18 +338,18 @@ describe('ngrx', () => {
|
||||
hasFile(`${statePath}/user.facade.spec.ts`);
|
||||
});
|
||||
|
||||
it('should build the ngrx actions', () => {
|
||||
it('should build the ngrx actions', async () => {
|
||||
const appConfig = getAppConfig();
|
||||
const tree = buildNgrxTree(appConfig, 'users');
|
||||
const tree = await buildNgrxTree(appConfig, 'users');
|
||||
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
const content = getFileContent(tree, `${statePath}/users.actions.ts`);
|
||||
|
||||
expect(content).toContain('UsersActionTypes');
|
||||
|
||||
expect(content).toContain('LoadUsers = "[Users] Load Users"');
|
||||
expect(content).toContain('UsersLoaded = "[Users] Users Loaded"');
|
||||
expect(content).toContain('UsersLoadError = "[Users] Users Load Error"');
|
||||
expect(content).toContain("LoadUsers = '[Users] Load Users'");
|
||||
expect(content).toContain("UsersLoaded = '[Users] Users Loaded'");
|
||||
expect(content).toContain("UsersLoadError = '[Users] Users Load Error'");
|
||||
|
||||
expect(content).toContain('class LoadUsers implements Action');
|
||||
expect(content).toContain('class UsersLoaded implements Action');
|
||||
@ -333,9 +359,9 @@ describe('ngrx', () => {
|
||||
expect(content).toContain('export const fromUsersActions');
|
||||
});
|
||||
|
||||
it('should build the ngrx selectors', () => {
|
||||
it('should build the ngrx selectors', async () => {
|
||||
const appConfig = getAppConfig();
|
||||
const tree = buildNgrxTree(appConfig, 'users');
|
||||
const tree = await buildNgrxTree(appConfig, 'users');
|
||||
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
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 includeFacade = true;
|
||||
const tree = buildNgrxTree(appConfig, 'users', includeFacade);
|
||||
const tree = await buildNgrxTree(appConfig, 'users', includeFacade);
|
||||
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
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 tree = buildNgrxTree(appConfig, 'user');
|
||||
const tree = await buildNgrxTree(appConfig, 'user');
|
||||
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
const content = getFileContent(tree, `${statePath}/user.reducer.ts`);
|
||||
@ -380,28 +406,34 @@ describe('ngrx', () => {
|
||||
`export interface UserState`,
|
||||
'export function userReducer',
|
||||
'state: UserState = initialState',
|
||||
'action: UserAction): UserState',
|
||||
'action: UserAction',
|
||||
'): UserState',
|
||||
'case UserActionTypes.UserLoaded'
|
||||
].forEach(text => {
|
||||
expect(content).toContain(text);
|
||||
});
|
||||
});
|
||||
|
||||
it('should build the ngrx effects', () => {
|
||||
it('should build the ngrx effects', async () => {
|
||||
const appConfig = getAppConfig();
|
||||
const tree = buildNgrxTree(appConfig, 'users');
|
||||
const tree = await buildNgrxTree(appConfig, 'users');
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
const content = getFileContent(tree, `${statePath}/users.effects.ts`);
|
||||
|
||||
[
|
||||
`import { DataPersistence } from \'@nrwl/nx\'`,
|
||||
`import { LoadUsers, UsersLoaded, UsersLoadError, UsersActionTypes } from \'./users.actions\'`,
|
||||
`import {
|
||||
LoadUsers,
|
||||
UsersLoaded,
|
||||
UsersLoadError,
|
||||
UsersActionTypes
|
||||
} from \'./users.actions\';`,
|
||||
`loadUsers$`,
|
||||
`run: (action: LoadUsers, state: UsersPartialState)`,
|
||||
`return new UsersLoaded([])`,
|
||||
`return new UsersLoadError(error)`,
|
||||
'private actions$: Actions',
|
||||
'private dataPersistence: DataPersistence<UsersPartialState>)'
|
||||
'private dataPersistence: DataPersistence<UsersPartialState>'
|
||||
].forEach(text => {
|
||||
expect(content).toContain(text);
|
||||
});
|
||||
@ -409,9 +441,9 @@ describe('ngrx', () => {
|
||||
});
|
||||
|
||||
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 tree = buildNgrxTree(appConfig);
|
||||
const tree = await buildNgrxTree(appConfig);
|
||||
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
const contents = tree.readContent(`${statePath}/user.reducer.spec.ts`);
|
||||
@ -422,18 +454,20 @@ 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');
|
||||
let libConfig = getLibConfig();
|
||||
let tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'super-users',
|
||||
module: libConfig.module,
|
||||
facade: true
|
||||
},
|
||||
appTree
|
||||
);
|
||||
let tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'super-users',
|
||||
module: libConfig.module,
|
||||
facade: true
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const barrel = tree.readContent(libConfig.barrel);
|
||||
expect(barrel).toContain(
|
||||
@ -441,18 +475,20 @@ 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');
|
||||
let libConfig = getLibConfig();
|
||||
let tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'super-users',
|
||||
module: libConfig.module,
|
||||
facade: false
|
||||
},
|
||||
appTree
|
||||
);
|
||||
let tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'super-users',
|
||||
module: libConfig.module,
|
||||
facade: false
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const barrel = tree.readContent(libConfig.barrel);
|
||||
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 tree = schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'super-users',
|
||||
module: appConfig.appModule
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: 'super-users',
|
||||
module: appConfig.appModule
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const statePath = `${findModuleParent(appConfig.appModule)}/+state`;
|
||||
const contents = tree.readContent(
|
||||
@ -483,19 +521,21 @@ describe('ngrx', () => {
|
||||
});
|
||||
});
|
||||
|
||||
function buildNgrxTree(
|
||||
async function buildNgrxTree(
|
||||
appConfig: AppConfig,
|
||||
featureName: string = 'user',
|
||||
withFacade = false
|
||||
): UnitTestTree {
|
||||
return schematicRunner.runSchematic(
|
||||
'ngrx',
|
||||
{
|
||||
name: featureName,
|
||||
module: appConfig.appModule,
|
||||
facade: withFacade
|
||||
},
|
||||
appTree
|
||||
);
|
||||
): Promise<UnitTestTree> {
|
||||
return await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'ngrx',
|
||||
{
|
||||
name: featureName,
|
||||
module: appConfig.appModule,
|
||||
facade: withFacade
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
}
|
||||
});
|
||||
|
||||
@ -6,8 +6,7 @@
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"Name of the NgRx feature (e.g., Products, Users, etc.). Recommended to use plural form for name.",
|
||||
"description": "Name of the NgRx feature (e.g., Products, Users, etc.). Recommended to use plural form for name.",
|
||||
"$default": {
|
||||
"$source": "argv",
|
||||
"index": 0
|
||||
@ -16,42 +15,35 @@
|
||||
},
|
||||
"module": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"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?"
|
||||
"description": "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?"
|
||||
},
|
||||
"directory": {
|
||||
"type": "string",
|
||||
"default": "+state",
|
||||
"description":
|
||||
"Override the name of the folder used to contain/group the NgRx files: contains actions, effects, reducers. selectors. (e.g., +state)"
|
||||
"description": "Override the name of the folder used to contain/group the NgRx files: contains actions, effects, reducers. selectors. (e.g., +state)"
|
||||
},
|
||||
"root": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Add StoreModule.forRoot and EffectsModule.forRoot() instead of forFeature (e.g., --root).",
|
||||
"description": "Add StoreModule.forRoot and EffectsModule.forRoot() instead of forFeature (e.g., --root).",
|
||||
"x-prompt": "Is this the root state of the application?"
|
||||
},
|
||||
"facade": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Create a Facade class for the the Feature (e.g., --facade).",
|
||||
"description": "Create a Facade class for the the Feature (e.g., --facade).",
|
||||
"x-prompt": "Would you like to add a Facade to your ngrx state"
|
||||
},
|
||||
"onlyAddFiles": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Only add new NgRx files, without changing the module file (e.g., --onlyAddFiles)."
|
||||
"description": "Only add new NgRx files, without changing the module file (e.g., --onlyAddFiles)."
|
||||
},
|
||||
"onlyEmptyRoot": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Do not generate any files. Only generate StoreModule.forRoot and EffectsModule.forRoot (e.g., --onlyEmptyRoot)."
|
||||
"description": "Do not generate any files. Only generate StoreModule.forRoot and EffectsModule.forRoot (e.g., --onlyEmptyRoot)."
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files",
|
||||
@ -61,8 +53,7 @@
|
||||
"skipPackageJson": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Do not add NgRx dependencies to package.json (e.g., --skipPackageJson)"
|
||||
"description": "Do not add NgRx dependencies to package.json (e.g., --skipPackageJson)"
|
||||
}
|
||||
},
|
||||
"required": ["module"]
|
||||
|
||||
@ -43,8 +43,7 @@
|
||||
"tags": {
|
||||
"type": "string",
|
||||
"description": "Add tags to the application (used for linting)",
|
||||
"x-prompt":
|
||||
"Which tags would you like to add to the node application? (used for linting)"
|
||||
"x-prompt": "Which tags would you like to add to the node application? (used for linting)"
|
||||
}
|
||||
},
|
||||
"required": []
|
||||
|
||||
@ -18,13 +18,11 @@
|
||||
},
|
||||
"angularJsImport": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
||||
"description": "Import expression of the AngularJS application (e.g., --angularJsImport=some_node_module/my_app)."
|
||||
},
|
||||
"angularJsCmpSelector": {
|
||||
"type": "string",
|
||||
"description":
|
||||
"The selector of an AngularJS component (e.g., --angularJsCmpSelector=myComponent)"
|
||||
"description": "The selector of an AngularJS component (e.g., --angularJsCmpSelector=myComponent)"
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files",
|
||||
@ -34,8 +32,7 @@
|
||||
"skipPackageJson": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description":
|
||||
"Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
||||
"description": "Do not add @angular/upgrade to package.json (e.g., --skipPackageJson)"
|
||||
},
|
||||
"router": {
|
||||
"type": "boolean",
|
||||
|
||||
@ -19,15 +19,17 @@ describe('upgrade-module', () => {
|
||||
appTree = createApp(appTree, 'myapp');
|
||||
});
|
||||
|
||||
it('should update the bootstrap logic', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should update the bootstrap logic', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const appModule = getFileContent(tree, '/apps/myapp/src/app/app.module.ts');
|
||||
expect(appModule).toContain(
|
||||
@ -41,7 +43,7 @@ describe('upgrade-module', () => {
|
||||
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(
|
||||
`/package.json`,
|
||||
JSON.stringify({
|
||||
@ -51,21 +53,23 @@ describe('upgrade-module', () => {
|
||||
})
|
||||
);
|
||||
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const packageJson = readJsonInTree(tree, '/package.json');
|
||||
expect(packageJson.dependencies['@angular/upgrade']).toEqual('4.4.4');
|
||||
expect(packageJson.dependencies['angular']).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not package.json when --skipPackageJson=true', () => {
|
||||
it('should not package.json when --skipPackageJson=true', async () => {
|
||||
appTree.overwrite(
|
||||
`/package.json`,
|
||||
JSON.stringify({
|
||||
@ -75,45 +79,51 @@ describe('upgrade-module', () => {
|
||||
})
|
||||
);
|
||||
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
skipPackageJson: true,
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
skipPackageJson: true,
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const packageJson = readJsonInTree(tree, '/package.json');
|
||||
expect(packageJson.dependencies['@angular/upgrade']).not.toBeDefined();
|
||||
});
|
||||
|
||||
it('should add router configuration when --router=true', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
router: true,
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should add router configuration when --router=true', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
router: true,
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const legacySetup = getFileContent(tree, '/apps/myapp/src/legacy-setup.ts');
|
||||
expect(legacySetup).toContain(`setUpLocationSync`);
|
||||
});
|
||||
|
||||
it('should support custom angularJsImport', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
angularJsImport: 'legacy-app',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
);
|
||||
it('should support custom angularJsImport', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync(
|
||||
'upgrade-module',
|
||||
{
|
||||
name: 'legacy',
|
||||
angularJsImport: 'legacy-app',
|
||||
project: 'myapp'
|
||||
},
|
||||
appTree
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
const legacySetup = getFileContent(tree, '/apps/myapp/src/legacy-setup.ts');
|
||||
expect(legacySetup).toContain(`import 'legacy-app';`);
|
||||
|
||||
@ -16,12 +16,10 @@ describe('workspace-schematic', () => {
|
||||
appTree = createEmptyWorkspace(appTree);
|
||||
});
|
||||
|
||||
it('should generate files', () => {
|
||||
const tree = schematicRunner.runSchematic(
|
||||
'workspace-schematic',
|
||||
{ name: 'custom' },
|
||||
appTree
|
||||
);
|
||||
it('should generate files', async () => {
|
||||
const tree = await schematicRunner
|
||||
.runSchematicAsync('workspace-schematic', { name: 'custom' }, appTree)
|
||||
.toPromise();
|
||||
expect(tree.exists('tools/schematics/custom/index.ts')).toBeTruthy();
|
||||
expect(tree.exists('tools/schematics/custom/schema.json')).toBeTruthy();
|
||||
});
|
||||
|
||||
@ -91,12 +91,10 @@ function hasDependencyOnTouchedProjects(
|
||||
deps[project]
|
||||
.map(d => d.projectName)
|
||||
.filter(k =>
|
||||
hasDependencyOnTouchedProjects(
|
||||
k,
|
||||
touchedProjects,
|
||||
deps,
|
||||
[...visisted, project]
|
||||
)
|
||||
hasDependencyOnTouchedProjects(k, touchedProjects, deps, [
|
||||
...visisted,
|
||||
project
|
||||
])
|
||||
).length > 0
|
||||
);
|
||||
}
|
||||
|
||||
@ -208,12 +208,14 @@ function withDepGraphOptions(yargs: yargs.Argv): yargs.Argv {
|
||||
}
|
||||
|
||||
function parseCSV(args: string[]) {
|
||||
return args.map(arg => arg.split(',')).reduce(
|
||||
(acc, value) => {
|
||||
return [...acc, ...value];
|
||||
},
|
||||
[] as string[]
|
||||
);
|
||||
return args
|
||||
.map(arg => arg.split(','))
|
||||
.reduce(
|
||||
(acc, value) => {
|
||||
return [...acc, ...value];
|
||||
},
|
||||
[] as string[]
|
||||
);
|
||||
}
|
||||
|
||||
function withParallel(yargs: yargs.Argv): yargs.Argv {
|
||||
|
||||
@ -267,7 +267,9 @@ export function getProjectNodes(angularJson, nxJson): ProjectNode[] {
|
||||
|
||||
const projectType =
|
||||
p.projectType === 'application'
|
||||
? key.endsWith('-e2e') ? ProjectType.e2e : ProjectType.app
|
||||
? key.endsWith('-e2e')
|
||||
? ProjectType.e2e
|
||||
: ProjectType.app
|
||||
: ProjectType.lib;
|
||||
|
||||
let implicitDependencies = nxJson.projects[key].implicitDependencies || [];
|
||||
|
||||
@ -224,14 +224,13 @@ class EnforceModuleBoundariesWalker extends Lint.RuleWalker {
|
||||
if (done[sourceProjectName]) return false;
|
||||
if (!this.deps[sourceProjectName]) return false;
|
||||
return this.deps[sourceProjectName]
|
||||
.map(
|
||||
dep =>
|
||||
dep.projectName === targetProjectName
|
||||
? true
|
||||
: this.isDependingOn(dep.projectName, targetProjectName, {
|
||||
...done,
|
||||
[`${sourceProjectName}`]: true
|
||||
})
|
||||
.map(dep =>
|
||||
dep.projectName === targetProjectName
|
||||
? true
|
||||
: this.isDependingOn(dep.projectName, targetProjectName, {
|
||||
...done,
|
||||
[`${sourceProjectName}`]: true
|
||||
})
|
||||
)
|
||||
.some(result => result);
|
||||
}
|
||||
|
||||
@ -264,11 +264,13 @@ export function findClass(
|
||||
): ts.ClassDeclaration {
|
||||
const nodes = getSourceNodes(source);
|
||||
|
||||
const clazz = <any>nodes.filter(
|
||||
n =>
|
||||
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
||||
(<any>n).name.text === className
|
||||
)[0];
|
||||
const clazz = <any>(
|
||||
nodes.filter(
|
||||
n =>
|
||||
n.kind === ts.SyntaxKind.ClassDeclaration &&
|
||||
(<any>n).name.text === className
|
||||
)[0]
|
||||
);
|
||||
|
||||
if (!clazz && !silent) {
|
||||
throw new Error(`Cannot find class '${className}'`);
|
||||
@ -315,9 +317,8 @@ export function addImportToTestBed(
|
||||
specPath: string,
|
||||
symbolName: string
|
||||
): Change[] {
|
||||
const allCalls: ts.CallExpression[] = <any>findNodes(
|
||||
source,
|
||||
ts.SyntaxKind.CallExpression
|
||||
const allCalls: ts.CallExpression[] = <any>(
|
||||
findNodes(source, ts.SyntaxKind.CallExpression)
|
||||
);
|
||||
|
||||
const configureTestingModuleObjectLiterals = allCalls
|
||||
@ -325,11 +326,10 @@ export function addImportToTestBed(
|
||||
.filter(
|
||||
(c: any) => c.expression.name.getText(source) === 'configureTestingModule'
|
||||
)
|
||||
.map(
|
||||
c =>
|
||||
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
||||
? c.arguments[0]
|
||||
: null
|
||||
.map(c =>
|
||||
c.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression
|
||||
? c.arguments[0]
|
||||
: null
|
||||
);
|
||||
|
||||
if (configureTestingModuleObjectLiterals.length > 0) {
|
||||
|
||||
@ -24,9 +24,8 @@ export function toClassName(str: string): string {
|
||||
*/
|
||||
export function toPropertyName(s: string): string {
|
||||
return s
|
||||
.replace(
|
||||
/(-|_|\.|\s)+(.)?/g,
|
||||
(_, __, chr) => (chr ? chr.toUpperCase() : '')
|
||||
.replace(/(-|_|\.|\s)+(.)?/g, (_, __, chr) =>
|
||||
chr ? chr.toUpperCase() : ''
|
||||
)
|
||||
.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
|
||||
*/
|
||||
export function deleteFile(from: string): Rule {
|
||||
return forEach((entry: FileEntry): FileEntry | null => {
|
||||
return entry.path === from ? null : entry;
|
||||
});
|
||||
return forEach(
|
||||
(entry: FileEntry): FileEntry | null => {
|
||||
return entry.path === from ? null : entry;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { SchematicTestRunner } from '@angular-devkit/schematics/testing';
|
||||
import { Tree } from '@angular-devkit/schematics';
|
||||
|
||||
import * as prettier from 'prettier';
|
||||
import * as path from 'path';
|
||||
|
||||
import { createEmptyWorkspace } from '../testing-utils';
|
||||
import { formatFiles } from './format-files';
|
||||
import { serializeJson } from '../fileutils';
|
||||
import * as appRoot from 'app-root-path';
|
||||
|
||||
describe('formatFiles', () => {
|
||||
let tree: Tree;
|
||||
@ -15,52 +17,89 @@ describe('formatFiles', () => {
|
||||
'@nrwl/schematics',
|
||||
path.join(__dirname, '../../collection.json')
|
||||
);
|
||||
tree = createEmptyWorkspace(Tree.empty());
|
||||
tree.overwrite(
|
||||
'package.json',
|
||||
serializeJson({
|
||||
scripts: {
|
||||
format: 'prettier'
|
||||
}
|
||||
spyOn(prettier, 'format').and.callFake(input => 'formated :: ' + input);
|
||||
tree = Tree.empty();
|
||||
});
|
||||
|
||||
it('should format created files', async () => {
|
||||
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 => {
|
||||
schematicRunner.callRule(formatFiles(), tree).subscribe(result => {
|
||||
expect(schematicRunner.tasks.length).toBe(1);
|
||||
expect(schematicRunner.tasks[0]).toEqual({
|
||||
name: 'node-package',
|
||||
options: {
|
||||
packageName: 'run format -- --untracked',
|
||||
quiet: true
|
||||
}
|
||||
});
|
||||
done();
|
||||
it('should format overwritten files', async () => {
|
||||
spyOn(prettier, 'resolveConfig').and.returnValue(Promise.resolve(null));
|
||||
tree.create('a.ts', 'const a=a');
|
||||
tree.overwrite('a.ts', 'const a=b');
|
||||
const result = await schematicRunner
|
||||
.callRule(formatFiles(), tree)
|
||||
.toPromise();
|
||||
expect(prettier.format).toHaveBeenCalledWith('const a=b', {
|
||||
filepath: appRoot.resolve('a.ts')
|
||||
});
|
||||
expect(result.read('a.ts').toString()).toEqual('formated :: const a=b');
|
||||
});
|
||||
|
||||
it('should not format files if there is no format npm script', done => {
|
||||
tree.overwrite(
|
||||
'package.json',
|
||||
serializeJson({
|
||||
scripts: {}
|
||||
})
|
||||
);
|
||||
schematicRunner.callRule(formatFiles(), tree).subscribe(result => {
|
||||
expect(schematicRunner.tasks.length).toBe(0);
|
||||
//TODO: test that a warning is emitted.
|
||||
done();
|
||||
it('should not format renamed files', async () => {
|
||||
spyOn(prettier, 'resolveConfig').and.returnValue(Promise.resolve(null));
|
||||
tree.create('a.ts', 'const a=a');
|
||||
tree.rename('a.ts', 'b.ts');
|
||||
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');
|
||||
});
|
||||
|
||||
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();
|
||||
describe('--skip-format', () => {
|
||||
it('should not format created files', async () => {
|
||||
spyOn(prettier, 'resolveConfig').and.returnValue(
|
||||
Promise.resolve({
|
||||
printWidth: 80
|
||||
})
|
||||
);
|
||||
tree.create('a.ts', 'const a=a');
|
||||
const result = await schematicRunner
|
||||
.callRule(
|
||||
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');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -1,25 +1,15 @@
|
||||
import { readJsonInTree } from '../ast-utils';
|
||||
import {
|
||||
TaskConfigurationGenerator,
|
||||
TaskConfiguration,
|
||||
Tree,
|
||||
SchematicContext,
|
||||
Rule,
|
||||
noop
|
||||
noop,
|
||||
OverwriteFileAction,
|
||||
CreateFileAction
|
||||
} from '@angular-devkit/schematics';
|
||||
import { stripIndents } from '@angular-devkit/core/src/utils/literals';
|
||||
|
||||
class FormatFiles implements TaskConfigurationGenerator<any> {
|
||||
toConfiguration(): TaskConfiguration<any> {
|
||||
return {
|
||||
name: 'node-package',
|
||||
options: {
|
||||
packageName: 'run format -- --untracked', // workaround. we should define a custom task executor.
|
||||
quiet: true
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
import { format, resolveConfig, getFileInfo } from 'prettier';
|
||||
import * as appRoot from 'app-root-path';
|
||||
import { from } from 'rxjs';
|
||||
import { filter, map, mergeMap } from 'rxjs/operators';
|
||||
|
||||
export function formatFiles(
|
||||
options: { skipFormat: boolean } = { skipFormat: false }
|
||||
@ -28,15 +18,45 @@ export function formatFiles(
|
||||
return noop();
|
||||
}
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const packageJson = readJsonInTree(host, 'package.json');
|
||||
if (packageJson.scripts && packageJson.scripts.format) {
|
||||
context.addTask(new FormatFiles());
|
||||
} else {
|
||||
context.logger.warn(stripIndents`
|
||||
Files were not formated during this code generation.
|
||||
The "format" npm script is missing in your package.json.
|
||||
Please either add a format script or pass --skip-format.
|
||||
`);
|
||||
const files = new Set(
|
||||
host.actions
|
||||
.filter(action => action.kind !== 'd' && action.kind !== 'r')
|
||||
.map((action: OverwriteFileAction | CreateFileAction) => ({
|
||||
path: action.path,
|
||||
content: action.content.toString()
|
||||
}))
|
||||
);
|
||||
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"
|
||||
integrity sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=
|
||||
|
||||
prettier@1.10.2:
|
||||
version "1.10.2"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.10.2.tgz#1af8356d1842276a99a5b5529c82dd9e9ad3cc93"
|
||||
integrity sha512-TcdNoQIWFoHblurqqU6d1ysopjq7UX0oRcT/hJ8qvBAELiYWn+Ugf0AXdnzISEJ7vuhNnQ98N8jR8Sh53x4IZg==
|
||||
prettier@1.15.3:
|
||||
version "1.15.3"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.15.3.tgz#1feaac5bdd181237b54dbe65d874e02a1472786a"
|
||||
integrity sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==
|
||||
|
||||
pretty-format@^23.6.0:
|
||||
version "23.6.0"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user