From a9383fa02afea9c9a6b931ea3ac079572974e55a Mon Sep 17 00:00:00 2001 From: Arjen Date: Thu, 15 Apr 2021 12:56:14 +0200 Subject: [PATCH 1/8] chore: migrate tslint to eslint (#199) --- .eslintrc.json | 113 +++++++++++++++++ .prettierignore | 53 ++++++++ README.md | 2 +- angular.json | 76 ++++++----- apps/example-app/.browserslistrc | 17 +++ apps/example-app/.eslintrc.json | 37 ++++++ apps/example-app/jest.config.js | 1 + .../{ => src}/app/app-routing.module.ts | 0 .../{ => src}/app/app.component.css | 0 .../{ => src}/app/app.component.html | 0 .../{ => src}/app/app.component.ts | 0 apps/example-app/{ => src}/app/app.module.ts | 0 .../app/examples/00-single-component.spec.ts | 0 .../app/examples/00-single-component.ts | 0 .../app/examples/01-nested-component.spec.ts | 0 .../app/examples/01-nested-component.ts | 4 +- .../app/examples/02-input-output.spec.ts | 2 +- .../{ => src}/app/examples/02-input-output.ts | 0 .../{ => src}/app/examples/03-forms.spec.ts | 0 .../{ => src}/app/examples/03-forms.ts | 0 .../examples/04-forms-with-material.spec.ts | 0 .../app/examples/04-forms-with-material.ts | 0 .../examples/05-component-provider.spec.ts | 0 .../app/examples/05-component-provider.ts | 0 .../app/examples/06-with-ngrx-store.spec.ts | 0 .../app/examples/06-with-ngrx-store.ts | 0 .../examples/07-with-ngrx-mock-store.spec.ts | 0 .../app/examples/07-with-ngrx-mock-store.ts | 0 .../app/examples/08-directive.spec.ts | 4 +- .../{ => src}/app/examples/08-directive.ts | 0 .../{ => src}/app/examples/09-router.spec.ts | 0 .../{ => src}/app/examples/09-router.ts | 4 +- .../10-inject-token-dependency.spec.ts | 0 .../examples/10-inject-token-dependency.ts | 2 +- .../app/examples/11-ng-content.spec.ts | 0 .../{ => src}/app/examples/11-ng-content.ts | 0 .../app/examples/12-service-component.spec.ts | 0 .../app/examples/12-service-component.ts | 0 .../examples/13-scrolling.component.spec.ts | 0 .../app/examples/13-scrolling.component.ts | 0 .../app/examples/14-async-component.spec.ts | 0 .../app/examples/14-async-component.ts | 2 +- .../app/examples/15-dialog.component.spec.ts | 0 .../app/examples/15-dialog.component.ts | 6 +- .../examples/16-input-getter-setter.spec.ts | 0 .../app/examples/16-input-getter-setter.ts | 1 + .../{ => src}/app/examples/README.md | 0 .../{ => src}/app/issues/issue-106.spec.ts | 0 .../{ => src}/app/material.module.ts | 0 apps/example-app/{ => src}/assets/.gitkeep | 0 .../environments/environment.prod.ts | 0 .../{ => src}/environments/environment.ts | 0 apps/example-app/{ => src}/favicon.ico | Bin apps/example-app/{ => src}/index.html | 0 apps/example-app/{ => src}/main.ts | 0 apps/example-app/{ => src}/polyfills.ts | 6 +- apps/example-app/{ => src}/styles.css | 0 apps/example-app/{ => src}/test-setup.ts | 2 +- apps/example-app/tsconfig.app.json | 9 ++ apps/example-app/tsconfig.editor.json | 7 ++ apps/example-app/tsconfig.json | 23 +++- apps/example-app/tsconfig.spec.json | 7 +- apps/example-app/tslint.json | 7 -- jest.config.js | 2 +- jest.preset.js | 7 +- migrations.json | 89 +++++++++++++ nx.json | 21 ++-- package.json | 76 ++++++----- projects/jest-utils/.eslintrc.json | 36 ++++++ projects/jest-utils/src/lib/create-mock.ts | 5 +- projects/jest-utils/test-setup.ts | 2 +- projects/jest-utils/tslint.json | 3 - projects/testing-library/.eslintrc.json | 36 ++++++ .../testing-library/migrations/4_0_0/index.ts | 30 ----- .../4_0_0/rules/noComponentParametersRule.ts | 44 ------- .../4_0_0/rules/noComponentPropertyRule.ts | 22 ---- .../4_0_0/rules/noCreateComponentRule.ts | 40 ------ .../testing-library/migrations/5_1_2/index.ts | 53 -------- .../rules/noAngularExtensionsImportRule.ts | 26 ---- .../testing-library/migrations/migration.json | 15 --- .../migrations/tsconfig.migrations.json | 17 --- projects/testing-library/ng-package.json | 4 +- projects/testing-library/package.json | 5 +- projects/testing-library/src/lib/models.ts | 1 + .../src/lib/testing-library.ts | 13 +- projects/testing-library/test-setup.ts | 2 +- .../testing-library/tests/directive.spec.ts | 11 +- .../tests/migration/4_0_0.spec.ts | 118 ------------------ .../tests/migration/5_1_2.spec.ts | 67 ---------- .../testing-library/tests/rerender.spec.ts | 10 +- projects/testing-library/tslint.json | 3 - tslint.json | 75 ----------- 92 files changed, 554 insertions(+), 664 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .prettierignore create mode 100644 apps/example-app/.browserslistrc create mode 100644 apps/example-app/.eslintrc.json rename apps/example-app/{ => src}/app/app-routing.module.ts (100%) rename apps/example-app/{ => src}/app/app.component.css (100%) rename apps/example-app/{ => src}/app/app.component.html (100%) rename apps/example-app/{ => src}/app/app.component.ts (100%) rename apps/example-app/{ => src}/app/app.module.ts (100%) rename apps/example-app/{ => src}/app/examples/00-single-component.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/00-single-component.ts (100%) rename apps/example-app/{ => src}/app/examples/01-nested-component.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/01-nested-component.ts (83%) rename apps/example-app/{ => src}/app/examples/02-input-output.spec.ts (93%) rename apps/example-app/{ => src}/app/examples/02-input-output.ts (100%) rename apps/example-app/{ => src}/app/examples/03-forms.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/03-forms.ts (100%) rename apps/example-app/{ => src}/app/examples/04-forms-with-material.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/04-forms-with-material.ts (100%) rename apps/example-app/{ => src}/app/examples/05-component-provider.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/05-component-provider.ts (100%) rename apps/example-app/{ => src}/app/examples/06-with-ngrx-store.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/06-with-ngrx-store.ts (100%) rename apps/example-app/{ => src}/app/examples/07-with-ngrx-mock-store.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/07-with-ngrx-mock-store.ts (100%) rename apps/example-app/{ => src}/app/examples/08-directive.spec.ts (94%) rename apps/example-app/{ => src}/app/examples/08-directive.ts (100%) rename apps/example-app/{ => src}/app/examples/09-router.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/09-router.ts (91%) rename apps/example-app/{ => src}/app/examples/10-inject-token-dependency.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/10-inject-token-dependency.ts (89%) rename apps/example-app/{ => src}/app/examples/11-ng-content.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/11-ng-content.ts (100%) rename apps/example-app/{ => src}/app/examples/12-service-component.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/12-service-component.ts (100%) rename apps/example-app/{ => src}/app/examples/13-scrolling.component.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/13-scrolling.component.ts (100%) rename apps/example-app/{ => src}/app/examples/14-async-component.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/14-async-component.ts (87%) rename apps/example-app/{ => src}/app/examples/15-dialog.component.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/15-dialog.component.ts (83%) rename apps/example-app/{ => src}/app/examples/16-input-getter-setter.spec.ts (100%) rename apps/example-app/{ => src}/app/examples/16-input-getter-setter.ts (88%) rename apps/example-app/{ => src}/app/examples/README.md (100%) rename apps/example-app/{ => src}/app/issues/issue-106.spec.ts (100%) rename apps/example-app/{ => src}/app/material.module.ts (100%) rename apps/example-app/{ => src}/assets/.gitkeep (100%) rename apps/example-app/{ => src}/environments/environment.prod.ts (100%) rename apps/example-app/{ => src}/environments/environment.ts (100%) rename apps/example-app/{ => src}/favicon.ico (100%) rename apps/example-app/{ => src}/index.html (100%) rename apps/example-app/{ => src}/main.ts (100%) rename apps/example-app/{ => src}/polyfills.ts (90%) rename apps/example-app/{ => src}/styles.css (100%) rename apps/example-app/{ => src}/test-setup.ts (83%) create mode 100644 apps/example-app/tsconfig.app.json create mode 100644 apps/example-app/tsconfig.editor.json delete mode 100644 apps/example-app/tslint.json create mode 100644 migrations.json create mode 100644 projects/jest-utils/.eslintrc.json delete mode 100644 projects/jest-utils/tslint.json create mode 100644 projects/testing-library/.eslintrc.json delete mode 100644 projects/testing-library/migrations/4_0_0/index.ts delete mode 100644 projects/testing-library/migrations/4_0_0/rules/noComponentParametersRule.ts delete mode 100644 projects/testing-library/migrations/4_0_0/rules/noComponentPropertyRule.ts delete mode 100644 projects/testing-library/migrations/4_0_0/rules/noCreateComponentRule.ts delete mode 100644 projects/testing-library/migrations/5_1_2/index.ts delete mode 100644 projects/testing-library/migrations/5_1_2/rules/noAngularExtensionsImportRule.ts delete mode 100644 projects/testing-library/migrations/migration.json delete mode 100644 projects/testing-library/migrations/tsconfig.migrations.json delete mode 100644 projects/testing-library/tests/migration/4_0_0.spec.ts delete mode 100644 projects/testing-library/tests/migration/5_1_2.spec.ts delete mode 100644 projects/testing-library/tslint.json delete mode 100644 tslint.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..5af8c266 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,113 @@ +{ + "root": true, + "ignorePatterns": ["**/*"], + "plugins": ["@nrwl/nx"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "parserOptions": { + "project": ["/tsconfig.*?.json"] + }, + "rules": { + "@nrwl/nx/enforce-module-boundaries": [ + "error", + { + "enforceBuildableLibDependency": true, + "allow": [], + "depConstraints": [ + { + "sourceTag": "*", + "onlyDependOnLibsWithTags": ["*"] + } + ] + } + ] + } + }, + { + "files": ["*.ts", "*.tsx"], + "extends": ["plugin:@nrwl/nx/typescript"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "extends": ["plugin:@nrwl/nx/javascript"], + "rules": {} + }, + { + "files": ["*.ts"], + "rules": { + "@typescript-eslint/consistent-type-definitions": "error", + "@typescript-eslint/dot-notation": "off", + "@typescript-eslint/naming-convention": "error", + "@typescript-eslint/no-shadow": [ + "error", + { + "hoist": "all" + } + ], + "@typescript-eslint/no-unused-expressions": "error", + "@typescript-eslint/prefer-function-type": "error", + "@typescript-eslint/quotes": ["error", "single"], + "@typescript-eslint/type-annotation-spacing": "error", + "@typescript-eslint/no-explicit-any": "off", + "arrow-body-style": "error", + "brace-style": ["error", "1tbs"], + "curly": "error", + "eol-last": "error", + "eqeqeq": ["error", "smart"], + "guard-for-in": "error", + "id-blacklist": "off", + "id-match": "off", + "import/no-deprecated": "warn", + "no-bitwise": "error", + "no-caller": "error", + "no-console": [ + "error", + { + "allow": [ + "log", + "warn", + "dir", + "timeLog", + "assert", + "clear", + "count", + "countReset", + "group", + "groupEnd", + "table", + "dirxml", + "error", + "groupCollapsed", + "Console", + "profile", + "profileEnd", + "timeStamp", + "context" + ] + } + ], + "no-empty": "off", + "no-eval": "error", + "no-new-wrappers": "error", + "no-throw-literal": "error", + "no-undef-init": "error", + "no-underscore-dangle": "off", + "radix": "error", + "spaced-comment": [ + "error", + "always", + { + "markers": ["/"] + } + ] + }, + "plugins": ["eslint-plugin-import", "@angular-eslint/eslint-plugin", "@typescript-eslint"] + }, + { + "files": ["*.html"], + "rules": {} + } + ] +} diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..2cbf2c26 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,53 @@ +# NPM Files +package-lock.json +migrations.json + +CHANGELOG.md + +#Ignore specific file types +*.svg +*.xml +*.png +*.jpg + +# compiled output +/dist +/tmp +/out-tsc +# dependencies +/node_modules + +# IDEs and editors +/.idea +.project +.classpath +.c9/ +*.launch +.settings/ +*.sublime-workspace + +# IDE - VSCode +.vscode/* +!.vscode/cSpell.json +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# misc +/.sass-cache +/connect.lock +/coverage +/libpeerconnection.log +npm-debug.log +testem.log +/typings +deployment.yaml + +# e2e +/*e2e/*.js +/*e2e/*.map + +# System Files +.DS_Store +Thumbs.db diff --git a/README.md b/README.md index 3ed51be4..0acdf9fa 100644 --- a/README.md +++ b/README.md @@ -139,7 +139,7 @@ describe('Counter', () => { }); ``` -[See more examples](https://github.com/testing-library/angular-testing-library/tree/master/apps/example-app/app/examples) +[See more examples](https://github.com/testing-library/angular-testing-library/tree/master/apps/example-app/src/app/examples) ## Installation diff --git a/angular.json b/angular.json index 85ad7d4e..46f51c32 100644 --- a/angular.json +++ b/angular.json @@ -1,12 +1,14 @@ { - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, - "newProjectRoot": "", + "cli": { + "analytics": false + }, + "defaultProject": "example-app", "projects": { "example-app": { - "root": "", - "sourceRoot": "apps/example-app", "projectType": "application", + "root": "apps/example-app", + "sourceRoot": "apps/example-app/src", "prefix": "app", "schematics": {}, "architect": { @@ -15,12 +17,12 @@ "options": { "aot": true, "outputPath": "dist/apps/example-app", - "index": "apps/example-app/index.html", - "main": "apps/example-app/main.ts", - "polyfills": "apps/example-app/polyfills.ts", - "tsConfig": "apps/example-app/tsconfig.json", - "assets": ["apps/example-app/favicon.ico", "apps/example-app/assets"], - "styles": ["apps/example-app/styles.css"], + "index": "apps/example-app/src/index.html", + "main": "apps/example-app/src/main.ts", + "polyfills": "apps/example-app/src/polyfills.ts", + "tsConfig": "apps/example-app/tsconfig.app.json", + "assets": ["apps/example-app/src/favicon.ico", "apps/example-app/src/assets"], + "styles": ["apps/example-app/src/styles.css"], "scripts": [] }, "configurations": { @@ -33,8 +35,8 @@ ], "fileReplacements": [ { - "replace": "apps/example-app/environments/environment.ts", - "with": "apps/example-app/environments/environment.prod.ts" + "replace": "apps/example-app/src/environments/environment.ts", + "with": "apps/example-app/src/environments/environment.prod.ts" } ], "optimization": true, @@ -46,7 +48,8 @@ "vendorChunk": false, "buildOptimizer": true } - } + }, + "outputs": ["{options.outputPath}"] }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", @@ -66,19 +69,18 @@ } }, "lint": { - "builder": "@angular-devkit/build-angular:tslint", + "builder": "@nrwl/linter:eslint", "options": { - "tsConfig": ["apps/example-app/tsconfig.json", "apps/example-app/tsconfig.spec.json"], - "exclude": ["**/node_modules/**"] + "lintFilePatterns": ["apps/example-app/src/**/*.ts", "apps/example-app/src/**/*.html"] } }, "test": { "builder": "@nrwl/jest:jest", "options": { "jestConfig": "apps/example-app/jest.config.js", - "tsConfig": "apps/example-app/tsconfig.spec.json", - "setupFile": "apps/example-app/test-setup.ts" - } + "setupFile": "apps/example-app/src/test-setup.ts" + }, + "outputs": ["coverage/"] } } }, @@ -102,10 +104,13 @@ } }, "lint": { - "builder": "@angular-devkit/build-angular:tslint", + "builder": "@nrwl/linter:eslint", "options": { - "tsConfig": ["projects/testing-library/tsconfig.lib.json", "projects/testing-library/tsconfig.spec.json"], - "exclude": ["**/node_modules/**"] + "lintFilePatterns": [ + "projects/testing-library/src/**/*.ts", + "projects/testing-library/src/**/*.html", + "projects/testing-library/src/**/*.html" + ] } }, "build": { @@ -116,12 +121,6 @@ { "command": "ng run testing-library:build-package" }, - { - "command": "tsc -p ./projects/testing-library/migrations/tsconfig.migrations.json" - }, - { - "command": "cpy ./projects/testing-library/migrations/migration.json ./dist/@testing-library/angular/migrations" - }, { "command": "cpy ./README.md ./dist/@testing-library/angular" } @@ -132,9 +131,9 @@ "builder": "@nrwl/jest:jest", "options": { "jestConfig": "projects/testing-library/jest.config.js", - "tsConfig": "projects/testing-library/tsconfig.spec.json", "setupFile": "projects/testing-library/test-setup.ts" - } + }, + "outputs": ["coverage/projects/testing-library"] } } }, @@ -158,10 +157,13 @@ } }, "lint": { - "builder": "@angular-devkit/build-angular:tslint", + "builder": "@nrwl/linter:eslint", "options": { - "tsConfig": ["projects/jest-utils/tsconfig.lib.json", "projects/jest-utils/tsconfig.spec.json"], - "exclude": ["**/node_modules/**"] + "lintFilePatterns": [ + "projects/jest-utils/src/**/*.ts", + "projects/jest-utils/src/**/*.html", + "projects/jest-utils/src/**/*.html" + ] } }, "build": { @@ -179,15 +181,11 @@ "builder": "@nrwl/jest:jest", "options": { "jestConfig": "projects/jest-utils/jest.config.js", - "tsConfig": "projects/jest-utils/tsconfig.spec.json", "setupFile": "projects/jest-utils/test-setup.ts" - } + }, + "outputs": ["coverage/projects/jest-utils"] } } } - }, - "defaultProject": "example-app", - "cli": { - "analytics": false } } diff --git a/apps/example-app/.browserslistrc b/apps/example-app/.browserslistrc new file mode 100644 index 00000000..427441dc --- /dev/null +++ b/apps/example-app/.browserslistrc @@ -0,0 +1,17 @@ +# This file is used by the build system to adjust CSS and JS output to support the specified browsers below. +# For additional information regarding the format and rule options, please see: +# https://github.com/browserslist/browserslist#queries + +# For the full list of supported browsers by the Angular framework, please see: +# https://angular.io/guide/browser-support + +# You can see what browsers were selected by your queries by running: +# npx browserslist + +last 1 Chrome version +last 1 Firefox version +last 2 Edge major versions +last 2 Safari major versions +last 2 iOS major versions +Firefox ESR +not IE 11 # Angular supports IE 11 only as an opt-in. To opt-in, remove the 'not' prefix on this line. diff --git a/apps/example-app/.eslintrc.json b/apps/example-app/.eslintrc.json new file mode 100644 index 00000000..2e1ae78b --- /dev/null +++ b/apps/example-app/.eslintrc.json @@ -0,0 +1,37 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], + "parserOptions": { + "project": ["apps/example-app/tsconfig.*?.json"] + }, + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "app", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "app", + "style": "kebab-case" + } + ] + }, + "plugins": ["@angular-eslint/eslint-plugin", "@typescript-eslint"] + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/apps/example-app/jest.config.js b/apps/example-app/jest.config.js index fe1aebd5..2be66c61 100644 --- a/apps/example-app/jest.config.js +++ b/apps/example-app/jest.config.js @@ -5,4 +5,5 @@ module.exports = { color: 'blue', }, preset: '../../jest.preset.js', + setupFilesAfterEnv: ['/src/test-setup.ts'], }; diff --git a/apps/example-app/app/app-routing.module.ts b/apps/example-app/src/app/app-routing.module.ts similarity index 100% rename from apps/example-app/app/app-routing.module.ts rename to apps/example-app/src/app/app-routing.module.ts diff --git a/apps/example-app/app/app.component.css b/apps/example-app/src/app/app.component.css similarity index 100% rename from apps/example-app/app/app.component.css rename to apps/example-app/src/app/app.component.css diff --git a/apps/example-app/app/app.component.html b/apps/example-app/src/app/app.component.html similarity index 100% rename from apps/example-app/app/app.component.html rename to apps/example-app/src/app/app.component.html diff --git a/apps/example-app/app/app.component.ts b/apps/example-app/src/app/app.component.ts similarity index 100% rename from apps/example-app/app/app.component.ts rename to apps/example-app/src/app/app.component.ts diff --git a/apps/example-app/app/app.module.ts b/apps/example-app/src/app/app.module.ts similarity index 100% rename from apps/example-app/app/app.module.ts rename to apps/example-app/src/app/app.module.ts diff --git a/apps/example-app/app/examples/00-single-component.spec.ts b/apps/example-app/src/app/examples/00-single-component.spec.ts similarity index 100% rename from apps/example-app/app/examples/00-single-component.spec.ts rename to apps/example-app/src/app/examples/00-single-component.spec.ts diff --git a/apps/example-app/app/examples/00-single-component.ts b/apps/example-app/src/app/examples/00-single-component.ts similarity index 100% rename from apps/example-app/app/examples/00-single-component.ts rename to apps/example-app/src/app/examples/00-single-component.ts diff --git a/apps/example-app/app/examples/01-nested-component.spec.ts b/apps/example-app/src/app/examples/01-nested-component.spec.ts similarity index 100% rename from apps/example-app/app/examples/01-nested-component.spec.ts rename to apps/example-app/src/app/examples/01-nested-component.spec.ts diff --git a/apps/example-app/app/examples/01-nested-component.ts b/apps/example-app/src/app/examples/01-nested-component.ts similarity index 83% rename from apps/example-app/app/examples/01-nested-component.ts rename to apps/example-app/src/app/examples/01-nested-component.ts index 8214c7a1..5b0faeb2 100644 --- a/apps/example-app/app/examples/01-nested-component.ts +++ b/apps/example-app/src/app/examples/01-nested-component.ts @@ -2,7 +2,7 @@ import { Component, Input, Output, EventEmitter } from '@angular/core'; @Component({ selector: 'app-button', - template: ` `, + template: ' ', }) export class NestedButtonComponent { @Input() name: string; @@ -11,7 +11,7 @@ export class NestedButtonComponent { @Component({ selector: 'app-value', - template: ` {{ value }} `, + template: ' {{ value }} ', }) export class NestedValueComponent { @Input() value: number; diff --git a/apps/example-app/app/examples/02-input-output.spec.ts b/apps/example-app/src/app/examples/02-input-output.spec.ts similarity index 93% rename from apps/example-app/app/examples/02-input-output.spec.ts rename to apps/example-app/src/app/examples/02-input-output.spec.ts index 1f56e6c0..7c907526 100644 --- a/apps/example-app/app/examples/02-input-output.spec.ts +++ b/apps/example-app/src/app/examples/02-input-output.spec.ts @@ -34,7 +34,7 @@ test('is possible to set input and listen for output with the template syntax', const sendSpy = jest.fn(); await render(InputOutputComponent, { - template: ``, + template: '', componentProperties: { sendValue: sendSpy, }, diff --git a/apps/example-app/app/examples/02-input-output.ts b/apps/example-app/src/app/examples/02-input-output.ts similarity index 100% rename from apps/example-app/app/examples/02-input-output.ts rename to apps/example-app/src/app/examples/02-input-output.ts diff --git a/apps/example-app/app/examples/03-forms.spec.ts b/apps/example-app/src/app/examples/03-forms.spec.ts similarity index 100% rename from apps/example-app/app/examples/03-forms.spec.ts rename to apps/example-app/src/app/examples/03-forms.spec.ts diff --git a/apps/example-app/app/examples/03-forms.ts b/apps/example-app/src/app/examples/03-forms.ts similarity index 100% rename from apps/example-app/app/examples/03-forms.ts rename to apps/example-app/src/app/examples/03-forms.ts diff --git a/apps/example-app/app/examples/04-forms-with-material.spec.ts b/apps/example-app/src/app/examples/04-forms-with-material.spec.ts similarity index 100% rename from apps/example-app/app/examples/04-forms-with-material.spec.ts rename to apps/example-app/src/app/examples/04-forms-with-material.spec.ts diff --git a/apps/example-app/app/examples/04-forms-with-material.ts b/apps/example-app/src/app/examples/04-forms-with-material.ts similarity index 100% rename from apps/example-app/app/examples/04-forms-with-material.ts rename to apps/example-app/src/app/examples/04-forms-with-material.ts diff --git a/apps/example-app/app/examples/05-component-provider.spec.ts b/apps/example-app/src/app/examples/05-component-provider.spec.ts similarity index 100% rename from apps/example-app/app/examples/05-component-provider.spec.ts rename to apps/example-app/src/app/examples/05-component-provider.spec.ts diff --git a/apps/example-app/app/examples/05-component-provider.ts b/apps/example-app/src/app/examples/05-component-provider.ts similarity index 100% rename from apps/example-app/app/examples/05-component-provider.ts rename to apps/example-app/src/app/examples/05-component-provider.ts diff --git a/apps/example-app/app/examples/06-with-ngrx-store.spec.ts b/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts similarity index 100% rename from apps/example-app/app/examples/06-with-ngrx-store.spec.ts rename to apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts diff --git a/apps/example-app/app/examples/06-with-ngrx-store.ts b/apps/example-app/src/app/examples/06-with-ngrx-store.ts similarity index 100% rename from apps/example-app/app/examples/06-with-ngrx-store.ts rename to apps/example-app/src/app/examples/06-with-ngrx-store.ts diff --git a/apps/example-app/app/examples/07-with-ngrx-mock-store.spec.ts b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts similarity index 100% rename from apps/example-app/app/examples/07-with-ngrx-mock-store.spec.ts rename to apps/example-app/src/app/examples/07-with-ngrx-mock-store.spec.ts diff --git a/apps/example-app/app/examples/07-with-ngrx-mock-store.ts b/apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts similarity index 100% rename from apps/example-app/app/examples/07-with-ngrx-mock-store.ts rename to apps/example-app/src/app/examples/07-with-ngrx-mock-store.ts diff --git a/apps/example-app/app/examples/08-directive.spec.ts b/apps/example-app/src/app/examples/08-directive.spec.ts similarity index 94% rename from apps/example-app/app/examples/08-directive.spec.ts rename to apps/example-app/src/app/examples/08-directive.spec.ts index 1b8f234c..c36822a3 100644 --- a/apps/example-app/app/examples/08-directive.spec.ts +++ b/apps/example-app/src/app/examples/08-directive.spec.ts @@ -4,7 +4,7 @@ import { SpoilerDirective } from './08-directive'; test('it is possible to test directives', async () => { await render(SpoilerDirective, { - template: `
`, + template: '
', }); const directive = screen.getByTestId('dir'); @@ -26,7 +26,7 @@ test('it is possible to test directives with props', async () => { const visible = 'There is nothing to see here ...'; await render(SpoilerDirective, { - template: `
`, + template: '
', componentProperties: { hidden, visible, diff --git a/apps/example-app/app/examples/08-directive.ts b/apps/example-app/src/app/examples/08-directive.ts similarity index 100% rename from apps/example-app/app/examples/08-directive.ts rename to apps/example-app/src/app/examples/08-directive.ts diff --git a/apps/example-app/app/examples/09-router.spec.ts b/apps/example-app/src/app/examples/09-router.spec.ts similarity index 100% rename from apps/example-app/app/examples/09-router.spec.ts rename to apps/example-app/src/app/examples/09-router.spec.ts diff --git a/apps/example-app/app/examples/09-router.ts b/apps/example-app/src/app/examples/09-router.ts similarity index 91% rename from apps/example-app/app/examples/09-router.ts rename to apps/example-app/src/app/examples/09-router.ts index e1ab5afb..035124c8 100644 --- a/apps/example-app/app/examples/09-router.ts +++ b/apps/example-app/src/app/examples/09-router.ts @@ -1,4 +1,4 @@ -import { OnInit, Component } from '@angular/core'; +import { Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { map } from 'rxjs/operators'; @@ -35,6 +35,6 @@ export class DetailComponent { @Component({ selector: 'app-detail-hidden', - template: ` You found the treasure! `, + template: ' You found the treasure! ', }) export class HiddenDetailComponent {} diff --git a/apps/example-app/app/examples/10-inject-token-dependency.spec.ts b/apps/example-app/src/app/examples/10-inject-token-dependency.spec.ts similarity index 100% rename from apps/example-app/app/examples/10-inject-token-dependency.spec.ts rename to apps/example-app/src/app/examples/10-inject-token-dependency.spec.ts diff --git a/apps/example-app/app/examples/10-inject-token-dependency.ts b/apps/example-app/src/app/examples/10-inject-token-dependency.ts similarity index 89% rename from apps/example-app/app/examples/10-inject-token-dependency.ts rename to apps/example-app/src/app/examples/10-inject-token-dependency.ts index 61bf5b41..8cc843e5 100644 --- a/apps/example-app/app/examples/10-inject-token-dependency.ts +++ b/apps/example-app/src/app/examples/10-inject-token-dependency.ts @@ -4,7 +4,7 @@ export const DATA = new InjectionToken<{ text: string }>('Components Data'); @Component({ selector: 'app-fixture', - template: ` {{ data.text }} `, + template: ' {{ data.text }} ', }) export class DataInjectedComponent { constructor(@Inject(DATA) public data: { text: string }) {} diff --git a/apps/example-app/app/examples/11-ng-content.spec.ts b/apps/example-app/src/app/examples/11-ng-content.spec.ts similarity index 100% rename from apps/example-app/app/examples/11-ng-content.spec.ts rename to apps/example-app/src/app/examples/11-ng-content.spec.ts diff --git a/apps/example-app/app/examples/11-ng-content.ts b/apps/example-app/src/app/examples/11-ng-content.ts similarity index 100% rename from apps/example-app/app/examples/11-ng-content.ts rename to apps/example-app/src/app/examples/11-ng-content.ts diff --git a/apps/example-app/app/examples/12-service-component.spec.ts b/apps/example-app/src/app/examples/12-service-component.spec.ts similarity index 100% rename from apps/example-app/app/examples/12-service-component.spec.ts rename to apps/example-app/src/app/examples/12-service-component.spec.ts diff --git a/apps/example-app/app/examples/12-service-component.ts b/apps/example-app/src/app/examples/12-service-component.ts similarity index 100% rename from apps/example-app/app/examples/12-service-component.ts rename to apps/example-app/src/app/examples/12-service-component.ts diff --git a/apps/example-app/app/examples/13-scrolling.component.spec.ts b/apps/example-app/src/app/examples/13-scrolling.component.spec.ts similarity index 100% rename from apps/example-app/app/examples/13-scrolling.component.spec.ts rename to apps/example-app/src/app/examples/13-scrolling.component.spec.ts diff --git a/apps/example-app/app/examples/13-scrolling.component.ts b/apps/example-app/src/app/examples/13-scrolling.component.ts similarity index 100% rename from apps/example-app/app/examples/13-scrolling.component.ts rename to apps/example-app/src/app/examples/13-scrolling.component.ts diff --git a/apps/example-app/app/examples/14-async-component.spec.ts b/apps/example-app/src/app/examples/14-async-component.spec.ts similarity index 100% rename from apps/example-app/app/examples/14-async-component.spec.ts rename to apps/example-app/src/app/examples/14-async-component.spec.ts diff --git a/apps/example-app/app/examples/14-async-component.ts b/apps/example-app/src/app/examples/14-async-component.ts similarity index 87% rename from apps/example-app/app/examples/14-async-component.ts rename to apps/example-app/src/app/examples/14-async-component.ts index fbfd45ff..f8521539 100644 --- a/apps/example-app/app/examples/14-async-component.ts +++ b/apps/example-app/src/app/examples/14-async-component.ts @@ -1,4 +1,4 @@ -import { ApplicationInitStatus, Component, OnDestroy } from '@angular/core'; +import { Component, OnDestroy } from '@angular/core'; import { Subject } from 'rxjs'; import { delay, filter, mapTo } from 'rxjs/operators'; diff --git a/apps/example-app/app/examples/15-dialog.component.spec.ts b/apps/example-app/src/app/examples/15-dialog.component.spec.ts similarity index 100% rename from apps/example-app/app/examples/15-dialog.component.spec.ts rename to apps/example-app/src/app/examples/15-dialog.component.spec.ts diff --git a/apps/example-app/app/examples/15-dialog.component.ts b/apps/example-app/src/app/examples/15-dialog.component.ts similarity index 83% rename from apps/example-app/app/examples/15-dialog.component.ts rename to apps/example-app/src/app/examples/15-dialog.component.ts index ba7eb0da..af5d8d89 100644 --- a/apps/example-app/app/examples/15-dialog.component.ts +++ b/apps/example-app/src/app/examples/15-dialog.component.ts @@ -2,8 +2,8 @@ import { Component, NgModule } from '@angular/core'; import { MatDialog, MatDialogRef } from '@angular/material/dialog'; @Component({ - selector: 'dialog-overview-example', - template: ``, + selector: 'app-dialog-overview-example', + template: '', }) export class DialogComponent { constructor(public dialog: MatDialog) {} @@ -14,7 +14,7 @@ export class DialogComponent { } @Component({ - selector: 'dialog-overview-example-dialog', + selector: 'app-dialog-overview-example-dialog', template: `

Dialog Title

Dialog content
diff --git a/apps/example-app/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts similarity index 100% rename from apps/example-app/app/examples/16-input-getter-setter.spec.ts rename to apps/example-app/src/app/examples/16-input-getter-setter.spec.ts diff --git a/apps/example-app/app/examples/16-input-getter-setter.ts b/apps/example-app/src/app/examples/16-input-getter-setter.ts similarity index 88% rename from apps/example-app/app/examples/16-input-getter-setter.ts rename to apps/example-app/src/app/examples/16-input-getter-setter.ts index d79f4fb9..11f8c949 100644 --- a/apps/example-app/app/examples/16-input-getter-setter.ts +++ b/apps/example-app/src/app/examples/16-input-getter-setter.ts @@ -7,6 +7,7 @@ import { Component, Input } from '@angular/core'; {{ value }} `, }) +// eslint-disable-next-line @angular-eslint/component-class-suffix export class InputGetterSetter { @Input() set value(value: string) { this.originalValue = value; diff --git a/apps/example-app/app/examples/README.md b/apps/example-app/src/app/examples/README.md similarity index 100% rename from apps/example-app/app/examples/README.md rename to apps/example-app/src/app/examples/README.md diff --git a/apps/example-app/app/issues/issue-106.spec.ts b/apps/example-app/src/app/issues/issue-106.spec.ts similarity index 100% rename from apps/example-app/app/issues/issue-106.spec.ts rename to apps/example-app/src/app/issues/issue-106.spec.ts diff --git a/apps/example-app/app/material.module.ts b/apps/example-app/src/app/material.module.ts similarity index 100% rename from apps/example-app/app/material.module.ts rename to apps/example-app/src/app/material.module.ts diff --git a/apps/example-app/assets/.gitkeep b/apps/example-app/src/assets/.gitkeep similarity index 100% rename from apps/example-app/assets/.gitkeep rename to apps/example-app/src/assets/.gitkeep diff --git a/apps/example-app/environments/environment.prod.ts b/apps/example-app/src/environments/environment.prod.ts similarity index 100% rename from apps/example-app/environments/environment.prod.ts rename to apps/example-app/src/environments/environment.prod.ts diff --git a/apps/example-app/environments/environment.ts b/apps/example-app/src/environments/environment.ts similarity index 100% rename from apps/example-app/environments/environment.ts rename to apps/example-app/src/environments/environment.ts diff --git a/apps/example-app/favicon.ico b/apps/example-app/src/favicon.ico similarity index 100% rename from apps/example-app/favicon.ico rename to apps/example-app/src/favicon.ico diff --git a/apps/example-app/index.html b/apps/example-app/src/index.html similarity index 100% rename from apps/example-app/index.html rename to apps/example-app/src/index.html diff --git a/apps/example-app/main.ts b/apps/example-app/src/main.ts similarity index 100% rename from apps/example-app/main.ts rename to apps/example-app/src/main.ts diff --git a/apps/example-app/polyfills.ts b/apps/example-app/src/polyfills.ts similarity index 90% rename from apps/example-app/polyfills.ts rename to apps/example-app/src/polyfills.ts index 5ead8153..1348d74b 100644 --- a/apps/example-app/polyfills.ts +++ b/apps/example-app/src/polyfills.ts @@ -14,7 +14,7 @@ * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html */ -/*************************************************************************************************** +/** ************************************************************************************************* * BROWSER POLYFILLS */ @@ -65,11 +65,11 @@ */ // (window as any).__Zone_enable_cross_context_check = true; -/*************************************************************************************************** +/** ************************************************************************************************* * Zone JS is required by default for Angular itself. */ import 'zone.js/dist/zone'; // Included with Angular CLI. -/*************************************************************************************************** +/** ************************************************************************************************* * APPLICATION IMPORTS */ diff --git a/apps/example-app/styles.css b/apps/example-app/src/styles.css similarity index 100% rename from apps/example-app/styles.css rename to apps/example-app/src/styles.css diff --git a/apps/example-app/test-setup.ts b/apps/example-app/src/test-setup.ts similarity index 83% rename from apps/example-app/test-setup.ts rename to apps/example-app/src/test-setup.ts index 13a4e108..8301387c 100644 --- a/apps/example-app/test-setup.ts +++ b/apps/example-app/src/test-setup.ts @@ -1,4 +1,4 @@ -import 'jest-preset-angular'; +import 'jest-preset-angular/setup-jest'; import '@testing-library/jest-dom'; import { configure } from '@testing-library/angular'; import { ReactiveFormsModule } from '@angular/forms'; diff --git a/apps/example-app/tsconfig.app.json b/apps/example-app/tsconfig.app.json new file mode 100644 index 00000000..629fd434 --- /dev/null +++ b/apps/example-app/tsconfig.app.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": [], + "allowJs": true + }, + "files": ["src/main.ts", "src/polyfills.ts"] +} diff --git a/apps/example-app/tsconfig.editor.json b/apps/example-app/tsconfig.editor.json new file mode 100644 index 00000000..20c4afdb --- /dev/null +++ b/apps/example-app/tsconfig.editor.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": ["**/*.ts"], + "compilerOptions": { + "types": ["jest", "node"] + } +} diff --git a/apps/example-app/tsconfig.json b/apps/example-app/tsconfig.json index 91857b27..de50e310 100644 --- a/apps/example-app/tsconfig.json +++ b/apps/example-app/tsconfig.json @@ -1,9 +1,22 @@ { "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/app", - "types": [], - "allowJs": true + "files": [], + "include": [], + "compilerOptions": {}, + "angularCompilerOptions": { + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true }, - "files": ["main.ts", "polyfills.ts"] + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + }, + { + "path": "./tsconfig.editor.json" + } + ] } diff --git a/apps/example-app/tsconfig.spec.json b/apps/example-app/tsconfig.spec.json index ba3de654..cfff29a5 100644 --- a/apps/example-app/tsconfig.spec.json +++ b/apps/example-app/tsconfig.spec.json @@ -1,9 +1,10 @@ { - "extends": "../../tsconfig.json", + "extends": "./tsconfig.json", "compilerOptions": { + "outDir": "../../dist/out-tsc", "module": "commonjs", - "types": ["node", "jest"] + "types": ["jest", "node"] }, - "files": ["test-setup.ts"], + "files": ["src/test-setup.ts"], "include": ["**/*.spec.ts", "**/*.d.ts"] } diff --git a/apps/example-app/tslint.json b/apps/example-app/tslint.json deleted file mode 100644 index 8006e74e..00000000 --- a/apps/example-app/tslint.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "../../tslint.json", - "rules": { - "directive-selector": [true, "attribute", "app", "camelCase"], - "component-selector": [true, "element", "app", "kebab-case"] - } -} diff --git a/jest.config.js b/jest.config.js index 17d489e2..b52842c3 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,3 +1,3 @@ module.exports = { - projects: ['/', '/projects/testing-library', '/projects/jest-utils'], + projects: ['/apps/example-app', '/projects/testing-library', '/projects/jest-utils'], }; diff --git a/jest.preset.js b/jest.preset.js index b5989195..21c2ab11 100644 --- a/jest.preset.js +++ b/jest.preset.js @@ -8,11 +8,10 @@ module.exports = { resolver: '@nrwl/jest/plugins/resolver', moduleFileExtensions: ['ts', 'js', 'html'], coverageReporters: ['html'], - setupFilesAfterEnv: ['/test-setup.ts'], snapshotSerializers: [ - 'jest-preset-angular/build/AngularNoNgAttributesSnapshotSerializer.js', - 'jest-preset-angular/build/AngularSnapshotSerializer.js', - 'jest-preset-angular/build/HTMLCommentSerializer.js', + 'jest-preset-angular/build/serializers/no-ng-attributes', + 'jest-preset-angular/build/serializers/ng-snapshot', + 'jest-preset-angular/build/serializers/html-comment', ], globals: { 'ts-jest': { diff --git a/migrations.json b/migrations.json new file mode 100644 index 00000000..1b29890b --- /dev/null +++ b/migrations.json @@ -0,0 +1,89 @@ +{ + "migrations": [ + { + "version": "11.0.0-beta.3", + "description": "Update the decoration script when using Angular CLI", + "factory": "./src/migrations/update-11-0-0/update-decorate-angular-cli", + "package": "@nrwl/workspace", + "name": "update-decorate-angular-cli" + }, + { + "version": "11.0.0-beta.3", + "description": "Update the @types/node package", + "factory": "./src/migrations/update-11-0-0/update-node-types", + "package": "@nrwl/workspace", + "name": "update-node-types" + }, + { + "version": "11.0.0-beta.3", + "description": "Rename tools/schematics into tools/generators", + "factory": "./src/migrations/update-11-0-0/rename-workspace-schematics", + "package": "@nrwl/workspace", + "name": "rename-workspace-schematics" + }, + { + "version": "11.0.0-beta.15", + "description": "Adds `outputs` based on builders", + "factory": "./src/migrations/update-11-0-0/add-outputs-in-workspace", + "package": "@nrwl/workspace", + "name": "add-outputs-in-workspace" + }, + { + "version": "11.0.0", + "description": "Check that the right update command is used", + "factory": "./src/migrations/update-11-0-0/update-command-check", + "package": "@nrwl/workspace", + "name": "update-command-check" + }, + { + "version": "11.0.2", + "description": "Rename the workspace-schematic script into workspace-generator script", + "factory": "./src/migrations/update-11-0-0/rename-workspace-schematic-script", + "package": "@nrwl/workspace", + "name": "rename-workspace-schematic-script" + }, + { + "version": "10.5.0-beta.0", + "description": "Update eslint config and builder to extend from new Nx Angular presets and lint templates", + "factory": "./src/migrations/update-10-5-0/add-template-support-and-presets-to-eslint", + "package": "@nrwl/angular", + "name": "add-template-support-and-presets-to-eslint" + }, + { + "version": "11.0.0-beta.13", + "description": "Update builder configurations and dependencies", + "factory": "./src/migrations/update-11-0-0/update-builders-config", + "package": "@nrwl/angular", + "name": "update-11-0-0" + }, + { + "version": "12.0.0-beta.0", + "description": "adjusts the ngcc postinstall command to just leave 'ngcc' in there. This fixes Ivy in Jest tests and Storybooks", + "factory": "./src/migrations/update-12-0-0/update-ngcc-postinstall", + "package": "@nrwl/angular", + "name": "update-ngcc-postinstall" + }, + { + "cli": "nx", + "version": "11.5.0-beta.0", + "description": "Update project .eslintrc.json files to always use project level tsconfigs", + "factory": "./src/migrations/update-11-5-0/always-use-project-level-tsconfigs-with-eslint", + "package": "@nrwl/linter", + "name": "always-use-project-level-tsconfigs-with-eslint" + }, + { + "version": "11.0.0-beta.4", + "description": "Rename ng-update into nx-migrate", + "factory": "./src/migrations/update-11-0-0/rename-ng-update-into-nx-migrate", + "package": "@nrwl/nx-plugin", + "name": "rename-ng-update-into-nx-migrate" + }, + { + "version": "11.0.17", + "description": "Update schema versions for executors and generators", + "factory": "./src/migrations/update-11-0-0/update-schema-version-for-executors-and-generators", + "package": "@nrwl/nx-plugin", + "name": "update-schema-version-for-executors-and-generators" + } + ] +} diff --git a/nx.json b/nx.json index 0473fa55..c99139c8 100644 --- a/nx.json +++ b/nx.json @@ -1,23 +1,24 @@ { - "npmScope": "testing-library", "implicitDependencies": { "angular.json": "*", - "package.json": "*", - "tsconfig.json": "*", - "tslint.json": "*", + "package.json": { + "dependencies": "*", + "devDependencies": "*" + }, + "tsconfig.base.json": "*", + ".eslintrc.json": "*", "nx.json": "*" }, + "affected": { + "defaultBase": "master" + }, + "npmScope": "testing-library", "tasksRunnerOptions": { "default": { "runner": "@nrwl/nx-cloud", "options": { "accessToken": "M2Q4YjlkNjMtMzY1NC00ZjkwLTk1ZjgtZjg5Y2VkMzFjM2FifHJlYWQtd3JpdGU=", - "cacheableOperations": [ - "build", - "test", - "lint", - "e2e" - ], + "cacheableOperations": ["build", "test", "lint", "e2e"], "canTrackAnalytics": false, "showUsageWarnings": true } diff --git a/package.json b/package.json index 5dd16630..eafa5772 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.0.0-semantically-released", "scripts": { "ng": "ng", + "nx": "nx", "postinstall": "ngcc", "start": "ng serve", "build": "nx run-many --target=build --projects=testing-library,jest-utils", @@ -17,57 +18,68 @@ "affected:lint": "nx affected:lint", "affected:dep-graph": "nx affected:dep-graph", "affected": "nx affected", + "format": "nx format:write", + "format:write": "nx format:write", + "format:check": "nx format:check", "precommit": "lint-staged", "semantic-release": "semantic-release" }, "dependencies": { - "@angular/animations": "^11.0.0", - "@angular/cdk": "^11.0.0", - "@angular/common": "^11.0.0", - "@angular/compiler": "^11.0.0", - "@angular/core": "^11.0.0", - "@angular/forms": "^11.0.0", - "@angular/material": "^11.0.0", - "@angular/platform-browser": "^11.0.0", - "@angular/platform-browser-dynamic": "^11.0.0", - "@angular/router": "^11.0.0", - "@ngrx/store": "^10.0.1", - "@nrwl/angular": "^10.3.3", - "@nrwl/nx-cloud": "^10.0.0", + "@angular/animations": "11.2.9", + "@angular/cdk": "11.2.9", + "@angular/common": "11.2.9", + "@angular/compiler": "11.2.9", + "@angular/core": "11.2.9", + "@angular/forms": "11.2.9", + "@angular/material": "11.2.9", + "@angular/platform-browser": "11.2.9", + "@angular/platform-browser-dynamic": "11.2.9", + "@angular/router": "11.2.9", + "@ngrx/store": "11.0.0", + "@nrwl/angular": "12.0.3", + "@nrwl/nx-cloud": "11.2.0", "@phenomnomnominal/tsquery": "^4.1.1", "@testing-library/dom": "7.29.4", "@testing-library/user-event": "^12.0.11", "core-js": "^3.6.5", "rxjs": "^6.5.5", "tslib": "^2.0.0", - "tslint": "~6.1.0", - "zone.js": "~0.10.3" + "zone.js": "~0.11.4" }, "devDependencies": { - "@angular-devkit/build-angular": "~0.1100.0", - "@angular/cli": "~11.0.0", - "@angular/compiler-cli": "^11.0.0", - "@angular/language-service": "^11.0.0", - "@nrwl/cli": "10.3.3", - "@nrwl/jest": "^10.3.3", - "@nrwl/node": "^10.3.3", - "@nrwl/nx-plugin": "^10.3.3", - "@nrwl/workspace": "^10.3.3", + "@angular-devkit/build-angular": "0.1102.8", + "@angular-eslint/eslint-plugin": "~2.1.0", + "@angular-eslint/eslint-plugin-template": "~2.1.0", + "@angular-eslint/template-parser": "~2.1.0", + "@angular/cli": "11.2.8", + "@angular/compiler-cli": "11.2.9", + "@angular/language-service": "11.2.9", + "@nrwl/cli": "12.0.3", + "@nrwl/eslint-plugin-nx": "12.0.3", + "@nrwl/jest": "12.0.3", + "@nrwl/linter": "12.0.3", + "@nrwl/node": "12.0.3", + "@nrwl/nx-plugin": "12.0.3", + "@nrwl/workspace": "12.0.3", "@testing-library/jest-dom": "^5.11.0", "@types/jest": "~26.0.3", - "@types/node": "^14.0.14", - "codelyzer": "^5.2.2", + "@types/node": "14.14.37", + "@typescript-eslint/eslint-plugin": "4.22.0", + "@typescript-eslint/parser": "4.22.0", "cpy-cli": "^3.1.1", + "eslint": "7.24.0", + "eslint-config-prettier": "8.2.0", + "eslint-plugin-import": "latest", "husky": "^4.2.5", "jest": "^26.1.0", - "jest-preset-angular": "8.3.1", + "jest-preset-angular": "8.4.0", "lint-staged": "^10.2.11", - "ng-packagr": "^11.0.1", - "prettier": "^2.0.5", + "ng-packagr": "11.2.4", + "prettier": "2.2.1", "rimraf": "^3.0.2", "semantic-release": "^17.1.1", - "ts-jest": "26.4.0", - "ts-node": "~8.10.2", - "typescript": "~4.0.5" + "ts-jest": "26.5.4", + "ts-node": "9.1.1", + "typescript": "4.1.4" } } diff --git a/projects/jest-utils/.eslintrc.json b/projects/jest-utils/.eslintrc.json new file mode 100644 index 00000000..4687290e --- /dev/null +++ b/projects/jest-utils/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": "../../.eslintrc.json", + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], + "parserOptions": { + "project": ["projects/jest-utils/tsconfig.*?.json"] + }, + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "lib", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "lib", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/projects/jest-utils/src/lib/create-mock.ts b/projects/jest-utils/src/lib/create-mock.ts index 7d18f152..7b9c1ecd 100644 --- a/projects/jest-utils/src/lib/create-mock.ts +++ b/projects/jest-utils/src/lib/create-mock.ts @@ -29,10 +29,7 @@ export function createMock(type: Type): Mock { return mock; } -export function createMockWithValues( - type: Type, - values: Partial>, -): Mock { +export function createMockWithValues(type: Type, values: Partial>): Mock { const mock = createMock(type); Object.entries(values).forEach(([field, value]) => { diff --git a/projects/jest-utils/test-setup.ts b/projects/jest-utils/test-setup.ts index 9020de51..0da94a0a 100644 --- a/projects/jest-utils/test-setup.ts +++ b/projects/jest-utils/test-setup.ts @@ -1,2 +1,2 @@ -import 'jest-preset-angular'; +import 'jest-preset-angular/setup-jest'; import '@testing-library/jest-dom'; diff --git a/projects/jest-utils/tslint.json b/projects/jest-utils/tslint.json deleted file mode 100644 index 0946f209..00000000 --- a/projects/jest-utils/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../tslint.json" -} diff --git a/projects/testing-library/.eslintrc.json b/projects/testing-library/.eslintrc.json new file mode 100644 index 00000000..f3960e87 --- /dev/null +++ b/projects/testing-library/.eslintrc.json @@ -0,0 +1,36 @@ +{ + "extends": "../../.eslintrc.json", + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts"], + "extends": ["plugin:@nrwl/nx/angular", "plugin:@angular-eslint/template/process-inline-templates"], + "parserOptions": { + "project": ["projects/testing-library/tsconfig.*?.json"] + }, + "rules": { + "@angular-eslint/directive-selector": [ + "error", + { + "type": "attribute", + "prefix": "lib", + "style": "camelCase" + } + ], + "@angular-eslint/component-selector": [ + "error", + { + "type": "element", + "prefix": "lib", + "style": "kebab-case" + } + ] + } + }, + { + "files": ["*.html"], + "extends": ["plugin:@nrwl/nx/angular-template"], + "rules": {} + } + ] +} diff --git a/projects/testing-library/migrations/4_0_0/index.ts b/projects/testing-library/migrations/4_0_0/index.ts deleted file mode 100644 index 1bd4aad4..00000000 --- a/projects/testing-library/migrations/4_0_0/index.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { Rule } from '@angular-devkit/schematics'; -import { TslintFixTask } from '@angular-devkit/schematics/tasks'; -import * as path from 'path'; - -function createRule(ruleName: string): TslintFixTask { - return new TslintFixTask( - { - rulesDirectory: path.join(__dirname, 'rules'), - rules: { - [ruleName]: [true], - }, - }, - { - includes: ['**/*.spec.ts', '**/*.test.ts'], - silent: false, - }, - ); -} - -export default function (): Rule { - return (_, context) => { - const noCreateComponentRule = createRule('no-create-component'); - const noComponentParametersRule = createRule('no-component-parameters'); - const noComponentPropertyRule = createRule('no-component-property'); - - const noCreateComponentRuleId = context.addTask(noCreateComponentRule); - const noComponentParametersRuleId = context.addTask(noComponentParametersRule, [noCreateComponentRuleId]); - context.addTask(noComponentPropertyRule, [noComponentParametersRuleId]); - }; -} diff --git a/projects/testing-library/migrations/4_0_0/rules/noComponentParametersRule.ts b/projects/testing-library/migrations/4_0_0/rules/noComponentParametersRule.ts deleted file mode 100644 index 791b3c15..00000000 --- a/projects/testing-library/migrations/4_0_0/rules/noComponentParametersRule.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as ts from 'typescript'; -import { Replacement, RuleFailure, Rules } from 'tslint'; -import { tsquery } from '@phenomnomnominal/tsquery'; - -const IS_COMPONENT_PROPERTY_QUERY = - 'CallExpression:has(Identifier[name="render"]) > ObjectLiteralExpression:first-child'; -const RENDER_OPTIONS_QUERY = 'CallExpression:has(Identifier[name="render"]) > ObjectLiteralExpression:last-child'; -const COMPONENT_PARAMETERS_PROPERTY_VALUE_QUERY = 'PropertyAssignment:has(Identifier[name="parameters"]) :last-child'; - -const FAILURE_MESSAGE = 'Found `parameters` parameter, use `componentProperties` instead.'; - -export class Rule extends Rules.AbstractRule { - public apply(ast: ts.SourceFile): Array { - return tsquery(ast, IS_COMPONENT_PROPERTY_QUERY) - .map((result) => { - const [parameterNode] = tsquery(result, COMPONENT_PARAMETERS_PROPERTY_VALUE_QUERY); - if (!parameterNode) { - return []; - } - const [renderOptionsNode] = tsquery(ast, RENDER_OPTIONS_QUERY); - - const renderOptionsText = renderOptionsNode.getFullText(); - const bracketIndex = renderOptionsText.indexOf('{'); - const renderOptions = - renderOptionsText.substring(0, bracketIndex + 1) + - `componentProperties:${parameterNode.getFullText()},` + - renderOptionsText.substr(bracketIndex + 1); - - const replacement = new Replacement(renderOptionsNode.getStart(), renderOptionsNode.getWidth(), renderOptions); - const start = renderOptionsNode.getStart(); - const end = renderOptionsNode.getEnd(); - - const replacementOriginal = new Replacement(parameterNode.getStart(), parameterNode.getWidth(), ''); - const startOriginal = renderOptionsNode.getStart(); - const endOriginal = renderOptionsNode.getEnd(); - - return [ - new RuleFailure(ast, startOriginal, endOriginal, FAILURE_MESSAGE, this.ruleName, replacementOriginal), - new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement), - ]; - }) - .reduce((rules, rule) => rules.concat(rule), []); - } -} diff --git a/projects/testing-library/migrations/4_0_0/rules/noComponentPropertyRule.ts b/projects/testing-library/migrations/4_0_0/rules/noComponentPropertyRule.ts deleted file mode 100644 index 9c6d012c..00000000 --- a/projects/testing-library/migrations/4_0_0/rules/noComponentPropertyRule.ts +++ /dev/null @@ -1,22 +0,0 @@ -import * as ts from 'typescript'; -import { Replacement, RuleFailure, Rules } from 'tslint'; -import { tsquery } from '@phenomnomnominal/tsquery'; - -const IS_COMPONENT_PROPERTY_QUERY = - 'CallExpression:has(Identifier[name="render"]) > ObjectLiteralExpression:first-child'; -const COMPONENT_PROPERTY_VALUE_QUERY = 'PropertyAssignment:has(Identifier[name="component"]) :last-child'; - -const FAILURE_MESSAGE = 'Found component propety syntax, signature looks different.'; - -export class Rule extends Rules.AbstractRule { - public apply(ast: ts.SourceFile): Array { - return tsquery(ast, IS_COMPONENT_PROPERTY_QUERY).map((result) => { - const [valueNode] = tsquery(result, COMPONENT_PROPERTY_VALUE_QUERY); - const replacement = new Replacement(result.getStart(), result.getWidth(), (valueNode || result).getText()); - const start = result.getStart(); - const end = result.getEnd(); - - return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement); - }); - } -} diff --git a/projects/testing-library/migrations/4_0_0/rules/noCreateComponentRule.ts b/projects/testing-library/migrations/4_0_0/rules/noCreateComponentRule.ts deleted file mode 100644 index 5ed4dbc0..00000000 --- a/projects/testing-library/migrations/4_0_0/rules/noCreateComponentRule.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as ts from 'typescript'; -import { Replacement, RuleFailure, Rules } from 'tslint'; -import { tsquery } from '@phenomnomnominal/tsquery'; - -const CREATE_COMPONENT_IDENTIFIER = 'Identifier[name="createComponent"]'; -const CREATE_COMPONENT_IMPORT_QUERY = `ImportSpecifier > ${CREATE_COMPONENT_IDENTIFIER}`; -const CREATE_COMPONENT_CALL_EXPRESSION_QUERY = `CallExpression > ${CREATE_COMPONENT_IDENTIFIER}`; - -const RENDER = 'render'; - -const FAILURE_MESSAGE = 'Found `createComponent`, use `render` instead.'; - -export class Rule extends Rules.AbstractRule { - public apply(ast: ts.SourceFile): Array { - const imports = this.getImports(ast); - const usages = this.getUsages(ast); - - return [...imports, ...usages]; - } - - private getImports(ast: ts.SourceFile): Array { - return tsquery(ast, CREATE_COMPONENT_IMPORT_QUERY).map((result) => { - const replacement = new Replacement(result.getStart(), result.getWidth(), RENDER); - const start = result.getStart(); - const end = result.getEnd(); - - return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement); - }); - } - - private getUsages(ast: ts.SourceFile): Array { - return tsquery(ast, CREATE_COMPONENT_CALL_EXPRESSION_QUERY).map((result) => { - const replacement = new Replacement(result.getStart(), result.getWidth(), RENDER); - const start = result.getStart(); - const end = result.getEnd(); - - return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement); - }); - } -} diff --git a/projects/testing-library/migrations/5_1_2/index.ts b/projects/testing-library/migrations/5_1_2/index.ts deleted file mode 100644 index b35fd19c..00000000 --- a/projects/testing-library/migrations/5_1_2/index.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { Rule, chain, Tree, SchematicContext } from '@angular-devkit/schematics'; -import { TslintFixTask } from '@angular-devkit/schematics/tasks'; -import * as path from 'path'; -import { stripIndents } from '@angular-devkit/core/src/utils/literals'; - -function createRule(ruleName: string): TslintFixTask { - return new TslintFixTask( - { - rulesDirectory: path.join(__dirname, 'rules'), - rules: { - [ruleName]: [true], - }, - }, - { - includes: ['**/*.spec.ts', '**/*.test.ts'], - silent: false, - }, - ); -} - -function displayInformation(tree, context: SchematicContext) { - context.logger.info(stripIndents` - @angular-extensions/testing-library has moved to @testing-library/angular. - - Learn more about this change here: https://github.com/testing-library/dom-testing-library/issues/260 - `); - - return tree; -} - -function updatePackageJson(host: Tree) { - if (host.exists('package.json')) { - // tslint:disable-next-line: no-non-null-assertion - const sourceText = host.read('package.json')!.toString('utf-8'); - const json = JSON.parse(sourceText); - - if (json['devDependencies'] && json['devDependencies']['@angular-extensions/testing-library']) { - json['devDependencies']['@testing-library/angular'] = '^6.0.0'; - delete json['devDependencies']['@angular-extensions/testing-library']; - host.overwrite('package.json', JSON.stringify(json, null, 2)); - } - } - - return host; -} - -export default function (): Rule { - return (host, context) => { - context.addTask(createRule('no-angular-extensions-import')); - - return chain([displayInformation, updatePackageJson])(host, context); - }; -} diff --git a/projects/testing-library/migrations/5_1_2/rules/noAngularExtensionsImportRule.ts b/projects/testing-library/migrations/5_1_2/rules/noAngularExtensionsImportRule.ts deleted file mode 100644 index f8ab045f..00000000 --- a/projects/testing-library/migrations/5_1_2/rules/noAngularExtensionsImportRule.ts +++ /dev/null @@ -1,26 +0,0 @@ -import * as ts from 'typescript'; -import { Replacement, RuleFailure, Rules } from 'tslint'; -import { tsquery } from '@phenomnomnominal/tsquery'; - -const IMPORT_QUERY = `ImportDeclaration StringLiteral[value="@angular-extensions/testing-library"]`; - -const FAILURE_MESSAGE = - 'Found the library `@angular-extensions/testing-library`, use `@testing-library/angular` instead.'; - -export class Rule extends Rules.AbstractRule { - public apply(ast: ts.SourceFile): Array { - const imports = this.getImports(ast); - return imports; - } - - private getImports(ast: ts.SourceFile): Array { - return tsquery(ast, IMPORT_QUERY).map((result) => { - // replace text between (single) quotes - const replacement = new Replacement(result.getStart() + 1, result.getWidth() - 2, '@testing-library/angular'); - const start = result.getStart(); - const end = result.getEnd(); - - return new RuleFailure(ast, start, end, FAILURE_MESSAGE, this.ruleName, replacement); - }); - } -} diff --git a/projects/testing-library/migrations/migration.json b/projects/testing-library/migrations/migration.json deleted file mode 100644 index 7a7cc7a4..00000000 --- a/projects/testing-library/migrations/migration.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "../../../node_modules/@angular-devkit/schematics/collection-schema.json", - "schematics": { - "migration-4.0.0": { - "version": "4.0.0", - "description": "Align API to *-testing-libraries", - "factory": "./4_0_0" - }, - "migration-5.1.2": { - "version": "5.1.2", - "description": "Migrate to @testing-library", - "factory": "./5_1_2" - } - } -} diff --git a/projects/testing-library/migrations/tsconfig.migrations.json b/projects/testing-library/migrations/tsconfig.migrations.json deleted file mode 100644 index 794ddbb2..00000000 --- a/projects/testing-library/migrations/tsconfig.migrations.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "target": "es5", - "sourceMap": true, - "rootDir": "./", - "outDir": "../../../dist/@testing-library/angular/migrations", - "noLib": false, - "baseUrl": "./", - "experimentalDecorators": true, - "skipLibCheck": true, - "declaration": true, - "removeComments": true, - "lib": ["es6"] - }, - "include": ["."] -} diff --git a/projects/testing-library/ng-package.json b/projects/testing-library/ng-package.json index 48f090fa..aab92535 100644 --- a/projects/testing-library/ng-package.json +++ b/projects/testing-library/ng-package.json @@ -5,10 +5,10 @@ "lib": { "entryFile": "index.ts" }, - "whitelistedNonPeerDependencies": [ + "allowedNonPeerDependencies": [ "@testing-library/dom", "@testing-library/user-event", "@phenomnomnominal/tsquery", - "tslint" + "eslint" ] } diff --git a/projects/testing-library/package.json b/projects/testing-library/package.json index 17ad15d4..18b231d0 100644 --- a/projects/testing-library/package.json +++ b/projects/testing-library/package.json @@ -32,12 +32,9 @@ "@testing-library/dom": "7.29.4", "@phenomnomnominal/tsquery": "^4.1.1", "tslib": "^2.0.0", - "tslint": "^5.16.0" + "eslint": "7.24.0" }, "publishConfig": { "access": "public" - }, - "ng-update": { - "migrations": "./migrations/migration.json" } } diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts index 5d9b225b..6248ef92 100644 --- a/projects/testing-library/src/lib/models.ts +++ b/projects/testing-library/src/lib/models.ts @@ -250,6 +250,7 @@ export interface RenderComponentOptions extends RenderComponentOptions { /** diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index 62c2c0c0..13f96f06 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -256,13 +256,9 @@ function addAutoDeclarations( wrapper, }: Pick, 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'>, ) { - const wrappers = () => { - return template ? [wrapper] : []; - }; + const wrappers = () => (template ? [wrapper] : []); - const components = () => { - return excludeComponentDeclaration ? [] : [component]; - }; + const components = () => (excludeComponentDeclaration ? [] : [component]); return [...declarations, ...wrappers(), ...components()]; } @@ -274,9 +270,7 @@ function addAutoImports({ imports, routes }: Pick, ' return animationIsDefined ? [] : [NoopAnimationsModule]; }; - const routing = () => { - return routes ? [RouterTestingModule.withRoutes(routes)] : []; - }; + const routing = () => (routes ? [RouterTestingModule.withRoutes(routes)] : []); return [...imports, ...animations(), ...routing()]; } @@ -341,6 +335,7 @@ if (typeof afterEach === 'function' && !process.env.ATL_SKIP_AUTO_CLEANUP) { }); } +// eslint-disable-next-line @angular-eslint/component-selector @Component({ selector: 'wrapper-component', template: '' }) class WrapperComponent {} diff --git a/projects/testing-library/test-setup.ts b/projects/testing-library/test-setup.ts index 9020de51..0da94a0a 100644 --- a/projects/testing-library/test-setup.ts +++ b/projects/testing-library/test-setup.ts @@ -1,2 +1,2 @@ -import 'jest-preset-angular'; +import 'jest-preset-angular/setup-jest'; import '@testing-library/jest-dom'; diff --git a/projects/testing-library/tests/directive.spec.ts b/projects/testing-library/tests/directive.spec.ts index 2d7f42a8..08db0eb3 100644 --- a/projects/testing-library/tests/directive.spec.ts +++ b/projects/testing-library/tests/directive.spec.ts @@ -112,16 +112,15 @@ describe('removeAngularAttributes', () => { }); }); - test('updates properties and invokes change detection', async () => { const component = await render(UpdateInputDirective, { template: '
', componentProperties: { - value: 'value1' - } + value: 'value1', + }, }); - component.getByText('value1') - component.fixture.componentInstance.value = 'updated value' - component.getByText('updated value') + component.getByText('value1'); + component.fixture.componentInstance.value = 'updated value'; + component.getByText('updated value'); }); diff --git a/projects/testing-library/tests/migration/4_0_0.spec.ts b/projects/testing-library/tests/migration/4_0_0.spec.ts deleted file mode 100644 index 8c82963b..00000000 --- a/projects/testing-library/tests/migration/4_0_0.spec.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { getSystemPath, normalize, virtualFs } from '@angular-devkit/core'; -import { TempScopedNodeJsSyncHost } from '@angular-devkit/core/node/testing'; -import { HostTree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; - -describe('Migration to version 4.0.0', () => { - /* tslint:disable */ - const fixtures = [ - { - description: 'template syntax', - input: virtualFs.stringToFileBuffer(` - import { createComponent } from '@testing-library/angular'; - import { HomeComponent } from './home.component'; - - async function setup() { - await createComponent('', { - declarations: [HomeComponent], - }); - }`), - expected: ` - import { render } from '@testing-library/angular'; - import { HomeComponent } from './home.component'; - - async function setup() { - await render('', { - declarations: [HomeComponent], - }); - }`, - }, - { - description: 'component syntax', - input: virtualFs.stringToFileBuffer(` - import { createComponent } from '@testing-library/angular'; - import { HomeComponent } from './home.component'; - - async function setup() { - await createComponent( - { - component: HomeComponent - }, - { - declarations: [HomeComponent], - } - ); - }`), - expected: ` - import { render } from '@testing-library/angular'; - import { HomeComponent } from './home.component'; - - async function setup() { - await render( - HomeComponent, - { - declarations: [HomeComponent], - } - ); - }`, - }, - { - description: 'component syntax with properties', - input: virtualFs.stringToFileBuffer(` - import { createComponent } from '@testing-library/angular'; - import { HomeComponent } from './home.component'; - - async function setup() { - await createComponent( - { - component: HomeComponent, - parameters: { - value: 'foo', - count: 2 - }, - }, - { - declarations: [HomeComponent], - } - ); - }`), - expected: ` - import { render } from '@testing-library/angular'; - import { HomeComponent } from './home.component'; - - async function setup() { - await render( - HomeComponent, - - {componentProperties: { - value: 'foo', - count: 2 - }, - declarations: [HomeComponent], - } - ); - }`, - }, - ]; - /* tslint:enable */ - - const schematicRunner = new SchematicTestRunner('migrations', require.resolve('../../migrations/migration.json')); - const specPath = normalize('tests/home.spec.ts'); - - fixtures.forEach(async ({ description, input, expected }) => { - it(description, async () => { - const host = new TempScopedNodeJsSyncHost(); - const tree = new UnitTestTree(new HostTree(host)); - tree.create('/package.json', JSON.stringify({})); - process.chdir(getSystemPath(host.root)); - await host.write(specPath, input).toPromise(); - - await schematicRunner.runSchematicAsync('migration-4.0.0', {}, tree).toPromise(); - await schematicRunner.engine.executePostTasks().toPromise(); - - const actual = await host.read(specPath).toPromise().then(virtualFs.fileBufferToString); - - expect(actual.replace(/\s/g, '')).toBe(expected.replace(/\s/g, '')); - }); - }); -}); diff --git a/projects/testing-library/tests/migration/5_1_2.spec.ts b/projects/testing-library/tests/migration/5_1_2.spec.ts deleted file mode 100644 index b41001f2..00000000 --- a/projects/testing-library/tests/migration/5_1_2.spec.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { getSystemPath, normalize, virtualFs } from '@angular-devkit/core'; -import { TempScopedNodeJsSyncHost } from '@angular-devkit/core/node/testing'; -import { HostTree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import { stripIndents } from '@angular-devkit/core/src/utils/literals'; - -describe('Migration to version 5.1.2', () => { - const schematicRunner = new SchematicTestRunner('migrations', require.resolve('../../migrations/migration.json')); - - test('it renames @angular-extensions to @testing-library (in files)', async () => { - const specPath = normalize('tests/home.spec.ts'); - - const host = new TempScopedNodeJsSyncHost(); - const tree = new UnitTestTree(new HostTree(host)); - tree.create('/package.json', JSON.stringify({})); - process.chdir(getSystemPath(host.root)); - await host - .write( - specPath, - virtualFs.stringToFileBuffer(stripIndents` - import { render } from '@angular-extensions/testing-library'; - import { render } from "@angular-extensions/testing-library"; - `), - ) - .toPromise(); - - await schematicRunner.runSchematicAsync('migration-5.1.2', {}, tree).toPromise(); - await schematicRunner.engine.executePostTasks().toPromise(); - - const actual = await host.read(specPath).toPromise().then(virtualFs.fileBufferToString); - - expect(actual).toBe(stripIndents` - import { render } from '@testing-library/angular'; - import { render } from "@testing-library/angular"; - `); - }); - - test('it renames @angular-extensions to @testing-library (in package.json)', async () => { - const packageJson = normalize('/package.json'); - const host = new TempScopedNodeJsSyncHost(); - const tree = new UnitTestTree(new HostTree(host)); - - tree.create( - packageJson, - JSON.stringify({ - devDependencies: { - '@angular-extensions/testing-library': '🦔', - }, - }), - ); - - await schematicRunner.runSchematicAsync('migration-5.1.2', {}, tree).toPromise(); - await schematicRunner.engine.executePostTasks().toPromise(); - - expect(tree.readContent(packageJson)).toBe( - JSON.stringify( - { - devDependencies: { - '@testing-library/angular': '^6.0.0', - }, - }, - null, - 2, - ), - ); - }); -}); diff --git a/projects/testing-library/tests/rerender.spec.ts b/projects/testing-library/tests/rerender.spec.ts index 0a1b9c79..5f7d152a 100644 --- a/projects/testing-library/tests/rerender.spec.ts +++ b/projects/testing-library/tests/rerender.spec.ts @@ -40,7 +40,7 @@ class FixtureWithNgOnChangesComponent implements OnChanges { test('will call ngOnChanges on rerender', async () => { const nameChanged = jest.fn(); const componentProperties = { nameChanged }; - const component = await render(FixtureWithNgOnChangesComponent, {componentProperties}); + const component = await render(FixtureWithNgOnChangesComponent, { componentProperties }); component.getByText('Sarah'); const name = 'Mark'; @@ -50,14 +50,12 @@ test('will call ngOnChanges on rerender', async () => { component.getByText(name); expect(nameChanged).toBeCalledWith(name, false); -}) +}); @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'fixture-onpush', - template: ` -
Number
- `, + template: `
Number
`, }) class FixtureWithOnPushComponent { @Input() activeField: string; @@ -70,4 +68,4 @@ test('update properties on rerender', async () => { expect(numberHtmlElementRef).not.toHaveClass('active'); rerender({ activeField: 'number' }); expect(numberHtmlElementRef).toHaveClass('active'); -}) +}); diff --git a/projects/testing-library/tslint.json b/projects/testing-library/tslint.json deleted file mode 100644 index 0946f209..00000000 --- a/projects/testing-library/tslint.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "extends": "../../tslint.json" -} diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 2b9e595a..00000000 --- a/tslint.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "rulesDirectory": ["node_modules/codelyzer"], - "rules": { - "arrow-return-shorthand": true, - "callable-types": true, - "class-name": true, - "comment-format": [true, "check-space"], - "curly": true, - "deprecation": { - "severity": "warn" - }, - "eofline": true, - "forin": true, - "import-blacklist": [true, "rxjs/Rx"], - "import-spacing": true, - "indent": [true, "spaces"], - "interface-over-type-literal": true, - "label-position": true, - "member-access": false, - "member-ordering": [ - true, - { - "order": ["static-field", "instance-field", "static-method", "instance-method"] - } - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [true, "debug", "info", "time", "timeEnd", "trace"], - "no-construct": true, - "no-debugger": true, - "no-duplicate-super": true, - "no-empty": false, - "no-empty-interface": true, - "no-eval": true, - "no-inferrable-types": [true, "ignore-params"], - "no-misused-new": true, - "no-non-null-assertion": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-string-throw": true, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": true, - "no-unnecessary-initializer": true, - "no-unused-expression": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "one-line": [true, "check-open-brace", "check-catch", "check-else", "check-whitespace"], - "prefer-const": true, - "quotemark": [true, "single"], - "radix": true, - "triple-equals": [true, "allow-null-check"], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - } - ], - "variable-name": false, - "whitespace": [true, "check-branch", "check-decl", "check-operator", "check-separator", "check-type"], - "no-output-on-prefix": true, - "no-inputs-metadata-property": true, - "no-outputs-metadata-property": true, - "no-host-metadata-property": true, - "no-input-rename": true, - "no-output-rename": true, - "use-lifecycle-interface": true, - "use-pipe-transform-interface": true, - "component-class-suffix": true, - "directive-class-suffix": true - } -} From 25a4ca336f270bfe9f9a40866dc283dcbf4d2a1c Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Thu, 15 Apr 2021 12:57:08 +0200 Subject: [PATCH 2/8] docs: add the-ult as a contributor (#200) --- .all-contributorsrc | 9 +++++++++ README.md | 1 + 2 files changed, 10 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index f6cf697b..6f2dd580 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -188,6 +188,15 @@ "code", "test" ] + }, + { + "login": "the-ult", + "name": "Arjen", + "avatar_url": "https://avatars.githubusercontent.com/u/4863062?v=4", + "profile": "https://github.com/the-ult", + "contributions": [ + "code" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 0acdf9fa..8033f7a6 100644 --- a/README.md +++ b/README.md @@ -208,6 +208,7 @@ Thanks goes to these people ([emoji key][emojis]):
Bo Vandersteene

💻
Janek

💻 ⚠️
Gleb Irovich

💻 ⚠️ +
Arjen

💻 From d33f0e93265d6ea79dc506a1bf2c7fb830cec7f8 Mon Sep 17 00:00:00 2001 From: Arjen Date: Fri, 16 Apr 2021 15:11:39 +0200 Subject: [PATCH 3/8] chore(lint): add and apply eslint-plugin-testing-library (#201) Closes #198 --- .eslintrc.json | 11 +++++++++-- .../src/app/examples/00-single-component.spec.ts | 6 +++--- .../src/app/examples/01-nested-component.spec.ts | 6 +++--- .../src/app/examples/02-input-output.spec.ts | 8 ++++---- .../app/examples/05-component-provider.spec.ts | 12 ++++++------ .../src/app/examples/06-with-ngrx-store.spec.ts | 6 +++--- .../src/app/examples/15-dialog.component.spec.ts | 1 + .../app/examples/16-input-getter-setter.spec.ts | 16 ++++++++-------- .../example-app/src/app/issues/issue-106.spec.ts | 8 ++++---- apps/example-app/tsconfig.spec.json | 2 +- package.json | 4 +++- projects/jest-utils/tsconfig.spec.json | 2 +- projects/testing-library/tsconfig.spec.json | 2 +- 13 files changed, 47 insertions(+), 37 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 5af8c266..b740f815 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -36,6 +36,7 @@ }, { "files": ["*.ts"], + "plugins": ["eslint-plugin-import", "@angular-eslint/eslint-plugin", "@typescript-eslint"], "rules": { "@typescript-eslint/consistent-type-definitions": "error", "@typescript-eslint/dot-notation": "off", @@ -102,8 +103,14 @@ "markers": ["/"] } ] - }, - "plugins": ["eslint-plugin-import", "@angular-eslint/eslint-plugin", "@typescript-eslint"] + } + }, + { + "files": ["*.spec.ts"], + "extends": ["plugin:testing-library/angular", "plugin:jest-dom/recommended"], + "rules": { + "testing-library/prefer-explicit-assert": "error" + } }, { "files": ["*.html"], diff --git a/apps/example-app/src/app/examples/00-single-component.spec.ts b/apps/example-app/src/app/examples/00-single-component.spec.ts index 460cae16..73e429bb 100644 --- a/apps/example-app/src/app/examples/00-single-component.spec.ts +++ b/apps/example-app/src/app/examples/00-single-component.spec.ts @@ -9,12 +9,12 @@ test('renders the current value and can increment and decrement', async () => { const decrementControl = screen.getByRole('button', { name: /decrement/i }); const valueControl = screen.getByTestId('value'); - expect(valueControl.textContent).toBe('0'); + expect(valueControl).toHaveTextContent('0'); fireEvent.click(incrementControl); fireEvent.click(incrementControl); - expect(valueControl.textContent).toBe('2'); + expect(valueControl).toHaveTextContent('2'); fireEvent.click(decrementControl); - expect(valueControl.textContent).toBe('1'); + expect(valueControl).toHaveTextContent('1'); }); diff --git a/apps/example-app/src/app/examples/01-nested-component.spec.ts b/apps/example-app/src/app/examples/01-nested-component.spec.ts index bbaf9c37..8f3a242d 100644 --- a/apps/example-app/src/app/examples/01-nested-component.spec.ts +++ b/apps/example-app/src/app/examples/01-nested-component.spec.ts @@ -11,12 +11,12 @@ test('renders the current value and can increment and decrement', async () => { const decrementControl = screen.getByRole('button', { name: /decrement/i }); const valueControl = screen.getByTestId('value'); - expect(valueControl.textContent).toBe('0'); + expect(valueControl).toHaveTextContent('0'); fireEvent.click(incrementControl); fireEvent.click(incrementControl); - expect(valueControl.textContent).toBe('2'); + expect(valueControl).toHaveTextContent('2'); fireEvent.click(decrementControl); - expect(valueControl.textContent).toBe('1'); + expect(valueControl).toHaveTextContent('1'); }); diff --git a/apps/example-app/src/app/examples/02-input-output.spec.ts b/apps/example-app/src/app/examples/02-input-output.spec.ts index 7c907526..663d63e0 100644 --- a/apps/example-app/src/app/examples/02-input-output.spec.ts +++ b/apps/example-app/src/app/examples/02-input-output.spec.ts @@ -18,12 +18,12 @@ test('is possible to set input and listen for output', async () => { const sendControl = screen.getByRole('button', { name: /send/i }); const valueControl = screen.getByTestId('value'); - expect(valueControl.textContent).toBe('47'); + expect(valueControl).toHaveTextContent('47'); fireEvent.click(incrementControl); fireEvent.click(incrementControl); fireEvent.click(incrementControl); - expect(valueControl.textContent).toBe('50'); + expect(valueControl).toHaveTextContent('50'); fireEvent.click(sendControl); expect(sendValue).toHaveBeenCalledTimes(1); @@ -44,12 +44,12 @@ test('is possible to set input and listen for output with the template syntax', const sendControl = screen.getByRole('button', { name: /send/i }); const valueControl = screen.getByTestId('value'); - expect(valueControl.textContent).toBe('47'); + expect(valueControl).toHaveTextContent('47'); fireEvent.click(incrementControl); fireEvent.click(incrementControl); fireEvent.click(incrementControl); - expect(valueControl.textContent).toBe('50'); + expect(valueControl).toHaveTextContent('50'); fireEvent.click(sendControl); expect(sendSpy).toHaveBeenCalledTimes(1); diff --git a/apps/example-app/src/app/examples/05-component-provider.spec.ts b/apps/example-app/src/app/examples/05-component-provider.spec.ts index 861eae76..79811245 100644 --- a/apps/example-app/src/app/examples/05-component-provider.spec.ts +++ b/apps/example-app/src/app/examples/05-component-provider.spec.ts @@ -18,14 +18,14 @@ test('renders the current value and can increment and decrement', async () => { const decrementControl = screen.getByRole('button', { name: /decrement/i }); const valueControl = screen.getByTestId('value'); - expect(valueControl.textContent).toBe('0'); + expect(valueControl).toHaveTextContent('0'); fireEvent.click(incrementControl); fireEvent.click(incrementControl); - expect(valueControl.textContent).toBe('2'); + expect(valueControl).toHaveTextContent('2'); fireEvent.click(decrementControl); - expect(valueControl.textContent).toBe('1'); + expect(valueControl).toHaveTextContent('1'); }); test('renders the current value and can increment and decrement with a mocked jest-utils service', async () => { @@ -48,14 +48,14 @@ test('renders the current value and can increment and decrement with a mocked je const decrementControl = screen.getByRole('button', { name: /decrement/i }); const valueControl = screen.getByTestId('value'); - expect(valueControl.textContent).toBe('50'); + expect(valueControl).toHaveTextContent('50'); fireEvent.click(incrementControl); fireEvent.click(incrementControl); - expect(valueControl.textContent).toBe('70'); + expect(valueControl).toHaveTextContent('70'); fireEvent.click(decrementControl); - expect(valueControl.textContent).toBe('60'); + expect(valueControl).toHaveTextContent('60'); }); test('renders the current value and can increment and decrement with provideMocked from jest-utils', async () => { diff --git a/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts b/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts index d8a80d87..b8a289bb 100644 --- a/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts +++ b/apps/example-app/src/app/examples/06-with-ngrx-store.spec.ts @@ -21,12 +21,12 @@ test('works with ngrx store', async () => { const decrementControl = screen.getByRole('button', { name: /decrement/i }); const valueControl = screen.getByTestId('value'); - expect(valueControl.textContent).toBe('0'); + expect(valueControl).toHaveTextContent('0'); fireEvent.click(incrementControl); fireEvent.click(incrementControl); - expect(valueControl.textContent).toBe('20'); + expect(valueControl).toHaveTextContent('20'); fireEvent.click(decrementControl); - expect(valueControl.textContent).toBe('10'); + expect(valueControl).toHaveTextContent('10'); }); diff --git a/apps/example-app/src/app/examples/15-dialog.component.spec.ts b/apps/example-app/src/app/examples/15-dialog.component.spec.ts index f5849abc..bcb41875 100644 --- a/apps/example-app/src/app/examples/15-dialog.component.spec.ts +++ b/apps/example-app/src/app/examples/15-dialog.component.spec.ts @@ -54,6 +54,7 @@ test('closes the dialog via the backdrop', async () => { await screen.findByRole('dialog'); await screen.findByRole('heading', { name: /dialog title/i }); + // eslint-disable-next-line testing-library/no-node-access fireEvent.click(document.querySelector('.cdk-overlay-backdrop')); await waitForElementToBeRemoved(() => screen.getByRole('dialog')); diff --git a/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts index 10e0e276..28d736c6 100644 --- a/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts +++ b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts @@ -6,20 +6,20 @@ test('should run logic in the input setter and getter', async () => { const valueControl = screen.getByTestId('value'); const getterValueControl = screen.getByTestId('value-getter'); - expect(valueControl.textContent).toBe('I am value from setter Angular'); - expect(getterValueControl.textContent).toBe('I am value from getter Angular'); + expect(valueControl).toHaveTextContent('I am value from setter Angular'); + expect(getterValueControl).toHaveTextContent('I am value from getter Angular'); }); test('should run logic in the input setter and getter while re-rendering', async () => { - const component = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } }); + const { rerender } = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } }); const valueControl = screen.getByTestId('value'); const getterValueControl = screen.getByTestId('value-getter'); - expect(valueControl.textContent).toBe('I am value from setter Angular'); - expect(getterValueControl.textContent).toBe('I am value from getter Angular'); + expect(valueControl).toHaveTextContent('I am value from setter Angular'); + expect(getterValueControl).toHaveTextContent('I am value from getter Angular'); - await component.rerender({ value: 'React' }); + await rerender({ value: 'React' }); - expect(valueControl.textContent).toBe('I am value from setter React'); - expect(getterValueControl.textContent).toBe('I am value from getter React'); + expect(valueControl).toHaveTextContent('I am value from setter React'); + expect(getterValueControl).toHaveTextContent('I am value from getter React'); }); diff --git a/apps/example-app/src/app/issues/issue-106.spec.ts b/apps/example-app/src/app/issues/issue-106.spec.ts index 54dd1cb2..52bc81e1 100644 --- a/apps/example-app/src/app/issues/issue-106.spec.ts +++ b/apps/example-app/src/app/issues/issue-106.spec.ts @@ -20,14 +20,14 @@ it('https://github.com/testing-library/angular-testing-library/issues/106', asyn const toggle = screen.getByTestId('toggle'); const hiddenText = screen.queryByTestId('getme'); - expect(hiddenText).toBeNull(); + expect(hiddenText).not.toBeInTheDocument(); fireEvent.click(toggle); // fails // await waitFor(() => expect(hiddenText).not.toBeNull()); // succeeds - await waitFor(() => expect(screen.queryByTestId('getme')).not.toBeNull()); + await waitFor(() => expect(screen.queryByTestId('getme')).toBeInTheDocument()); }); it('better https://github.com/testing-library/angular-testing-library/issues/106', async () => { @@ -35,8 +35,8 @@ it('better https://github.com/testing-library/angular-testing-library/issues/106 const toggle = screen.getByTestId('toggle'); const hiddenText = screen.queryByTestId('getme'); - expect(hiddenText).toBeNull(); + expect(hiddenText).not.toBeInTheDocument(); fireEvent.click(toggle); - screen.getByTestId('getme'); + expect(screen.getByTestId('getme')).toBeInTheDocument(); }); diff --git a/apps/example-app/tsconfig.spec.json b/apps/example-app/tsconfig.spec.json index cfff29a5..afe056ed 100644 --- a/apps/example-app/tsconfig.spec.json +++ b/apps/example-app/tsconfig.spec.json @@ -3,7 +3,7 @@ "compilerOptions": { "outDir": "../../dist/out-tsc", "module": "commonjs", - "types": ["jest", "node"] + "types": ["jest", "node", "@testing-library/jest-dom"] }, "files": ["src/test-setup.ts"], "include": ["**/*.spec.ts", "**/*.d.ts"] diff --git a/package.json b/package.json index eafa5772..0c75c278 100644 --- a/package.json +++ b/package.json @@ -61,7 +61,7 @@ "@nrwl/node": "12.0.3", "@nrwl/nx-plugin": "12.0.3", "@nrwl/workspace": "12.0.3", - "@testing-library/jest-dom": "^5.11.0", + "@testing-library/jest-dom": "^5.11.10", "@types/jest": "~26.0.3", "@types/node": "14.14.37", "@typescript-eslint/eslint-plugin": "4.22.0", @@ -70,6 +70,8 @@ "eslint": "7.24.0", "eslint-config-prettier": "8.2.0", "eslint-plugin-import": "latest", + "eslint-plugin-jest-dom": "3.8.0", + "eslint-plugin-testing-library": "^4.0.1", "husky": "^4.2.5", "jest": "^26.1.0", "jest-preset-angular": "8.4.0", diff --git a/projects/jest-utils/tsconfig.spec.json b/projects/jest-utils/tsconfig.spec.json index ba3de654..091c5cf3 100644 --- a/projects/jest-utils/tsconfig.spec.json +++ b/projects/jest-utils/tsconfig.spec.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "module": "commonjs", - "types": ["node", "jest"] + "types": ["node", "jest", "@testing-library/jest-dom"] }, "files": ["test-setup.ts"], "include": ["**/*.spec.ts", "**/*.d.ts"] diff --git a/projects/testing-library/tsconfig.spec.json b/projects/testing-library/tsconfig.spec.json index ba3de654..091c5cf3 100644 --- a/projects/testing-library/tsconfig.spec.json +++ b/projects/testing-library/tsconfig.spec.json @@ -2,7 +2,7 @@ "extends": "../../tsconfig.json", "compilerOptions": { "module": "commonjs", - "types": ["node", "jest"] + "types": ["node", "jest", "@testing-library/jest-dom"] }, "files": ["test-setup.ts"], "include": ["**/*.spec.ts", "**/*.d.ts"] From 5d586b86f262ebd8cbb2e9742d51538550a2ccf7 Mon Sep 17 00:00:00 2001 From: Tim Deschryver <28659384+timdeschryver@users.noreply.github.com> Date: Fri, 16 Apr 2021 18:40:40 +0200 Subject: [PATCH 4/8] chore: remove tsquery (#202) --- package.json | 1 - projects/testing-library/ng-package.json | 7 +------ projects/testing-library/package.json | 4 +--- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 0c75c278..0490d1c6 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,6 @@ "@ngrx/store": "11.0.0", "@nrwl/angular": "12.0.3", "@nrwl/nx-cloud": "11.2.0", - "@phenomnomnominal/tsquery": "^4.1.1", "@testing-library/dom": "7.29.4", "@testing-library/user-event": "^12.0.11", "core-js": "^3.6.5", diff --git a/projects/testing-library/ng-package.json b/projects/testing-library/ng-package.json index aab92535..146b130f 100644 --- a/projects/testing-library/ng-package.json +++ b/projects/testing-library/ng-package.json @@ -5,10 +5,5 @@ "lib": { "entryFile": "index.ts" }, - "allowedNonPeerDependencies": [ - "@testing-library/dom", - "@testing-library/user-event", - "@phenomnomnominal/tsquery", - "eslint" - ] + "allowedNonPeerDependencies": ["@testing-library/dom"] } diff --git a/projects/testing-library/package.json b/projects/testing-library/package.json index 18b231d0..7fb78fff 100644 --- a/projects/testing-library/package.json +++ b/projects/testing-library/package.json @@ -30,9 +30,7 @@ }, "dependencies": { "@testing-library/dom": "7.29.4", - "@phenomnomnominal/tsquery": "^4.1.1", - "tslib": "^2.0.0", - "eslint": "7.24.0" + "tslib": "^2.0.0" }, "publishConfig": { "access": "public" From ea504fc8e080ab4428d922ff72de7c022878f251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20De=20Boey?= Date: Wed, 21 Apr 2021 16:49:31 +0200 Subject: [PATCH 5/8] chore: add tests for Node 16 (#204) --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 533b8363..0ee20df6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,12 +7,12 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - node: [12, 14] + node: [12, 14, 16] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v2 - name: use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v1 + uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - name: install From 431ac3e241bbeb6b69f8c7fb147a0cc0a3dc0015 Mon Sep 17 00:00:00 2001 From: Suguru Inatomi Date: Thu, 22 Apr 2021 19:40:05 +0900 Subject: [PATCH 6/8] docs: use the correct testing command (#205) --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 53c5985d..8c53210b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,8 +10,7 @@ Hi there, thanks for being willing to contribute! ## Testing -- Run `npm run test:lib` to test the library -- Run `npm run test:app` to test the application +- Run `npm run test` to test the library and the example application - Run `npm run build` to build the library ## Push changes From 5f72ebf8de1b0b31b8851e4e2fe06778e69dbdf9 Mon Sep 17 00:00:00 2001 From: Suguru Inatomi Date: Fri, 23 Apr 2021 02:33:12 +0900 Subject: [PATCH 7/8] feat(testing-library): add an overload for template rendering (#206) --- .../src/app/examples/08-directive.spec.ts | 12 ++-- projects/testing-library/src/lib/models.ts | 26 ++++++++ .../src/lib/testing-library.ts | 41 ++++++++++--- ...ective.spec.ts => render-template.spec.ts} | 60 ++++++++++++++----- 4 files changed, 109 insertions(+), 30 deletions(-) rename projects/testing-library/tests/{directive.spec.ts => render-template.spec.ts} (61%) diff --git a/apps/example-app/src/app/examples/08-directive.spec.ts b/apps/example-app/src/app/examples/08-directive.spec.ts index c36822a3..5df9413a 100644 --- a/apps/example-app/src/app/examples/08-directive.spec.ts +++ b/apps/example-app/src/app/examples/08-directive.spec.ts @@ -3,8 +3,8 @@ import { render, screen, fireEvent } from '@testing-library/angular'; import { SpoilerDirective } from './08-directive'; test('it is possible to test directives', async () => { - await render(SpoilerDirective, { - template: '
', + await render('
', { + declarations: [SpoilerDirective], }); const directive = screen.getByTestId('dir'); @@ -25,8 +25,8 @@ test('it is possible to test directives with props', async () => { const hidden = 'SPOILER ALERT'; const visible = 'There is nothing to see here ...'; - await render(SpoilerDirective, { - template: '
', + await render('
', { + declarations: [SpoilerDirective], componentProperties: { hidden, visible, @@ -49,8 +49,8 @@ test('it is possible to test directives with props in template', async () => { const hidden = 'SPOILER ALERT'; const visible = 'There is nothing to see here ...'; - await render(SpoilerDirective, { - template: ``, + await render(``, { + declarations: [SpoilerDirective], }); expect(screen.queryByText(visible)).not.toBeInTheDocument(); diff --git a/projects/testing-library/src/lib/models.ts b/projects/testing-library/src/lib/models.ts index 6248ef92..b1984477 100644 --- a/projects/testing-library/src/lib/models.ts +++ b/projects/testing-library/src/lib/models.ts @@ -250,6 +250,9 @@ export interface RenderComponentOptions extends RenderComponentOptions { @@ -262,6 +265,8 @@ export interface RenderDirectiveOptions` * }) + * + * @deprecated Use `render(template, { declarations: [SomeDirective] })` instead. */ template: string; /** @@ -282,6 +287,27 @@ export interface RenderDirectiveOptions; } +// eslint-disable-next-line @typescript-eslint/ban-types +export interface RenderTemplateOptions + extends RenderComponentOptions { + /** + * @description + * An Angular component to wrap the component in. + * The template will be overridden with the `template` option. + * + * @default + * `WrapperComponent`, an empty component that strips the `ng-version` attribute + * + * @example + * const component = await render(SpoilerDirective, { + * template: `
` + * wrapper: CustomWrapperComponent + * }) + */ + wrapper?: Type; + componentProperties?: Partial; +} + export interface Config extends Pick, 'excludeComponentDeclaration'> { /** * DOM Testing Library config diff --git a/projects/testing-library/src/lib/testing-library.ts b/projects/testing-library/src/lib/testing-library.ts index 13f96f06..fe3a22ca 100644 --- a/projects/testing-library/src/lib/testing-library.ts +++ b/projects/testing-library/src/lib/testing-library.ts @@ -22,7 +22,7 @@ import { waitForOptions as dtlWaitForOptions, configure as dtlConfigure, } from '@testing-library/dom'; -import { RenderComponentOptions, RenderDirectiveOptions, RenderResult } from './models'; +import { RenderComponentOptions, RenderDirectiveOptions, RenderTemplateOptions, RenderResult } from './models'; import { getConfig } from './config'; const mountedFixtures = new Set>(); @@ -32,14 +32,24 @@ export async function render( component: Type, renderOptions?: RenderComponentOptions, ): Promise>; +/** + * @deprecated Use `render(template, { declarations: [DirectiveType] })` instead. + */ export async function render( component: Type, renderOptions?: RenderDirectiveOptions, ): Promise>; +export async function render( + template: string, + renderOptions?: RenderTemplateOptions, +): Promise>; export async function render( - sut: Type, - renderOptions: RenderComponentOptions | RenderDirectiveOptions = {}, + sut: Type | string, + renderOptions: + | RenderComponentOptions + | RenderDirectiveOptions + | RenderTemplateOptions = {}, ): Promise> { const { dom: domConfig, ...globalConfig } = getConfig(); const { @@ -69,7 +79,12 @@ export async function render( }); TestBed.configureTestingModule({ - declarations: addAutoDeclarations(sut, { declarations, excludeComponentDeclaration, template, wrapper }), + declarations: addAutoDeclarations(sut, { + declarations, + excludeComponentDeclaration, + template, + wrapper, + }), imports: addAutoImports({ imports: imports.concat(defaultImports), routes, @@ -176,7 +191,7 @@ export async function render( detectChanges, navigate, rerender, - debugElement: fixture.debugElement.query(By.directive(sut)), + debugElement: typeof sut === 'string' ? fixture.debugElement : fixture.debugElement.query(By.directive(sut)), container: fixture.nativeElement, debug: (element = fixture.nativeElement, maxLength, options) => Array.isArray(element) @@ -193,14 +208,18 @@ async function createComponent(component: Type): Promise( - component: Type, + sut: Type | string, { template, wrapper }: Pick, 'template' | 'wrapper'>, ): Promise> { + if (typeof sut === 'string') { + TestBed.overrideTemplate(wrapper, sut); + return createComponent(wrapper); + } if (template) { TestBed.overrideTemplate(wrapper, template); return createComponent(wrapper); } - return createComponent(component); + return createComponent(sut); } function setComponentProperties( @@ -248,7 +267,7 @@ function getChangesObj(oldProps: Partial | null, newProps: Par } function addAutoDeclarations( - component: Type, + sut: Type | string, { declarations, excludeComponentDeclaration, @@ -256,9 +275,13 @@ function addAutoDeclarations( wrapper, }: Pick, 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'>, ) { + if (typeof sut === 'string') { + return [...declarations, wrapper]; + } + const wrappers = () => (template ? [wrapper] : []); - const components = () => (excludeComponentDeclaration ? [] : [component]); + const components = () => (excludeComponentDeclaration ? [] : [sut]); return [...declarations, ...wrappers(), ...components()]; } diff --git a/projects/testing-library/tests/directive.spec.ts b/projects/testing-library/tests/render-template.spec.ts similarity index 61% rename from projects/testing-library/tests/directive.spec.ts rename to projects/testing-library/tests/render-template.spec.ts index 08db0eb3..1bc4e30d 100644 --- a/projects/testing-library/tests/directive.spec.ts +++ b/projects/testing-library/tests/render-template.spec.ts @@ -1,8 +1,11 @@ +/* eslint-disable testing-library/no-container */ +/* eslint-disable testing-library/render-result-naming-convention */ import { Directive, HostListener, ElementRef, Input, Output, EventEmitter, Component } from '@angular/core'; import { render, fireEvent } from '../src/public_api'; @Directive({ + // eslint-disable-next-line @angular-eslint/directive-selector selector: '[onOff]', }) export class OnOffDirective { @@ -21,6 +24,7 @@ export class OnOffDirective { } @Directive({ + // eslint-disable-next-line @angular-eslint/directive-selector selector: '[update]', }) export class UpdateInputDirective { @@ -32,27 +36,53 @@ export class UpdateInputDirective { constructor(private el: ElementRef) {} } +@Component({ + // eslint-disable-next-line @angular-eslint/component-selector + selector: 'greeting', + template: 'Hello {{ name }}!', +}) +export class GreetingComponent { + @Input() name = 'World'; +} + test('the directive renders', async () => { - const component = await render(OnOffDirective, { - template: '
', + const component = await render('
', { + declarations: [OnOffDirective], }); expect(component.container.querySelector('[onoff]')).toBeInTheDocument(); }); -test('uses the default props', async () => { +test('the component renders', async () => { + const component = await render('', { + declarations: [GreetingComponent], + }); + + expect(component.container.querySelector('greeting')).toBeInTheDocument(); + expect(component.getByText('Hello Angular!')); +}); + +test('the directive renders (compatibility with the deprecated signature)', async () => { const component = await render(OnOffDirective, { template: '
', }); + expect(component.container.querySelector('[onoff]')).toBeInTheDocument(); +}); + +test.only('uses the default props', async () => { + const component = await render('
', { + declarations: [OnOffDirective], + }); + fireEvent.click(component.getByText('init')); fireEvent.click(component.getByText('on')); fireEvent.click(component.getByText('off')); }); test('overrides input properties', async () => { - const component = await render(OnOffDirective, { - template: '
', + const component = await render('
', { + declarations: [OnOffDirective], }); fireEvent.click(component.getByText('init')); @@ -62,8 +92,8 @@ test('overrides input properties', async () => { test('overrides input properties via a wrapper', async () => { // `bar` will be set as a property on the wrapper component, the property will be used to pass to the directive - const component = await render(OnOffDirective, { - template: '
', + const component = await render('
', { + declarations: [OnOffDirective], componentProperties: { bar: 'hello', }, @@ -77,8 +107,8 @@ test('overrides input properties via a wrapper', async () => { test('overrides output properties', async () => { const clicked = jest.fn(); - const component = await render(OnOffDirective, { - template: '
', + const component = await render('
', { + declarations: [OnOffDirective], componentProperties: { clicked, }, @@ -93,8 +123,8 @@ test('overrides output properties', async () => { describe('removeAngularAttributes', () => { test('should remove angular attributes', async () => { - await render(OnOffDirective, { - template: '
', + await render('
', { + declarations: [OnOffDirective], removeAngularAttributes: true, }); @@ -103,8 +133,8 @@ describe('removeAngularAttributes', () => { }); test('is disabled by default', async () => { - await render(OnOffDirective, { - template: '
', + await render('
', { + declarations: [OnOffDirective], }); expect(document.querySelector('[ng-version]')).not.toBeNull(); @@ -113,8 +143,8 @@ describe('removeAngularAttributes', () => { }); test('updates properties and invokes change detection', async () => { - const component = await render(UpdateInputDirective, { - template: '
', + const component = await render('
', { + declarations: [UpdateInputDirective], componentProperties: { value: 'value1', }, From ed7fe768f76531341914ac918c37efede2b31392 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Thu, 22 Apr 2021 19:34:37 +0200 Subject: [PATCH 8/8] docs: add lacolaco as a contributor (#207) --- .all-contributorsrc | 10 ++++++++++ README.md | 1 + 2 files changed, 11 insertions(+) diff --git a/.all-contributorsrc b/.all-contributorsrc index 6f2dd580..78b7aad7 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -197,6 +197,16 @@ "contributions": [ "code" ] + }, + { + "login": "lacolaco", + "name": "Suguru Inatomi", + "avatar_url": "https://avatars.githubusercontent.com/u/1529180?v=4", + "profile": "https://lacolaco.net", + "contributions": [ + "code", + "ideas" + ] } ], "contributorsPerLine": 7, diff --git a/README.md b/README.md index 8033f7a6..b542de69 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,7 @@ Thanks goes to these people ([emoji key][emojis]):
Janek

💻 ⚠️
Gleb Irovich

💻 ⚠️
Arjen

💻 +
Suguru Inatomi

💻 🤔