diff --git a/.all-contributorsrc b/.all-contributorsrc
index f6cf697b..78b7aad7 100644
--- a/.all-contributorsrc
+++ b/.all-contributorsrc
@@ -188,6 +188,25 @@
"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"
+ ]
+ },
+ {
+ "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/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 00000000..b740f815
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,120 @@
+{
+ "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"],
+ "plugins": ["eslint-plugin-import", "@angular-eslint/eslint-plugin", "@typescript-eslint"],
+ "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": ["/"]
+ }
+ ]
+ }
+ },
+ {
+ "files": ["*.spec.ts"],
+ "extends": ["plugin:testing-library/angular", "plugin:jest-dom/recommended"],
+ "rules": {
+ "testing-library/prefer-explicit-assert": "error"
+ }
+ },
+ {
+ "files": ["*.html"],
+ "rules": {}
+ }
+ ]
+}
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
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/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
diff --git a/README.md b/README.md
index 3ed51be4..b542de69 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
@@ -208,6 +208,8 @@ Thanks goes to these people ([emoji key][emojis]):
 Bo Vandersteene 💻 |
 Janek 💻 ⚠️ |
 Gleb Irovich 💻 ⚠️ |
+  Arjen 💻 |
+  Suguru Inatomi 💻 🤔 |
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/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/app/examples/16-input-getter-setter.spec.ts
deleted file mode 100644
index 10e0e276..00000000
--- a/apps/example-app/app/examples/16-input-getter-setter.spec.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { render, screen } from '@testing-library/angular';
-import { InputGetterSetter } from './16-input-getter-setter';
-
-test('should run logic in the input setter and getter', async () => {
- 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');
-});
-
-test('should run logic in the input setter and getter while re-rendering', async () => {
- const component = 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');
-
- await component.rerender({ value: 'React' });
-
- expect(valueControl.textContent).toBe('I am value from setter React');
- expect(getterValueControl.textContent).toBe('I am value from getter React');
-});
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 80%
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
index 460cae16..73e429bb 100644
--- a/apps/example-app/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/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 83%
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
index bbaf9c37..8f3a242d 100644
--- a/apps/example-app/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/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 83%
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..663d63e0 100644
--- a/apps/example-app/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);
@@ -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,
},
@@ -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/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 89%
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
index 861eae76..79811245 100644
--- a/apps/example-app/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/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 84%
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
index d8a80d87..b8a289bb 100644
--- 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
@@ -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/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 85%
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..5df9413a 100644
--- a/apps/example-app/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/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 97%
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
index f5849abc..bcb41875 100644
--- a/apps/example-app/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/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/src/app/examples/16-input-getter-setter.spec.ts b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts
new file mode 100644
index 00000000..28d736c6
--- /dev/null
+++ b/apps/example-app/src/app/examples/16-input-getter-setter.spec.ts
@@ -0,0 +1,25 @@
+import { render, screen } from '@testing-library/angular';
+import { InputGetterSetter } from './16-input-getter-setter';
+
+test('should run logic in the input setter and getter', async () => {
+ await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
+ const valueControl = screen.getByTestId('value');
+ const getterValueControl = screen.getByTestId('value-getter');
+
+ 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 { rerender } = await render(InputGetterSetter, { componentProperties: { value: 'Angular' } });
+ const valueControl = screen.getByTestId('value');
+ const getterValueControl = screen.getByTestId('value-getter');
+
+ expect(valueControl).toHaveTextContent('I am value from setter Angular');
+ expect(getterValueControl).toHaveTextContent('I am value from getter Angular');
+
+ await rerender({ value: '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/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 82%
rename from apps/example-app/app/issues/issue-106.spec.ts
rename to apps/example-app/src/app/issues/issue-106.spec.ts
index 54dd1cb2..52bc81e1 100644
--- a/apps/example-app/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/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..afe056ed 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", "@testing-library/jest-dom"]
},
- "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..0490d1c6 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,69 @@
"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",
- "@phenomnomnominal/tsquery": "^4.1.1",
+ "@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",
"@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",
- "@testing-library/jest-dom": "^5.11.0",
+ "@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.10",
"@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",
+ "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.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/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/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..146b130f 100644
--- a/projects/testing-library/ng-package.json
+++ b/projects/testing-library/ng-package.json
@@ -5,10 +5,5 @@
"lib": {
"entryFile": "index.ts"
},
- "whitelistedNonPeerDependencies": [
- "@testing-library/dom",
- "@testing-library/user-event",
- "@phenomnomnominal/tsquery",
- "tslint"
- ]
+ "allowedNonPeerDependencies": ["@testing-library/dom"]
}
diff --git a/projects/testing-library/package.json b/projects/testing-library/package.json
index 17ad15d4..7fb78fff 100644
--- a/projects/testing-library/package.json
+++ b/projects/testing-library/package.json
@@ -30,14 +30,9 @@
},
"dependencies": {
"@testing-library/dom": "7.29.4",
- "@phenomnomnominal/tsquery": "^4.1.1",
- "tslib": "^2.0.0",
- "tslint": "^5.16.0"
+ "tslib": "^2.0.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..b1984477 100644
--- a/projects/testing-library/src/lib/models.ts
+++ b/projects/testing-library/src/lib/models.ts
@@ -250,6 +250,10 @@ export interface RenderComponentOptions
extends RenderComponentOptions {
/**
@@ -261,6 +265,8 @@ export interface RenderDirectiveOptions`
* })
+ *
+ * @deprecated Use `render(template, { declarations: [SomeDirective] })` instead.
*/
template: string;
/**
@@ -281,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 62c2c0c0..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,13 +275,13 @@ function addAutoDeclarations(
wrapper,
}: Pick, 'declarations' | 'excludeComponentDeclaration' | 'template' | 'wrapper'>,
) {
- const wrappers = () => {
- return template ? [wrapper] : [];
- };
+ if (typeof sut === 'string') {
+ return [...declarations, wrapper];
+ }
- const components = () => {
- return excludeComponentDeclaration ? [] : [component];
- };
+ const wrappers = () => (template ? [wrapper] : []);
+
+ const components = () => (excludeComponentDeclaration ? [] : [sut]);
return [...declarations, ...wrappers(), ...components()];
}
@@ -274,9 +293,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 +358,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/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/directive.spec.ts b/projects/testing-library/tests/render-template.spec.ts
similarity index 57%
rename from projects/testing-library/tests/directive.spec.ts
rename to projects/testing-library/tests/render-template.spec.ts
index 2d7f42a8..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();
@@ -112,16 +142,15 @@ 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'
- }
+ 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/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/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"]
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
- }
-}