Compare commits
463 Commits
Author | SHA1 | Date | |
---|---|---|---|
2ab8e88924 | |||
a91dd2e42a | |||
6eca80b4aa | |||
cea46786a2 | |||
9c5fc1693a | |||
42f5770b7b | |||
01db37435f | |||
07a003352d | |||
ac009d293d | |||
eb8f8c93c8 | |||
18a5117d1e | |||
ff72da60d3 | |||
d4a723a464 | |||
9c2f0b8ac4 | |||
dc081fb0bf | |||
f882099f9d | |||
24498eb416 | |||
4c2cdc682b | |||
1cb66bb39f | |||
7ff5ef27c7 | |||
03d8e317c4 | |||
1de4fe5dbf | |||
879ff08f0e | |||
a15d7ac1da | |||
4a6abbdfc6 | |||
78eb5f6777 | |||
0cdb5231c2 | |||
5af845d049 | |||
a5c28497b5 | |||
801ad62ae3 | |||
7d4d2e29b0 | |||
c33f719ddc | |||
69fc6b4f75 | |||
5ec4c02a43 | |||
f0489ee72a | |||
d0f625305b | |||
c15a58fa2b | |||
3d67d1970b | |||
ce08a3c8c7 | |||
bc29712271 | |||
cc48b5c066 | |||
deba0e21f1 | |||
0469d9240a | |||
cdda60a430 | |||
7570356bfa | |||
c4a97d822e | |||
fc4dfc5eb1 | |||
25d95dae6d | |||
1c4fcce2a1 | |||
6e73faaed7 | |||
41c9910613 | |||
aaddef213d | |||
02f3aee1db | |||
c27ba96093 | |||
c5a474cb54 | |||
d5264f5645 | |||
0cd4b87021 | |||
b1e7775a8a | |||
87f5feff11 | |||
c3ddc3d6b1 | |||
cec39a7d16 | |||
c6c8e15813 | |||
752fd14fe5 | |||
776067cd43 | |||
e87a46be21 | |||
89a7ff3ada | |||
3d6e50dc02 | |||
264950bbf2 | |||
84c5be0b5b | |||
eda8f2f8b9 | |||
cc52945d00 | |||
07f184a69d | |||
a123ef58b1 | |||
024126dde4 | |||
4275c34818 | |||
c4e6f585c5 | |||
7467fd36b9 | |||
aca01985fd | |||
eb5e14e6e0 | |||
b8af10902f | |||
f411c9e5b9 | |||
7f455e6eec | |||
e36caafa52 | |||
5e89d98876 | |||
200dbd4860 | |||
c90952884a | |||
7c2d8fc672 | |||
a50a688aaf | |||
6ec7297e43 | |||
f264cd1cb8 | |||
fc17bddcde | |||
0765626761 | |||
f146b34042 | |||
f899d6ea44 | |||
c18d7a1469 | |||
2c7ff82f31 | |||
3f8f3a2daa | |||
f5eeb1a714 | |||
2af3d9c040 | |||
4664acce50 | |||
3797861dfe | |||
d6d3984524 | |||
c17f5c10cc | |||
9cb318f5a2 | |||
b026dd8b52 | |||
0ebc316311 | |||
dc412c5f02 | |||
e80278cf02 | |||
307699ac89 | |||
4df0b7e9de | |||
371831f9cb | |||
8e305e7099 | |||
481df830ad | |||
14b4718cc2 | |||
7b6e73cb98 | |||
f2ca4634e2 | |||
d30cf2f9d6 | |||
e9cb6fbe87 | |||
99960a98d2 | |||
9ac3383d01 | |||
06ac75724f | |||
a1d691ecc8 | |||
6e329721be | |||
739bf5c325 | |||
ee340b7c6c | |||
17ddab98fb | |||
4f65f473e4 | |||
527a04d21e | |||
f2ee468d76 | |||
0320096538 | |||
7abb48adfe | |||
b40d3c0817 | |||
0e5617152a | |||
dba402344f | |||
13d176302b | |||
e3b801053a | |||
6626739798 | |||
396033da80 | |||
02ee9d2938 | |||
a4c7f183d7 | |||
d690eec88f | |||
10e4dfae27 | |||
f8d948b46b | |||
9cf78d5701 | |||
45471dbbd6 | |||
387e8386d1 | |||
eec6e4be7a | |||
b711f25892 | |||
788f0453f7 | |||
45b1775a53 | |||
53e4ff72d2 | |||
7813a7d129 | |||
c0ced6dc2d | |||
8157ee87b0 | |||
ab051aba27 | |||
5a61ef0c49 | |||
c451dbda9f | |||
0d38288078 | |||
2e9b953e9d | |||
a94383f168 | |||
75c40ddd61 | |||
86a75a0670 | |||
c776825fdd | |||
1cc9383d91 | |||
8ed1e53e99 | |||
7833c88ac4 | |||
12f177399f | |||
5be32366be | |||
5b7d2eeabf | |||
6cd10a1b10 | |||
822652aa0d | |||
cf47ace493 | |||
0595f11950 | |||
35df312ea4 | |||
489eb8519e | |||
b76a2dc2cb | |||
f2f5f7fc6e | |||
8ee23ba67b | |||
ecb422b360 | |||
60389d5441 | |||
b186db70db | |||
324b6f1b1a | |||
cdba1d37a4 | |||
dc42c97ee4 | |||
bc00e8d312 | |||
720b71d01f | |||
1132b07c53 | |||
9230194794 | |||
d724896f04 | |||
29866dfb91 | |||
a249622159 | |||
9f2393fb80 | |||
d5f8040d0a | |||
e0b8ea136b | |||
879b2273c1 | |||
f24972b1b1 | |||
d2886b3bb4 | |||
f296fea112 | |||
2605fc46e7 | |||
9d54b3a14b | |||
d09a6283ed | |||
1c168c3a44 | |||
0f74479c47 | |||
790bb949f6 | |||
2adcad6dd2 | |||
242ef1ace1 | |||
842b6a1247 | |||
98335529eb | |||
ca7ee794bf | |||
f9f2ba6faf | |||
aea1d211d4 | |||
57a518a36d | |||
29b83189b0 | |||
1d3df7885d | |||
fd06ffa2af | |||
36a1622dd1 | |||
7a91b23cb5 | |||
4b90b6a226 | |||
b13daa4cdf | |||
0c6f026828 | |||
a2520bd267 | |||
b928a209a4 | |||
89e16ed6a5 | |||
1a1f99af37 | |||
df2cd37ed2 | |||
12a71bc6bc | |||
7d270c235a | |||
b0b7248504 | |||
78460c1848 | |||
75b119eafc | |||
64b0ae93f7 | |||
7c0b25f5a6 | |||
07b5df3a19 | |||
e7023726f4 | |||
a9ccd9254c | |||
335f3271d2 | |||
7f93f7ef47 | |||
cf46a87fcd | |||
ad6680f602 | |||
5e287f67af | |||
ecfe6e0609 | |||
df9790dd11 | |||
67cfc4c9bc | |||
a68e623c80 | |||
9e3915ba48 | |||
ba2de61748 | |||
a9a4edebe2 | |||
64f2ffa166 | |||
13020b9cc2 | |||
96b96fba0f | |||
2cbe53a9ba | |||
48755114e5 | |||
a5d5f67be7 | |||
dfb58c44a2 | |||
69948ce919 | |||
3190ccf3b2 | |||
a8ea8173aa | |||
e13a49d1f0 | |||
2f0b8f675a | |||
c2aed033ba | |||
0f8a780b0d | |||
c5bc2e77c8 | |||
079310dc7c | |||
0d2cdf6165 | |||
436dde271f | |||
96891a076f | |||
9ce0067bdf | |||
345940bbc1 | |||
c49507b289 | |||
c730142508 | |||
27aa00b15f | |||
36a00a255b | |||
0e3249c89b | |||
920019ab70 | |||
82c8b44db7 | |||
bb3a307d5a | |||
dcb0ddaf5e | |||
4c1edd52c5 | |||
d512e27979 | |||
0619d82e0b | |||
a4038d5b94 | |||
e3d5e1fab7 | |||
035036308a | |||
0d29259d9b | |||
26b0f3dc96 | |||
5c9306b0fe | |||
3befb0e4b9 | |||
97bb88f10b | |||
6c7467a58b | |||
c579a85c12 | |||
400fdd08fd | |||
c1fe6c9c81 | |||
c58a0bea91 | |||
88a934b93c | |||
cde5cced69 | |||
472bedd3ea | |||
d8a06d03bd | |||
32020f9fb3 | |||
d574b14934 | |||
00c5d89e7d | |||
d2c8aefe64 | |||
ba796bbdd3 | |||
a0bb2ba7b7 | |||
f9fa3b5b6c | |||
f89d438116 | |||
1abe791d46 | |||
1502ae78b6 | |||
bad6e719de | |||
8c7129f3d2 | |||
dbff6f71e1 | |||
fcd934ccf6 | |||
45a8f340d9 | |||
5856513405 | |||
01fa3ee5c3 | |||
b8d69ffdf3 | |||
7ef60ec2a9 | |||
83f905c0e1 | |||
72ba3a3918 | |||
df10597da4 | |||
5db2e794a9 | |||
486aa06747 | |||
01ce1b32df | |||
c78b0b2c51 | |||
9ade1c3ea3 | |||
315a4cfcd4 | |||
11c04027ab | |||
eabe3b4c39 | |||
d471454675 | |||
bf57776b59 | |||
a32579ae5b | |||
780601d27a | |||
c909e731d7 | |||
9b8eb42354 | |||
0757174e8e | |||
3a43cdefe8 | |||
38c48beddd | |||
ad5749fb04 | |||
f6a838e9ee | |||
a6d1f4aaf1 | |||
eca8d11ee2 | |||
a195b7dbe4 | |||
083d7ec902 | |||
9d2d0cae6d | |||
c2f4a9bf71 | |||
231095fe8a | |||
28a532483a | |||
83853a215d | |||
8248307a99 | |||
67bd88b19a | |||
9f698b4de0 | |||
742f3d6787 | |||
323651bd38 | |||
9d397eb5a1 | |||
6114cd2bd4 | |||
d494f7bd5e | |||
ec6a7ab721 | |||
ad6d2b4619 | |||
c093390010 | |||
acd69f2be2 | |||
5d2f341653 | |||
420d1c35f5 | |||
08647267bb | |||
215d50d2f6 | |||
bf2cb6fa48 | |||
e97a2d4123 | |||
585e3f6adc | |||
7f77ce1a48 | |||
a1616ce181 | |||
1c22dff714 | |||
8d1d6e8f70 | |||
e7f4aba5a3 | |||
fdbe9f5d9f | |||
8bead6bfdd | |||
52dda73dbb | |||
31b3888a2f | |||
6f938470c2 | |||
776c4afc03 | |||
536dd647c6 | |||
51d581ab27 | |||
75294e7dad | |||
04bada7a9d | |||
2349143477 | |||
e9bff5fe9f | |||
411cb0cb92 | |||
53e1fb3554 | |||
2cb3b66640 | |||
5af3144330 | |||
e4043cbb3a | |||
fff424a35f | |||
b5d1c8b05a | |||
d713e33cc4 | |||
3d327d25f0 | |||
077283bf0f | |||
9ec25ea036 | |||
878cfe669c | |||
5f0be3cb2e | |||
9e28e14c08 | |||
954d002884 | |||
0a48591e53 | |||
d37c723951 | |||
9078ca557e | |||
2be1ef6ba0 | |||
47c02efccb | |||
d7ecfb432a | |||
59abf4a33f | |||
d6e715e726 | |||
fcfcd1037c | |||
f3ccd29e7b | |||
5c0bdae809 | |||
838902556b | |||
c6872c02d8 | |||
819982ea20 | |||
f9daa136c3 | |||
6a0d2ed6c8 | |||
2c1f35e794 | |||
5345e8da45 | |||
e35269dd87 | |||
60a03b7ef7 | |||
305b5a3887 | |||
bc549361d3 | |||
084b627f2e | |||
6755d00601 | |||
cba1da3e44 | |||
7be8bb1489 | |||
c7c0c1f626 | |||
3aa4629f92 | |||
2d86dbb090 | |||
91767ff0f9 | |||
078b004ecc | |||
930d204d83 | |||
8d82cdfc77 | |||
cb6996b5c3 | |||
a4f7740332 | |||
ba0faa2f77 | |||
3e68029522 | |||
b4e26b5828 | |||
15cf7fcac2 | |||
24ff0eb13b | |||
cf86f72eb7 | |||
61486f14f1 | |||
d16a7f3ecc | |||
82761ec50e | |||
235bfa77a9 | |||
299ae1bb1c | |||
80f7522dab | |||
028921e369 | |||
a4e11bb524 | |||
a4131752d2 | |||
060dcfbba1 | |||
4be7008f80 | |||
4a0d05515e | |||
83ab99c746 | |||
270da1f69f | |||
6b0e46e36c | |||
3642707145 | |||
0ea76edfd8 | |||
d493a83b2b | |||
f1721d5cef | |||
5b3fd6aa82 | |||
6f829180f7 | |||
27b95ba64a | |||
ef405b1e90 | |||
441073bad5 |
@ -32,8 +32,8 @@ var_4_win: &cache_key_win_fallback v7-angular-win-node-12-{{ checksum ".bazelver
|
|||||||
|
|
||||||
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
# Cache key for the `components-repo-unit-tests` job. **Note** when updating the SHA in the
|
||||||
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
# cache keys also update the SHA for the "COMPONENTS_REPO_COMMIT" environment variable.
|
||||||
var_5: &components_repo_unit_tests_cache_key v9-angular-components-09e68db8ed5b1253f2fe38ff954ef0df019fc25a
|
var_5: &components_repo_unit_tests_cache_key v7-angular-components-f428c00465dfcf8a020237f22532480eedbd2cb6
|
||||||
var_6: &components_repo_unit_tests_cache_key_fallback v9-angular-components-
|
var_6: &components_repo_unit_tests_cache_key_fallback v7-angular-components-
|
||||||
|
|
||||||
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
# Workspace initially persisted by the `setup` job, and then enhanced by `build-npm-packages` and
|
||||||
# `build-ivy-npm-packages`.
|
# `build-ivy-npm-packages`.
|
||||||
@ -656,18 +656,6 @@ jobs:
|
|||||||
- run: yarn tsc -p packages
|
- run: yarn tsc -p packages
|
||||||
- run: yarn tsc -p modules
|
- run: yarn tsc -p modules
|
||||||
- run: yarn bazel build //packages/zone.js:npm_package
|
- run: yarn bazel build //packages/zone.js:npm_package
|
||||||
# Build test fixtures for a test that rely on Bazel-generated fixtures. Note that disabling
|
|
||||||
# specific tests which are reliant on such generated fixtures is not an option as SystemJS
|
|
||||||
# in the Saucelabs legacy job always fetches referenced files, even if the imports would be
|
|
||||||
# guarded by an check to skip in the Saucelabs legacy job. We should be good running such
|
|
||||||
# test in all supported browsers on Saucelabs anyway until this job can be removed.
|
|
||||||
- run:
|
|
||||||
name: Preparing Bazel-generated fixtures required in legacy tests
|
|
||||||
command: |
|
|
||||||
yarn bazel build //packages/core/test:downleveled_es5_fixture
|
|
||||||
# Needed for the ES5 downlevel reflector test in `packages/core/test/reflection`.
|
|
||||||
cp dist/bin/packages/core/test/reflection/es5_downleveled_inheritance_fixture.js \
|
|
||||||
dist/all/@angular/core/test/reflection/es5_downleveled_inheritance_fixture.js
|
|
||||||
- run:
|
- run:
|
||||||
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
|
# Waiting on ready ensures that we don't run tests too early without Saucelabs not being ready.
|
||||||
name: Waiting for Saucelabs tunnel to connect
|
name: Waiting for Saucelabs tunnel to connect
|
||||||
@ -743,8 +731,8 @@ jobs:
|
|||||||
- run: yarn --cwd packages/zone.js promisetest
|
- run: yarn --cwd packages/zone.js promisetest
|
||||||
- run: yarn --cwd packages/zone.js promisefinallytest
|
- run: yarn --cwd packages/zone.js promisefinallytest
|
||||||
- run: yarn bazel build //packages/zone.js:npm_package &&
|
- run: yarn bazel build //packages/zone.js:npm_package &&
|
||||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-mix.umd.js ./packages/zone.js/test/extra/ &&
|
cp dist/bin/packages/zone.js/npm_package/dist/zone-mix.js ./packages/zone.js/test/extra/ &&
|
||||||
cp dist/bin/packages/zone.js/npm_package/bundles/zone-patch-electron.umd.js ./packages/zone.js/test/extra/ &&
|
cp dist/bin/packages/zone.js/npm_package/dist/zone-patch-electron.js ./packages/zone.js/test/extra/ &&
|
||||||
yarn --cwd packages/zone.js electrontest
|
yarn --cwd packages/zone.js electrontest
|
||||||
- run: yarn --cwd packages/zone.js jesttest
|
- run: yarn --cwd packages/zone.js jesttest
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ setPublicVar COMPONENTS_REPO_TMP_DIR "/tmp/angular-components-repo"
|
|||||||
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
|
setPublicVar COMPONENTS_REPO_URL "https://github.com/angular/components.git"
|
||||||
setPublicVar COMPONENTS_REPO_BRANCH "master"
|
setPublicVar COMPONENTS_REPO_BRANCH "master"
|
||||||
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
|
# **NOTE**: When updating the commit SHA, also update the cache key in the CircleCI `config.yml`.
|
||||||
setPublicVar COMPONENTS_REPO_COMMIT "09e68db8ed5b1253f2fe38ff954ef0df019fc25a"
|
setPublicVar COMPONENTS_REPO_COMMIT "f428c00465dfcf8a020237f22532480eedbd2cb6"
|
||||||
|
|
||||||
|
|
||||||
####################################################################################################
|
####################################################################################################
|
||||||
|
29
.github/angular-robot.yml
vendored
29
.github/angular-robot.yml
vendored
@ -68,20 +68,20 @@ merge:
|
|||||||
- "packages/**/integrationtest/**"
|
- "packages/**/integrationtest/**"
|
||||||
- "packages/**/test/**"
|
- "packages/**/test/**"
|
||||||
- "packages/zone.js/*"
|
- "packages/zone.js/*"
|
||||||
- "packages/zone.js/dist/**"
|
|
||||||
- "packages/zone.js/doc/**"
|
- "packages/zone.js/doc/**"
|
||||||
- "packages/zone.js/example/**"
|
- "packages/zone.js/example/**"
|
||||||
- "packages/zone.js/scripts/**"
|
- "packages/zone.js/scripts/**"
|
||||||
|
|
||||||
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
# comment that will be added to a PR when there is a conflict, leave empty or set to false to disable
|
||||||
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.\nPlease help to unblock it by resolving these conflicts. Thanks!"
|
mergeConflictComment: "Hi @{{PRAuthor}}! This PR has merge conflicts due to recent upstream merges.
|
||||||
|
\nPlease help to unblock it by resolving these conflicts. Thanks!"
|
||||||
|
|
||||||
# label to monitor
|
# label to monitor
|
||||||
mergeLabel: "action: merge"
|
mergeLabel: "PR action: merge"
|
||||||
|
|
||||||
# adding any of these labels will also add the merge label
|
# adding any of these labels will also add the merge label
|
||||||
mergeLinkedLabels:
|
mergeLinkedLabels:
|
||||||
- "action: merge-assistance"
|
- "PR action: merge-assistance"
|
||||||
|
|
||||||
# list of checks that will determine if the merge label can be added
|
# list of checks that will determine if the merge label can be added
|
||||||
checks:
|
checks:
|
||||||
@ -94,17 +94,17 @@ merge:
|
|||||||
|
|
||||||
# whether the PR shouldn't have a conflict with the base branch
|
# whether the PR shouldn't have a conflict with the base branch
|
||||||
noConflict: true
|
noConflict: true
|
||||||
# list of labels that a PR needs to have, checked with a regexp (e.g. "target:" will work for the label "target: master")
|
# list of labels that a PR needs to have, checked with a regexp (e.g. "PR target:" will work for the label "PR target: master")
|
||||||
requiredLabels:
|
requiredLabels:
|
||||||
- "target: *"
|
- "PR target: *"
|
||||||
- "cla: yes"
|
- "cla: yes"
|
||||||
|
|
||||||
# list of labels that a PR shouldn't have, checked after the required labels with a regexp
|
# list of labels that a PR shouldn't have, checked after the required labels with a regexp
|
||||||
forbiddenLabels:
|
forbiddenLabels:
|
||||||
- "target: TBD"
|
- "PR target: TBD"
|
||||||
- "action: cleanup"
|
- "PR action: cleanup"
|
||||||
- "action: review"
|
- "PR action: review"
|
||||||
- "state: blocked"
|
- "PR state: blocked"
|
||||||
- "cla: no"
|
- "cla: no"
|
||||||
|
|
||||||
# list of PR statuses that need to be successful
|
# list of PR statuses that need to be successful
|
||||||
@ -121,7 +121,12 @@ merge:
|
|||||||
# the comment that will be added when the merge label is added despite failing checks, leave empty or set to false to disable
|
# the comment that will be added when the merge label is added despite failing checks, leave empty or set to false to disable
|
||||||
# {{MERGE_LABEL}} will be replaced by the value of the mergeLabel option
|
# {{MERGE_LABEL}} will be replaced by the value of the mergeLabel option
|
||||||
# {{PLACEHOLDER}} will be replaced by the list of failing checks
|
# {{PLACEHOLDER}} will be replaced by the list of failing checks
|
||||||
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:\n{{PLACEHOLDER}}\n\n**If you want your PR to be merged, it has to pass all the CI checks.**\n\nIf you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
|
mergeRemovedComment: "I see that you just added the `{{MERGE_LABEL}}` label, but the following checks are still failing:
|
||||||
|
\n{{PLACEHOLDER}}
|
||||||
|
\n
|
||||||
|
\n**If you want your PR to be merged, it has to pass all the CI checks.**
|
||||||
|
\n
|
||||||
|
\nIf you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help."
|
||||||
|
|
||||||
# options for the triage plugin
|
# options for the triage plugin
|
||||||
triage:
|
triage:
|
||||||
@ -181,4 +186,4 @@ rerunCircleCI:
|
|||||||
# set to true to disable
|
# set to true to disable
|
||||||
disabled: false
|
disabled: false
|
||||||
# the label which when added triggers a rerun of the default CircleCI workflow
|
# the label which when added triggers a rerun of the default CircleCI workflow
|
||||||
triggerRerunLabel: "action: rerun CI at HEAD"
|
triggerRerunLabel: "PR action: rerun CI at HEAD"
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -40,9 +40,6 @@ yarn-error.log
|
|||||||
# User specific bazel settings
|
# User specific bazel settings
|
||||||
.bazelrc.user
|
.bazelrc.user
|
||||||
|
|
||||||
# User specific ng-dev settings
|
|
||||||
.ng-dev.user*
|
|
||||||
|
|
||||||
.notes.md
|
.notes.md
|
||||||
baseline.json
|
baseline.json
|
||||||
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import {CaretakerConfig} from '../dev-infra/caretaker/config';
|
|
||||||
|
|
||||||
/** The configuration for `ng-dev caretaker` commands. */
|
|
||||||
export const caretaker: CaretakerConfig = {
|
|
||||||
githubQueries: [
|
|
||||||
{
|
|
||||||
name: 'Merge Queue',
|
|
||||||
query: `is:pr is:open status:success label:"action: merge"`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Merge Assistance Queue',
|
|
||||||
query: `is:pr is:open status:success label:"action: merge-assistance"`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Primary Triage Queue',
|
|
||||||
query: `is:open is:issue no:milestone`,
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
@ -7,6 +7,18 @@ export const commitMessage: CommitMessageConfig = {
|
|||||||
maxLineLength: 120,
|
maxLineLength: 120,
|
||||||
minBodyLength: 20,
|
minBodyLength: 20,
|
||||||
minBodyLengthTypeExcludes: ['docs'],
|
minBodyLengthTypeExcludes: ['docs'],
|
||||||
|
types: [
|
||||||
|
'build',
|
||||||
|
'ci',
|
||||||
|
'docs',
|
||||||
|
'feat',
|
||||||
|
'fix',
|
||||||
|
'perf',
|
||||||
|
'refactor',
|
||||||
|
'release',
|
||||||
|
'style',
|
||||||
|
'test',
|
||||||
|
],
|
||||||
scopes: [
|
scopes: [
|
||||||
'animations',
|
'animations',
|
||||||
'bazel',
|
'bazel',
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {caretaker} from './caretaker';
|
|
||||||
import {commitMessage} from './commit-message';
|
import {commitMessage} from './commit-message';
|
||||||
import {format} from './format';
|
import {format} from './format';
|
||||||
import {github} from './github';
|
import {github} from './github';
|
||||||
@ -9,5 +8,4 @@ module.exports = {
|
|||||||
format,
|
format,
|
||||||
github,
|
github,
|
||||||
merge,
|
merge,
|
||||||
caretaker,
|
|
||||||
};
|
};
|
||||||
|
@ -1,25 +1,38 @@
|
|||||||
import {DevInfraMergeConfig} from '../dev-infra/pr/merge/config';
|
import {MergeConfig} from '../dev-infra/pr/merge/config';
|
||||||
import {getDefaultTargetLabelConfiguration} from '../dev-infra/pr/merge/defaults';
|
|
||||||
import {github} from './github';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
|
* Configuration for the merge tool in `ng-dev`. This sets up the labels which
|
||||||
* are respected by the merge script (e.g. the target labels).
|
* are respected by the merge script (e.g. the target labels).
|
||||||
*/
|
*/
|
||||||
export const merge: DevInfraMergeConfig['merge'] = async api => {
|
export const merge = (): MergeConfig => {
|
||||||
|
// TODO: resume dynamically determining patch branch
|
||||||
|
const patch = '10.0.x';
|
||||||
return {
|
return {
|
||||||
githubApiMerge: false,
|
githubApiMerge: false,
|
||||||
claSignedLabel: 'cla: yes',
|
claSignedLabel: 'cla: yes',
|
||||||
mergeReadyLabel: /^action: merge(-assistance)?/,
|
mergeReadyLabel: /^PR action: merge(-assistance)?/,
|
||||||
caretakerNoteLabel: 'action: merge-assistance',
|
caretakerNoteLabel: 'PR action: merge-assistance',
|
||||||
commitMessageFixupLabel: 'commit message fixup',
|
commitMessageFixupLabel: 'commit message fixup',
|
||||||
labels: await getDefaultTargetLabelConfiguration(api, github, '@angular/core'),
|
labels: [
|
||||||
|
{
|
||||||
|
pattern: 'PR target: master-only',
|
||||||
|
branches: ['master'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'PR target: patch-only',
|
||||||
|
branches: [patch],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
pattern: 'PR target: master & patch',
|
||||||
|
branches: ['master', patch],
|
||||||
|
},
|
||||||
|
],
|
||||||
requiredBaseCommits: {
|
requiredBaseCommits: {
|
||||||
// PRs that target either `master` or the patch branch, need to be rebased
|
// PRs that target either `master` or the patch branch, need to be rebased
|
||||||
// on top of the latest commit message validation fix.
|
// on top of the latest commit message validation fix.
|
||||||
// These SHAs are the commits that update the required license text in the header.
|
// These SHAs are the commits that update the required license text in the header.
|
||||||
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
|
'master': '5aeb9a4124922d8ac08eb73b8f322905a32b0b3a',
|
||||||
'10.0.x': '27b95ba64a5d99757f4042073fd1860e20e3ed24',
|
[patch]: '27b95ba64a5d99757f4042073fd1860e20e3ed24'
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -115,42 +115,6 @@ pullapprove_conditions:
|
|||||||
|
|
||||||
|
|
||||||
groups:
|
groups:
|
||||||
# =========================================================
|
|
||||||
# Global Approvers
|
|
||||||
#
|
|
||||||
# All reviews performed for global approvals require using
|
|
||||||
# the `Reviewed-for:` specifier to set the approval
|
|
||||||
# specificity as documented at:
|
|
||||||
# https://docs.pullapprove.com/reviewed-for/
|
|
||||||
# =========================================================
|
|
||||||
global-approvers:
|
|
||||||
type: optional
|
|
||||||
reviewers:
|
|
||||||
teams:
|
|
||||||
- framework-global-approvers
|
|
||||||
reviews:
|
|
||||||
request: 0
|
|
||||||
required: 1
|
|
||||||
reviewed_for: required
|
|
||||||
|
|
||||||
# =========================================================
|
|
||||||
# Global Approvers For Docs
|
|
||||||
#
|
|
||||||
# All reviews performed for global docs approvals require
|
|
||||||
# using the `Reviewed-for:` specifier to set the approval
|
|
||||||
# specificity as documented at:
|
|
||||||
# https://docs.pullapprove.com/reviewed-for/
|
|
||||||
# =========================================================
|
|
||||||
global-docs-approvers:
|
|
||||||
type: optional
|
|
||||||
reviewers:
|
|
||||||
teams:
|
|
||||||
- framework-global-approvers-for-docs-only-changes
|
|
||||||
reviews:
|
|
||||||
request: 0
|
|
||||||
required: 1
|
|
||||||
reviewed_for: required
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Require review on all PRs
|
# Require review on all PRs
|
||||||
#
|
#
|
||||||
@ -159,9 +123,6 @@ groups:
|
|||||||
# one review is provided before the group is satisfied.
|
# one review is provided before the group is satisfied.
|
||||||
# =========================================================
|
# =========================================================
|
||||||
required-minimum-review:
|
required-minimum-review:
|
||||||
conditions:
|
|
||||||
- *can-be-global-approved
|
|
||||||
- *can-be-global-docs-approved
|
|
||||||
reviews:
|
reviews:
|
||||||
request: 0 # Do not request any reviews from the reviewer group
|
request: 0 # Do not request any reviews from the reviewer group
|
||||||
required: 1 # Require that all PRs have approval from at least one of the users in the group
|
required: 1 # Require that all PRs have approval from at least one of the users in the group
|
||||||
@ -196,12 +157,48 @@ groups:
|
|||||||
- manughub # Manu Murthy
|
- manughub # Manu Murthy
|
||||||
- mgechev # Minko Gechev
|
- mgechev # Minko Gechev
|
||||||
- mhevery # Miško Hevery
|
- mhevery # Miško Hevery
|
||||||
|
- michaelprentice # Michael Prentice
|
||||||
- mmalerba # Miles Malerba
|
- mmalerba # Miles Malerba
|
||||||
- petebacondarwin # Pete Bacon Darwin
|
- petebacondarwin # Pete Bacon Darwin
|
||||||
- pkozlowski-opensource # Pawel Kozlowski
|
- pkozlowski-opensource # Pawel Kozlowski
|
||||||
- Splaktar # Michael Prentice
|
|
||||||
- StephenFluin # Stephen Fluin
|
- StephenFluin # Stephen Fluin
|
||||||
|
|
||||||
|
# =========================================================
|
||||||
|
# Global Approvers
|
||||||
|
#
|
||||||
|
# All reviews performed for global approvals require using
|
||||||
|
# the `Reviewed-for:` specifier to set the approval
|
||||||
|
# specificity as documented at:
|
||||||
|
# https://docs.pullapprove.com/reviewed-for/
|
||||||
|
# =========================================================
|
||||||
|
global-approvers:
|
||||||
|
type: optional
|
||||||
|
reviewers:
|
||||||
|
teams:
|
||||||
|
- framework-global-approvers
|
||||||
|
reviews:
|
||||||
|
request: 0
|
||||||
|
required: 1
|
||||||
|
reviewed_for: required
|
||||||
|
|
||||||
|
# =========================================================
|
||||||
|
# Global Approvers For Docs
|
||||||
|
#
|
||||||
|
# All reviews performed for global docs approvals require
|
||||||
|
# using the `Reviewed-for:` specifier to set the approval
|
||||||
|
# specificity as documented at:
|
||||||
|
# https://docs.pullapprove.com/reviewed-for/
|
||||||
|
# =========================================================
|
||||||
|
global-docs-approvers:
|
||||||
|
type: optional
|
||||||
|
reviewers:
|
||||||
|
teams:
|
||||||
|
- framework-global-approvers-for-docs-only-changes
|
||||||
|
reviews:
|
||||||
|
request: 0
|
||||||
|
required: 1
|
||||||
|
reviewed_for: required
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Framework: Animations
|
# Framework: Animations
|
||||||
# =========================================================
|
# =========================================================
|
||||||
@ -335,7 +332,6 @@ groups:
|
|||||||
'aio/content/images/guide/dependency-injection-in-action/**',
|
'aio/content/images/guide/dependency-injection-in-action/**',
|
||||||
'aio/content/guide/dependency-injection-navtree.md',
|
'aio/content/guide/dependency-injection-navtree.md',
|
||||||
'aio/content/guide/dependency-injection-providers.md',
|
'aio/content/guide/dependency-injection-providers.md',
|
||||||
'aio/content/guide/lightweight-injection-tokens.md',
|
|
||||||
'aio/content/guide/displaying-data.md',
|
'aio/content/guide/displaying-data.md',
|
||||||
'aio/content/examples/displaying-data/**',
|
'aio/content/examples/displaying-data/**',
|
||||||
'aio/content/images/guide/displaying-data/**',
|
'aio/content/images/guide/displaying-data/**',
|
||||||
@ -509,8 +505,8 @@ groups:
|
|||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
'packages/core/src/i18n/**',
|
'packages/core/src/i18n/**',
|
||||||
'packages/core/src/render3/i18n/**',
|
'packages/core/src/render3/i18n.ts',
|
||||||
'packages/core/src/render3/instructions/i18n.ts',
|
'packages/core/src/render3/i18n.md',
|
||||||
'packages/core/src/render3/interfaces/i18n.ts',
|
'packages/core/src/render3/interfaces/i18n.ts',
|
||||||
'packages/common/locales/**',
|
'packages/common/locales/**',
|
||||||
'packages/common/src/i18n/**',
|
'packages/common/src/i18n/**',
|
||||||
@ -787,21 +783,6 @@ groups:
|
|||||||
- JiaLiPassion
|
- JiaLiPassion
|
||||||
- mhevery
|
- mhevery
|
||||||
|
|
||||||
# =========================================================
|
|
||||||
# in-memory-web-api
|
|
||||||
# =========================================================
|
|
||||||
in-memory-web-api:
|
|
||||||
conditions:
|
|
||||||
- *can-be-global-approved
|
|
||||||
- *can-be-global-docs-approved
|
|
||||||
- >
|
|
||||||
contains_any_globs(files, [
|
|
||||||
'packages/misc/angular-in-memory-web-api/**',
|
|
||||||
])
|
|
||||||
reviewers:
|
|
||||||
users:
|
|
||||||
- IgorMinar
|
|
||||||
- crisbeto
|
|
||||||
|
|
||||||
# =========================================================
|
# =========================================================
|
||||||
# Benchpress
|
# Benchpress
|
||||||
@ -882,7 +863,6 @@ groups:
|
|||||||
- *can-be-global-docs-approved
|
- *can-be-global-docs-approved
|
||||||
- >
|
- >
|
||||||
contains_any_globs(files, [
|
contains_any_globs(files, [
|
||||||
'aio/content/guide/roadmap.md',
|
|
||||||
'aio/content/marketing/**',
|
'aio/content/marketing/**',
|
||||||
'aio/content/images/bios/**',
|
'aio/content/images/bios/**',
|
||||||
'aio/content/images/marketing/**',
|
'aio/content/images/marketing/**',
|
||||||
@ -1110,7 +1090,6 @@ groups:
|
|||||||
'dev-infra/**',
|
'dev-infra/**',
|
||||||
'docs/BAZEL.md',
|
'docs/BAZEL.md',
|
||||||
'docs/CARETAKER.md',
|
'docs/CARETAKER.md',
|
||||||
'docs/CODING_STANDARDS.md',
|
|
||||||
'docs/COMMITTER.md',
|
'docs/COMMITTER.md',
|
||||||
'docs/DEBUG.md',
|
'docs/DEBUG.md',
|
||||||
'docs/DEBUG_COMPONENTS_REPO_IVY.md',
|
'docs/DEBUG_COMPONENTS_REPO_IVY.md',
|
||||||
|
@ -44654,7 +44654,7 @@ const FOLDERS_IGNORE = [
|
|||||||
const DEFAULT_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([...FOLDERS_IGNORE,
|
const DEFAULT_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([...FOLDERS_IGNORE,
|
||||||
|
|
||||||
// ignore cruft
|
// ignore cruft
|
||||||
'yarn.lock', '.lock-wscript', '.wafpickle-{0..9}', '*.swp', '._*', 'npm-debug.log', 'yarn-error.log', '.npmrc', '.yarnrc', '.yarnrc.yml', '.npmignore', '.gitignore', '.DS_Store']);
|
'yarn.lock', '.lock-wscript', '.wafpickle-{0..9}', '*.swp', '._*', 'npm-debug.log', 'yarn-error.log', '.npmrc', '.yarnrc', '.npmignore', '.gitignore', '.DS_Store']);
|
||||||
|
|
||||||
const NEVER_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([
|
const NEVER_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([
|
||||||
// never ignore these files
|
// never ignore these files
|
||||||
@ -44663,7 +44663,6 @@ const NEVER_IGNORE = (0, (_filter || _load_filter()).ignoreLinesToRegex)([
|
|||||||
function packWithIgnoreAndHeaders(cwd, ignoreFunction, { mapHeader } = {}) {
|
function packWithIgnoreAndHeaders(cwd, ignoreFunction, { mapHeader } = {}) {
|
||||||
return tar.pack(cwd, {
|
return tar.pack(cwd, {
|
||||||
ignore: ignoreFunction,
|
ignore: ignoreFunction,
|
||||||
sort: true,
|
|
||||||
map: header => {
|
map: header => {
|
||||||
const suffix = header.name === '.' ? '' : `/${header.name}`;
|
const suffix = header.name === '.' ? '' : `/${header.name}`;
|
||||||
header.name = `package${suffix}`;
|
header.name = `package${suffix}`;
|
||||||
@ -46679,7 +46678,7 @@ function mkdirfix (name, opts, cb) {
|
|||||||
/* 194 */
|
/* 194 */
|
||||||
/***/ (function(module, exports) {
|
/***/ (function(module, exports) {
|
||||||
|
|
||||||
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.22.5","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
|
module.exports = {"name":"yarn","installationMethod":"unknown","version":"1.22.4","license":"BSD-2-Clause","preferGlobal":true,"description":"📦🐈 Fast, reliable, and secure dependency management.","dependencies":{"@zkochan/cmd-shim":"^3.1.0","babel-runtime":"^6.26.0","bytes":"^3.0.0","camelcase":"^4.0.0","chalk":"^2.1.0","cli-table3":"^0.4.0","commander":"^2.9.0","death":"^1.0.0","debug":"^3.0.0","deep-equal":"^1.0.1","detect-indent":"^5.0.0","dnscache":"^1.0.1","glob":"^7.1.1","gunzip-maybe":"^1.4.0","hash-for-dep":"^1.2.3","imports-loader":"^0.8.0","ini":"^1.3.4","inquirer":"^6.2.0","invariant":"^2.2.0","is-builtin-module":"^2.0.0","is-ci":"^1.0.10","is-webpack-bundle":"^1.0.0","js-yaml":"^3.13.1","leven":"^2.0.0","loud-rejection":"^1.2.0","micromatch":"^2.3.11","mkdirp":"^0.5.1","node-emoji":"^1.6.1","normalize-url":"^2.0.0","npm-logical-tree":"^1.2.1","object-path":"^0.11.2","proper-lockfile":"^2.0.0","puka":"^1.0.0","read":"^1.0.7","request":"^2.87.0","request-capture-har":"^1.2.2","rimraf":"^2.5.0","semver":"^5.1.0","ssri":"^5.3.0","strip-ansi":"^4.0.0","strip-bom":"^3.0.0","tar-fs":"^1.16.0","tar-stream":"^1.6.1","uuid":"^3.0.1","v8-compile-cache":"^2.0.0","validate-npm-package-license":"^3.0.4","yn":"^2.0.0"},"devDependencies":{"babel-core":"^6.26.0","babel-eslint":"^7.2.3","babel-loader":"^6.2.5","babel-plugin-array-includes":"^2.0.3","babel-plugin-inline-import":"^3.0.0","babel-plugin-transform-builtin-extend":"^1.1.2","babel-plugin-transform-inline-imports-commonjs":"^1.0.0","babel-plugin-transform-runtime":"^6.4.3","babel-preset-env":"^1.6.0","babel-preset-flow":"^6.23.0","babel-preset-stage-0":"^6.0.0","babylon":"^6.5.0","commitizen":"^2.9.6","cz-conventional-changelog":"^2.0.0","eslint":"^4.3.0","eslint-config-fb-strict":"^22.0.0","eslint-plugin-babel":"^5.0.0","eslint-plugin-flowtype":"^2.35.0","eslint-plugin-jasmine":"^2.6.2","eslint-plugin-jest":"^21.0.0","eslint-plugin-jsx-a11y":"^6.0.2","eslint-plugin-prefer-object-spread":"^1.2.1","eslint-plugin-prettier":"^2.1.2","eslint-plugin-react":"^7.1.0","eslint-plugin-relay":"^0.0.28","eslint-plugin-yarn-internal":"file:scripts/eslint-rules","execa":"^0.11.0","fancy-log":"^1.3.2","flow-bin":"^0.66.0","git-release-notes":"^3.0.0","gulp":"^4.0.0","gulp-babel":"^7.0.0","gulp-if":"^2.0.1","gulp-newer":"^1.0.0","gulp-plumber":"^1.0.1","gulp-sourcemaps":"^2.2.0","jest":"^22.4.4","jsinspect":"^0.12.6","minimatch":"^3.0.4","mock-stdin":"^0.3.0","prettier":"^1.5.2","string-replace-loader":"^2.1.1","temp":"^0.8.3","webpack":"^2.1.0-beta.25","yargs":"^6.3.0"},"resolutions":{"sshpk":"^1.14.2"},"engines":{"node":">=4.0.0"},"repository":"yarnpkg/yarn","bin":{"yarn":"./bin/yarn.js","yarnpkg":"./bin/yarn.js"},"scripts":{"build":"gulp build","build-bundle":"node ./scripts/build-webpack.js","build-chocolatey":"powershell ./scripts/build-chocolatey.ps1","build-deb":"./scripts/build-deb.sh","build-dist":"bash ./scripts/build-dist.sh","build-win-installer":"scripts\\build-windows-installer.bat","changelog":"git-release-notes $(git describe --tags --abbrev=0 $(git describe --tags --abbrev=0)^)..$(git describe --tags --abbrev=0) scripts/changelog.md","dupe-check":"yarn jsinspect ./src","lint":"eslint . && flow check","pkg-tests":"yarn --cwd packages/pkg-tests jest yarn.test.js","prettier":"eslint src __tests__ --fix","release-branch":"./scripts/release-branch.sh","test":"yarn lint && yarn test-only","test-only":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --verbose","test-only-debug":"node --inspect-brk --max_old_space_size=4096 node_modules/jest/bin/jest.js --runInBand --verbose","test-coverage":"node --max_old_space_size=4096 node_modules/jest/bin/jest.js --coverage --verbose","watch":"gulp watch","commit":"git-cz"},"jest":{"collectCoverageFrom":["src/**/*.js"],"testEnvironment":"node","modulePathIgnorePatterns":["__tests__/fixtures/","packages/pkg-tests/pkg-tests-fixtures","dist/"],"testPathIgnorePatterns":["__tests__/(fixtures|__mocks__)/","updates/","_(temp|mock|install|init|helpers).js$","packages/pkg-tests"]},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}}}
|
||||||
|
|
||||||
/***/ }),
|
/***/ }),
|
||||||
/* 195 */
|
/* 195 */
|
||||||
@ -98339,7 +98338,7 @@ var _buildSubCommands = (0, (_buildSubCommands2 || _load_buildSubCommands()).def
|
|||||||
|
|
||||||
const bundle = yield fetchBundle(config, bundleUrl);
|
const bundle = yield fetchBundle(config, bundleUrl);
|
||||||
|
|
||||||
const yarnPath = path.resolve(config.lockfileFolder, `.yarn/releases/yarn-${bundleVersion}.cjs`);
|
const yarnPath = path.resolve(config.lockfileFolder, `.yarn/releases/yarn-${bundleVersion}.js`);
|
||||||
reporter.log(`Saving it into ${chalk.magenta(yarnPath)}...`);
|
reporter.log(`Saving it into ${chalk.magenta(yarnPath)}...`);
|
||||||
yield (_fs || _load_fs()).mkdirp(path.dirname(yarnPath));
|
yield (_fs || _load_fs()).mkdirp(path.dirname(yarnPath));
|
||||||
yield (_fs || _load_fs()).writeFile(yarnPath, bundle);
|
yield (_fs || _load_fs()).writeFile(yarnPath, bundle);
|
||||||
@ -100191,7 +100190,7 @@ let main = exports.main = (() => {
|
|||||||
|
|
||||||
const config = new (_config || _load_config()).default(reporter);
|
const config = new (_config || _load_config()).default(reporter);
|
||||||
const outputWrapperEnabled = (0, (_conversion || _load_conversion()).boolifyWithDefault)(process.env.YARN_WRAP_OUTPUT, true);
|
const outputWrapperEnabled = (0, (_conversion || _load_conversion()).boolifyWithDefault)(process.env.YARN_WRAP_OUTPUT, true);
|
||||||
const shouldWrapOutput = outputWrapperEnabled && !(_commander || _load_commander()).default.json && command.hasWrapper((_commander || _load_commander()).default, (_commander || _load_commander()).default.args) && !(commandName === 'init' && (_commander || _load_commander()).default[`2`]);
|
const shouldWrapOutput = outputWrapperEnabled && !(_commander || _load_commander()).default.json && command.hasWrapper((_commander || _load_commander()).default, (_commander || _load_commander()).default.args);
|
||||||
|
|
||||||
if (shouldWrapOutput) {
|
if (shouldWrapOutput) {
|
||||||
reporter.header(commandName, { name: 'yarn', version: (_yarnVersion || _load_yarnVersion()).version });
|
reporter.header(commandName, { name: 'yarn', version: (_yarnVersion || _load_yarnVersion()).version });
|
||||||
@ -100605,7 +100604,7 @@ let start = (() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (/\.[cm]?js$/.test(yarnPath)) {
|
if (yarnPath.endsWith(`.js`)) {
|
||||||
exitCode = yield (0, (_child || _load_child()).spawnp)(process.execPath, [yarnPath, ...argv], opts);
|
exitCode = yield (0, (_child || _load_child()).spawnp)(process.execPath, [yarnPath, ...argv], opts);
|
||||||
} else {
|
} else {
|
||||||
exitCode = yield (0, (_child || _load_child()).spawnp)(yarnPath, argv, opts);
|
exitCode = yield (0, (_child || _load_child()).spawnp)(yarnPath, argv, opts);
|
2
.yarnrc
2
.yarnrc
@ -2,4 +2,4 @@
|
|||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
yarn-path ".yarn/releases/yarn-1.22.5.js"
|
yarn-path ".yarn/releases/yarn-1.22.4.js"
|
||||||
|
@ -20,9 +20,9 @@ filegroup(
|
|||||||
# do not sort
|
# do not sort
|
||||||
srcs = [
|
srcs = [
|
||||||
"@npm//:node_modules/core-js/client/core.js",
|
"@npm//:node_modules/core-js/client/core.js",
|
||||||
"//packages/zone.js/bundles:zone.umd.js",
|
"//packages/zone.js/dist:zone.js",
|
||||||
"//packages/zone.js/bundles:zone-testing.umd.js",
|
"//packages/zone.js/dist:zone-testing.js",
|
||||||
"//packages/zone.js/bundles:task-tracking.umd.js",
|
"//packages/zone.js/dist:task-tracking.js",
|
||||||
"//:test-events.js",
|
"//:test-events.js",
|
||||||
"//:third_party/shims_for_IE.js",
|
"//:third_party/shims_for_IE.js",
|
||||||
# Including systemjs because it defines `__eval`, which produces correct stack traces.
|
# Including systemjs because it defines `__eval`, which produces correct stack traces.
|
||||||
@ -34,7 +34,7 @@ filegroup(
|
|||||||
filegroup(
|
filegroup(
|
||||||
name = "angularjs_scripts",
|
name = "angularjs_scripts",
|
||||||
srcs = [
|
srcs = [
|
||||||
# We also declare the unminified AngularJS files since these can be used for
|
# We also declare the unminfied AngularJS files since these can be used for
|
||||||
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
|
# local debugging (e.g. see: packages/upgrade/test/common/test_helpers.ts)
|
||||||
"@npm//:node_modules/angular/angular.js",
|
"@npm//:node_modules/angular/angular.js",
|
||||||
"@npm//:node_modules/angular/angular.min.js",
|
"@npm//:node_modules/angular/angular.min.js",
|
||||||
|
371
CHANGELOG.md
371
CHANGELOG.md
@ -1,206 +1,3 @@
|
|||||||
<a name="10.1.3"></a>
|
|
||||||
## 10.1.3 (2020-09-23)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **http:** Fix error message when we call jsonp without importing HttpClientJsonpModule ([#38756](https://github.com/angular/angular/issues/38756)) ([3902ec0](https://github.com/angular/angular/commit/3902ec0))
|
|
||||||
* **ngcc:** fix compilation of `ChangeDetectorRef` in pipe constructors ([#38892](https://github.com/angular/angular/issues/38892)) ([093c3a1](https://github.com/angular/angular/commit/093c3a1)), closes [#38666](https://github.com/angular/angular/issues/38666) [#38883](https://github.com/angular/angular/issues/38883)
|
|
||||||
|
|
||||||
|
|
||||||
### Reverts
|
|
||||||
|
|
||||||
* feat(router): better warning message when a router outlet has not been instantiated ([#38920](https://github.com/angular/angular/issues/38920)) ([04d0aa6](https://github.com/angular/angular/commit/04d0aa6))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.1.2"></a>
|
|
||||||
## 10.1.2 (2020-09-16)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** detect pipes in ICUs in template binder ([#38810](https://github.com/angular/angular/issues/38810)) ([ec2dbe7](https://github.com/angular/angular/commit/ec2dbe7)), closes [#38539](https://github.com/angular/angular/issues/38539) [#38539](https://github.com/angular/angular/issues/38539) [#38539](https://github.com/angular/angular/issues/38539)
|
|
||||||
* **core:** clear the `RefreshTransplantedView` when detached ([#38768](https://github.com/angular/angular/issues/38768)) ([edb7f90](https://github.com/angular/angular/commit/edb7f90)), closes [#38619](https://github.com/angular/angular/issues/38619)
|
|
||||||
* **localize:** ensure that `formatOptions` is optional ([#38787](https://github.com/angular/angular/issues/38787)) ([a47383d](https://github.com/angular/angular/commit/a47383d))
|
|
||||||
* **router:** Ensure routes are processed in priority order and only if needed ([#38780](https://github.com/angular/angular/issues/38780)) ([9c51ba3](https://github.com/angular/angular/commit/9c51ba3)), closes [#38691](https://github.com/angular/angular/issues/38691)
|
|
||||||
* **upgrade:** add try/catch when downgrading injectables ([#38671](https://github.com/angular/angular/issues/38671)) ([5de2ac3](https://github.com/angular/angular/commit/5de2ac3)), closes [#37579](https://github.com/angular/angular/issues/37579)
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **compiler-cli:** only emit directive/pipe references that are used ([#38843](https://github.com/angular/angular/issues/38843)) ([5658405](https://github.com/angular/angular/commit/5658405))
|
|
||||||
* **compiler-cli:** optimize computation of type-check scope information ([#38843](https://github.com/angular/angular/issues/38843)) ([ebede67](https://github.com/angular/angular/commit/ebede67))
|
|
||||||
* **ngcc:** introduce cache for sharing data across entry-points ([#38840](https://github.com/angular/angular/issues/38840)) ([58411e7](https://github.com/angular/angular/commit/58411e7))
|
|
||||||
* **ngcc:** reduce maximum worker count ([#38840](https://github.com/angular/angular/issues/38840)) ([ea36466](https://github.com/angular/angular/commit/ea36466))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.1.1"></a>
|
|
||||||
## 10.1.1 (2020-09-09)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler:** correct confusion between field and property names ([#38685](https://github.com/angular/angular/issues/38685)) ([a1c34c6](https://github.com/angular/angular/commit/a1c34c6))
|
|
||||||
* **compiler-cli:** compute source-mappings for localized strings ([#38747](https://github.com/angular/angular/issues/38747)) ([b4eb016](https://github.com/angular/angular/commit/b4eb016)), closes [#38588](https://github.com/angular/angular/issues/38588)
|
|
||||||
* **compiler-cli:** ensure that a declaration is available in type-to-value conversion ([#38684](https://github.com/angular/angular/issues/38684)) ([56d5ff2](https://github.com/angular/angular/commit/56d5ff2)), closes [#38670](https://github.com/angular/angular/issues/38670)
|
|
||||||
* **core:** reset `tView` between tests in Ivy TestBed ([#38659](https://github.com/angular/angular/issues/38659)) ([efc7606](https://github.com/angular/angular/commit/efc7606)), closes [#38600](https://github.com/angular/angular/issues/38600)
|
|
||||||
* **localize:** do not expose NodeJS typings in $localize runtime code ([#38700](https://github.com/angular/angular/issues/38700)) ([4de8dc3](https://github.com/angular/angular/commit/4de8dc3)), closes [#38692](https://github.com/angular/angular/issues/38692)
|
|
||||||
* **localize:** enable whitespace preservation marker in XLIFF files ([#38737](https://github.com/angular/angular/issues/38737)) ([190dca0](https://github.com/angular/angular/commit/190dca0)), closes [#38679](https://github.com/angular/angular/issues/38679)
|
|
||||||
* **localize:** install `[@angular](https://github.com/angular)/localize` in `devDependencies` by default ([#38680](https://github.com/angular/angular/issues/38680)) ([dbab744](https://github.com/angular/angular/commit/dbab744)), closes [#38329](https://github.com/angular/angular/issues/38329)
|
|
||||||
* **localize:** render context of translation file parse errors ([#38673](https://github.com/angular/angular/issues/38673)) ([32f33f0](https://github.com/angular/angular/commit/32f33f0)), closes [#38377](https://github.com/angular/angular/issues/38377)
|
|
||||||
* **localize:** render location in XLIFF 2 even if there is no metadata ([#38713](https://github.com/angular/angular/issues/38713)) ([ab4f953](https://github.com/angular/angular/commit/ab4f953)), closes [#38705](https://github.com/angular/angular/issues/38705)
|
|
||||||
* **ngcc:** use aliased exported types correctly ([#38666](https://github.com/angular/angular/issues/38666)) ([6a28675](https://github.com/angular/angular/commit/6a28675)), closes [#38238](https://github.com/angular/angular/issues/38238)
|
|
||||||
* **router:** If users are using the Alt key when clicking the router links, prioritize browser’s default behavior ([#38375](https://github.com/angular/angular/issues/38375)) ([309709d](https://github.com/angular/angular/commit/309709d))
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **core:** use `ngDevMode` to tree-shake error messages ([#38612](https://github.com/angular/angular/issues/38612)) ([b084bff](https://github.com/angular/angular/commit/b084bff))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.1.0"></a>
|
|
||||||
# 10.1.0 (2020-09-02)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **bazel:** provide LinkablePackageInfo from ng_module ([#37623](https://github.com/angular/angular/issues/37623)) ([6898eab](https://github.com/angular/angular/commit/6898eab))
|
|
||||||
* **common:** add ReadonlyMap in place of Map in keyValuePipe ([#37311](https://github.com/angular/angular/issues/37311)) ([3373453](https://github.com/angular/angular/commit/3373453)), closes [#37308](https://github.com/angular/angular/issues/37308)
|
|
||||||
* **compiler-cli:** add `SourceFile.getOriginalLocation()` to sourcemaps package ([#32912](https://github.com/angular/angular/issues/32912)) ([6abb8d0](https://github.com/angular/angular/commit/6abb8d0))
|
|
||||||
* **compiler-cli:** Add compiler option to report errors when assigning to restricted input fields ([#38249](https://github.com/angular/angular/issues/38249)) ([71138f6](https://github.com/angular/angular/commit/71138f6))
|
|
||||||
* **compiler-cli:** add support for TypeScript 4.0 ([#38076](https://github.com/angular/angular/issues/38076)) ([0fc44e0](https://github.com/angular/angular/commit/0fc44e0))
|
|
||||||
* **compiler-cli:** explain why an expression cannot be used in AOT compilations ([#37587](https://github.com/angular/angular/issues/37587)) ([712f1bd](https://github.com/angular/angular/commit/712f1bd))
|
|
||||||
* **compiler:** support unary operators for more accurate type checking ([#37918](https://github.com/angular/angular/issues/37918)) ([874792d](https://github.com/angular/angular/commit/874792d)), closes [#20845](https://github.com/angular/angular/issues/20845) [#36178](https://github.com/angular/angular/issues/36178)
|
|
||||||
* **core:** rename async to waitForAsync to avoid confusing ([#37583](https://github.com/angular/angular/issues/37583)) ([8f07429](https://github.com/angular/angular/commit/8f07429))
|
|
||||||
* **core:** support injection token as predicate in queries ([#37506](https://github.com/angular/angular/issues/37506)) ([97dc85b](https://github.com/angular/angular/commit/97dc85b)), closes [#21152](https://github.com/angular/angular/issues/21152) [#36144](https://github.com/angular/angular/issues/36144)
|
|
||||||
* **core:** update reference and doc to change `async` to `waitAsync`. ([#37583](https://github.com/angular/angular/issues/37583)) ([8fbf40b](https://github.com/angular/angular/commit/8fbf40b))
|
|
||||||
* **forms:** AbstractControl to store raw validators in addition to combined validators function ([#37881](https://github.com/angular/angular/issues/37881)) ([ad7046b](https://github.com/angular/angular/commit/ad7046b))
|
|
||||||
* **localize:** allow duplicate messages to be handled during extraction ([#38082](https://github.com/angular/angular/issues/38082)) ([cf9a47b](https://github.com/angular/angular/commit/cf9a47b)), closes [#38077](https://github.com/angular/angular/issues/38077)
|
|
||||||
* **localize:** expose `canParse()` diagnostics ([#37909](https://github.com/angular/angular/issues/37909)) ([ec32eba](https://github.com/angular/angular/commit/ec32eba)), closes [#37901](https://github.com/angular/angular/issues/37901)
|
|
||||||
* **localize:** implement message extraction tool ([#32912](https://github.com/angular/angular/issues/32912)) ([190561d](https://github.com/angular/angular/commit/190561d))
|
|
||||||
* **platform-browser:** Allow `sms`-URLs ([#31463](https://github.com/angular/angular/issues/31463)) ([fc5c34d](https://github.com/angular/angular/commit/fc5c34d)), closes [#31462](https://github.com/angular/angular/issues/31462)
|
|
||||||
* **platform-server:** add option for absolute URL HTTP support ([#37539](https://github.com/angular/angular/issues/37539)) ([d37049a](https://github.com/angular/angular/commit/d37049a)), closes [#37071](https://github.com/angular/angular/issues/37071)
|
|
||||||
* **router:** better warning message when a router outlet has not been instantiated ([#30246](https://github.com/angular/angular/issues/30246)) ([1609815](https://github.com/angular/angular/commit/1609815))
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **bazel:** fix integration test for bazel building ([#38629](https://github.com/angular/angular/issues/38629)) ([dd82f2f](https://github.com/angular/angular/commit/dd82f2f))
|
|
||||||
* **common:** date pipe gives wrong week number ([#37632](https://github.com/angular/angular/issues/37632)) ([ef1fb6d](https://github.com/angular/angular/commit/ef1fb6d)), closes [#33961](https://github.com/angular/angular/issues/33961)
|
|
||||||
* **common:** narrow `NgIf` context variables in template type checker ([#36627](https://github.com/angular/angular/issues/36627)) ([9c8bc4a](https://github.com/angular/angular/commit/9c8bc4a))
|
|
||||||
* **compiler-cli:** avoid creating value expressions for symbols from type-only imports ([#37912](https://github.com/angular/angular/issues/37912)) ([18098d3](https://github.com/angular/angular/commit/18098d3)), closes [#37900](https://github.com/angular/angular/issues/37900)
|
|
||||||
* **compiler-cli:** ensure source-maps can handle webpack:// protocol ([#32912](https://github.com/angular/angular/issues/32912)) ([decd95e](https://github.com/angular/angular/commit/decd95e))
|
|
||||||
* **compiler-cli:** only read source-map comment from last line ([#32912](https://github.com/angular/angular/issues/32912)) ([07a07e3](https://github.com/angular/angular/commit/07a07e3))
|
|
||||||
* **compiler-cli:** type-check inputs that include undefined when there's coercion members ([#38273](https://github.com/angular/angular/issues/38273)) ([7525f3a](https://github.com/angular/angular/commit/7525f3a))
|
|
||||||
* **compiler:** incorrectly inferring namespace for HTML nodes inside SVG ([#38477](https://github.com/angular/angular/issues/38477)) ([0dda97e](https://github.com/angular/angular/commit/0dda97e)), closes [#37218](https://github.com/angular/angular/issues/37218)
|
|
||||||
* **compiler:** mark `NgModuleFactory` construction as not side effectful ([#38147](https://github.com/angular/angular/issues/38147)) ([7f8c222](https://github.com/angular/angular/commit/7f8c222))
|
|
||||||
* **core:** Allow modification of lifecycle hooks any time before bootstrap ([#35464](https://github.com/angular/angular/issues/35464)) ([737506e](https://github.com/angular/angular/commit/737506e)), closes [#30497](https://github.com/angular/angular/issues/30497)
|
|
||||||
* **core:** detect DI parameters in JIT mode for downleveled ES2015 classes ([#38463](https://github.com/angular/angular/issues/38463)) ([ca07da4](https://github.com/angular/angular/commit/ca07da4)), closes [#38453](https://github.com/angular/angular/issues/38453)
|
|
||||||
* **core:** determine required DOMParser feature availability ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([c509243](https://github.com/angular/angular/commit/c509243))
|
|
||||||
* **core:** do not trigger CSP alert/report in Firefox and Chrome ([#36578](https://github.com/angular/angular/issues/36578)) ([#36578](https://github.com/angular/angular/issues/36578)) ([b950d46](https://github.com/angular/angular/commit/b950d46)), closes [#25214](https://github.com/angular/angular/issues/25214)
|
|
||||||
* **core:** move generated i18n statements to the `consts` field of ComponentDef ([#38404](https://github.com/angular/angular/issues/38404)) ([cb05c01](https://github.com/angular/angular/commit/cb05c01))
|
|
||||||
* **elements:** run strategy methods in correct zone ([#37814](https://github.com/angular/angular/issues/37814)) ([8df888d](https://github.com/angular/angular/commit/8df888d)), closes [#24181](https://github.com/angular/angular/issues/24181)
|
|
||||||
* **forms:** handle form groups/arrays own pending async validation ([#22575](https://github.com/angular/angular/issues/22575)) ([77b62a5](https://github.com/angular/angular/commit/77b62a5)), closes [#10064](https://github.com/angular/angular/issues/10064)
|
|
||||||
* **language-service:** non-existent module format in package output ([#37623](https://github.com/angular/angular/issues/37623)) ([413a0fb](https://github.com/angular/angular/commit/413a0fb))
|
|
||||||
* **localize:** ensure required XLIFF parameters are serialized ([#38575](https://github.com/angular/angular/issues/38575)) ([f0af387](https://github.com/angular/angular/commit/f0af387)), closes [#38570](https://github.com/angular/angular/issues/38570)
|
|
||||||
* **localize:** extract the correct message ids ([#38498](https://github.com/angular/angular/issues/38498)) ([ac461e1](https://github.com/angular/angular/commit/ac461e1))
|
|
||||||
* **localize:** render ICU placeholders in extracted translation files ([#38484](https://github.com/angular/angular/issues/38484)) ([81c3e80](https://github.com/angular/angular/commit/81c3e80))
|
|
||||||
* **localize:** render text of extracted placeholders ([#38536](https://github.com/angular/angular/issues/38536)) ([14e90be](https://github.com/angular/angular/commit/14e90be))
|
|
||||||
* **ngcc:** detect synthesized delegate constructors for downleveled ES2015 classes ([#38463](https://github.com/angular/angular/issues/38463)) ([3b9c802](https://github.com/angular/angular/commit/3b9c802)), closes [#38453](https://github.com/angular/angular/issues/38453) [#38453](https://github.com/angular/angular/issues/38453)
|
|
||||||
* **router:** defer loading of wildcard module until needed ([#38348](https://github.com/angular/angular/issues/38348)) ([8f708b5](https://github.com/angular/angular/commit/8f708b5)), closes [#25494](https://github.com/angular/angular/issues/25494)
|
|
||||||
* **router:** fix navigation ignoring logic to compare to the browser url ([#37716](https://github.com/angular/angular/issues/37716)) ([a5ffca0](https://github.com/angular/angular/commit/a5ffca0)), closes [#16710](https://github.com/angular/angular/issues/16710) [#13586](https://github.com/angular/angular/issues/13586)
|
|
||||||
* **router:** properly compare array queryParams for equality ([#37709](https://github.com/angular/angular/issues/37709)) ([#37860](https://github.com/angular/angular/issues/37860)) ([1801d0c](https://github.com/angular/angular/commit/1801d0c))
|
|
||||||
* **router:** remove parenthesis for primary outlet segment after removing auxiliary outlet segment ([#24656](https://github.com/angular/angular/issues/24656)) ([#37163](https://github.com/angular/angular/issues/37163)) ([71f008f](https://github.com/angular/angular/commit/71f008f))
|
|
||||||
* **router:** restore 'history.state' object for navigations coming from Angular router ([#28108](https://github.com/angular/angular/issues/28108)) ([#28176](https://github.com/angular/angular/issues/28176)) ([df76a20](https://github.com/angular/angular/commit/df76a20))
|
|
||||||
|
|
||||||
### Code Refactoring
|
|
||||||
* **router:** export DefaultRouteReuseStrategy to Router public_api ([#31575](https://github.com/angular/angular/issues/31575)) ([ca79880](https://github.com/angular/angular/commit/ca79880))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
* **compiler-cli:** don't emit template guards when child scope is empty ([#38418](https://github.com/angular/angular/issues/38418)) ([1388c17](https://github.com/angular/angular/commit/1388c17))
|
|
||||||
* **compiler-cli:** fix regressions in incremental program reuse ([#37641](https://github.com/angular/angular/issues/37641)) ([5103d90](https://github.com/angular/angular/commit/5103d90))
|
|
||||||
* **compiler-cli:** only generate directive declarations when used ([#38418](https://github.com/angular/angular/issues/38418)) ([fb8f4b4](https://github.com/angular/angular/commit/fb8f4b4))
|
|
||||||
* **compiler-cli:** only generate type-check code for referenced DOM elements ([#38418](https://github.com/angular/angular/issues/38418)) ([f42e6ce](https://github.com/angular/angular/commit/f42e6ce))
|
|
||||||
* **forms:** use internal `ngDevMode` flag to tree-shake error messages in prod builds ([#37821](https://github.com/angular/angular/issues/37821)) ([201a546](https://github.com/angular/angular/commit/201a546)), closes [#37697](https://github.com/angular/angular/issues/37697)
|
|
||||||
* **ngcc:** shortcircuit tokenizing in ESM dependency host ([#37639](https://github.com/angular/angular/issues/37639)) ([bd7f440](https://github.com/angular/angular/commit/bd7f440))
|
|
||||||
* **ngcc:** use `EntryPointManifest` to speed up noop `ProgramBaseEntryPointFinder` ([#37665](https://github.com/angular/angular/issues/37665)) ([9318e23](https://github.com/angular/angular/commit/9318e23))
|
|
||||||
* **router:** apply prioritizedGuardValue operator to optimize CanLoad guards ([#37523](https://github.com/angular/angular/issues/37523)) ([d7dd295](https://github.com/angular/angular/commit/d7dd295))
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.14"></a>
|
|
||||||
## 10.0.14 (2020-08-26)
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.12"></a>
|
|
||||||
## 10.0.12 (2020-08-24)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **compiler-cli:** adding references to const enums in runtime code ([#38542](https://github.com/angular/angular/issues/38542)) ([814b436](https://github.com/angular/angular/commit/814b436)), closes [#38513](https://github.com/angular/angular/issues/38513)
|
|
||||||
* **core:** remove closing body tag from inert DOM builder ([#38454](https://github.com/angular/angular/issues/38454)) ([5528536](https://github.com/angular/angular/commit/5528536))
|
|
||||||
* **localize:** include the last placeholder in parsed translation text ([#38452](https://github.com/angular/angular/issues/38452)) ([57d1a48](https://github.com/angular/angular/commit/57d1a48))
|
|
||||||
* **localize:** parse all parts of a translation with nested HTML ([#38452](https://github.com/angular/angular/issues/38452)) ([07b99f5](https://github.com/angular/angular/commit/07b99f5)), closes [#38422](https://github.com/angular/angular/issues/38422)
|
|
||||||
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
* **language-service:** introduce hybrid visitor to locate AST node ([#38540](https://github.com/angular/angular/issues/38540)) ([66d8c22](https://github.com/angular/angular/commit/66d8c22))
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.11"></a>
|
|
||||||
## 10.0.11 (2020-08-19)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **router:** ensure routerLinkActive updates when associated routerLinks change (resubmit of [#38349](https://github.com/angular/angular/issues/38349)) ([#38511](https://github.com/angular/angular/issues/38511)) ([0af9533](https://github.com/angular/angular/commit/0af9533)), closes [#18469](https://github.com/angular/angular/issues/18469)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.10"></a>
|
|
||||||
## 10.0.10 (2020-08-17)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **common:** Allow scrolling when browser supports scrollTo ([#38468](https://github.com/angular/angular/issues/38468)) ([b32126c](https://github.com/angular/angular/commit/b32126c)), closes [#30630](https://github.com/angular/angular/issues/30630)
|
|
||||||
* **core:** detect DI parameters in JIT mode for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([863acb6](https://github.com/angular/angular/commit/863acb6)), closes [#38453](https://github.com/angular/angular/issues/38453)
|
|
||||||
* **core:** error if CSS custom property in host binding has number in name ([#38432](https://github.com/angular/angular/issues/38432)) ([cb83b8a](https://github.com/angular/angular/commit/cb83b8a)), closes [#37292](https://github.com/angular/angular/issues/37292)
|
|
||||||
* **core:** fix multiple nested views removal from ViewContainerRef ([#38317](https://github.com/angular/angular/issues/38317)) ([d5e09f4](https://github.com/angular/angular/commit/d5e09f4)), closes [#38201](https://github.com/angular/angular/issues/38201)
|
|
||||||
* **ngcc:** detect synthesized delegate constructors for downleveled ES2015 classes ([#38500](https://github.com/angular/angular/issues/38500)) ([f3dd6c2](https://github.com/angular/angular/commit/f3dd6c2)), closes [#38453](https://github.com/angular/angular/issues/38453) [#38453](https://github.com/angular/angular/issues/38453)
|
|
||||||
* **router:** ensure routerLinkActive updates when associated routerLinks change ([#38349](https://github.com/angular/angular/issues/38349)) ([989e8a1](https://github.com/angular/angular/commit/989e8a1)), closes [#18469](https://github.com/angular/angular/issues/18469)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.9"></a>
|
|
||||||
## 10.0.9 (2020-08-12)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **common:** ensure scrollRestoration is writable ([#30630](https://github.com/angular/angular/issues/30630)) ([#38357](https://github.com/angular/angular/issues/38357)) ([58f4b3a](https://github.com/angular/angular/commit/58f4b3a)), closes [#30629](https://github.com/angular/angular/issues/30629)
|
|
||||||
* **compiler:** evaluate safe navigation expressions in correct binding order ([#37911](https://github.com/angular/angular/issues/37911)) ([f5b9d87](https://github.com/angular/angular/commit/f5b9d87)), closes [#37194](https://github.com/angular/angular/issues/37194)
|
|
||||||
* **compiler-cli:** avoid creating value expressions for symbols from type-only imports ([#38415](https://github.com/angular/angular/issues/38415)) ([ca2b4bc](https://github.com/angular/angular/commit/ca2b4bc)), closes [#37912](https://github.com/angular/angular/issues/37912)
|
|
||||||
* **compiler-cli:** infer quote expressions as any type in type checker ([#37917](https://github.com/angular/angular/issues/37917)) ([5b87c67](https://github.com/angular/angular/commit/5b87c67)), closes [#36568](https://github.com/angular/angular/issues/36568)
|
|
||||||
* **compiler-cli:** mark eager `NgModuleFactory` construction as not side effectful ([#38320](https://github.com/angular/angular/issues/38320)) ([016a41b](https://github.com/angular/angular/commit/016a41b)), closes [#38147](https://github.com/angular/angular/issues/38147)
|
|
||||||
* **compiler-cli:** match wrapHost parameter types within plugin interface ([#38004](https://github.com/angular/angular/issues/38004)) ([df01a82](https://github.com/angular/angular/commit/df01a82))
|
|
||||||
* **compiler-cli:** preserve quotes in class member names ([#38387](https://github.com/angular/angular/issues/38387)) ([c9acb7b](https://github.com/angular/angular/commit/c9acb7b)), closes [#38311](https://github.com/angular/angular/issues/38311)
|
|
||||||
* **core:** prevent NgModule scope being overwritten in JIT compiler ([#37795](https://github.com/angular/angular/issues/37795)) ([3acebdc](https://github.com/angular/angular/commit/3acebdc)), closes [#37105](https://github.com/angular/angular/issues/37105)
|
|
||||||
* **core:** queries not matching string injection tokens ([#38321](https://github.com/angular/angular/issues/38321)) ([32109dc](https://github.com/angular/angular/commit/32109dc)), closes [#38313](https://github.com/angular/angular/issues/38313) [#38315](https://github.com/angular/angular/issues/38315)
|
|
||||||
* **core:** Store the currently selected ICU in `LView` ([#38345](https://github.com/angular/angular/issues/38345)) ([ee5123f](https://github.com/angular/angular/commit/ee5123f))
|
|
||||||
* **platform-server:** remove styles added by ServerStylesHost on destruction ([#38367](https://github.com/angular/angular/issues/38367)) ([7f11149](https://github.com/angular/angular/commit/7f11149))
|
|
||||||
* **router:** prevent calling unsubscribe on undefined subscription in RouterPreloader ([#38344](https://github.com/angular/angular/issues/38344)) ([4151314](https://github.com/angular/angular/commit/4151314))
|
|
||||||
* **service-worker:** fix the chrome debugger syntax highlighter ([#38332](https://github.com/angular/angular/issues/38332)) ([f5d5bac](https://github.com/angular/angular/commit/f5d5bac))
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.8"></a>
|
<a name="10.0.8"></a>
|
||||||
## 10.0.8 (2020-08-04)
|
## 10.0.8 (2020-08-04)
|
||||||
|
|
||||||
@ -269,6 +66,7 @@
|
|||||||
* **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146)
|
* **bazel:** provide LinkablePackageInfo from ng_module ([#37778](https://github.com/angular/angular/issues/37778)) ([6cd10a1](https://github.com/angular/angular/commit/6cd10a1)), closes [/github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl#L144-L146](https://github.com//github.com/bazelbuild/rules_nodejs/blob/9a5de3728b05bf1647bbb87ad99f54e626604705/internal/linker/link_node_modules.bzl/issues/L144-L146)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.3"></a>
|
<a name="10.0.3"></a>
|
||||||
## 10.0.3 (2020-07-08)
|
## 10.0.3 (2020-07-08)
|
||||||
|
|
||||||
@ -279,16 +77,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.12"></a>
|
|
||||||
## [9.1.12](https://github.com/angular/angular/compare/9.1.11...9.1.12) (2020-07-08)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **core:** infinite loop if injectable using inheritance has a custom decorator ([6c1ab47](https://github.com/angular/angular/commit/6c1ab47)), closes [#35733](https://github.com/angular/angular/issues/35733)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="10.0.2"></a>
|
<a name="10.0.2"></a>
|
||||||
## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30)
|
## [10.0.2](https://github.com/angular/angular/compare/10.0.1...10.0.2) (2020-06-30)
|
||||||
|
|
||||||
@ -400,6 +188,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802))
|
* **compiler:** avoid undefined expressions in holey array ([#36343](https://github.com/angular/angular/issues/36343)) ([5516802](https://github.com/angular/angular/commit/5516802))
|
||||||
* **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([4aa4e6f](https://github.com/angular/angular/commit/4aa4e6f)), closes [#36006](https://github.com/angular/angular/issues/36006)
|
* **compiler:** handle type references to namespaced symbols correctly ([#36106](https://github.com/angular/angular/issues/36106)) ([4aa4e6f](https://github.com/angular/angular/commit/4aa4e6f)), closes [#36006](https://github.com/angular/angular/issues/36006)
|
||||||
* **compiler:** normalize line endings in ICU expansions ([#36741](https://github.com/angular/angular/issues/36741)) ([70dd27f](https://github.com/angular/angular/commit/70dd27f)), closes [#36725](https://github.com/angular/angular/issues/36725)
|
* **compiler:** normalize line endings in ICU expansions ([#36741](https://github.com/angular/angular/issues/36741)) ([70dd27f](https://github.com/angular/angular/commit/70dd27f)), closes [#36725](https://github.com/angular/angular/issues/36725)
|
||||||
|
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
|
||||||
* **compiler:** remove outdated and invalid warning for unresolved DI parameters ([#36985](https://github.com/angular/angular/issues/36985)) ([d0280a0](https://github.com/angular/angular/commit/d0280a0))
|
* **compiler:** remove outdated and invalid warning for unresolved DI parameters ([#36985](https://github.com/angular/angular/issues/36985)) ([d0280a0](https://github.com/angular/angular/commit/d0280a0))
|
||||||
* **compiler:** resolve enum values in binary operations ([#36461](https://github.com/angular/angular/issues/36461)) ([64022f5](https://github.com/angular/angular/commit/64022f5)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
* **compiler:** resolve enum values in binary operations ([#36461](https://github.com/angular/angular/issues/36461)) ([64022f5](https://github.com/angular/angular/commit/64022f5)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
||||||
* **compiler:** switch to 'referencedFiles' for shim generation ([#36211](https://github.com/angular/angular/issues/36211)) ([4213e8d](https://github.com/angular/angular/commit/4213e8d))
|
* **compiler:** switch to 'referencedFiles' for shim generation ([#36211](https://github.com/angular/angular/issues/36211)) ([4213e8d](https://github.com/angular/angular/commit/4213e8d))
|
||||||
@ -656,30 +445,6 @@ subscribe to the observable and call markForCheck as needed.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.11"></a>
|
|
||||||
## [9.1.11](https://github.com/angular/angular/compare/9.1.10...9.1.11) (2020-06-10)
|
|
||||||
|
|
||||||
### Reverts
|
|
||||||
|
|
||||||
* **elements:** fire custom element output events during component initialization ([dc9da17](https://github.com/angular/angular/commit/dc9da17))
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.10"></a>
|
|
||||||
## [9.1.10](https://github.com/angular/angular/compare/9.1.9...9.1.10) (2020-06-09)
|
|
||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
|
||||||
|
|
||||||
* **elements:** fire custom element output events during component initialization ([454e073](https://github.com/angular/angular/commit/454e073)), closes [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L167-L170](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L167-L170) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts#L164](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/create-custom-element.ts/issues/L164) [/github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts#L158](https://github.com/angular/angular/blob/c0143cb2abdd172de1b95fd1d2c4cfc738640e28/packages/elements/src/component-factory-strategy.ts/issues/L158) [#36141](https://github.com/angular/angular/issues/36141)
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
|
||||||
|
|
||||||
* **ngcc:** cache parsed tsconfig between runs ([1aae94a](https://github.com/angular/angular/commit/1aae94a)), closes [#37417](https://github.com/angular/angular/issues/37417) [#36882](https://github.com/angular/angular/issues/36882)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.9"></a>
|
<a name="9.1.9"></a>
|
||||||
## [9.1.9](https://github.com/angular/angular/compare/9.1.8...9.1.9) (2020-05-20)
|
## [9.1.9](https://github.com/angular/angular/compare/9.1.8...9.1.9) (2020-05-20)
|
||||||
|
|
||||||
@ -721,7 +486,6 @@ This release contains various API docs improvements.
|
|||||||
* **compiler-cli**: Revert "fix(compiler-cli): fix case-sensitivity issues in NgtscCompilerHost (#36968)" (#37003)
|
* **compiler-cli**: Revert "fix(compiler-cli): fix case-sensitivity issues in NgtscCompilerHost (#36968)" (#37003)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.5"></a>
|
<a name="9.1.5"></a>
|
||||||
## [9.1.5](https://github.com/angular/angular/compare/9.1.4...9.1.5) (2020-05-07)
|
## [9.1.5](https://github.com/angular/angular/compare/9.1.4...9.1.5) (2020-05-07)
|
||||||
|
|
||||||
@ -767,7 +531,6 @@ This release contains various API docs improvements.
|
|||||||
* **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([c440165](https://github.com/angular/angular/commit/c440165)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
* **ngcc:** recognize enum declarations emitted in JavaScript ([#36550](https://github.com/angular/angular/issues/36550)) ([c440165](https://github.com/angular/angular/commit/c440165)), closes [#35584](https://github.com/angular/angular/issues/35584)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<a name="9.1.3"></a>
|
<a name="9.1.3"></a>
|
||||||
## [9.1.3](https://github.com/angular/angular/compare/9.1.2...9.1.3) (2020-04-22)
|
## [9.1.3](https://github.com/angular/angular/compare/9.1.2...9.1.3) (2020-04-22)
|
||||||
|
|
||||||
@ -782,8 +545,8 @@ This release contains various API docs improvements.
|
|||||||
* **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([fe1d9ba](https://github.com/angular/angular/commit/fe1d9ba)), closes [#35945](https://github.com/angular/angular/issues/35945)
|
* **core:** prevent unknown property check for AOT-compiled components ([#36072](https://github.com/angular/angular/issues/36072)) ([fe1d9ba](https://github.com/angular/angular/commit/fe1d9ba)), closes [#35945](https://github.com/angular/angular/issues/35945)
|
||||||
* **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([9724169](https://github.com/angular/angular/commit/9724169)), closes [#36619](https://github.com/angular/angular/issues/36619)
|
* **core:** properly identify modules affected by overrides in TestBed ([#36649](https://github.com/angular/angular/issues/36649)) ([9724169](https://github.com/angular/angular/commit/9724169)), closes [#36619](https://github.com/angular/angular/issues/36619)
|
||||||
* **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([5bab498](https://github.com/angular/angular/commit/5bab498))
|
* **language-service:** properly evaluate types in comparable expressions ([#36529](https://github.com/angular/angular/issues/36529)) ([5bab498](https://github.com/angular/angular/commit/5bab498))
|
||||||
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596/issues/issuecomment-250890218)
|
* **ngcc:** display unlocker process output in sync mode ([#36637](https://github.com/angular/angular/issues/36637)) ([da159bd](https://github.com/angular/angular/commit/da159bd)), closes [/github.com/nodejs/node/issues/3596#issuecomment-250890218](https://github.com/nodejs/node/issues/3596#issuecomment-250890218)
|
||||||
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860/issues/issuecomment-614694269)
|
* **ngcc:** do not use cached file-system ([#36687](https://github.com/angular/angular/issues/36687)) ([18be33a](https://github.com/angular/angular/commit/18be33a)), closes [/github.com/angular/angular-cli/issues/16860#issuecomment-614694269](https://github.com/angular/angular-cli/issues/16860#issuecomment-614694269)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -804,7 +567,7 @@ This release contains various API docs improvements.
|
|||||||
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([a67afcc](https://github.com/angular/angular/commit/a67afcc)), closes [#36492](https://github.com/angular/angular/issues/36492)
|
* **upgrade:** update $locationShim to handle Location changes before initialization ([#36498](https://github.com/angular/angular/issues/36498)) ([a67afcc](https://github.com/angular/angular/commit/a67afcc)), closes [#36492](https://github.com/angular/angular/issues/36492)
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular/issues/issuecomment-608401834)
|
* **ngcc:** only load if it is needed ([#36486](https://github.com/angular/angular/issues/36486)) ([e06512b](https://github.com/angular/angular/commit/e06512b)) * **ngcc:** read dependencies from entry-point manifest ([#36486](https://github.com/angular/angular/issues/36486)) ([918e628](https://github.com/angular/angular/commit/918e628)), closes [#issuecomment-608401834](https://github.com/angular/angular#issuecomment-608401834)
|
||||||
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([603b094](https://github.com/angular/angular/commit/603b094))
|
* **ngcc:** reduce the size of the entry-point manifest file ([#36486](https://github.com/angular/angular/issues/36486)) ([603b094](https://github.com/angular/angular/commit/603b094))
|
||||||
|
|
||||||
|
|
||||||
@ -824,7 +587,7 @@ This release contains various API docs improvements.
|
|||||||
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([a631b99](https://github.com/angular/angular/commit/a631b99))
|
* **core:** undecorated-classes migration should handle derived abstract classes ([#35339](https://github.com/angular/angular/issues/35339)) ([a631b99](https://github.com/angular/angular/commit/a631b99))
|
||||||
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([ff523c9](https://github.com/angular/angular/commit/ff523c9)), closes [#36191](https://github.com/angular/angular/issues/36191)
|
* **language-service:** infer type of elements of array-like objects ([#36312](https://github.com/angular/angular/issues/36312)) ([ff523c9](https://github.com/angular/angular/commit/ff523c9)), closes [#36191](https://github.com/angular/angular/issues/36191)
|
||||||
* **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([ffa4e11](https://github.com/angular/angular/commit/ffa4e11))
|
* **language-service:** use the `HtmlAst` to get the span of HTML tag ([#36371](https://github.com/angular/angular/issues/36371)) ([ffa4e11](https://github.com/angular/angular/commit/ffa4e11))
|
||||||
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [/github.com/angular/angular/issues/36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414/issues/issuecomment-609644282)
|
* **ngcc:** add process title ([#36448](https://github.com/angular/angular/issues/36448)) ([136596d](https://github.com/angular/angular/commit/136596d)), closes [36414#issuecomment-609644282](https://github.com/angular/angular/issues/36414#issuecomment-609644282)
|
||||||
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([cb0a2a0](https://github.com/angular/angular/commit/cb0a2a0))
|
* **ngcc:** allow ngcc configuration to match pre-release versions of packages ([#36370](https://github.com/angular/angular/issues/36370)) ([cb0a2a0](https://github.com/angular/angular/commit/cb0a2a0))
|
||||||
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([879457c](https://github.com/angular/angular/commit/879457c)), closes [#36089](https://github.com/angular/angular/issues/36089)
|
* **ngcc:** correctly detect imported TypeScript helpers ([#36284](https://github.com/angular/angular/issues/36284)) ([879457c](https://github.com/angular/angular/commit/879457c)), closes [#36089](https://github.com/angular/angular/issues/36089)
|
||||||
* **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([0daa488](https://github.com/angular/angular/commit/0daa488))
|
* **ngcc:** correctly identify relative Windows-style import paths ([#36372](https://github.com/angular/angular/issues/36372)) ([0daa488](https://github.com/angular/angular/commit/0daa488))
|
||||||
@ -901,9 +664,12 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([17cf04e](https://github.com/angular/angular/commit/17cf04e))
|
* **animations:** allow computeStyle to work on elements created in Node ([#35810](https://github.com/angular/angular/issues/35810)) ([17cf04e](https://github.com/angular/angular/commit/17cf04e))
|
||||||
* **animations:** false positive when detecting Node in Webpack builds ([#35134](https://github.com/angular/angular/issues/35134)) ([dc4ae4b](https://github.com/angular/angular/commit/dc4ae4b)), closes [#35117](https://github.com/angular/angular/issues/35117)
|
* **animations:** false positive when detecting Node in Webpack builds ([#35134](https://github.com/angular/angular/issues/35134)) ([dc4ae4b](https://github.com/angular/angular/commit/dc4ae4b)), closes [#35117](https://github.com/angular/angular/issues/35117)
|
||||||
* **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([35c9f0d](https://github.com/angular/angular/commit/35c9f0d)), closes [#35463](https://github.com/angular/angular/issues/35463)
|
* **animations:** process shorthand `margin` and `padding` styles correctly ([#35701](https://github.com/angular/angular/issues/35701)) ([35c9f0d](https://github.com/angular/angular/commit/35c9f0d)), closes [#35463](https://github.com/angular/angular/issues/35463)
|
||||||
|
* **bazel:** devserver shows blank page in Windows ([#35159](https://github.com/angular/angular/issues/35159)) ([727f92f](https://github.com/angular/angular/commit/727f92f))
|
||||||
* **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([9581658](https://github.com/angular/angular/commit/9581658))
|
* **bazel:** do not use manifest paths for generated imports within compilation unit ([#35841](https://github.com/angular/angular/issues/35841)) ([9581658](https://github.com/angular/angular/commit/9581658))
|
||||||
* **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([5c2a908](https://github.com/angular/angular/commit/5c2a908)), closes [angular/components#18652](https://github.com/angular/components/issues/18652)
|
* **bazel:** ng_package rule creates incorrect UMD module exports ([#35792](https://github.com/angular/angular/issues/35792)) ([5c2a908](https://github.com/angular/angular/commit/5c2a908)), closes [angular/components#18652](https://github.com/angular/components/issues/18652)
|
||||||
* **bazel:** prod server doesn't serve files in windows ([#35991](https://github.com/angular/angular/issues/35991)) ([96e3449](https://github.com/angular/angular/commit/96e3449))
|
* **bazel:** prod server doesn't serve files in windows ([#35991](https://github.com/angular/angular/issues/35991)) ([96e3449](https://github.com/angular/angular/commit/96e3449))
|
||||||
|
* **bazel:** spawn prod server using port 4200 ([#35160](https://github.com/angular/angular/issues/35160)) ([829f506](https://github.com/angular/angular/commit/829f506))
|
||||||
|
* **bazel:** update ibazel to 0.11.1 ([#35158](https://github.com/angular/angular/issues/35158)) ([4e6d237](https://github.com/angular/angular/commit/4e6d237))
|
||||||
* **bazel:** update several packages for better windows support ([#35991](https://github.com/angular/angular/issues/35991)) ([32f099a](https://github.com/angular/angular/commit/32f099a))
|
* **bazel:** update several packages for better windows support ([#35991](https://github.com/angular/angular/issues/35991)) ([32f099a](https://github.com/angular/angular/commit/32f099a))
|
||||||
* **bazel:** update typescript peer dependency range ([#36013](https://github.com/angular/angular/issues/36013)) ([5e3a898](https://github.com/angular/angular/commit/5e3a898))
|
* **bazel:** update typescript peer dependency range ([#36013](https://github.com/angular/angular/issues/36013)) ([5e3a898](https://github.com/angular/angular/commit/5e3a898))
|
||||||
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([407fa42](https://github.com/angular/angular/commit/407fa42)), closes [#35743](https://github.com/angular/angular/issues/35743)
|
* **common:** let `KeyValuePipe` accept type unions with `null` ([#36093](https://github.com/angular/angular/issues/36093)) ([407fa42](https://github.com/angular/angular/commit/407fa42)), closes [#35743](https://github.com/angular/angular/issues/35743)
|
||||||
@ -912,6 +678,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([2ce5fa3](https://github.com/angular/angular/commit/2ce5fa3))
|
* **compiler:** Propagate value span of ExpressionBinding to ParsedProperty ([#36133](https://github.com/angular/angular/issues/36133)) ([2ce5fa3](https://github.com/angular/angular/commit/2ce5fa3))
|
||||||
* **compiler:** do not recurse to find static symbols of same module ([#35262](https://github.com/angular/angular/issues/35262)) ([e179c58](https://github.com/angular/angular/commit/e179c58))
|
* **compiler:** do not recurse to find static symbols of same module ([#35262](https://github.com/angular/angular/issues/35262)) ([e179c58](https://github.com/angular/angular/commit/e179c58))
|
||||||
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
|
* **compiler:** record correct end of expression ([#34690](https://github.com/angular/angular/issues/34690)) ([df890d7](https://github.com/angular/angular/commit/df890d7)), closes [#33477](https://github.com/angular/angular/issues/33477)
|
||||||
|
* **compiler:** report errors for missing binding names ([#34595](https://github.com/angular/angular/issues/34595)) ([d13cab7](https://github.com/angular/angular/commit/d13cab7))
|
||||||
* **compiler:** support directive inputs with interpolations on `<ng-template>`s ([#35984](https://github.com/angular/angular/issues/35984)) ([79659ee](https://github.com/angular/angular/commit/79659ee)), closes [#35752](https://github.com/angular/angular/issues/35752)
|
* **compiler:** support directive inputs with interpolations on `<ng-template>`s ([#35984](https://github.com/angular/angular/issues/35984)) ([79659ee](https://github.com/angular/angular/commit/79659ee)), closes [#35752](https://github.com/angular/angular/issues/35752)
|
||||||
* **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([40da51f](https://github.com/angular/angular/commit/40da51f))
|
* **compiler:** support i18n attributes on `<ng-template>` tags ([#35681](https://github.com/angular/angular/issues/35681)) ([40da51f](https://github.com/angular/angular/commit/40da51f))
|
||||||
* **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([2c41bb8](https://github.com/angular/angular/commit/2c41bb8)), closes [#35186](https://github.com/angular/angular/issues/35186)
|
* **compiler:** type-checking error for duplicate variables in templates ([#35674](https://github.com/angular/angular/issues/35674)) ([2c41bb8](https://github.com/angular/angular/commit/2c41bb8)), closes [#35186](https://github.com/angular/angular/issues/35186)
|
||||||
@ -949,13 +716,19 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([f71d132](https://github.com/angular/angular/commit/f71d132))
|
* **core:** workaround Terser inlining bug ([#36200](https://github.com/angular/angular/issues/36200)) ([f71d132](https://github.com/angular/angular/commit/f71d132))
|
||||||
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([e066bdd](https://github.com/angular/angular/commit/e066bdd))
|
* **elements:** correctly handle setting inputs to `undefined` ([#36140](https://github.com/angular/angular/issues/36140)) ([e066bdd](https://github.com/angular/angular/commit/e066bdd))
|
||||||
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([447a600](https://github.com/angular/angular/commit/447a600)), closes [#36130](https://github.com/angular/angular/issues/36130)
|
* **elements:** correctly set `SimpleChange#firstChange` for pre-existing inputs ([#36140](https://github.com/angular/angular/issues/36140)) ([447a600](https://github.com/angular/angular/commit/447a600)), closes [#36130](https://github.com/angular/angular/issues/36130)
|
||||||
|
* **elements:** schematics fail with schema.json not found error ([#35211](https://github.com/angular/angular/issues/35211)) ([94d002b](https://github.com/angular/angular/commit/94d002b)), closes [#35154](https://github.com/angular/angular/issues/35154)
|
||||||
|
* **forms:** change Array.reduce usage to Array.forEach ([#35349](https://github.com/angular/angular/issues/35349)) ([554c2cb](https://github.com/angular/angular/commit/554c2cb))
|
||||||
* **ivy:** `LFrame` needs to release memory on `leaveView()` ([#35156](https://github.com/angular/angular/issues/35156)) ([b9b512f](https://github.com/angular/angular/commit/b9b512f)), closes [#35148](https://github.com/angular/angular/issues/35148)
|
* **ivy:** `LFrame` needs to release memory on `leaveView()` ([#35156](https://github.com/angular/angular/issues/35156)) ([b9b512f](https://github.com/angular/angular/commit/b9b512f)), closes [#35148](https://github.com/angular/angular/issues/35148)
|
||||||
* **ivy:** add attributes and classes to host elements based on selector ([#34481](https://github.com/angular/angular/issues/34481)) ([f95b8ce](https://github.com/angular/angular/commit/f95b8ce))
|
* **ivy:** add attributes and classes to host elements based on selector ([#34481](https://github.com/angular/angular/issues/34481)) ([f95b8ce](https://github.com/angular/angular/commit/f95b8ce))
|
||||||
|
* **ivy:** ensure module imports are instantiated before the module being declared ([#35172](https://github.com/angular/angular/issues/35172)) ([b6a3a73](https://github.com/angular/angular/commit/b6a3a73))
|
||||||
* **ivy:** error if directive with synthetic property binding is on same node as directive that injects ViewContainerRef ([#35343](https://github.com/angular/angular/issues/35343)) ([d6bc63f](https://github.com/angular/angular/commit/d6bc63f)), closes [#35342](https://github.com/angular/angular/issues/35342)
|
* **ivy:** error if directive with synthetic property binding is on same node as directive that injects ViewContainerRef ([#35343](https://github.com/angular/angular/issues/35343)) ([d6bc63f](https://github.com/angular/angular/commit/d6bc63f)), closes [#35342](https://github.com/angular/angular/issues/35342)
|
||||||
* **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([40039d8](https://github.com/angular/angular/commit/40039d8)), closes [#34572](https://github.com/angular/angular/issues/34572)
|
* **ivy:** narrow `NgIf` context variables in template type checker ([#35125](https://github.com/angular/angular/issues/35125)) ([40039d8](https://github.com/angular/angular/commit/40039d8)), closes [#34572](https://github.com/angular/angular/issues/34572)
|
||||||
* **ivy:** queries should match elements inside ng-container with the descendants: false option ([#35384](https://github.com/angular/angular/issues/35384)) ([3f4e02b](https://github.com/angular/angular/commit/3f4e02b)), closes [#34768](https://github.com/angular/angular/issues/34768)
|
* **ivy:** queries should match elements inside ng-container with the descendants: false option ([#35384](https://github.com/angular/angular/issues/35384)) ([3f4e02b](https://github.com/angular/angular/commit/3f4e02b)), closes [#34768](https://github.com/angular/angular/issues/34768)
|
||||||
|
* **ivy:** repeat template guards to narrow types in event handlers ([#35193](https://github.com/angular/angular/issues/35193)) ([dea1b96](https://github.com/angular/angular/commit/dea1b96)), closes [#35073](https://github.com/angular/angular/issues/35073)
|
||||||
|
* **ivy:** set namespace for host elements of dynamically created components ([#35136](https://github.com/angular/angular/issues/35136)) ([480a4c3](https://github.com/angular/angular/commit/480a4c3))
|
||||||
* **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([3e3a1ef](https://github.com/angular/angular/commit/3e3a1ef)), closes [#34267](https://github.com/angular/angular/issues/34267)
|
* **ivy:** support dynamic query tokens in AOT mode ([#35307](https://github.com/angular/angular/issues/35307)) ([3e3a1ef](https://github.com/angular/angular/commit/3e3a1ef)), closes [#34267](https://github.com/angular/angular/issues/34267)
|
||||||
* **ivy:** wrong context passed to ngOnDestroy when resolved multiple times ([#35249](https://github.com/angular/angular/issues/35249)) ([5fbfe69](https://github.com/angular/angular/commit/5fbfe69)), closes [#35167](https://github.com/angular/angular/issues/35167)
|
* **ivy:** wrong context passed to ngOnDestroy when resolved multiple times ([#35249](https://github.com/angular/angular/issues/35249)) ([5fbfe69](https://github.com/angular/angular/commit/5fbfe69)), closes [#35167](https://github.com/angular/angular/issues/35167)
|
||||||
|
* **language-service:** Suggest ? and ! operator on nullable receiver ([#35200](https://github.com/angular/angular/issues/35200)) ([3cc24a9](https://github.com/angular/angular/commit/3cc24a9))
|
||||||
* **language-service:** fix calculation of pipe spans ([#35986](https://github.com/angular/angular/issues/35986)) ([406419b](https://github.com/angular/angular/commit/406419b))
|
* **language-service:** fix calculation of pipe spans ([#35986](https://github.com/angular/angular/issues/35986)) ([406419b](https://github.com/angular/angular/commit/406419b))
|
||||||
* **language-service:** get the right 'ElementAst' in the nested HTML tag ([#35317](https://github.com/angular/angular/issues/35317)) ([8e354da](https://github.com/angular/angular/commit/8e354da))
|
* **language-service:** get the right 'ElementAst' in the nested HTML tag ([#35317](https://github.com/angular/angular/issues/35317)) ([8e354da](https://github.com/angular/angular/commit/8e354da))
|
||||||
* **language-service:** infer $implicit value for ngIf template contexts ([#35941](https://github.com/angular/angular/issues/35941)) ([18b1bd4](https://github.com/angular/angular/commit/18b1bd4))
|
* **language-service:** infer $implicit value for ngIf template contexts ([#35941](https://github.com/angular/angular/issues/35941)) ([18b1bd4](https://github.com/angular/angular/commit/18b1bd4))
|
||||||
@ -980,6 +753,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([fde8915](https://github.com/angular/angular/commit/fde8915)), closes [#35399](https://github.com/angular/angular/issues/35399)
|
* **ngcc:** correctly detect outer aliased class identifiers in ES5 ([#35527](https://github.com/angular/angular/issues/35527)) ([fde8915](https://github.com/angular/angular/commit/fde8915)), closes [#35399](https://github.com/angular/angular/issues/35399)
|
||||||
* **ngcc:** do not crash on entry-point that fails to compile ([#36083](https://github.com/angular/angular/issues/36083)) ([ff665b9](https://github.com/angular/angular/commit/ff665b9))
|
* **ngcc:** do not crash on entry-point that fails to compile ([#36083](https://github.com/angular/angular/issues/36083)) ([ff665b9](https://github.com/angular/angular/commit/ff665b9))
|
||||||
* **ngcc:** do not crash on overlapping entry-points ([#36083](https://github.com/angular/angular/issues/36083)) ([c9f554c](https://github.com/angular/angular/commit/c9f554c))
|
* **ngcc:** do not crash on overlapping entry-points ([#36083](https://github.com/angular/angular/issues/36083)) ([c9f554c](https://github.com/angular/angular/commit/c9f554c))
|
||||||
|
* **ngcc:** ensure that path-mapped secondary entry-points are processed correctly ([#35227](https://github.com/angular/angular/issues/35227)) ([c3c1140](https://github.com/angular/angular/commit/c3c1140)), closes [#35188](https://github.com/angular/angular/issues/35188)
|
||||||
* **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([b6e8847](https://github.com/angular/angular/commit/b6e8847)), closes [#34356](https://github.com/angular/angular/issues/34356)
|
* **ngcc:** handle imports in dts files when processing CommonJS ([#35191](https://github.com/angular/angular/issues/35191)) ([b6e8847](https://github.com/angular/angular/commit/b6e8847)), closes [#34356](https://github.com/angular/angular/issues/34356)
|
||||||
* **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([73cf7d5](https://github.com/angular/angular/commit/73cf7d5)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
* **ngcc:** handle mappings outside the content when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([73cf7d5](https://github.com/angular/angular/commit/73cf7d5)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
||||||
* **ngcc:** handle missing sources when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([72c4fda](https://github.com/angular/angular/commit/72c4fda)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
* **ngcc:** handle missing sources when flattening source-maps ([#35718](https://github.com/angular/angular/issues/35718)) ([72c4fda](https://github.com/angular/angular/commit/72c4fda)), closes [#35709](https://github.com/angular/angular/issues/35709)
|
||||||
@ -1237,7 +1011,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **compiler-cli:** require node 10 as runtime engine ([#34722](https://github.com/angular/angular/issues/34722)) ([7b77b3d](https://github.com/angular/angular/commit/7b77b3d))
|
* **compiler-cli:** require node 10 as runtime engine ([#34722](https://github.com/angular/angular/issues/34722)) ([7b77b3d](https://github.com/angular/angular/commit/7b77b3d))
|
||||||
* **language-service:** specific suggestions for template context diags ([#34751](https://github.com/angular/angular/issues/34751)) ([cc7fca4](https://github.com/angular/angular/commit/cc7fca4))
|
* **language-service:** specific suggestions for template context diags ([#34751](https://github.com/angular/angular/issues/34751)) ([cc7fca4](https://github.com/angular/angular/commit/cc7fca4))
|
||||||
* **language-service:** support multiple symbol definitions ([#34782](https://github.com/angular/angular/issues/34782)) ([2f2396c](https://github.com/angular/angular/commit/2f2396c))
|
* **language-service:** support multiple symbol definitions ([#34782](https://github.com/angular/angular/issues/34782)) ([2f2396c](https://github.com/angular/angular/commit/2f2396c))
|
||||||
* **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [/github.com/angular/angular/issues/32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431/issues/issuecomment-571825781)
|
* **ngcc:** lock ngcc when processing ([#34722](https://github.com/angular/angular/issues/34722)) ([6dd51f1](https://github.com/angular/angular/commit/6dd51f1)), closes [32431#issuecomment-571825781](https://github.com/angular/angular/issues/32431#issuecomment-571825781)
|
||||||
* work around 'noImplicityAny' incompatibility due to ts3.7 update ([#34798](https://github.com/angular/angular/issues/34798)) ([251d548](https://github.com/angular/angular/commit/251d548))
|
* work around 'noImplicityAny' incompatibility due to ts3.7 update ([#34798](https://github.com/angular/angular/issues/34798)) ([251d548](https://github.com/angular/angular/commit/251d548))
|
||||||
* **animations:** not waiting for child animations to finish when removing parent in Ivy ([#34702](https://github.com/angular/angular/issues/34702)) ([92c17fe](https://github.com/angular/angular/commit/92c17fe)), closes [#33597](https://github.com/angular/angular/issues/33597)
|
* **animations:** not waiting for child animations to finish when removing parent in Ivy ([#34702](https://github.com/angular/angular/issues/34702)) ([92c17fe](https://github.com/angular/angular/commit/92c17fe)), closes [#33597](https://github.com/angular/angular/issues/33597)
|
||||||
* **common:** ensure diffing in ngStyle/ngClass correctly emits value changes ([#34307](https://github.com/angular/angular/issues/34307)) ([93a035f](https://github.com/angular/angular/commit/93a035f)), closes [#34336](https://github.com/angular/angular/issues/34336) [#34444](https://github.com/angular/angular/issues/34444)
|
* **common:** ensure diffing in ngStyle/ngClass correctly emits value changes ([#34307](https://github.com/angular/angular/issues/34307)) ([93a035f](https://github.com/angular/angular/commit/93a035f)), closes [#34336](https://github.com/angular/angular/issues/34336) [#34444](https://github.com/angular/angular/issues/34444)
|
||||||
@ -1368,7 +1142,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d))
|
* **ngcc:** do not output duplicate ɵprov properties ([#34085](https://github.com/angular/angular/issues/34085)) ([5a8d25d](https://github.com/angular/angular/commit/5a8d25d))
|
||||||
* **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa))
|
* **ngcc:** render localized strings when in ES5 format ([#33857](https://github.com/angular/angular/issues/33857)) ([c6695fa](https://github.com/angular/angular/commit/c6695fa))
|
||||||
* **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8))
|
* **ngcc:** render UMD global imports correctly ([#34012](https://github.com/angular/angular/issues/34012)) ([83989b8](https://github.com/angular/angular/commit/83989b8))
|
||||||
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [/github.com/angular/angular/issues/33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685/issues/issuecomment-557091719)
|
* **ngcc:** report errors from `analyze` and `resolve` processing ([#33964](https://github.com/angular/angular/issues/33964)) ([ca5d772](https://github.com/angular/angular/commit/ca5d772)), closes [33685#issuecomment-557091719](https://github.com/angular/angular/issues/33685#issuecomment-557091719)
|
||||||
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223)
|
* **router:** make routerLinkActive work with query params which contain arrays ([#22666](https://github.com/angular/angular/issues/22666)) ([f1bf5b2](https://github.com/angular/angular/commit/f1bf5b2)), closes [#22223](https://github.com/angular/angular/issues/22223)
|
||||||
* **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793)
|
* **service-worker:** allow creating post api requests after cache failure ([#33930](https://github.com/angular/angular/issues/33930)) ([63c9123](https://github.com/angular/angular/commit/63c9123)), closes [#33793](https://github.com/angular/angular/issues/33793)
|
||||||
* **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd))
|
* **service-worker:** throw when using the unsupported `versionedFiles` option in config ([#33903](https://github.com/angular/angular/issues/33903)) ([250e6fd](https://github.com/angular/angular/commit/250e6fd))
|
||||||
@ -1447,7 +1221,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **language-service:** Should not crash if expr ends unexpectedly ([#33524](https://github.com/angular/angular/issues/33524)) ([9ebac71](https://github.com/angular/angular/commit/9ebac71))
|
* **language-service:** Should not crash if expr ends unexpectedly ([#33524](https://github.com/angular/angular/issues/33524)) ([9ebac71](https://github.com/angular/angular/commit/9ebac71))
|
||||||
* **ngcc:** handle new `__spreadArrays` tslib helper ([#33617](https://github.com/angular/angular/issues/33617)) ([d749dd3](https://github.com/angular/angular/commit/d749dd3)), closes [#33614](https://github.com/angular/angular/issues/33614)
|
* **ngcc:** handle new `__spreadArrays` tslib helper ([#33617](https://github.com/angular/angular/issues/33617)) ([d749dd3](https://github.com/angular/angular/commit/d749dd3)), closes [#33614](https://github.com/angular/angular/issues/33614)
|
||||||
* **ngcc:** override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 ([#33533](https://github.com/angular/angular/issues/33533)) ([93a23b9](https://github.com/angular/angular/commit/93a23b9))
|
* **ngcc:** override `getInternalNameOfClass()` and `getAdjacentNameOfClass()` for ES5 ([#33533](https://github.com/angular/angular/issues/33533)) ([93a23b9](https://github.com/angular/angular/commit/93a23b9))
|
||||||
* **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337/issues/issuecomment-545487737)
|
* **ngcc:** render adjacent statements after static properties ([#33630](https://github.com/angular/angular/issues/33630)) ([fe12d0d](https://github.com/angular/angular/commit/fe12d0d)), closes [/github.com/angular/angular/pull/33337#issuecomment-545487737](https://github.com/angular/angular/pull/33337#issuecomment-545487737)
|
||||||
* **ngcc:** render new definitions using the inner name of the class ([#33533](https://github.com/angular/angular/issues/33533)) ([85298e3](https://github.com/angular/angular/commit/85298e3))
|
* **ngcc:** render new definitions using the inner name of the class ([#33533](https://github.com/angular/angular/issues/33533)) ([85298e3](https://github.com/angular/angular/commit/85298e3))
|
||||||
* **service-worker:** ensure initialization before handling messages ([#32525](https://github.com/angular/angular/issues/32525)) ([72eba77](https://github.com/angular/angular/commit/72eba77)), closes [#25611](https://github.com/angular/angular/issues/25611)
|
* **service-worker:** ensure initialization before handling messages ([#32525](https://github.com/angular/angular/issues/32525)) ([72eba77](https://github.com/angular/angular/commit/72eba77)), closes [#25611](https://github.com/angular/angular/issues/25611)
|
||||||
* **compiler:** i18n - ignore `alt-trans` tags in XLIFF 1.2 ([#33450](https://github.com/angular/angular/issues/33450)) ([936700a](https://github.com/angular/angular/commit/936700a)), closes [#33161](https://github.com/angular/angular/issues/33161)
|
* **compiler:** i18n - ignore `alt-trans` tags in XLIFF 1.2 ([#33450](https://github.com/angular/angular/issues/33450)) ([936700a](https://github.com/angular/angular/commit/936700a)), closes [#33161](https://github.com/angular/angular/issues/33161)
|
||||||
@ -1477,7 +1251,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **language-service:** Add directive selectors & banana-in-a-box to completions ([#33311](https://github.com/angular/angular/issues/33311)) ([49eec5d](https://github.com/angular/angular/commit/49eec5d))
|
* **language-service:** Add directive selectors & banana-in-a-box to completions ([#33311](https://github.com/angular/angular/issues/33311)) ([49eec5d](https://github.com/angular/angular/commit/49eec5d))
|
||||||
* **language-service:** Add global symbol for $any() ([#33245](https://github.com/angular/angular/issues/33245)) ([3f257e9](https://github.com/angular/angular/commit/3f257e9))
|
* **language-service:** Add global symbol for $any() ([#33245](https://github.com/angular/angular/issues/33245)) ([3f257e9](https://github.com/angular/angular/commit/3f257e9))
|
||||||
* **language-service:** Preserve CRLF in templates for language-service ([#33241](https://github.com/angular/angular/issues/33241)) ([65a0d2b](https://github.com/angular/angular/commit/65a0d2b))
|
* **language-service:** Preserve CRLF in templates for language-service ([#33241](https://github.com/angular/angular/issues/33241)) ([65a0d2b](https://github.com/angular/angular/commit/65a0d2b))
|
||||||
* **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049/issues/issuecomment-540485703)
|
* **ngcc:** do not fail when multiple workers try to create the same directory ([#33237](https://github.com/angular/angular/issues/33237)) ([8017229](https://github.com/angular/angular/commit/8017229)), closes [/github.com/angular/angular/pull/33049#issuecomment-540485703](https://github.com/angular/angular/pull/33049#issuecomment-540485703)
|
||||||
* **bazel:** Remove angular devkit and restore ngc postinstall ([#32946](https://github.com/angular/angular/issues/32946)) ([f036684](https://github.com/angular/angular/commit/f036684))
|
* **bazel:** Remove angular devkit and restore ngc postinstall ([#32946](https://github.com/angular/angular/issues/32946)) ([f036684](https://github.com/angular/angular/commit/f036684))
|
||||||
* **common:** remove deprecated support for intl API ([#29250](https://github.com/angular/angular/issues/29250)) ([9e7668f](https://github.com/angular/angular/commit/9e7668f)), closes [#18284](https://github.com/angular/angular/issues/18284)
|
* **common:** remove deprecated support for intl API ([#29250](https://github.com/angular/angular/issues/29250)) ([9e7668f](https://github.com/angular/angular/commit/9e7668f)), closes [#18284](https://github.com/angular/angular/issues/18284)
|
||||||
* **compiler:** absolute source span for template attribute expressions ([#33189](https://github.com/angular/angular/issues/33189)) ([fd4fed1](https://github.com/angular/angular/commit/fd4fed1))
|
* **compiler:** absolute source span for template attribute expressions ([#33189](https://github.com/angular/angular/issues/33189)) ([fd4fed1](https://github.com/angular/angular/commit/fd4fed1))
|
||||||
@ -1534,7 +1308,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **language-service:** Turn on strict mode for test project ([#32783](https://github.com/angular/angular/issues/32783)) ([28358b6](https://github.com/angular/angular/commit/28358b6))
|
* **language-service:** Turn on strict mode for test project ([#32783](https://github.com/angular/angular/issues/32783)) ([28358b6](https://github.com/angular/angular/commit/28358b6))
|
||||||
* **ngcc:** ensure private exports are added for `ModuleWithProviders` ([#32902](https://github.com/angular/angular/issues/32902)) ([002a97d](https://github.com/angular/angular/commit/002a97d))
|
* **ngcc:** ensure private exports are added for `ModuleWithProviders` ([#32902](https://github.com/angular/angular/issues/32902)) ([002a97d](https://github.com/angular/angular/commit/002a97d))
|
||||||
* **ngcc:** handle presence of both `ctorParameters` and `__decorate` ([#32901](https://github.com/angular/angular/issues/32901)) ([747f0cf](https://github.com/angular/angular/commit/747f0cf))
|
* **ngcc:** handle presence of both `ctorParameters` and `__decorate` ([#32901](https://github.com/angular/angular/issues/32901)) ([747f0cf](https://github.com/angular/angular/commit/747f0cf))
|
||||||
* **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [/github.com/angular/angular/issues/31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354/issues/issuecomment-532080537)
|
* **ngcc:** make the build-marker error more clear ([#32712](https://github.com/angular/angular/issues/32712)) ([0ea4875](https://github.com/angular/angular/commit/0ea4875)), closes [31354#issuecomment-532080537](https://github.com/angular/angular/issues/31354#issuecomment-532080537)
|
||||||
* **upgrade:** fix AngularJsUrlCodec to support Safari ([#32959](https://github.com/angular/angular/issues/32959)) ([39e8ceb](https://github.com/angular/angular/commit/39e8ceb))
|
* **upgrade:** fix AngularJsUrlCodec to support Safari ([#32959](https://github.com/angular/angular/issues/32959)) ([39e8ceb](https://github.com/angular/angular/commit/39e8ceb))
|
||||||
* **ivy:** ensure `window.ng.getDebugNode` returns debug info for component elements ([#32780](https://github.com/angular/angular/issues/32780)) ([5651fa3](https://github.com/angular/angular/commit/5651fa3))
|
* **ivy:** ensure `window.ng.getDebugNode` returns debug info for component elements ([#32780](https://github.com/angular/angular/issues/32780)) ([5651fa3](https://github.com/angular/angular/commit/5651fa3))
|
||||||
* **ivy:** ensure multiple map-based bindings do not skip intermediate values ([#32774](https://github.com/angular/angular/issues/32774)) ([86fd571](https://github.com/angular/angular/commit/86fd571))
|
* **ivy:** ensure multiple map-based bindings do not skip intermediate values ([#32774](https://github.com/angular/angular/issues/32774)) ([86fd571](https://github.com/angular/angular/commit/86fd571))
|
||||||
@ -1643,7 +1417,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** graceful evaluation of unknown or invalid expressions ([#33453](https://github.com/angular/angular/issues/33453)) ([ce30888](https://github.com/angular/angular/commit/ce30888))
|
* **ivy:** graceful evaluation of unknown or invalid expressions ([#33453](https://github.com/angular/angular/issues/33453)) ([ce30888](https://github.com/angular/angular/commit/ce30888))
|
||||||
* **ivy:** implement unknown element detection in jit mode ([#33419](https://github.com/angular/angular/issues/33419)) ([c83f501](https://github.com/angular/angular/commit/c83f501))
|
* **ivy:** implement unknown element detection in jit mode ([#33419](https://github.com/angular/angular/issues/33419)) ([c83f501](https://github.com/angular/angular/commit/c83f501))
|
||||||
* add a flag in bootstrap to enable coalesce event change detection to improve performance ([#30533](https://github.com/angular/angular/issues/30533)) ([44623a1](https://github.com/angular/angular/commit/44623a1))
|
* add a flag in bootstrap to enable coalesce event change detection to improve performance ([#30533](https://github.com/angular/angular/issues/30533)) ([44623a1](https://github.com/angular/angular/commit/44623a1))
|
||||||
* **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367/issues/issuecomment-547643246)
|
* **bazel:** update [@bazel](https://github.com/bazel)/schematics to Bazel 1.0.0 ([#33476](https://github.com/angular/angular/issues/33476)) ([540d104](https://github.com/angular/angular/commit/540d104)), closes [/github.com/angular/angular/pull/33367#issuecomment-547643246](https://github.com/angular/angular/pull/33367#issuecomment-547643246)
|
||||||
* **bazel:** update bazel-schematics to use Ivy and new rollup_bundle ([#33435](https://github.com/angular/angular/issues/33435)) ([bf913cc](https://github.com/angular/angular/commit/bf913cc))
|
* **bazel:** update bazel-schematics to use Ivy and new rollup_bundle ([#33435](https://github.com/angular/angular/issues/33435)) ([bf913cc](https://github.com/angular/angular/commit/bf913cc))
|
||||||
* **ivy:** i18n - support inlining of XTB formatted translation files ([#33444](https://github.com/angular/angular/issues/33444)) ([2c623fd](https://github.com/angular/angular/commit/2c623fd))
|
* **ivy:** i18n - support inlining of XTB formatted translation files ([#33444](https://github.com/angular/angular/issues/33444)) ([2c623fd](https://github.com/angular/angular/commit/2c623fd))
|
||||||
* **language-service:** add support for text replacement ([#33091](https://github.com/angular/angular/issues/33091)) ([da4eb91](https://github.com/angular/angular/commit/da4eb91))
|
* **language-service:** add support for text replacement ([#33091](https://github.com/angular/angular/issues/33091)) ([da4eb91](https://github.com/angular/angular/commit/da4eb91))
|
||||||
@ -1685,7 +1459,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **ivy:** i18n - implement compile-time inlining ([#32881](https://github.com/angular/angular/issues/32881)) ([2cdb3a0](https://github.com/angular/angular/commit/2cdb3a0))
|
* **ivy:** i18n - implement compile-time inlining ([#32881](https://github.com/angular/angular/issues/32881)) ([2cdb3a0](https://github.com/angular/angular/commit/2cdb3a0))
|
||||||
* **ivy:** i18n - render legacy message ids in `$localize` if requested ([#32937](https://github.com/angular/angular/issues/32937)) ([bcbf3e4](https://github.com/angular/angular/commit/bcbf3e4))
|
* **ivy:** i18n - render legacy message ids in `$localize` if requested ([#32937](https://github.com/angular/angular/issues/32937)) ([bcbf3e4](https://github.com/angular/angular/commit/bcbf3e4))
|
||||||
* **language-service:** module definitions on directive hover ([#32763](https://github.com/angular/angular/issues/32763)) ([0d186dd](https://github.com/angular/angular/commit/0d186dd)), closes [#32565](https://github.com/angular/angular/issues/32565)
|
* **language-service:** module definitions on directive hover ([#32763](https://github.com/angular/angular/issues/32763)) ([0d186dd](https://github.com/angular/angular/commit/0d186dd)), closes [#32565](https://github.com/angular/angular/issues/32565)
|
||||||
* **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999/issues/issuecomment-539937368)
|
* **ngcc:** expose `--create-ivy-entry-points` option on ivy-ngcc ([#33049](https://github.com/angular/angular/issues/33049)) ([b2b917d](https://github.com/angular/angular/commit/b2b917d)), closes [/github.com/angular/angular/pull/32999#issuecomment-539937368](https://github.com/angular/angular/pull/32999#issuecomment-539937368)
|
||||||
* update rxjs peerDependencies minimum requirment to 6.5.3 ([#32812](https://github.com/angular/angular/issues/32812)) ([66658c4](https://github.com/angular/angular/commit/66658c4))
|
* update rxjs peerDependencies minimum requirment to 6.5.3 ([#32812](https://github.com/angular/angular/issues/32812)) ([66658c4](https://github.com/angular/angular/commit/66658c4))
|
||||||
* **ivy:** support ng-add in localize package ([#32791](https://github.com/angular/angular/issues/32791)) ([e41cbfb](https://github.com/angular/angular/commit/e41cbfb))
|
* **ivy:** support ng-add in localize package ([#32791](https://github.com/angular/angular/issues/32791)) ([e41cbfb](https://github.com/angular/angular/commit/e41cbfb))
|
||||||
* **language-service:** allow retreiving synchronized analyzed NgModules ([#32779](https://github.com/angular/angular/issues/32779)) ([98feee7](https://github.com/angular/angular/commit/98feee7))
|
* **language-service:** allow retreiving synchronized analyzed NgModules ([#32779](https://github.com/angular/angular/issues/32779)) ([98feee7](https://github.com/angular/angular/commit/98feee7))
|
||||||
@ -2064,6 +1838,7 @@ This release contains various API docs improvements.
|
|||||||
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
|
* **language-service:** Eagarly initialize data members ([#31577](https://github.com/angular/angular/issues/31577)) ([0110de2](https://github.com/angular/angular/commit/0110de2))
|
||||||
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
|
* **bazel:** revert location of xi18n outputs to bazel-genfiles ([#31410](https://github.com/angular/angular/issues/31410)) ([1d3e227](https://github.com/angular/angular/commit/1d3e227))
|
||||||
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
|
* **compiler:** give ASTWithSource its own visit method ([#31347](https://github.com/angular/angular/issues/31347)) ([6aaca21](https://github.com/angular/angular/commit/6aaca21))
|
||||||
|
* **core:** handle `undefined` meta in `injectArgs` ([#31333](https://github.com/angular/angular/issues/31333)) ([80ccd6c](https://github.com/angular/angular/commit/80ccd6c)), closes [CLI #14888](https://github.com/angular/angular-cli/issues/14888)
|
||||||
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
|
* **service-worker:** cache opaque responses in data groups with `freshness` strategy ([#30977](https://github.com/angular/angular/issues/30977)) ([d7be38f](https://github.com/angular/angular/commit/d7be38f)), closes [#30968](https://github.com/angular/angular/issues/30968)
|
||||||
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
|
* **service-worker:** cache opaque responses when requests exceeds timeout threshold ([#30977](https://github.com/angular/angular/issues/30977)) ([93abc35](https://github.com/angular/angular/commit/93abc35))
|
||||||
|
|
||||||
@ -2093,6 +1868,7 @@ This release contains various API docs improvements.
|
|||||||
|
|
||||||
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480))
|
* use the correct WTF array to iterate over ([#31208](https://github.com/angular/angular/issues/31208)) ([4aed480](https://github.com/angular/angular/commit/4aed480))
|
||||||
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524)
|
* **compiler-cli:** Return original sourceFile instead of redirected sourceFile from getSourceFile ([#26036](https://github.com/angular/angular/issues/26036)) ([13dbb98](https://github.com/angular/angular/commit/13dbb98)), closes [#22524](https://github.com/angular/angular/issues/22524)
|
||||||
|
* **core:** export provider interfaces that are part of the public API types ([#31377](https://github.com/angular/angular/issues/31377)) ([bebf089](https://github.com/angular/angular/commit/bebf089)), closes [/github.com/angular/angular/pull/31377#discussion_r299254408](https://github.com/angular/angular/pull/31377/issues/discussion_r299254408) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L365-L366](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L365-L366) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts#L283-L284](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/interface/provider.ts/issues/L283-L284) [/github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts#L23](https://github.com/angular/angular/blob/9e34670b2/packages/core/src/di/index.ts/issues/L23)
|
||||||
|
|
||||||
|
|
||||||
<a name="8.1.1"></a>
|
<a name="8.1.1"></a>
|
||||||
@ -2270,6 +2046,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
### Features
|
### Features
|
||||||
|
|
||||||
* add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336))
|
* add support for TypeScript 3.4 (and drop older versions) ([#29372](https://github.com/angular/angular/issues/29372)) ([ef85336](https://github.com/angular/angular/commit/ef85336))
|
||||||
|
* **common:** add ability to watch for AngularJS URL updates through `onUrlChange` hook ([#30466](https://github.com/angular/angular/issues/30466)) ([8022d36](https://github.com/angular/angular/commit/8022d36))
|
||||||
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
|
* **common:** stricter types for `SlicePipe` ([#30156](https://github.com/angular/angular/issues/30156)) ([722b2fa](https://github.com/angular/angular/commit/722b2fa))
|
||||||
* **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
|
* **bazel:** use `rbe_autoconfig()` and new container ([#29336](https://github.com/angular/angular/issues/29336)) ([e562acc](https://github.com/angular/angular/commit/e562acc))
|
||||||
* **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
|
* **common:** add @angular/common/upgrade package for `$location`-related APIs ([#30055](https://github.com/angular/angular/issues/30055)) ([152d99e](https://github.com/angular/angular/commit/152d99e))
|
||||||
@ -2386,6 +2163,8 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
|
* **bazel:** use `//:tsconfig.json` as the default for `ng_module` ([#29670](https://github.com/angular/angular/issues/29670)) ([b14537a](https://github.com/angular/angular/commit/b14537a))
|
||||||
* **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c))
|
* **compiler-cli:** ngcc - cope with processing entry-points multiple times ([#29657](https://github.com/angular/angular/issues/29657)) ([6b39c9c](https://github.com/angular/angular/commit/6b39c9c))
|
||||||
* **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8))
|
* **core:** static-query schematic should detect static queries in getters. ([#29609](https://github.com/angular/angular/issues/29609)) ([33016b8](https://github.com/angular/angular/commit/33016b8))
|
||||||
|
* **common:** escape query selector used when anchor scrolling ([#29577](https://github.com/angular/angular/issues/29577)) ([7671c73](https://github.com/angular/angular/commit/7671c73)), closes [#28193](https://github.com/angular/angular/issues/28193)
|
||||||
|
* **router:** adjust setting navigationTransition when a new navigation cancels an existing one ([#29636](https://github.com/angular/angular/issues/29636)) ([e884c0c](https://github.com/angular/angular/commit/e884c0c)), closes [#29389](https://github.com/angular/angular/issues/29389) [#29590](https://github.com/angular/angular/issues/29590)
|
||||||
* **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
|
* **bazel:** allow `ng_module` users to set `createExternalSymbolFactoryReexports` ([#29459](https://github.com/angular/angular/issues/29459)) ([21be0fb](https://github.com/angular/angular/commit/21be0fb))
|
||||||
* **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960))
|
* **bazel:** workaround problem reading summary files from node_modules ([#29459](https://github.com/angular/angular/issues/29459)) ([769d960](https://github.com/angular/angular/commit/769d960))
|
||||||
* **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564))
|
* **compiler:** inherit param types when class has a constructor which takes no declared parameters and delegates up ([#29232](https://github.com/angular/angular/issues/29232)) ([0007564](https://github.com/angular/angular/commit/0007564))
|
||||||
@ -2412,7 +2191,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
* **platform-server:** update minimum domino version to latest released ([#28893](https://github.com/angular/angular/issues/28893)) ([79e2ca0](https://github.com/angular/angular/commit/79e2ca0))
|
* **platform-server:** update minimum domino version to latest released ([#28893](https://github.com/angular/angular/issues/28893)) ([79e2ca0](https://github.com/angular/angular/commit/79e2ca0))
|
||||||
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([72ecc45](https://github.com/angular/angular/commit/72ecc45))
|
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([72ecc45](https://github.com/angular/angular/commit/72ecc45))
|
||||||
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([586234b](https://github.com/angular/angular/commit/586234b)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([586234b](https://github.com/angular/angular/commit/586234b)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
||||||
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([48214e2](https://github.com/angular/angular/commit/48214e2)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
||||||
* **bazel:** Pin browsers for schematics ([#28913](https://github.com/angular/angular/issues/28913)) ([1145bdb](https://github.com/angular/angular/commit/1145bdb))
|
* **bazel:** Pin browsers for schematics ([#28913](https://github.com/angular/angular/issues/28913)) ([1145bdb](https://github.com/angular/angular/commit/1145bdb))
|
||||||
* **bazel:** rxjs_umd_modules should always be present ([#28881](https://github.com/angular/angular/issues/28881)) ([9ae14db](https://github.com/angular/angular/commit/9ae14db))
|
* **bazel:** rxjs_umd_modules should always be present ([#28881](https://github.com/angular/angular/issues/28881)) ([9ae14db](https://github.com/angular/angular/commit/9ae14db))
|
||||||
* **compiler:** use correct variable in invalid function ([#28656](https://github.com/angular/angular/issues/28656)) ([f75acbd](https://github.com/angular/angular/commit/f75acbd))
|
* **compiler:** use correct variable in invalid function ([#28656](https://github.com/angular/angular/issues/28656)) ([f75acbd](https://github.com/angular/angular/commit/f75acbd))
|
||||||
@ -2474,6 +2253,7 @@ To learn about the release highlights and our CLI-powered automated update workf
|
|||||||
|
|
||||||
* **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([b408445](https://github.com/angular/angular/commit/b408445))
|
* **core:** deprecate integration with the Web Tracing Framework (WTF) ([#30642](https://github.com/angular/angular/issues/30642)) ([b408445](https://github.com/angular/angular/commit/b408445))
|
||||||
* **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([361f181](https://github.com/angular/angular/commit/361f181))
|
* **platform-webworker:** deprecate platform-webworker ([#30642](https://github.com/angular/angular/issues/30642)) ([361f181](https://github.com/angular/angular/commit/361f181))
|
||||||
|
* `TestBed.get()` has two signatures, one which is typed and another which accepts and returns `any`. The signature for `any` is deprecated; all usage of `TestBed.get()` should go through the typed API. This mainly affects string tokens
|
||||||
(which aren't supported) and abstract class tokens.
|
(which aren't supported) and abstract class tokens.
|
||||||
|
|
||||||
Before:
|
Before:
|
||||||
@ -2626,7 +2406,7 @@ This release contains various API docs improvements.
|
|||||||
* **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635)
|
* **animations:** ensure `position` and `display` styles are handled outside of keyframes/web-animations ([#28911](https://github.com/angular/angular/issues/28911)) ([86981b3](https://github.com/angular/angular/commit/86981b3)), closes [#24923](https://github.com/angular/angular/issues/24923) [#25635](https://github.com/angular/angular/issues/25635)
|
||||||
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2))
|
* **router:** removed obsolete TODO comment ([#29085](https://github.com/angular/angular/issues/29085)) ([2a25ac2](https://github.com/angular/angular/commit/2a25ac2))
|
||||||
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
* **service-worker:** detect new version even if files are identical to an old one ([#26006](https://github.com/angular/angular/issues/26006)) ([5669333](https://github.com/angular/angular/commit/5669333)), closes [#24338](https://github.com/angular/angular/issues/24338)
|
||||||
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [/github.com/angular/angular/issues/23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012/issues/issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
* **service-worker:** ignore passive mixed content requests ([#25994](https://github.com/angular/angular/issues/25994)) ([b598e88](https://github.com/angular/angular/commit/b598e88)), closes [23012#issuecomment-376430187](https://github.com/angular/angular/issues/23012#issuecomment-376430187) [#23012](https://github.com/angular/angular/issues/23012)
|
||||||
|
|
||||||
|
|
||||||
<a name="7.2.7"></a>
|
<a name="7.2.7"></a>
|
||||||
@ -2722,6 +2502,14 @@ This release contains various API docs improvements.
|
|||||||
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)
|
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### Performance Improvements
|
### Performance Improvements
|
||||||
|
|
||||||
|
|
||||||
@ -2869,9 +2657,42 @@ This release contains various API docs improvements.
|
|||||||
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
|
# [7.1.0](https://github.com/angular/angular/compare/7.1.0-rc.0...7.1.0) (2018-11-21)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
|
||||||
|
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
|
||||||
|
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
||||||
|
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
|
||||||
|
* **compiler:** generate inputs with aliases properly ([#26774](https://github.com/angular/angular/issues/26774)) ([19fcfc3](https://github.com/angular/angular/commit/19fcfc3))
|
||||||
|
* **compiler:** generate relative paths only in summary file errors ([#26759](https://github.com/angular/angular/issues/26759)) ([56f44be](https://github.com/angular/angular/commit/56f44be))
|
||||||
|
* **core:** ignore comment nodes under unsafe elements ([#25879](https://github.com/angular/angular/issues/25879)) ([d5cbcef](https://github.com/angular/angular/commit/d5cbcef))
|
||||||
|
* **core:** Remove static dependency from @angular/core to @angular/compiler ([#26734](https://github.com/angular/angular/issues/26734)) ([d042c4a](https://github.com/angular/angular/commit/d042c4a))
|
||||||
|
* **core:** support computed base class in metadata inheritance ([#24014](https://github.com/angular/angular/issues/24014)) ([95743e3](https://github.com/angular/angular/commit/95743e3))
|
||||||
|
* **bazel:** unknown replay compiler error in windows ([#26711](https://github.com/angular/angular/issues/26711)) ([aed95fd](https://github.com/angular/angular/commit/aed95fd))
|
||||||
|
* **core:** ensure that `ɵdefineNgModule` is available in flat-file formats ([#26403](https://github.com/angular/angular/issues/26403)) ([a64859b](https://github.com/angular/angular/commit/a64859b))
|
||||||
|
* **router:** remove type bludgeoning of context and outlet when running CanDeactivate ([#26496](https://github.com/angular/angular/issues/26496)) ([496372d](https://github.com/angular/angular/commit/496372d)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
||||||
|
* **service-worker:** add typing to public api guard and fix lint errors ([#25860](https://github.com/angular/angular/issues/25860)) ([1061875](https://github.com/angular/angular/commit/1061875))
|
||||||
|
* **upgrade:** improve downgrading-related error messages ([#26217](https://github.com/angular/angular/issues/26217)) ([7dbc103](https://github.com/angular/angular/commit/7dbc103))
|
||||||
|
* **upgrade:** make typings compatible with older AngularJS typings ([#26880](https://github.com/angular/angular/issues/26880)) ([64647af](https://github.com/angular/angular/commit/64647af)), closes [#26420](https://github.com/angular/angular/issues/26420)
|
||||||
|
* **compiler-cli:** add missing tslib dependency ([#27063](https://github.com/angular/angular/issues/27063)) ([c31e78f](https://github.com/angular/angular/commit/c31e78f))
|
||||||
|
* **compiler-cli:** only pass canonical genfile paths to compiler host ([#27062](https://github.com/angular/angular/issues/27062)) ([0ada23a](https://github.com/angular/angular/commit/0ada23a))
|
||||||
|
* **router:** add `relativeLinkResolution` to `recognize` operator ([#26990](https://github.com/angular/angular/issues/26990)) ([a752971](https://github.com/angular/angular/commit/a752971)), closes [#26983](https://github.com/angular/angular/issues/26983)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
|
* **bazel:** Bazel workspace schematics ([#26971](https://github.com/angular/angular/issues/26971)) ([b07bd30](https://github.com/angular/angular/commit/b07bd30))
|
||||||
|
* **router:** add prioritizedGuardValue operator optimization and allowing UrlTree return from guard ([#26478](https://github.com/angular/angular/issues/26478)) ([fdfedce](https://github.com/angular/angular/commit/fdfedce))
|
||||||
|
* **compiler:** ability to mark an InvokeFunctionExpr as pure ([#26860](https://github.com/angular/angular/issues/26860)) ([4dfa71f](https://github.com/angular/angular/commit/4dfa71f))
|
||||||
|
* **forms:** add updateOn option to FormBuilder ([#24599](https://github.com/angular/angular/issues/24599)) ([e9e804f](https://github.com/angular/angular/commit/e9e804f))
|
||||||
|
* **router:** allow guards to return UrlTree as well as boolean ([#26521](https://github.com/angular/angular/issues/26521)) ([081f95c](https://github.com/angular/angular/commit/081f95c))
|
||||||
|
* **router:** allow redirect from guards by returning UrlTree ([#26521](https://github.com/angular/angular/issues/26521)) ([152ca66](https://github.com/angular/angular/commit/152ca66))
|
||||||
|
* **router:** guard returning UrlTree cancels current navigation and redirects ([#26521](https://github.com/angular/angular/issues/26521)) ([4e9f2e5](https://github.com/angular/angular/commit/4e9f2e5)), closes [#24618](https://github.com/angular/angular/issues/24618)
|
||||||
|
* **service-worker:** add typing for messagesClicked in SwPush service ([#25860](https://github.com/angular/angular/issues/25860)) ([c78c221](https://github.com/angular/angular/commit/c78c221))
|
||||||
|
* **service-worker:** close notifications and focus window on click ([#25860](https://github.com/angular/angular/issues/25860)) ([f5d5a3d](https://github.com/angular/angular/commit/f5d5a3d))
|
||||||
|
* **service-worker:** handle 'notificationclick' events ([#25860](https://github.com/angular/angular/issues/25860)) ([cf6ea28](https://github.com/angular/angular/commit/cf6ea28)), closes [#20956](https://github.com/angular/angular/issues/20956) [#22311](https://github.com/angular/angular/issues/22311)
|
||||||
|
* **upgrade:** support downgrading multiple modules ([#26217](https://github.com/angular/angular/issues/26217)) ([93837e9](https://github.com/angular/angular/commit/93837e9)), closes [#26062](https://github.com/angular/angular/issues/26062)
|
||||||
|
* **router:** add pathParamsChange mode for runGuardsAndResolvers ([#26861](https://github.com/angular/angular/issues/26861)) ([bf6ac6c](https://github.com/angular/angular/commit/bf6ac6c)), closes [#18253](https://github.com/angular/angular/issues/18253)
|
||||||
|
|
||||||
|
|
||||||
<a name="7.1.0-rc.0"></a>
|
<a name="7.1.0-rc.0"></a>
|
||||||
@ -2974,7 +2795,10 @@ This release contains various API docs improvements.
|
|||||||
|
|
||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
* **core:** allow null value for renderer setElement(…) ([#17065](https://github.com/angular/angular/issues/17065)) ([ff15043](https://github.com/angular/angular/commit/ff15043)), closes [#13686](https://github.com/angular/angular/issues/13686)
|
||||||
|
* **router:** fix regression where navigateByUrl promise didn't resolve on CanLoad failure ([#26455](https://github.com/angular/angular/issues/26455)) ([1c9b065](https://github.com/angular/angular/commit/1c9b065)), closes [#26284](https://github.com/angular/angular/issues/26284)
|
||||||
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
* **service-worker:** clean up caches from old SW versions ([#26319](https://github.com/angular/angular/issues/26319)) ([2326b9c](https://github.com/angular/angular/commit/2326b9c))
|
||||||
|
* **upgrade:** properly destroy upgraded component elements and descendants ([#26209](https://github.com/angular/angular/issues/26209)) ([071934e](https://github.com/angular/angular/commit/071934e)), closes [#26208](https://github.com/angular/angular/issues/26208)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
@ -3146,6 +2970,7 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
|
|||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
|
* **animations:** always render end-state styles for orphaned DOM nodes ([#24236](https://github.com/angular/angular/issues/24236)) ([dc4a3d0](https://github.com/angular/angular/commit/dc4a3d0))
|
||||||
|
* **animations:** set animations styles properly on platform-server ([#24624](https://github.com/angular/angular/issues/24624)) ([0b356d4](https://github.com/angular/angular/commit/0b356d4))
|
||||||
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
|
* **animations:** do not throw errors when a destroyed component is animated ([#23836](https://github.com/angular/angular/issues/23836)) ([d2a8687](https://github.com/angular/angular/commit/d2a8687))
|
||||||
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
|
* **animations:** Fix browser detection logic ([#24188](https://github.com/angular/angular/issues/24188)) ([b492b9e](https://github.com/angular/angular/commit/b492b9e))
|
||||||
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
|
* **animations:** properly clean up queried element styles in safari/edge ([#23633](https://github.com/angular/angular/issues/23633)) ([da9ff25](https://github.com/angular/angular/commit/da9ff25))
|
||||||
@ -3157,6 +2982,7 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
|
|||||||
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([0b4d85e](https://github.com/angular/angular/commit/0b4d85e)), closes [#24831](https://github.com/angular/angular/issues/24831)
|
* **common:** format fractional seconds ([#24844](https://github.com/angular/angular/issues/24844)) ([0b4d85e](https://github.com/angular/angular/commit/0b4d85e)), closes [#24831](https://github.com/angular/angular/issues/24831)
|
||||||
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), closes [#24155](https://github.com/angular/angular/issues/24155)
|
* **common:** properly update collection reference in NgForOf ([#24684](https://github.com/angular/angular/issues/24684)) ([ff84c5c](https://github.com/angular/angular/commit/ff84c5c)), closes [#24155](https://github.com/angular/angular/issues/24155)
|
||||||
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609)
|
* **common:** use correct currency format for locale de-AT ([#24658](https://github.com/angular/angular/issues/24658)) ([dcabb05](https://github.com/angular/angular/commit/dcabb05)), closes [#24609](https://github.com/angular/angular/issues/24609)
|
||||||
|
* **common:** use correct ICU plural for locale mk ([#24659](https://github.com/angular/angular/issues/24659)) ([64a8584](https://github.com/angular/angular/commit/64a8584))
|
||||||
* **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f))
|
* **compiler:** fix a few non-tree-shakeable code patterns ([#24677](https://github.com/angular/angular/issues/24677)) ([50d4a4f](https://github.com/angular/angular/commit/50d4a4f))
|
||||||
* **compiler:** i18n_extractor now outputs the correct source file name ([#24885](https://github.com/angular/angular/issues/24885)) ([c8ad965](https://github.com/angular/angular/commit/c8ad965)), closes [#24884](https://github.com/angular/angular/issues/24884)
|
* **compiler:** i18n_extractor now outputs the correct source file name ([#24885](https://github.com/angular/angular/issues/24885)) ([c8ad965](https://github.com/angular/angular/commit/c8ad965)), closes [#24884](https://github.com/angular/angular/issues/24884)
|
||||||
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
* **compiler:** support `.` in import statements. ([#20634](https://github.com/angular/angular/issues/20634)) ([d8f7b29](https://github.com/angular/angular/commit/d8f7b29)), closes [#20363](https://github.com/angular/angular/issues/20363)
|
||||||
@ -3192,6 +3018,7 @@ Note: the 6.1.5 release on npm accidentally glitched-out midway, so we cut 6.1.6
|
|||||||
* **service-worker:** don't include sourceMappingURL in ngsw-worker ([#24877](https://github.com/angular/angular/issues/24877)) ([8620373](https://github.com/angular/angular/commit/8620373)), closes [#23596](https://github.com/angular/angular/issues/23596)
|
* **service-worker:** don't include sourceMappingURL in ngsw-worker ([#24877](https://github.com/angular/angular/issues/24877)) ([8620373](https://github.com/angular/angular/commit/8620373)), closes [#23596](https://github.com/angular/angular/issues/23596)
|
||||||
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9))
|
* **service-worker:** avoid network requests when looking up hashed resources in cache ([#24127](https://github.com/angular/angular/issues/24127)) ([52d43a9](https://github.com/angular/angular/commit/52d43a9))
|
||||||
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
* **service-worker:** fix `SwPush.unsubscribe()` ([#24162](https://github.com/angular/angular/issues/24162)) ([3ed2d75](https://github.com/angular/angular/commit/3ed2d75)), closes [#24095](https://github.com/angular/angular/issues/24095)
|
||||||
|
* **service-worker:** add badge to NOTIFICATION_OPTION_NAMES ([#23241](https://github.com/angular/angular/issues/23241)) ([fb59b2d](https://github.com/angular/angular/commit/fb59b2d)), closes [#23196](https://github.com/angular/angular/issues/23196)
|
||||||
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
|
* **service-worker:** check platformBrowser before accessing navigator.serviceWorker ([#21231](https://github.com/angular/angular/issues/21231)) ([0bdd30e](https://github.com/angular/angular/commit/0bdd30e))
|
||||||
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
|
* **service-worker:** correctly handle requests with empty `clientId` ([#23625](https://github.com/angular/angular/issues/23625)) ([e0ed59e](https://github.com/angular/angular/commit/e0ed59e)), closes [#23526](https://github.com/angular/angular/issues/23526)
|
||||||
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
|
* **service-worker:** deprecate `versionedFiles` in asset-group resources ([#23584](https://github.com/angular/angular/issues/23584)) ([1d378e2](https://github.com/angular/angular/commit/1d378e2))
|
||||||
@ -3392,6 +3219,8 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
|||||||
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
|
* **forms:** multiple validators for array method ([#20766](https://github.com/angular/angular/issues/20766)) ([941e88f](https://github.com/angular/angular/commit/941e88f)), closes [#20665](https://github.com/angular/angular/issues/20665)
|
||||||
* **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958)
|
* **forms:** allow markAsPending to emit events ([#20212](https://github.com/angular/angular/issues/20212)) ([e86b64b](https://github.com/angular/angular/commit/e86b64b)), closes [#17958](https://github.com/angular/angular/issues/17958)
|
||||||
* **platform-browser:** add token marking which the type of animation module nearest in the injector tree ([#23075](https://github.com/angular/angular/issues/23075)) ([b551f84](https://github.com/angular/angular/commit/b551f84))
|
* **platform-browser:** add token marking which the type of animation module nearest in the injector tree ([#23075](https://github.com/angular/angular/issues/23075)) ([b551f84](https://github.com/angular/angular/commit/b551f84))
|
||||||
|
* **platform-browser:** do not throw error when Hammer.js not loaded ([#22257](https://github.com/angular/angular/issues/22257)) ([991300b](https://github.com/angular/angular/commit/991300b)), closes [#16992](https://github.com/angular/angular/issues/16992)
|
||||||
|
* **platform-browser:** fix [#19604](https://github.com/angular/angular/issues/19604), can config hammerOptions ([#21979](https://github.com/angular/angular/issues/21979)) ([1d571b2](https://github.com/angular/angular/commit/1d571b2))
|
||||||
* **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0))
|
* **platform-server:** bump Domino to v2.0 ([#22411](https://github.com/angular/angular/issues/22411)) ([d3827a0](https://github.com/angular/angular/commit/d3827a0))
|
||||||
* **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f))
|
* **router:** add navigationSource and restoredState to NavigationStart event ([#21728](https://github.com/angular/angular/issues/21728)) ([c40ae7f](https://github.com/angular/angular/commit/c40ae7f))
|
||||||
* **service-worker:** add support for configuring navigations URLs ([#23339](https://github.com/angular/angular/issues/23339)) ([08325aa](https://github.com/angular/angular/commit/08325aa)), closes [#20404](https://github.com/angular/angular/issues/20404)
|
* **service-worker:** add support for configuring navigations URLs ([#23339](https://github.com/angular/angular/issues/23339)) ([08325aa](https://github.com/angular/angular/commit/08325aa)), closes [#20404](https://github.com/angular/angular/issues/20404)
|
||||||
@ -3610,7 +3439,12 @@ To learn about the release highlights and our new CLI-powered update workflow fo
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **platform-server:** generate correct stylings for camel case names ([#22263](https://github.com/angular/angular/issues/22263)) ([de02a7a](https://github.com/angular/angular/commit/de02a7a)), closes [#19235](https://github.com/angular/angular/issues/19235)
|
||||||
|
* **router:** don't mutate route configs ([#22358](https://github.com/angular/angular/issues/22358)) ([8f0a064](https://github.com/angular/angular/commit/8f0a064)), closes [#22203](https://github.com/angular/angular/issues/22203)
|
||||||
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
* **router:** fix URL serialization so special characters are only encoded where needed ([#22337](https://github.com/angular/angular/issues/22337)) ([789a47e](https://github.com/angular/angular/commit/789a47e)), closes [#10280](https://github.com/angular/angular/issues/10280)
|
||||||
|
* **upgrade:** correctly destroy nested downgraded component ([#22400](https://github.com/angular/angular/issues/22400)) ([4aef9de](https://github.com/angular/angular/commit/4aef9de)), closes [#22392](https://github.com/angular/angular/issues/22392)
|
||||||
|
* **upgrade:** correctly handle `=` bindings in `@angular/upgrade` ([#22167](https://github.com/angular/angular/issues/22167)) ([6638390](https://github.com/angular/angular/commit/6638390))
|
||||||
|
* **upgrade:** fix empty transclusion content with AngularJS@>=1.5.8 ([#22167](https://github.com/angular/angular/issues/22167)) ([a9a0e27](https://github.com/angular/angular/commit/a9a0e27)), closes [#22175](https://github.com/angular/angular/issues/22175)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -4005,6 +3839,15 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
|
|||||||
<a name="5.1.0-beta.0"></a>
|
<a name="5.1.0-beta.0"></a>
|
||||||
# [5.1.0-beta.0](https://github.com/angular/angular/compare/5.0.0-rc.4...5.1.0-beta.0) (2017-11-08)
|
# [5.1.0-beta.0](https://github.com/angular/angular/compare/5.0.0-rc.4...5.1.0-beta.0) (2017-11-08)
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **compiler:** don't overwrite missingTranslation's value in JIT ([#19952](https://github.com/angular/angular/issues/19952)) ([799cbb9](https://github.com/angular/angular/commit/799cbb9))
|
||||||
|
* **compiler:** report a reasonable error with invalid metadata ([#20062](https://github.com/angular/angular/issues/20062)) ([da22c48](https://github.com/angular/angular/commit/da22c48))
|
||||||
|
* **compiler-cli:** don't report emit diagnostics when `--noEmitOnError` is off ([#20063](https://github.com/angular/angular/issues/20063)) ([8639995](https://github.com/angular/angular/commit/8639995))
|
||||||
|
* **core:** `__symbol__` should return `__zone_symbol__` without zone.js loaded ([#19541](https://github.com/angular/angular/issues/19541)) ([678d1cf](https://github.com/angular/angular/commit/678d1cf))
|
||||||
|
* **core:** should support event.stopImmediatePropagation ([#19222](https://github.com/angular/angular/issues/19222)) ([7083791](https://github.com/angular/angular/commit/7083791))
|
||||||
|
* **platform-browser:** support Symbols in custom `jasmineToString()` method ([#19794](https://github.com/angular/angular/issues/19794)) ([5a6efa7](https://github.com/angular/angular/commit/5a6efa7))
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
* **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815)
|
* **compiler:** introduce `TestBed.overrideTemplateUsingTestingModule` ([a460066](https://github.com/angular/angular/commit/a460066)), closes [#19815](https://github.com/angular/angular/issues/19815)
|
||||||
@ -4040,12 +3883,14 @@ Note: Due to an animation fix back in 5.1.1 ([c2b3792](https://github.com/angula
|
|||||||
* **compiler-cli:** add watch mode to `ngc` ([#18818](https://github.com/angular/angular/issues/18818)) ([06d01b2](https://github.com/angular/angular/commit/06d01b2))
|
* **compiler-cli:** add watch mode to `ngc` ([#18818](https://github.com/angular/angular/issues/18818)) ([06d01b2](https://github.com/angular/angular/commit/06d01b2))
|
||||||
* **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261))
|
* **compiler-cli:** lower metadata `useValue` and `data` literal fields ([#18905](https://github.com/angular/angular/issues/18905)) ([0e64261](https://github.com/angular/angular/commit/0e64261))
|
||||||
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
|
* **compiler:** add representation of placeholders to xliff & xmb ([b3085e9](https://github.com/angular/angular/commit/b3085e9)), closes [#17345](https://github.com/angular/angular/issues/17345)
|
||||||
|
* **compiler:** allow multiple exportAs names ([#18723](https://github.com/angular/angular/issues/18723)) ([7ec28fe](https://github.com/angular/angular/commit/7ec28fe))
|
||||||
* **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21))
|
* **compiler:** enabled strict checking of parameters to an `@Injectable` ([#19412](https://github.com/angular/angular/issues/19412)) ([dfb8d21](https://github.com/angular/angular/commit/dfb8d21))
|
||||||
* **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5))
|
* **compiler:** make `.ngsummary.json` files portable ([2572bf5](https://github.com/angular/angular/commit/2572bf5))
|
||||||
* **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2))
|
* **compiler:** reuse the TypeScript typecheck for template typechecking. ([#19152](https://github.com/angular/angular/issues/19152)) ([996c7c2](https://github.com/angular/angular/commit/996c7c2))
|
||||||
* **compiler:** set `enableLegacyTemplate` to false by default ([#18756](https://github.com/angular/angular/issues/18756)) ([56238fe](https://github.com/angular/angular/commit/56238fe))
|
* **compiler:** set `enableLegacyTemplate` to false by default ([#18756](https://github.com/angular/angular/issues/18756)) ([56238fe](https://github.com/angular/angular/commit/56238fe))
|
||||||
* **compiler:** use typescript for resolving resource paths ([43226cb](https://github.com/angular/angular/commit/43226cb))
|
* **compiler:** use typescript for resolving resource paths ([43226cb](https://github.com/angular/angular/commit/43226cb))
|
||||||
* **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd))
|
* **core:** Create StaticInjector which does not depend on Reflect polyfill. ([d9d00bd](https://github.com/angular/angular/commit/d9d00bd))
|
||||||
|
* **core:** add option to remove blank text nodes from compiled templates ([#18823](https://github.com/angular/angular/issues/18823)) ([b8b551c](https://github.com/angular/angular/commit/b8b551c))
|
||||||
* **core:** support for bootstrap with custom zone ([#17672](https://github.com/angular/angular/issues/17672)) ([344a5ca](https://github.com/angular/angular/commit/344a5ca))
|
* **core:** support for bootstrap with custom zone ([#17672](https://github.com/angular/angular/issues/17672)) ([344a5ca](https://github.com/angular/angular/commit/344a5ca))
|
||||||
* **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b))
|
* **forms:** add default updateOn values for groups and arrays ([#18536](https://github.com/angular/angular/issues/18536)) ([ff5c58b](https://github.com/angular/angular/commit/ff5c58b))
|
||||||
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
|
* **forms:** add options arg to abstract controls ([ebef5e6](https://github.com/angular/angular/commit/ebef5e6))
|
||||||
@ -4404,6 +4249,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
* **animations:** properly collect :enter nodes that exist within multi-level DOM trees ([40f77cb](https://github.com/angular/angular/commit/40f77cb)), closes [#17632](https://github.com/angular/angular/issues/17632)
|
* **animations:** properly collect :enter nodes that exist within multi-level DOM trees ([40f77cb](https://github.com/angular/angular/commit/40f77cb)), closes [#17632](https://github.com/angular/angular/issues/17632)
|
||||||
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
||||||
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
||||||
|
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
|
||||||
* **animations:** remove duplicate license header ([e096a85](https://github.com/angular/angular/commit/e096a85))
|
* **animations:** remove duplicate license header ([e096a85](https://github.com/angular/angular/commit/e096a85))
|
||||||
* **common/http:** document HttpClient, fixing a few other issues ([1855989](https://github.com/angular/angular/commit/1855989))
|
* **common/http:** document HttpClient, fixing a few other issues ([1855989](https://github.com/angular/angular/commit/1855989))
|
||||||
* **common/http:** don't guess Content-Type for FormData bodies ([#18104](https://github.com/angular/angular/issues/18104)) ([4f1e4ff](https://github.com/angular/angular/commit/4f1e4ff)), closes [#18096](https://github.com/angular/angular/issues/18096)
|
* **common/http:** don't guess Content-Type for FormData bodies ([#18104](https://github.com/angular/angular/issues/18104)) ([4f1e4ff](https://github.com/angular/angular/commit/4f1e4ff)), closes [#18096](https://github.com/angular/angular/issues/18096)
|
||||||
@ -4512,6 +4358,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
|
|
||||||
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
* **animations:** compute removal node height correctly ([185075d](https://github.com/angular/angular/commit/185075d))
|
||||||
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
* **animations:** do not treat a `0` animation state as `void` ([451257a](https://github.com/angular/angular/commit/451257a))
|
||||||
|
* **animations:** properly collect :enter nodes in a partially updated collection ([6ca4692](https://github.com/angular/angular/commit/6ca4692)), closes [#17440](https://github.com/angular/angular/issues/17440)
|
||||||
* **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5))
|
* **animations:** remove duplicate license header ([b192dd5](https://github.com/angular/angular/commit/b192dd5))
|
||||||
* **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491)
|
* **forms:** temp roll back breaking change with min/max directives ([b8c39cd](https://github.com/angular/angular/commit/b8c39cd)), closes [#17491](https://github.com/angular/angular/issues/17491)
|
||||||
|
|
||||||
@ -4747,6 +4594,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
* **benchpress:** Update types for TypeScript nullability support ([14669f2](https://github.com/angular/angular/commit/14669f2))
|
* **benchpress:** Update types for TypeScript nullability support ([14669f2](https://github.com/angular/angular/commit/14669f2))
|
||||||
* **common:** Update types for TypeScript nullability support ([d8b73e4](https://github.com/angular/angular/commit/d8b73e4))
|
* **common:** Update types for TypeScript nullability support ([d8b73e4](https://github.com/angular/angular/commit/d8b73e4))
|
||||||
* **compiler:** fix build error in xliff2 ([bd704c9](https://github.com/angular/angular/commit/bd704c9))
|
* **compiler:** fix build error in xliff2 ([bd704c9](https://github.com/angular/angular/commit/bd704c9))
|
||||||
|
* **compiler:** fix inheritance for AOT with summaries ([#15583](https://github.com/angular/angular/issues/15583)) ([8ef621a](https://github.com/angular/angular/commit/8ef621a))
|
||||||
* **compiler:** ignore calls to unresolved symbols in metadata ([38a7e0d](https://github.com/angular/angular/commit/38a7e0d)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
* **compiler:** ignore calls to unresolved symbols in metadata ([38a7e0d](https://github.com/angular/angular/commit/38a7e0d)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
||||||
* **compiler:** ignore calls to unresolved symbols in metadata ([#15970](https://github.com/angular/angular/issues/15970)) ([ce47d33](https://github.com/angular/angular/commit/ce47d33)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
* **compiler:** ignore calls to unresolved symbols in metadata ([#15970](https://github.com/angular/angular/issues/15970)) ([ce47d33](https://github.com/angular/angular/commit/ce47d33)), closes [#15969](https://github.com/angular/angular/issues/15969)
|
||||||
* **compiler:** Inform user where Quoted error was thrown ([a77b126](https://github.com/angular/angular/commit/a77b126))
|
* **compiler:** Inform user where Quoted error was thrown ([a77b126](https://github.com/angular/angular/commit/a77b126))
|
||||||
@ -4763,8 +4611,10 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
* **http:** Update types for TypeScript nullability support ([c36ec9b](https://github.com/angular/angular/commit/c36ec9b))
|
* **http:** Update types for TypeScript nullability support ([c36ec9b](https://github.com/angular/angular/commit/c36ec9b))
|
||||||
* **http:** Update types for TypeScript nullability support ([ec028b8](https://github.com/angular/angular/commit/ec028b8))
|
* **http:** Update types for TypeScript nullability support ([ec028b8](https://github.com/angular/angular/commit/ec028b8))
|
||||||
* **language-service:** avoid throwing exceptions when reporting metadata errors ([7764c5c](https://github.com/angular/angular/commit/7764c5c))
|
* **language-service:** avoid throwing exceptions when reporting metadata errors ([7764c5c](https://github.com/angular/angular/commit/7764c5c))
|
||||||
|
* **language-service:** detect when there isn't a tsconfig.json ([258d539](https://github.com/angular/angular/commit/258d539)), closes [#15874](https://github.com/angular/angular/issues/15874)
|
||||||
* **language-service:** improve resilience to incomplete information ([71a8627](https://github.com/angular/angular/commit/71a8627))
|
* **language-service:** improve resilience to incomplete information ([71a8627](https://github.com/angular/angular/commit/71a8627))
|
||||||
* **language-service:** infer correct type of `?.` expressions ([0a3a9af](https://github.com/angular/angular/commit/0a3a9af)), closes [#15885](https://github.com/angular/angular/issues/15885)
|
* **language-service:** infer correct type of `?.` expressions ([0a3a9af](https://github.com/angular/angular/commit/0a3a9af)), closes [#15885](https://github.com/angular/angular/issues/15885)
|
||||||
|
* **language-service:** initialize static reflector correctly ([fe0d02f](https://github.com/angular/angular/commit/fe0d02f)), closes [#15768](https://github.com/angular/angular/issues/15768)
|
||||||
* **language-service:** look for type constructors on canonical symbol ([2ddf3bc](https://github.com/angular/angular/commit/2ddf3bc))
|
* **language-service:** look for type constructors on canonical symbol ([2ddf3bc](https://github.com/angular/angular/commit/2ddf3bc))
|
||||||
* **language-service:** only use canonical symbols ([5a88d2f](https://github.com/angular/angular/commit/5a88d2f))
|
* **language-service:** only use canonical symbols ([5a88d2f](https://github.com/angular/angular/commit/5a88d2f))
|
||||||
* **language-service:** parse extended i18n forms ([bde9771](https://github.com/angular/angular/commit/bde9771))
|
* **language-service:** parse extended i18n forms ([bde9771](https://github.com/angular/angular/commit/bde9771))
|
||||||
@ -4789,6 +4639,7 @@ Note: the 4.4.0 release on npm accidentally glitched-out midway, so we cut 4.4.1
|
|||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
* **animations:** Update types for TypeScript nullability support ([38d75d4](https://github.com/angular/angular/commit/38d75d4)), closes [#15870](https://github.com/angular/angular/issues/15870)
|
||||||
* **compiler:** add source files to xmb/xliff translations ([#14705](https://github.com/angular/angular/issues/14705)) ([4054055](https://github.com/angular/angular/commit/4054055)), closes [#14190](https://github.com/angular/angular/issues/14190)
|
* **compiler:** add source files to xmb/xliff translations ([#14705](https://github.com/angular/angular/issues/14705)) ([4054055](https://github.com/angular/angular/commit/4054055)), closes [#14190](https://github.com/angular/angular/issues/14190)
|
||||||
* **compiler:** Implement i18n XLIFF 2.0 serializer ([#14185](https://github.com/angular/angular/issues/14185)) ([09c4cb2](https://github.com/angular/angular/commit/09c4cb2)), closes [#11735](https://github.com/angular/angular/issues/11735)
|
* **compiler:** Implement i18n XLIFF 2.0 serializer ([#14185](https://github.com/angular/angular/issues/14185)) ([09c4cb2](https://github.com/angular/angular/commit/09c4cb2)), closes [#11735](https://github.com/angular/angular/issues/11735)
|
||||||
* **upgrade:** allow setting the angularjs lib at runtime ([#15168](https://github.com/angular/angular/issues/15168)) ([e927aea](https://github.com/angular/angular/commit/e927aea))
|
* **upgrade:** allow setting the angularjs lib at runtime ([#15168](https://github.com/angular/angular/issues/15168)) ([e927aea](https://github.com/angular/angular/commit/e927aea))
|
||||||
@ -5526,18 +5377,27 @@ returned value being an array.
|
|||||||
|
|
||||||
### Bug Fixes
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **animations:** fix internal jscompiler issue and AOT quoting ([#13798](https://github.com/angular/angular/issues/13798)) ([c2aa981](https://github.com/angular/angular/commit/c2aa981))
|
||||||
|
* **common:** support numeric value as discrete cases for NgPlural ([#13876](https://github.com/angular/angular/issues/13876)) ([f364557](https://github.com/angular/angular/commit/f364557))
|
||||||
* **compiler:** [i18n] XMB/XTB placeholder names can contain only A-Z, 0-9, _n ([d02eab4](https://github.com/angular/angular/commit/d02eab4))
|
* **compiler:** [i18n] XMB/XTB placeholder names can contain only A-Z, 0-9, _n ([d02eab4](https://github.com/angular/angular/commit/d02eab4))
|
||||||
* **compiler:** fix regexp to support firefox 31 ([#14082](https://github.com/angular/angular/issues/14082)) ([b2f9d56](https://github.com/angular/angular/commit/b2f9d56)), closes [#14029](https://github.com/angular/angular/issues/14029) [#13900](https://github.com/angular/angular/issues/13900)
|
* **compiler:** fix regexp to support firefox 31 ([#14082](https://github.com/angular/angular/issues/14082)) ([b2f9d56](https://github.com/angular/angular/commit/b2f9d56)), closes [#14029](https://github.com/angular/angular/issues/14029) [#13900](https://github.com/angular/angular/issues/13900)
|
||||||
* **core:** export animation classes required for Renderer impl ([#14002](https://github.com/angular/angular/issues/14002)) ([83361d8](https://github.com/angular/angular/commit/83361d8)), closes [#14001](https://github.com/angular/angular/issues/14001)
|
* **core:** export animation classes required for Renderer impl ([#14002](https://github.com/angular/angular/issues/14002)) ([83361d8](https://github.com/angular/angular/commit/83361d8)), closes [#14001](https://github.com/angular/angular/issues/14001)
|
||||||
* **core:** fix not declared variable in view engine ([#14045](https://github.com/angular/angular/issues/14045)) ([d3a3a8e](https://github.com/angular/angular/commit/d3a3a8e))
|
* **core:** fix not declared variable in view engine ([#14045](https://github.com/angular/angular/issues/14045)) ([d3a3a8e](https://github.com/angular/angular/commit/d3a3a8e))
|
||||||
|
* **http:** don't create a blob out of ArrayBuffer when type is application/octet-stream ([#13992](https://github.com/angular/angular/issues/13992)) ([1200cf2](https://github.com/angular/angular/commit/1200cf2)), closes [#13973](https://github.com/angular/angular/issues/13973)
|
||||||
|
* **router:** enable loadChildren with function in aot ([#13909](https://github.com/angular/angular/issues/13909)) ([635bf02](https://github.com/angular/angular/commit/635bf02)), closes [#11075](https://github.com/angular/angular/issues/11075)
|
||||||
|
* **router:** routerLinkActive should not throw when not initialized ([#13273](https://github.com/angular/angular/issues/13273)) ([e8ea741](https://github.com/angular/angular/commit/e8ea741)), closes [#13270](https://github.com/angular/angular/issues/13270)
|
||||||
|
* **upgrade:** detect async downgrade component changes ([#13812](https://github.com/angular/angular/issues/13812)) ([d6382bf](https://github.com/angular/angular/commit/d6382bf)), closes [#6385](https://github.com/angular/angular/issues/6385) [#6385](https://github.com/angular/angular/issues/6385) [#10660](https://github.com/angular/angular/issues/10660) [#12318](https://github.com/angular/angular/issues/12318) [#12034](https://github.com/angular/angular/issues/12034)
|
||||||
* **upgrade/static:** ensure upgraded injector is initialized early enough ([#14065](https://github.com/angular/angular/issues/14065)) ([6152eb2](https://github.com/angular/angular/commit/6152eb2)), closes [#13811](https://github.com/angular/angular/issues/13811)
|
* **upgrade/static:** ensure upgraded injector is initialized early enough ([#14065](https://github.com/angular/angular/issues/14065)) ([6152eb2](https://github.com/angular/angular/commit/6152eb2)), closes [#13811](https://github.com/angular/angular/issues/13811)
|
||||||
|
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
|
* **build:** optionally build an ES2015 distro ([#13471](https://github.com/angular/angular/issues/13471)) ([be6c95a](https://github.com/angular/angular/commit/be6c95a))
|
||||||
* **core:** add event support to view engine ([0adb97b](https://github.com/angular/angular/commit/0adb97b))
|
* **core:** add event support to view engine ([0adb97b](https://github.com/angular/angular/commit/0adb97b))
|
||||||
* **core:** add initial view engine ([#14014](https://github.com/angular/angular/issues/14014)) ([2f87eb5](https://github.com/angular/angular/commit/2f87eb5))
|
* **core:** add initial view engine ([#14014](https://github.com/angular/angular/issues/14014)) ([2f87eb5](https://github.com/angular/angular/commit/2f87eb5))
|
||||||
* **core:** add pure expression support to view engine ([6541737](https://github.com/angular/angular/commit/6541737))
|
* **core:** add pure expression support to view engine ([6541737](https://github.com/angular/angular/commit/6541737))
|
||||||
|
* **core:** Add type information to injector.get() ([#13785](https://github.com/angular/angular/issues/13785)) ([d169c24](https://github.com/angular/angular/commit/d169c24))
|
||||||
|
* **security:** allow calc and gradient functions. ([#13943](https://github.com/angular/angular/issues/13943)) ([e19bf70](https://github.com/angular/angular/commit/e19bf70))
|
||||||
* **tsc-wrapped:** Support of vinyl like config file was added ([#13987](https://github.com/angular/angular/issues/13987)) ([0c7726d](https://github.com/angular/angular/commit/0c7726d))
|
* **tsc-wrapped:** Support of vinyl like config file was added ([#13987](https://github.com/angular/angular/issues/13987)) ([0c7726d](https://github.com/angular/angular/commit/0c7726d))
|
||||||
* **upgrade:** Support ng-model in downgraded components ([#10578](https://github.com/angular/angular/issues/10578)) ([e21e9c5](https://github.com/angular/angular/commit/e21e9c5))
|
* **upgrade:** Support ng-model in downgraded components ([#10578](https://github.com/angular/angular/issues/10578)) ([e21e9c5](https://github.com/angular/angular/commit/e21e9c5))
|
||||||
|
|
||||||
@ -6065,12 +5925,19 @@ Note: The 2.3.0-beta.0 release also contains all the changes present in the 2.2.
|
|||||||
|
|
||||||
### Features (summary of all features from 2.2.0-beta.0 - 2.2.0-rc.0 releases)
|
### Features (summary of all features from 2.2.0-beta.0 - 2.2.0-rc.0 releases)
|
||||||
|
|
||||||
|
* **common:** support narrow forms for month and weekdays in DatePipe ([#12297](https://github.com/angular/angular/issues/12297)) ([f77ab6a](https://github.com/angular/angular/commit/f77ab6a)), closes [#12294](https://github.com/angular/angular/issues/12294)
|
||||||
* **core:** map 'for' attribute to 'htmlFor' property ([#10546](https://github.com/angular/angular/issues/10546)) ([634b3bb](https://github.com/angular/angular/commit/634b3bb)), closes [#7516](https://github.com/angular/angular/issues/7516)
|
* **core:** map 'for' attribute to 'htmlFor' property ([#10546](https://github.com/angular/angular/issues/10546)) ([634b3bb](https://github.com/angular/angular/commit/634b3bb)), closes [#7516](https://github.com/angular/angular/issues/7516)
|
||||||
* **core:** add the find method to QueryList ([7c16ef9](https://github.com/angular/angular/commit/7c16ef9))
|
* **core:** add the find method to QueryList ([7c16ef9](https://github.com/angular/angular/commit/7c16ef9))
|
||||||
|
* **forms:** add hasError and getError to AbstractControlDirective ([#11985](https://github.com/angular/angular/issues/11985)) ([592f40a](https://github.com/angular/angular/commit/592f40a)), closes [#7255](https://github.com/angular/angular/issues/7255)
|
||||||
|
* **forms:** add ng-pending CSS class during async validation ([#11243](https://github.com/angular/angular/issues/11243)) ([97bc971](https://github.com/angular/angular/commit/97bc971)), closes [#10336](https://github.com/angular/angular/issues/10336)
|
||||||
* **forms:** add emitEvent to AbstractControl methods ([#11949](https://github.com/angular/angular/issues/11949)) ([b9fc090](https://github.com/angular/angular/commit/b9fc090))
|
* **forms:** add emitEvent to AbstractControl methods ([#11949](https://github.com/angular/angular/issues/11949)) ([b9fc090](https://github.com/angular/angular/commit/b9fc090))
|
||||||
|
* **forms:** make 'parent' a public property of 'AbstractControl' ([#11855](https://github.com/angular/angular/issues/11855)) ([445e592](https://github.com/angular/angular/commit/445e592))
|
||||||
|
* **forms:** Validator.pattern accepts a RegExp ([#12323](https://github.com/angular/angular/issues/12323)) ([bf60418](https://github.com/angular/angular/commit/bf60418))
|
||||||
* **router:** add a provider making angular1/angular2 integration easier ([#12769](https://github.com/angular/angular/issues/12769)) ([6e35d13](https://github.com/angular/angular/commit/6e35d13))
|
* **router:** add a provider making angular1/angular2 integration easier ([#12769](https://github.com/angular/angular/issues/12769)) ([6e35d13](https://github.com/angular/angular/commit/6e35d13))
|
||||||
* **router:** add support for custom url matchers ([7340735](https://github.com/angular/angular/commit/7340735)), closes [#12442](https://github.com/angular/angular/issues/12442) [#12772](https://github.com/angular/angular/issues/12772)
|
* **router:** add support for custom url matchers ([7340735](https://github.com/angular/angular/commit/7340735)), closes [#12442](https://github.com/angular/angular/issues/12442) [#12772](https://github.com/angular/angular/issues/12772)
|
||||||
* **router:** export routerLinkActive w/ isActive property ([c9f58cf](https://github.com/angular/angular/commit/c9f58cf))
|
* **router:** export routerLinkActive w/ isActive property ([c9f58cf](https://github.com/angular/angular/commit/c9f58cf))
|
||||||
|
* **router:** add support for ng1/ng2 migration ([#12160](https://github.com/angular/angular/issues/12160)) ([8b9ab44](https://github.com/angular/angular/commit/8b9ab44))
|
||||||
|
* **upgrade:** add support for AoT compiled upgrade applications ([d6791ff](https://github.com/angular/angular/commit/d6791ff)), closes [#12239](https://github.com/angular/angular/issues/12239)
|
||||||
* **upgrade:** add support for `require` in UpgradeComponent ([fe1d0e2](https://github.com/angular/angular/commit/fe1d0e2))
|
* **upgrade:** add support for `require` in UpgradeComponent ([fe1d0e2](https://github.com/angular/angular/commit/fe1d0e2))
|
||||||
* **upgrade:** add/improve support for lifecycle hooks in UpgradeComponent ([469010e](https://github.com/angular/angular/commit/469010e))
|
* **upgrade:** add/improve support for lifecycle hooks in UpgradeComponent ([469010e](https://github.com/angular/angular/commit/469010e))
|
||||||
|
|
||||||
|
@ -230,6 +230,7 @@ Must be one of the following:
|
|||||||
* **fix**: A bug fix
|
* **fix**: A bug fix
|
||||||
* **perf**: A code change that improves performance
|
* **perf**: A code change that improves performance
|
||||||
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
* **refactor**: A code change that neither fixes a bug nor adds a feature
|
||||||
|
* **style**: Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
|
||||||
* **test**: Adding missing tests or correcting existing tests
|
* **test**: Adding missing tests or correcting existing tests
|
||||||
|
|
||||||
|
|
||||||
|
@ -16,6 +16,13 @@ import {BuildNums, PrNums, SHA} from './constants';
|
|||||||
|
|
||||||
const logger = new Logger('mock-external-apis');
|
const logger = new Logger('mock-external-apis');
|
||||||
|
|
||||||
|
const log = (...args: any[]) => {
|
||||||
|
// Filter out non-matching URL checks
|
||||||
|
if (!/^matching.+: false$/.test(args[0])) {
|
||||||
|
logger.log(...args);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const AIO_CIRCLE_CI_TOKEN = getEnvVar('AIO_CIRCLE_CI_TOKEN');
|
const AIO_CIRCLE_CI_TOKEN = getEnvVar('AIO_CIRCLE_CI_TOKEN');
|
||||||
const AIO_GITHUB_TOKEN = getEnvVar('AIO_GITHUB_TOKEN');
|
const AIO_GITHUB_TOKEN = getEnvVar('AIO_GITHUB_TOKEN');
|
||||||
|
|
||||||
@ -84,8 +91,8 @@ const createArchive = (buildNum: number, prNum: number, sha: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Create request scopes
|
// Create request scopes
|
||||||
const circleCiApi = nock(CIRCLE_CI_API_HOST).persist();
|
const circleCiApi = nock(CIRCLE_CI_API_HOST).log(log).persist();
|
||||||
const githubApi = nock(GITHUB_API_HOST).persist().matchHeader('Authorization', `token ${AIO_GITHUB_TOKEN}`);
|
const githubApi = nock(GITHUB_API_HOST).log(log).persist().matchHeader('Authorization', `token ${AIO_GITHUB_TOKEN}`);
|
||||||
|
|
||||||
//////////////////////////////
|
//////////////////////////////
|
||||||
|
|
||||||
|
@ -27,28 +27,28 @@
|
|||||||
"body-parser": "^1.19.0",
|
"body-parser": "^1.19.0",
|
||||||
"delete-empty": "^3.0.0",
|
"delete-empty": "^3.0.0",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"jasmine": "^3.6.1",
|
"jasmine": "^3.5.0",
|
||||||
"nock": "^13.0.4",
|
"nock": "^12.0.3",
|
||||||
"node-fetch": "^2.6.1",
|
"node-fetch": "^2.6.0",
|
||||||
"shelljs": "^0.8.4",
|
"shelljs": "^0.8.4",
|
||||||
"source-map-support": "^0.5.19",
|
"source-map-support": "^0.5.19",
|
||||||
"tar-stream": "^2.1.3",
|
"tar-stream": "^2.1.2",
|
||||||
"tslib": "^2.0.1"
|
"tslib": "^1.11.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/body-parser": "^1.19.0",
|
"@types/body-parser": "^1.19.0",
|
||||||
"@types/express": "^4.17.8",
|
"@types/express": "^4.17.6",
|
||||||
"@types/jasmine": "^3.5.14",
|
"@types/jasmine": "^3.5.10",
|
||||||
"@types/nock": "^11.1.0",
|
"@types/nock": "^11.1.0",
|
||||||
"@types/node": "^14.6.4",
|
"@types/node": "^13.13.2",
|
||||||
"@types/node-fetch": "^2.5.7",
|
"@types/node-fetch": "^2.5.7",
|
||||||
"@types/shelljs": "^0.8.8",
|
"@types/shelljs": "^0.8.7",
|
||||||
"@types/supertest": "^2.0.10",
|
"@types/supertest": "^2.0.8",
|
||||||
"nodemon": "^2.0.4",
|
"nodemon": "^2.0.3",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"supertest": "^4.0.2",
|
"supertest": "^4.0.2",
|
||||||
"tslint": "^6.1.3",
|
"tslint": "^6.1.1",
|
||||||
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
"tslint-jasmine-noSkipOrFocus": "^1.0.9",
|
||||||
"typescript": "^4.0.2"
|
"typescript": "^3.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -214,24 +214,23 @@ describe('GithubApi', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should call \'https.request()\' with the correct options', async () => {
|
it('should call \'https.request()\' with the correct options', () => {
|
||||||
const requestHandler = nock('https://api.github.com')
|
const requestHandler = nock('https://api.github.com')
|
||||||
.intercept('/path', 'method')
|
.intercept('/path', 'method')
|
||||||
.reply(200);
|
.reply(200);
|
||||||
|
|
||||||
await (api as any).request('method', '/path');
|
(api as any).request('method', '/path');
|
||||||
requestHandler.done();
|
requestHandler.done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should add the \'Authorization\' header containing the \'githubToken\'', async () => {
|
it('should add the \'Authorization\' header containing the \'githubToken\'', () => {
|
||||||
const requestHandler = nock('https://api.github.com')
|
const requestHandler = nock('https://api.github.com')
|
||||||
.intercept('/path', 'method', undefined, {
|
.intercept('/path', 'method', undefined, {
|
||||||
reqheaders: {Authorization: 'token 12345'},
|
reqheaders: {Authorization: 'token 12345'},
|
||||||
})
|
})
|
||||||
.reply(200);
|
.reply(200);
|
||||||
|
(api as any).request('method', '/path');
|
||||||
await (api as any).request('method', '/path');
|
|
||||||
requestHandler.done();
|
requestHandler.done();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -245,13 +244,12 @@ describe('GithubApi', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should \'JSON.stringify\' and send the data along with the request', async () => {
|
it('should \'JSON.stringify\' and send the data along with the request', () => {
|
||||||
const data = {key: 'value'};
|
const data = {key: 'value'};
|
||||||
const requestHandler = nock('https://api.github.com')
|
const requestHandler = nock('https://api.github.com')
|
||||||
.intercept('/path', 'method', JSON.stringify(data))
|
.intercept('/path', 'method', JSON.stringify(data))
|
||||||
.reply(200);
|
.reply(200);
|
||||||
|
(api as any).request('method', '/path', data);
|
||||||
await (api as any).request('method', '/path', data);
|
|
||||||
requestHandler.done();
|
requestHandler.done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,13 +21,11 @@ import { ItemDirective } from './item.directive';
|
|||||||
ItemDirective
|
ItemDirective
|
||||||
],
|
],
|
||||||
// #enddocregion declarations
|
// #enddocregion declarations
|
||||||
// #docregion imports
|
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
HttpClientModule
|
HttpClientModule
|
||||||
],
|
],
|
||||||
// #enddocregion imports
|
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
@ -1,27 +1,27 @@
|
|||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { ReactiveModule } from './reactive/reactive.module';
|
|
||||||
import { TemplateModule } from './template/template.module';
|
import { TemplateModule } from './template/template.module';
|
||||||
|
import { ReactiveModule } from './reactive/reactive.module';
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
describe('AppComponent', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
TestBed
|
beforeEach(async(() => {
|
||||||
.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [ReactiveModule, TemplateModule],
|
imports: [ReactiveModule, TemplateModule],
|
||||||
declarations: [AppComponent],
|
declarations: [
|
||||||
})
|
AppComponent
|
||||||
.compileComponents();
|
],
|
||||||
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should create the app', waitForAsync(() => {
|
it('should create the app', async(() => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
const app = fixture.componentInstance;
|
const app = fixture.componentInstance;
|
||||||
|
|
||||||
expect(app).toBeTruthy();
|
expect(app).toBeTruthy();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should render title', waitForAsync(() => {
|
it('should render title', async(() => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { ReactiveFormsModule } from '@angular/forms';
|
import { ReactiveFormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { createNewEvent } from '../../shared/utils';
|
|
||||||
import { FavoriteColorComponent } from './favorite-color.component';
|
import { FavoriteColorComponent } from './favorite-color.component';
|
||||||
|
import { createNewEvent } from '../../shared/utils';
|
||||||
|
|
||||||
describe('Favorite Color Component', () => {
|
describe('Favorite Color Component', () => {
|
||||||
let component: FavoriteColorComponent;
|
let component: FavoriteColorComponent;
|
||||||
let fixture: ComponentFixture<FavoriteColorComponent>;
|
let fixture: ComponentFixture<FavoriteColorComponent>;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule(
|
imports: [ ReactiveFormsModule ],
|
||||||
{imports: [ReactiveFormsModule], declarations: [FavoriteColorComponent]})
|
declarations: [ FavoriteColorComponent ]
|
||||||
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed, tick, fakeAsync } from '@angular/core/testing';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
|
|
||||||
import { createNewEvent } from '../../shared/utils';
|
|
||||||
import { FavoriteColorComponent } from './favorite-color.component';
|
import { FavoriteColorComponent } from './favorite-color.component';
|
||||||
|
import { createNewEvent } from '../../shared/utils';
|
||||||
|
|
||||||
describe('FavoriteColorComponent', () => {
|
describe('FavoriteColorComponent', () => {
|
||||||
let component: FavoriteColorComponent;
|
let component: FavoriteColorComponent;
|
||||||
let fixture: ComponentFixture<FavoriteColorComponent>;
|
let fixture: ComponentFixture<FavoriteColorComponent>;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({imports: [FormsModule], declarations: [FavoriteColorComponent]})
|
TestBed.configureTestingModule({
|
||||||
|
imports: [ FormsModule ],
|
||||||
|
declarations: [ FavoriteColorComponent ]
|
||||||
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
<!-- #enddocregion translated-plural -->
|
<!-- #enddocregion translated-plural -->
|
||||||
<!-- #docregion translated-select -->
|
<!-- #docregion translated-select -->
|
||||||
<!-- #docregion translate-select-1 -->
|
<!-- #docregion translate-select-1 -->
|
||||||
|
</trans-unit>
|
||||||
<trans-unit id="f99f34ac9bd4606345071bd813858dec29f3b7d1" datatype="html">
|
<trans-unit id="f99f34ac9bd4606345071bd813858dec29f3b7d1" datatype="html">
|
||||||
<source>The author is <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></source>
|
<source>The author is <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></source>
|
||||||
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></target>
|
<target>L'auteur est <x id="ICU" equiv-text="{gender, select, male {...} female {...} other {...}}"/></target>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
// TODO: Add unit tests for this file.
|
|
||||||
// tslint:disable: no-output-native
|
// tslint:disable: no-output-native
|
||||||
// #docregion
|
// #docregion
|
||||||
import { Component, Output, OnInit, EventEmitter, NgModule } from '@angular/core';
|
import { Component, Output, OnInit, EventEmitter, NgModule } from '@angular/core';
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
"tests": [
|
"tests": [
|
||||||
{
|
{
|
||||||
"cmd": "yarn",
|
"cmd": "yarn",
|
||||||
"args": ["tsc", "--project", "tsconfig.spec.json", "--module", "commonjs"]
|
"args": [ "tsc", "--project", "./tsconfig.app.json" ]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmd": "yarn",
|
|
||||||
"args": ["jasmine", "out-tsc/**/*.spec.js"]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
import { docRegionFromEvent, docRegionSubscriber } from './creating';
|
|
||||||
|
|
||||||
describe('observables', () => {
|
|
||||||
it('should create an observable using the constructor', () => {
|
|
||||||
const console = {log: jasmine.createSpy('log')};
|
|
||||||
docRegionSubscriber(console);
|
|
||||||
expect(console.log).toHaveBeenCalledTimes(4);
|
|
||||||
expect(console.log.calls.allArgs()).toEqual([
|
|
||||||
[1],
|
|
||||||
[2],
|
|
||||||
[3],
|
|
||||||
['Finished sequence'],
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should listen to input changes', () => {
|
|
||||||
let triggerInputChange;
|
|
||||||
const input = {
|
|
||||||
value: 'Test',
|
|
||||||
addEventListener: jasmine
|
|
||||||
.createSpy('addEvent')
|
|
||||||
.and.callFake((eventName: string, cb: (e) => void) => {
|
|
||||||
if (eventName === 'keydown') {
|
|
||||||
triggerInputChange = cb;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
removeEventListener: jasmine.createSpy('removeEventListener'),
|
|
||||||
};
|
|
||||||
|
|
||||||
const document = { getElementById: () => input };
|
|
||||||
docRegionFromEvent(document);
|
|
||||||
triggerInputChange({keyCode: 65});
|
|
||||||
expect(input.value).toBe('Test');
|
|
||||||
|
|
||||||
triggerInputChange({keyCode: 27});
|
|
||||||
expect(input.value).toBe('');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should call removeEventListener when unsubscribing', (doneFn: DoneFn) => {
|
|
||||||
const input = {
|
|
||||||
addEventListener: jasmine.createSpy('addEvent'),
|
|
||||||
removeEventListener: jasmine
|
|
||||||
.createSpy('removeEvent')
|
|
||||||
.and.callFake((eventName: string, cb: (e) => void) => {
|
|
||||||
if (eventName === 'keydown') {
|
|
||||||
doneFn();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
const document = { getElementById: () => input };
|
|
||||||
const subscription = docRegionFromEvent(document);
|
|
||||||
subscription.unsubscribe();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,11 +1,10 @@
|
|||||||
// #docplaster
|
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
export function docRegionSubscriber(console) {
|
// #docregion subscriber
|
||||||
// #docregion subscriber
|
|
||||||
// This function runs when subscribe() is called
|
// This function runs when subscribe() is called
|
||||||
function sequenceSubscriber(observer) {
|
function sequenceSubscriber(observer) {
|
||||||
// synchronously deliver 1, 2, and 3, then complete
|
// synchronously deliver 1, 2, and 3, then complete
|
||||||
observer.next(1);
|
observer.next(1);
|
||||||
observer.next(2);
|
observer.next(2);
|
||||||
@ -15,24 +14,24 @@ export function docRegionSubscriber(console) {
|
|||||||
// unsubscribe function doesn't need to do anything in this
|
// unsubscribe function doesn't need to do anything in this
|
||||||
// because values are delivered synchronously
|
// because values are delivered synchronously
|
||||||
return {unsubscribe() {}};
|
return {unsubscribe() {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Observable that will deliver the above sequence
|
// Create a new Observable that will deliver the above sequence
|
||||||
const sequence = new Observable(sequenceSubscriber);
|
const sequence = new Observable(sequenceSubscriber);
|
||||||
|
|
||||||
// execute the Observable and print the result of each notification
|
// execute the Observable and print the result of each notification
|
||||||
sequence.subscribe({
|
sequence.subscribe({
|
||||||
next(num) { console.log(num); },
|
next(num) { console.log(num); },
|
||||||
complete() { console.log('Finished sequence'); }
|
complete() { console.log('Finished sequence'); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Logs:
|
// Logs:
|
||||||
// 1
|
// 1
|
||||||
// 2
|
// 2
|
||||||
// 3
|
// 3
|
||||||
// Finished sequence
|
// Finished sequence
|
||||||
// #enddocregion subscriber
|
|
||||||
}
|
// #enddocregion subscriber
|
||||||
|
|
||||||
// #docregion fromevent
|
// #docregion fromevent
|
||||||
|
|
||||||
@ -52,18 +51,16 @@ function fromEvent(target, eventName) {
|
|||||||
|
|
||||||
// #enddocregion fromevent
|
// #enddocregion fromevent
|
||||||
|
|
||||||
export function docRegionFromEvent(document) {
|
// #docregion fromevent_use
|
||||||
// #docregion fromevent_use
|
|
||||||
|
|
||||||
const ESC_KEY = 27;
|
const ESC_KEY = 27;
|
||||||
const nameInput = document.getElementById('name') as HTMLInputElement;
|
const nameInput = document.getElementById('name') as HTMLInputElement;
|
||||||
|
|
||||||
const subscription = fromEvent(nameInput, 'keydown').subscribe((e: KeyboardEvent) => {
|
const subscription = fromEvent(nameInput, 'keydown')
|
||||||
|
.subscribe((e: KeyboardEvent) => {
|
||||||
if (e.keyCode === ESC_KEY) {
|
if (e.keyCode === ESC_KEY) {
|
||||||
nameInput.value = '';
|
nameInput.value = '';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// #enddocregion fromevent_use
|
|
||||||
return subscription;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// #enddocregion fromevent_use
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// TODO: Add unit tests for this file.
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
// #docregion
|
// #docregion
|
||||||
|
|
||||||
// Create an Observable that will start listening to geolocation updates
|
// Create an Observable that will start listening to geolocation updates
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
import { docRegionDelaySequence, docRegionMulticastSequence } from './multicasting';
|
|
||||||
|
|
||||||
describe('multicasting', () => {
|
|
||||||
let console;
|
|
||||||
beforeEach(() => {
|
|
||||||
jasmine.clock().install();
|
|
||||||
console = {log: jasmine.createSpy('log')};
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
jasmine.clock().uninstall();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create an observable and emit in sequence', () => {
|
|
||||||
docRegionDelaySequence(console);
|
|
||||||
jasmine.clock().tick(10000);
|
|
||||||
expect(console.log).toHaveBeenCalledTimes(12);
|
|
||||||
expect(console.log.calls.allArgs()).toEqual([
|
|
||||||
[1],
|
|
||||||
['1st subscribe: 1'],
|
|
||||||
['2nd subscribe: 1'],
|
|
||||||
[2],
|
|
||||||
['1st subscribe: 2'],
|
|
||||||
['2nd subscribe: 2'],
|
|
||||||
[3],
|
|
||||||
['Finished sequence'],
|
|
||||||
['1st subscribe: 3'],
|
|
||||||
['1st sequence finished.'],
|
|
||||||
['2nd subscribe: 3'],
|
|
||||||
['2nd sequence finished.']
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create an observable and multicast the emissions', () => {
|
|
||||||
docRegionMulticastSequence(console);
|
|
||||||
jasmine.clock().tick(10000);
|
|
||||||
expect(console.log).toHaveBeenCalledTimes(7);
|
|
||||||
expect(console.log.calls.allArgs()).toEqual([
|
|
||||||
['1st subscribe: 1'],
|
|
||||||
['1st subscribe: 2'],
|
|
||||||
['2nd subscribe: 2'],
|
|
||||||
['1st subscribe: 3'],
|
|
||||||
['2nd subscribe: 3'],
|
|
||||||
['1st sequence finished.'],
|
|
||||||
['2nd sequence finished.']
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,10 +1,9 @@
|
|||||||
// #docplaster
|
|
||||||
|
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
|
|
||||||
export function docRegionDelaySequence(console) {
|
// #docregion delay_sequence
|
||||||
// #docregion delay_sequence
|
|
||||||
function sequenceSubscriber(observer) {
|
function sequenceSubscriber(observer) {
|
||||||
const seq = [1, 2, 3];
|
const seq = [1, 2, 3];
|
||||||
let timeoutId;
|
let timeoutId;
|
||||||
|
|
||||||
@ -24,61 +23,58 @@ export function docRegionDelaySequence(console) {
|
|||||||
doInSequence(seq, 0);
|
doInSequence(seq, 0);
|
||||||
|
|
||||||
// Unsubscribe should clear the timeout to stop execution
|
// Unsubscribe should clear the timeout to stop execution
|
||||||
return {
|
return {unsubscribe() {
|
||||||
unsubscribe() {
|
|
||||||
clearTimeout(timeoutId);
|
clearTimeout(timeoutId);
|
||||||
}
|
}};
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Create a new Observable that will deliver the above sequence
|
// Create a new Observable that will deliver the above sequence
|
||||||
const sequence = new Observable(sequenceSubscriber);
|
const sequence = new Observable(sequenceSubscriber);
|
||||||
|
|
||||||
sequence.subscribe({
|
sequence.subscribe({
|
||||||
next(num) { console.log(num); },
|
next(num) { console.log(num); },
|
||||||
complete() { console.log('Finished sequence'); }
|
complete() { console.log('Finished sequence'); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// Logs:
|
// Logs:
|
||||||
// (at 1 second): 1
|
// (at 1 second): 1
|
||||||
// (at 2 seconds): 2
|
// (at 2 seconds): 2
|
||||||
// (at 3 seconds): 3
|
// (at 3 seconds): 3
|
||||||
// (at 3 seconds): Finished sequence
|
// (at 3 seconds): Finished sequence
|
||||||
|
|
||||||
// #enddocregion delay_sequence
|
// #enddocregion delay_sequence
|
||||||
|
|
||||||
// #docregion subscribe_twice
|
// #docregion subscribe_twice
|
||||||
|
|
||||||
// Subscribe starts the clock, and will emit after 1 second
|
// Subscribe starts the clock, and will emit after 1 second
|
||||||
sequence.subscribe({
|
sequence.subscribe({
|
||||||
next(num) { console.log('1st subscribe: ' + num); },
|
next(num) { console.log('1st subscribe: ' + num); },
|
||||||
complete() { console.log('1st sequence finished.'); }
|
complete() { console.log('1st sequence finished.'); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// After 1/2 second, subscribe again.
|
// After 1/2 second, subscribe again.
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
sequence.subscribe({
|
sequence.subscribe({
|
||||||
next(num) { console.log('2nd subscribe: ' + num); },
|
next(num) { console.log('2nd subscribe: ' + num); },
|
||||||
complete() { console.log('2nd sequence finished.'); }
|
complete() { console.log('2nd sequence finished.'); }
|
||||||
});
|
});
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
||||||
// Logs:
|
// Logs:
|
||||||
// (at 1 second): 1st subscribe: 1
|
// (at 1 second): 1st subscribe: 1
|
||||||
// (at 1.5 seconds): 2nd subscribe: 1
|
// (at 1.5 seconds): 2nd subscribe: 1
|
||||||
// (at 2 seconds): 1st subscribe: 2
|
// (at 2 seconds): 1st subscribe: 2
|
||||||
// (at 2.5 seconds): 2nd subscribe: 2
|
// (at 2.5 seconds): 2nd subscribe: 2
|
||||||
// (at 3 seconds): 1st subscribe: 3
|
// (at 3 seconds): 1st subscribe: 3
|
||||||
// (at 3 seconds): 1st sequence finished
|
// (at 3 seconds): 1st sequence finished
|
||||||
// (at 3.5 seconds): 2nd subscribe: 3
|
// (at 3.5 seconds): 2nd subscribe: 3
|
||||||
// (at 3.5 seconds): 2nd sequence finished
|
// (at 3.5 seconds): 2nd sequence finished
|
||||||
|
|
||||||
// #enddocregion subscribe_twice
|
// #enddocregion subscribe_twice
|
||||||
}
|
|
||||||
|
|
||||||
export function docRegionMulticastSequence(console) {
|
// #docregion multicast_sequence
|
||||||
// #docregion multicast_sequence
|
|
||||||
function multicastSequenceSubscriber() {
|
function multicastSequenceSubscriber() {
|
||||||
const seq = [1, 2, 3];
|
const seq = [1, 2, 3];
|
||||||
// Keep track of each observer (one for every active subscription)
|
// Keep track of each observer (one for every active subscription)
|
||||||
const observers = [];
|
const observers = [];
|
||||||
@ -88,7 +84,7 @@ export function docRegionMulticastSequence(console) {
|
|||||||
|
|
||||||
// Return the subscriber function (runs when subscribe()
|
// Return the subscriber function (runs when subscribe()
|
||||||
// function is invoked)
|
// function is invoked)
|
||||||
return observer => {
|
return (observer) => {
|
||||||
observers.push(observer);
|
observers.push(observer);
|
||||||
// When this is the first subscription, start the sequence
|
// When this is the first subscription, start the sequence
|
||||||
if (observers.length === 1) {
|
if (observers.length === 1) {
|
||||||
@ -115,11 +111,11 @@ export function docRegionMulticastSequence(console) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run through an array of numbers, emitting one value
|
// Run through an array of numbers, emitting one value
|
||||||
// per second until it gets to the end of the array.
|
// per second until it gets to the end of the array.
|
||||||
function doSequence(observer, arr, idx) {
|
function doSequence(observer, arr, idx) {
|
||||||
return setTimeout(() => {
|
return setTimeout(() => {
|
||||||
observer.next(arr[idx]);
|
observer.next(arr[idx]);
|
||||||
if (idx === arr.length - 1) {
|
if (idx === arr.length - 1) {
|
||||||
@ -128,33 +124,32 @@ export function docRegionMulticastSequence(console) {
|
|||||||
doSequence(observer, arr, ++idx);
|
doSequence(observer, arr, ++idx);
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new Observable that will deliver the above sequence
|
// Create a new Observable that will deliver the above sequence
|
||||||
const multicastSequence = new Observable(multicastSequenceSubscriber());
|
const multicastSequence = new Observable(multicastSequenceSubscriber());
|
||||||
|
|
||||||
// Subscribe starts the clock, and begins to emit after 1 second
|
// Subscribe starts the clock, and begins to emit after 1 second
|
||||||
multicastSequence.subscribe({
|
multicastSequence.subscribe({
|
||||||
next(num) { console.log('1st subscribe: ' + num); },
|
next(num) { console.log('1st subscribe: ' + num); },
|
||||||
complete() { console.log('1st sequence finished.'); }
|
complete() { console.log('1st sequence finished.'); }
|
||||||
});
|
});
|
||||||
|
|
||||||
// After 1 1/2 seconds, subscribe again (should "miss" the first value).
|
// After 1 1/2 seconds, subscribe again (should "miss" the first value).
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
multicastSequence.subscribe({
|
multicastSequence.subscribe({
|
||||||
next(num) { console.log('2nd subscribe: ' + num); },
|
next(num) { console.log('2nd subscribe: ' + num); },
|
||||||
complete() { console.log('2nd sequence finished.'); }
|
complete() { console.log('2nd sequence finished.'); }
|
||||||
});
|
});
|
||||||
}, 1500);
|
}, 1500);
|
||||||
|
|
||||||
// Logs:
|
// Logs:
|
||||||
// (at 1 second): 1st subscribe: 1
|
// (at 1 second): 1st subscribe: 1
|
||||||
// (at 2 seconds): 1st subscribe: 2
|
// (at 2 seconds): 1st subscribe: 2
|
||||||
// (at 2 seconds): 2nd subscribe: 2
|
// (at 2 seconds): 2nd subscribe: 2
|
||||||
// (at 3 seconds): 1st subscribe: 3
|
// (at 3 seconds): 1st subscribe: 3
|
||||||
// (at 3 seconds): 1st sequence finished
|
// (at 3 seconds): 1st sequence finished
|
||||||
// (at 3 seconds): 2nd subscribe: 3
|
// (at 3 seconds): 2nd subscribe: 3
|
||||||
// (at 3 seconds): 2nd sequence finished
|
// (at 3 seconds): 2nd sequence finished
|
||||||
|
|
||||||
// #enddocregion multicast_sequence
|
// #enddocregion multicast_sequence
|
||||||
}
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
import { docRegionObserver } from './subscribing';
|
|
||||||
|
|
||||||
describe('subscribing', () => {
|
|
||||||
it('should subscribe and emit', () => {
|
|
||||||
const console = {log: jasmine.createSpy('log')};
|
|
||||||
docRegionObserver(console);
|
|
||||||
expect(console.log).toHaveBeenCalledTimes(8);
|
|
||||||
expect(console.log.calls.allArgs()).toEqual([
|
|
||||||
['Observer got a next value: 1'],
|
|
||||||
['Observer got a next value: 2'],
|
|
||||||
['Observer got a next value: 3'],
|
|
||||||
['Observer got a complete notification'],
|
|
||||||
['Observer got a next value: 1'],
|
|
||||||
['Observer got a next value: 2'],
|
|
||||||
['Observer got a next value: 3'],
|
|
||||||
['Observer got a complete notification'],
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,35 +1,32 @@
|
|||||||
// #docplaster
|
|
||||||
import { of } from 'rxjs';
|
|
||||||
|
|
||||||
export function docRegionObserver(console) {
|
import { Observable, of } from 'rxjs';
|
||||||
// #docregion observer
|
|
||||||
|
|
||||||
// Create simple observable that emits three values
|
// #docregion observer
|
||||||
const myObservable = of(1, 2, 3);
|
|
||||||
|
|
||||||
// Create observer object
|
// Create simple observable that emits three values
|
||||||
const myObserver = {
|
const myObservable = of(1, 2, 3);
|
||||||
|
|
||||||
|
// Create observer object
|
||||||
|
const myObserver = {
|
||||||
next: x => console.log('Observer got a next value: ' + x),
|
next: x => console.log('Observer got a next value: ' + x),
|
||||||
error: err => console.error('Observer got an error: ' + err),
|
error: err => console.error('Observer got an error: ' + err),
|
||||||
complete: () => console.log('Observer got a complete notification'),
|
complete: () => console.log('Observer got a complete notification'),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Execute with the observer object
|
// Execute with the observer object
|
||||||
myObservable.subscribe(myObserver);
|
myObservable.subscribe(myObserver);
|
||||||
|
// Logs:
|
||||||
|
// Observer got a next value: 1
|
||||||
|
// Observer got a next value: 2
|
||||||
|
// Observer got a next value: 3
|
||||||
|
// Observer got a complete notification
|
||||||
|
|
||||||
// Logs:
|
// #enddocregion observer
|
||||||
// Observer got a next value: 1
|
|
||||||
// Observer got a next value: 2
|
|
||||||
// Observer got a next value: 3
|
|
||||||
// Observer got a complete notification
|
|
||||||
|
|
||||||
// #enddocregion observer
|
// #docregion sub_fn
|
||||||
|
myObservable.subscribe(
|
||||||
// #docregion sub_fn
|
|
||||||
myObservable.subscribe(
|
|
||||||
x => console.log('Observer got a next value: ' + x),
|
x => console.log('Observer got a next value: ' + x),
|
||||||
err => console.error('Observer got an error: ' + err),
|
err => console.error('Observer got an error: ' + err),
|
||||||
() => console.log('Observer got a complete notification')
|
() => console.log('Observer got a complete notification')
|
||||||
);
|
);
|
||||||
// #enddocregion sub_fn
|
// #enddocregion sub_fn
|
||||||
}
|
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
"tests": [
|
"tests": [
|
||||||
{
|
{
|
||||||
"cmd": "yarn",
|
"cmd": "yarn",
|
||||||
"args": ["tsc", "--project", "tsconfig.spec.json", "--module", "commonjs"]
|
"args": [ "tsc", "--project", "./tsconfig.app.json" ]
|
||||||
},
|
|
||||||
{
|
|
||||||
"cmd": "yarn",
|
|
||||||
"args": ["jasmine", "out-tsc/**/*.spec.js"]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// TODO: Add unit tests for this file.
|
|
||||||
import { pipe, range, timer, zip } from 'rxjs';
|
import { pipe, range, timer, zip } from 'rxjs';
|
||||||
import { ajax } from 'rxjs/ajax';
|
import { ajax } from 'rxjs/ajax';
|
||||||
import { retryWhen, map, mergeMap } from 'rxjs/operators';
|
import { retryWhen, map, mergeMap } from 'rxjs/operators';
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
import { of } from 'rxjs';
|
|
||||||
import { docRegionTypeahead } from './typeahead';
|
|
||||||
|
|
||||||
describe('typeahead', () => {
|
|
||||||
let document;
|
|
||||||
let ajax;
|
|
||||||
let triggertInputChange;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
jasmine.clock().install();
|
|
||||||
const input = {
|
|
||||||
addEventListener: jasmine
|
|
||||||
.createSpy('addEvent')
|
|
||||||
.and.callFake((eventName: string, cb: (e) => void) => {
|
|
||||||
if (eventName === 'input') {
|
|
||||||
triggertInputChange = cb;
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
removeEventListener: jasmine.createSpy('removeEvent'),
|
|
||||||
};
|
|
||||||
|
|
||||||
document = { getElementById: (id: string) => input };
|
|
||||||
ajax = jasmine.createSpy('ajax').and.callFake((url: string) => of('foo bar'));
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
|
||||||
jasmine.clock().uninstall();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should make an ajax call to the corrent endpoint', () => {
|
|
||||||
docRegionTypeahead(document, ajax);
|
|
||||||
triggertInputChange({ target: { value: 'foo' } });
|
|
||||||
jasmine.clock().tick(11);
|
|
||||||
expect(ajax).toHaveBeenCalledWith('/api/endpoint?search=foo');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not make an ajax call, when the input length < 3', () => {
|
|
||||||
docRegionTypeahead(document, ajax);
|
|
||||||
triggertInputChange({ target: { value: '' } });
|
|
||||||
jasmine.clock().tick(11);
|
|
||||||
expect(ajax).not.toHaveBeenCalled();
|
|
||||||
triggertInputChange({ target: { value: 'fo' } });
|
|
||||||
jasmine.clock().tick(11);
|
|
||||||
expect(ajax).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not make an ajax call for intermediate values when debouncing', () => {
|
|
||||||
docRegionTypeahead(document, ajax);
|
|
||||||
triggertInputChange({ target: { value: 'foo' } });
|
|
||||||
jasmine.clock().tick(9);
|
|
||||||
triggertInputChange({ target: { value: 'bar' } });
|
|
||||||
jasmine.clock().tick(9);
|
|
||||||
triggertInputChange({ target: { value: 'baz' } });
|
|
||||||
jasmine.clock().tick(9);
|
|
||||||
triggertInputChange({ target: { value: 'qux' } });
|
|
||||||
expect(ajax).not.toHaveBeenCalled();
|
|
||||||
jasmine.clock().tick(10);
|
|
||||||
expect(ajax).toHaveBeenCalledTimes(1);
|
|
||||||
expect(ajax).toHaveBeenCalledWith('/api/endpoint?search=qux');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not make an ajax call, when the input value has not changed', () => {
|
|
||||||
docRegionTypeahead(document, ajax);
|
|
||||||
triggertInputChange({ target: { value: 'foo' } });
|
|
||||||
jasmine.clock().tick(11);
|
|
||||||
expect(ajax).toHaveBeenCalled();
|
|
||||||
ajax.calls.reset();
|
|
||||||
triggertInputChange({ target: { value: 'foo' } });
|
|
||||||
jasmine.clock().tick(11);
|
|
||||||
expect(ajax).not.toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,32 +1,18 @@
|
|||||||
/*
|
import { fromEvent } from 'rxjs';
|
||||||
Because of how the code is merged together using the doc regions,
|
import { ajax } from 'rxjs/ajax';
|
||||||
we need to indent the imports with the function below.
|
import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
|
||||||
*/
|
|
||||||
// #docplaster
|
|
||||||
// #docregion
|
|
||||||
import { fromEvent } from 'rxjs';
|
|
||||||
import { ajax } from 'rxjs/ajax';
|
|
||||||
import { debounceTime, distinctUntilChanged, filter, map, switchMap } from 'rxjs/operators';
|
|
||||||
|
|
||||||
// #enddocregion
|
|
||||||
/* tslint:disable:no-shadowed-variable */
|
|
||||||
/* tslint:disable:align */
|
|
||||||
export function docRegionTypeahead(document, ajax) {
|
|
||||||
// #docregion
|
|
||||||
const searchBox = document.getElementById('search-box');
|
|
||||||
|
|
||||||
const typeahead = fromEvent(searchBox, 'input').pipe(
|
const searchBox = document.getElementById('search-box');
|
||||||
|
|
||||||
|
const typeahead = fromEvent(searchBox, 'input').pipe(
|
||||||
map((e: KeyboardEvent) => (e.target as HTMLInputElement).value),
|
map((e: KeyboardEvent) => (e.target as HTMLInputElement).value),
|
||||||
filter(text => text.length > 2),
|
filter(text => text.length > 2),
|
||||||
debounceTime(10),
|
debounceTime(10),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
switchMap(searchTerm => ajax(`/api/endpoint?search=${searchTerm}`))
|
switchMap(() => ajax('/api/endpoint'))
|
||||||
);
|
);
|
||||||
|
|
||||||
typeahead.subscribe(data => {
|
typeahead.subscribe(data => {
|
||||||
// Handle the data from the API
|
// Handle the data from the API
|
||||||
});
|
});
|
||||||
|
|
||||||
// #enddocregion
|
|
||||||
return typeahead;
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { MyLibComponent } from './my-lib.component';
|
import { MyLibComponent } from './my-lib.component';
|
||||||
|
|
||||||
@ -6,8 +6,11 @@ describe('MyLibComponent', () => {
|
|||||||
let component: MyLibComponent;
|
let component: MyLibComponent;
|
||||||
let fixture: ComponentFixture<MyLibComponent>;
|
let fixture: ComponentFixture<MyLibComponent>;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({declarations: [MyLibComponent]}).compileComponents();
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ MyLibComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
import { DebugElement } from '@angular/core';
|
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
describe('AppComponent', () => {
|
describe('AppComponent', () => {
|
||||||
let de: DebugElement;
|
let de: DebugElement;
|
||||||
let comp: AppComponent;
|
let comp: AppComponent;
|
||||||
let fixture: ComponentFixture<AppComponent>;
|
let fixture: ComponentFixture<AppComponent>;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({declarations: [AppComponent]}).compileComponents();
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ AppComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -19,11 +22,12 @@ describe('AppComponent', () => {
|
|||||||
de = fixture.debugElement.query(By.css('h1'));
|
de = fixture.debugElement.query(By.css('h1'));
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should create component', () => expect(comp).toBeDefined());
|
it('should create component', () => expect(comp).toBeDefined() );
|
||||||
|
|
||||||
it('should have expected <h1> text', () => {
|
it('should have expected <h1> text', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const h1 = de.nativeElement;
|
const h1 = de.nativeElement;
|
||||||
expect(h1.textContent).toMatch(/angular/i, '<h1> should say something about "Angular"');
|
expect(h1.textContent).toMatch(/angular/i,
|
||||||
|
'<h1> should say something about "Angular"');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
<script src="systemjs.config.js"></script>
|
<script src="systemjs.config.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
@ -10,8 +10,8 @@ import { Hero } from '../shared/hero.model';
|
|||||||
template: `
|
template: `
|
||||||
<section>
|
<section>
|
||||||
Our list of heroes:
|
Our list of heroes:
|
||||||
<toh-hero *ngFor="let hero of heroes" [hero]="hero">
|
<hero-profile *ngFor="let hero of heroes" [hero]="hero">
|
||||||
</toh-hero>
|
</hero-profile>
|
||||||
Total powers: {{totalPowers}}<br>
|
Total powers: {{totalPowers}}<br>
|
||||||
Average power: {{totalPowers / heroes.length}}
|
Average power: {{totalPowers / heroes.length}}
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion
|
// #docregion
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
import { TestBed, async } from '@angular/core/testing';
|
||||||
// #enddocregion
|
// #enddocregion
|
||||||
import { AppComponent } from './app-initial.component';
|
import { AppComponent } from './app-initial.component';
|
||||||
/*
|
/*
|
||||||
@ -12,24 +12,24 @@ describe('AppComponent', () => {
|
|||||||
*/
|
*/
|
||||||
describe('AppComponent (initial CLI version)', () => {
|
describe('AppComponent (initial CLI version)', () => {
|
||||||
// #docregion
|
// #docregion
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
declarations: [
|
||||||
declarations: [AppComponent],
|
AppComponent
|
||||||
})
|
],
|
||||||
.compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
it('should create the app', waitForAsync(() => {
|
it('should create the app', async(() => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
const app = fixture.componentInstance;
|
const app = fixture.componentInstance;
|
||||||
expect(app).toBeTruthy();
|
expect(app).toBeTruthy();
|
||||||
}));
|
}));
|
||||||
it(`should have as title 'app'`, waitForAsync(() => {
|
it(`should have as title 'app'`, async(() => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
const app = fixture.componentInstance;
|
const app = fixture.componentInstance;
|
||||||
expect(app.title).toEqual('app');
|
expect(app.title).toEqual('app');
|
||||||
}));
|
}));
|
||||||
it('should render title', waitForAsync(() => {
|
it('should render title', async(() => {
|
||||||
const fixture = TestBed.createComponent(AppComponent);
|
const fixture = TestBed.createComponent(AppComponent);
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
const compiled = fixture.nativeElement;
|
const compiled = fixture.nativeElement;
|
||||||
@ -43,13 +43,16 @@ import { DebugElement } from '@angular/core';
|
|||||||
import { ComponentFixture } from '@angular/core/testing';
|
import { ComponentFixture } from '@angular/core/testing';
|
||||||
|
|
||||||
describe('AppComponent (initial CLI version - as it should be)', () => {
|
describe('AppComponent (initial CLI version - as it should be)', () => {
|
||||||
|
|
||||||
let app: AppComponent;
|
let app: AppComponent;
|
||||||
let de: DebugElement;
|
let de: DebugElement;
|
||||||
let fixture: ComponentFixture<AppComponent>;
|
let fixture: ComponentFixture<AppComponent>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [AppComponent],
|
declarations: [
|
||||||
|
AppComponent
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
fixture = TestBed.createComponent(AppComponent);
|
fixture = TestBed.createComponent(AppComponent);
|
||||||
@ -67,6 +70,7 @@ describe('AppComponent (initial CLI version - as it should be)', () => {
|
|||||||
|
|
||||||
it('should render title in an h1 tag', () => {
|
it('should render title in an h1 tag', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(de.nativeElement.querySelector('h1').textContent).toContain('Welcome to app!');
|
expect(de.nativeElement.querySelector('h1').textContent)
|
||||||
|
.toContain('Welcome to app!');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// For more examples:
|
// For more examples:
|
||||||
// https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts
|
// https://github.com/angular/angular/blob/master/modules/@angular/router/test/integration.spec.ts
|
||||||
|
|
||||||
import { waitForAsync, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
import { async, ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
|
||||||
|
|
||||||
import { asyncData } from '../testing';
|
import { asyncData } from '../testing';
|
||||||
|
|
||||||
@ -21,9 +21,9 @@ import { AppModule } from './app.module';
|
|||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { AboutComponent } from './about/about.component';
|
import { AboutComponent } from './about/about.component';
|
||||||
import { DashboardComponent } from './dashboard/dashboard.component';
|
import { DashboardComponent } from './dashboard/dashboard.component';
|
||||||
|
import { TwainService } from './twain/twain.service';
|
||||||
|
|
||||||
import { HeroService, TestHeroService } from './model/testing/test-hero.service';
|
import { HeroService, TestHeroService } from './model/testing/test-hero.service';
|
||||||
import { TwainService } from './twain/twain.service';
|
|
||||||
|
|
||||||
let comp: AppComponent;
|
let comp: AppComponent;
|
||||||
let fixture: ComponentFixture<AppComponent>;
|
let fixture: ComponentFixture<AppComponent>;
|
||||||
@ -32,14 +32,16 @@ let router: Router;
|
|||||||
let location: SpyLocation;
|
let location: SpyLocation;
|
||||||
|
|
||||||
describe('AppComponent & RouterTestingModule', () => {
|
describe('AppComponent & RouterTestingModule', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
TestBed
|
beforeEach(async(() => {
|
||||||
.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
AppModule,
|
AppModule,
|
||||||
RouterTestingModule.withRoutes(routes),
|
RouterTestingModule.withRoutes(routes),
|
||||||
],
|
],
|
||||||
providers: [{provide: HeroService, useClass: TestHeroService}]
|
providers: [
|
||||||
|
{ provide: HeroService, useClass: TestHeroService }
|
||||||
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
@ -77,6 +79,7 @@ describe('AppComponent & RouterTestingModule', () => {
|
|||||||
advance();
|
advance();
|
||||||
expectPathToBe('/heroes');
|
expectPathToBe('/heroes');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -91,9 +94,9 @@ let loader: SpyNgModuleFactoryLoader;
|
|||||||
|
|
||||||
///////// Can't get lazy loaded Heroes to work yet
|
///////// Can't get lazy loaded Heroes to work yet
|
||||||
xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
|
xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
TestBed
|
beforeEach(async(() => {
|
||||||
.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [
|
imports: [
|
||||||
AppModule,
|
AppModule,
|
||||||
RouterTestingModule.withRoutes(routes),
|
RouterTestingModule.withRoutes(routes),
|
||||||
@ -105,11 +108,11 @@ xdescribe('AppComponent & Lazy Loading (not working yet)', () => {
|
|||||||
beforeEach(fakeAsync(() => {
|
beforeEach(fakeAsync(() => {
|
||||||
createComponent();
|
createComponent();
|
||||||
loader = TestBed.inject(NgModuleFactoryLoader) as SpyNgModuleFactoryLoader;
|
loader = TestBed.inject(NgModuleFactoryLoader) as SpyNgModuleFactoryLoader;
|
||||||
loader.stubbedModules = {expected: HeroModule};
|
loader.stubbedModules = { expected: HeroModule };
|
||||||
router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]);
|
router.resetConfig([{path: 'heroes', loadChildren: 'expected'}]);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should navigate to "Heroes" on click', waitForAsync(() => {
|
it('should navigate to "Heroes" on click', async(() => {
|
||||||
page.heroesLinkDe.nativeElement.click();
|
page.heroesLinkDe.nativeElement.click();
|
||||||
advance();
|
advance();
|
||||||
expectPathToBe('/heroes');
|
expectPathToBe('/heroes');
|
||||||
|
@ -1,42 +1,40 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { Component, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
import { Component, DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { RouterLinkDirectiveStub } from '../testing';
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
import { RouterLinkDirectiveStub } from '../testing';
|
||||||
|
|
||||||
// #docregion component-stubs
|
// #docregion component-stubs
|
||||||
@Component({selector: 'app-banner', template: ''})
|
@Component({selector: 'app-banner', template: ''})
|
||||||
class BannerStubComponent {
|
class BannerStubComponent {}
|
||||||
}
|
|
||||||
|
|
||||||
@Component({selector: 'router-outlet', template: ''})
|
@Component({selector: 'router-outlet', template: ''})
|
||||||
class RouterOutletStubComponent {
|
class RouterOutletStubComponent { }
|
||||||
}
|
|
||||||
|
|
||||||
@Component({selector: 'app-welcome', template: ''})
|
@Component({selector: 'app-welcome', template: ''})
|
||||||
class WelcomeStubComponent {
|
class WelcomeStubComponent {}
|
||||||
}
|
|
||||||
// #enddocregion component-stubs
|
// #enddocregion component-stubs
|
||||||
|
|
||||||
let comp: AppComponent;
|
let comp: AppComponent;
|
||||||
let fixture: ComponentFixture<AppComponent>;
|
let fixture: ComponentFixture<AppComponent>;
|
||||||
|
|
||||||
describe('AppComponent & TestModule', () => {
|
describe('AppComponent & TestModule', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
// #docregion testbed-stubs
|
// #docregion testbed-stubs
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent, RouterLinkDirectiveStub, BannerStubComponent, RouterOutletStubComponent,
|
AppComponent,
|
||||||
|
RouterLinkDirectiveStub,
|
||||||
|
BannerStubComponent,
|
||||||
|
RouterOutletStubComponent,
|
||||||
WelcomeStubComponent
|
WelcomeStubComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
// #enddocregion testbed-stubs
|
// #enddocregion testbed-stubs
|
||||||
.compileComponents()
|
.compileComponents().then(() => {
|
||||||
.then(() => {
|
|
||||||
fixture = TestBed.createComponent(AppComponent);
|
fixture = TestBed.createComponent(AppComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
});
|
});
|
||||||
@ -46,10 +44,9 @@ describe('AppComponent & TestModule', () => {
|
|||||||
|
|
||||||
//////// Testing w/ NO_ERRORS_SCHEMA //////
|
//////// Testing w/ NO_ERRORS_SCHEMA //////
|
||||||
describe('AppComponent & NO_ERRORS_SCHEMA', () => {
|
describe('AppComponent & NO_ERRORS_SCHEMA', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
// #docregion no-errors-schema, mixed-setup
|
// #docregion no-errors-schema, mixed-setup
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
// #enddocregion no-errors-schema
|
// #enddocregion no-errors-schema
|
||||||
@ -57,11 +54,10 @@ describe('AppComponent & NO_ERRORS_SCHEMA', () => {
|
|||||||
// #docregion no-errors-schema
|
// #docregion no-errors-schema
|
||||||
RouterLinkDirectiveStub
|
RouterLinkDirectiveStub
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [ NO_ERRORS_SCHEMA ]
|
||||||
})
|
})
|
||||||
// #enddocregion no-errors-schema, mixed-setup
|
// #enddocregion no-errors-schema, mixed-setup
|
||||||
.compileComponents()
|
.compileComponents().then(() => {
|
||||||
.then(() => {
|
|
||||||
fixture = TestBed.createComponent(AppComponent);
|
fixture = TestBed.createComponent(AppComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
});
|
});
|
||||||
@ -76,15 +72,22 @@ import { AppModule } from './app.module';
|
|||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
|
||||||
describe('AppComponent & AppModule', () => {
|
describe('AppComponent & AppModule', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
TestBed
|
beforeEach(async(() => {
|
||||||
.configureTestingModule({imports: [AppModule]})
|
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [ AppModule ]
|
||||||
|
})
|
||||||
|
|
||||||
// Get rid of app's Router configuration otherwise many failures.
|
// Get rid of app's Router configuration otherwise many failures.
|
||||||
// Doing so removes Router declarations; add the Router stubs
|
// Doing so removes Router declarations; add the Router stubs
|
||||||
.overrideModule(AppModule, {
|
.overrideModule(AppModule, {
|
||||||
remove: {imports: [AppRoutingModule]},
|
remove: {
|
||||||
add: {declarations: [RouterLinkDirectiveStub, RouterOutletStubComponent]}
|
imports: [ AppRoutingModule ]
|
||||||
|
},
|
||||||
|
add: {
|
||||||
|
declarations: [ RouterLinkDirectiveStub, RouterOutletStubComponent ]
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
.compileComponents()
|
.compileComponents()
|
||||||
@ -107,7 +110,8 @@ function tests() {
|
|||||||
fixture.detectChanges(); // trigger initial data binding
|
fixture.detectChanges(); // trigger initial data binding
|
||||||
|
|
||||||
// find DebugElements with an attached RouterLinkStubDirective
|
// find DebugElements with an attached RouterLinkStubDirective
|
||||||
linkDes = fixture.debugElement.queryAll(By.directive(RouterLinkDirectiveStub));
|
linkDes = fixture.debugElement
|
||||||
|
.queryAll(By.directive(RouterLinkDirectiveStub));
|
||||||
|
|
||||||
// get attached link directive instances
|
// get attached link directive instances
|
||||||
// using each DebugElement's injector
|
// using each DebugElement's injector
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion import-async
|
// #docregion import-async
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
// #enddocregion import-async
|
// #enddocregion import-async
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
@ -14,10 +14,9 @@ describe('BannerComponent (external files)', () => {
|
|||||||
|
|
||||||
describe('Two beforeEach', () => {
|
describe('Two beforeEach', () => {
|
||||||
// #docregion async-before-each
|
// #docregion async-before-each
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
declarations: [ BannerComponent ],
|
||||||
declarations: [BannerComponent],
|
|
||||||
})
|
})
|
||||||
.compileComponents(); // compile template and css
|
.compileComponents(); // compile template and css
|
||||||
}));
|
}));
|
||||||
@ -37,10 +36,9 @@ describe('BannerComponent (external files)', () => {
|
|||||||
|
|
||||||
describe('One beforeEach', () => {
|
describe('One beforeEach', () => {
|
||||||
// #docregion one-before-each
|
// #docregion one-before-each
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
declarations: [ BannerComponent ],
|
||||||
declarations: [BannerComponent],
|
|
||||||
})
|
})
|
||||||
.compileComponents()
|
.compileComponents()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -71,3 +69,4 @@ describe('BannerComponent (external files)', () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion import-by
|
// #docregion import-by
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
// #enddocregion import-by
|
// #enddocregion import-by
|
||||||
// #docregion import-debug-element
|
// #docregion import-debug-element
|
||||||
import { DebugElement } from '@angular/core';
|
import { DebugElement } from '@angular/core';
|
||||||
// #enddocregion import-debug-element
|
// #enddocregion import-debug-element
|
||||||
// #docregion v1
|
// #docregion v1
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { By } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
// #enddocregion v1
|
// #enddocregion v1
|
||||||
import { BannerComponent } from './banner-initial.component';
|
import { BannerComponent } from './banner-initial.component';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// #docregion v1
|
// #docregion v1
|
||||||
import { BannerComponent } from './banner.component';
|
import { BannerComponent } from './banner.component';
|
||||||
@ -19,12 +17,15 @@ describe('BannerComponent', () => {
|
|||||||
// #enddocregion v1
|
// #enddocregion v1
|
||||||
*/
|
*/
|
||||||
describe('BannerComponent (initial CLI generated)', () => {
|
describe('BannerComponent (initial CLI generated)', () => {
|
||||||
// #docregion v1
|
// #docregion v1
|
||||||
let component: BannerComponent;
|
let component: BannerComponent;
|
||||||
let fixture: ComponentFixture<BannerComponent>;
|
let fixture: ComponentFixture<BannerComponent>;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({declarations: [BannerComponent]}).compileComponents();
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ BannerComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -43,7 +44,9 @@ describe('BannerComponent (initial CLI generated)', () => {
|
|||||||
describe('BannerComponent (minimal)', () => {
|
describe('BannerComponent (minimal)', () => {
|
||||||
it('should create', () => {
|
it('should create', () => {
|
||||||
// #docregion configureTestingModule
|
// #docregion configureTestingModule
|
||||||
TestBed.configureTestingModule({declarations: [BannerComponent]});
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ BannerComponent ]
|
||||||
|
});
|
||||||
// #enddocregion configureTestingModule
|
// #enddocregion configureTestingModule
|
||||||
// #docregion createComponent
|
// #docregion createComponent
|
||||||
const fixture = TestBed.createComponent(BannerComponent);
|
const fixture = TestBed.createComponent(BannerComponent);
|
||||||
@ -62,7 +65,9 @@ describe('BannerComponent (with beforeEach)', () => {
|
|||||||
let fixture: ComponentFixture<BannerComponent>;
|
let fixture: ComponentFixture<BannerComponent>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({declarations: [BannerComponent]});
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ BannerComponent ]
|
||||||
|
});
|
||||||
fixture = TestBed.createComponent(BannerComponent);
|
fixture = TestBed.createComponent(BannerComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
});
|
});
|
||||||
|
@ -1,21 +1,22 @@
|
|||||||
|
|
||||||
// #docplaster
|
// #docplaster
|
||||||
import { DebugElement } from '@angular/core';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { DebugElement } from '@angular/core';
|
||||||
|
|
||||||
import { addMatchers, click } from '../../testing';
|
import { addMatchers, click } from '../../testing';
|
||||||
import { Hero } from '../model/hero';
|
|
||||||
|
|
||||||
|
import { Hero } from '../model/hero';
|
||||||
import { DashboardHeroComponent } from './dashboard-hero.component';
|
import { DashboardHeroComponent } from './dashboard-hero.component';
|
||||||
|
|
||||||
beforeEach(addMatchers);
|
beforeEach( addMatchers );
|
||||||
|
|
||||||
describe('DashboardHeroComponent class only', () => {
|
describe('DashboardHeroComponent class only', () => {
|
||||||
// #docregion class-only
|
// #docregion class-only
|
||||||
it('raises the selected event when clicked', () => {
|
it('raises the selected event when clicked', () => {
|
||||||
const comp = new DashboardHeroComponent();
|
const comp = new DashboardHeroComponent();
|
||||||
const hero: Hero = {id: 42, name: 'Test'};
|
const hero: Hero = { id: 42, name: 'Test' };
|
||||||
comp.hero = hero;
|
comp.hero = hero;
|
||||||
|
|
||||||
comp.selected.subscribe((selectedHero: Hero) => expect(selectedHero).toBe(hero));
|
comp.selected.subscribe((selectedHero: Hero) => expect(selectedHero).toBe(hero));
|
||||||
@ -25,16 +26,18 @@ describe('DashboardHeroComponent class only', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('DashboardHeroComponent when tested directly', () => {
|
describe('DashboardHeroComponent when tested directly', () => {
|
||||||
|
|
||||||
let comp: DashboardHeroComponent;
|
let comp: DashboardHeroComponent;
|
||||||
let expectedHero: Hero;
|
let expectedHero: Hero;
|
||||||
let fixture: ComponentFixture<DashboardHeroComponent>;
|
let fixture: ComponentFixture<DashboardHeroComponent>;
|
||||||
let heroDe: DebugElement;
|
let heroDe: DebugElement;
|
||||||
let heroEl: HTMLElement;
|
let heroEl: HTMLElement;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
// #docregion setup, config-testbed
|
// #docregion setup, config-testbed
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({declarations: [DashboardHeroComponent]})
|
declarations: [ DashboardHeroComponent ]
|
||||||
|
})
|
||||||
// #enddocregion setup, config-testbed
|
// #enddocregion setup, config-testbed
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
@ -49,7 +52,7 @@ describe('DashboardHeroComponent when tested directly', () => {
|
|||||||
heroEl = heroDe.nativeElement;
|
heroEl = heroDe.nativeElement;
|
||||||
|
|
||||||
// mock the hero supplied by the parent component
|
// mock the hero supplied by the parent component
|
||||||
expectedHero = {id: 42, name: 'Test Name'};
|
expectedHero = { id: 42, name: 'Test Name' };
|
||||||
|
|
||||||
// simulate the parent setting the input property with that hero
|
// simulate the parent setting the input property with that hero
|
||||||
comp.hero = expectedHero;
|
comp.hero = expectedHero;
|
||||||
@ -108,10 +111,11 @@ describe('DashboardHeroComponent when inside a test host', () => {
|
|||||||
let fixture: ComponentFixture<TestHostComponent>;
|
let fixture: ComponentFixture<TestHostComponent>;
|
||||||
let heroEl: HTMLElement;
|
let heroEl: HTMLElement;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
// #docregion test-host-setup
|
// #docregion test-host-setup
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({declarations: [DashboardHeroComponent, TestHostComponent]})
|
declarations: [ DashboardHeroComponent, TestHostComponent ]
|
||||||
|
})
|
||||||
// #enddocregion test-host-setup
|
// #enddocregion test-host-setup
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
@ -151,10 +155,8 @@ import { Component } from '@angular/core';
|
|||||||
</dashboard-hero>`
|
</dashboard-hero>`
|
||||||
})
|
})
|
||||||
class TestHostComponent {
|
class TestHostComponent {
|
||||||
hero: Hero = {id: 42, name: 'Test Name'};
|
hero: Hero = {id: 42, name: 'Test Name' };
|
||||||
selectedHero: Hero;
|
selectedHero: Hero;
|
||||||
onSelected(hero: Hero) {
|
onSelected(hero: Hero) { this.selectedHero = hero; }
|
||||||
this.selectedHero = hero;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// #enddocregion test-host
|
// #enddocregion test-host
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing';
|
import { async, inject, ComponentFixture, TestBed
|
||||||
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { addMatchers, asyncData, click } from '../../testing';
|
import { addMatchers, asyncData, click } from '../../testing';
|
||||||
import { HeroService } from '../model/hero.service';
|
import { HeroService } from '../model/hero.service';
|
||||||
@ -11,7 +12,7 @@ import { Router } from '@angular/router';
|
|||||||
import { DashboardComponent } from './dashboard.component';
|
import { DashboardComponent } from './dashboard.component';
|
||||||
import { DashboardModule } from './dashboard.module';
|
import { DashboardModule } from './dashboard.module';
|
||||||
|
|
||||||
beforeEach(addMatchers);
|
beforeEach ( addMatchers );
|
||||||
|
|
||||||
let comp: DashboardComponent;
|
let comp: DashboardComponent;
|
||||||
let fixture: ComponentFixture<DashboardComponent>;
|
let fixture: ComponentFixture<DashboardComponent>;
|
||||||
@ -20,7 +21,9 @@ let fixture: ComponentFixture<DashboardComponent>;
|
|||||||
|
|
||||||
describe('DashboardComponent (deep)', () => {
|
describe('DashboardComponent (deep)', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({imports: [DashboardModule]});
|
TestBed.configureTestingModule({
|
||||||
|
imports: [ DashboardModule ]
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
compileAndCreate();
|
compileAndCreate();
|
||||||
@ -40,8 +43,10 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
|
|||||||
|
|
||||||
describe('DashboardComponent (shallow)', () => {
|
describe('DashboardComponent (shallow)', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule(
|
TestBed.configureTestingModule({
|
||||||
{declarations: [DashboardComponent], schemas: [NO_ERRORS_SCHEMA]});
|
declarations: [ DashboardComponent ],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
compileAndCreate();
|
compileAndCreate();
|
||||||
@ -58,20 +63,19 @@ describe('DashboardComponent (shallow)', () => {
|
|||||||
/** Add TestBed providers, compile, and create DashboardComponent */
|
/** Add TestBed providers, compile, and create DashboardComponent */
|
||||||
function compileAndCreate() {
|
function compileAndCreate() {
|
||||||
// #docregion compile-and-create-body
|
// #docregion compile-and-create-body
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
// #docregion router-spy
|
// #docregion router-spy
|
||||||
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
|
const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
|
||||||
const heroServiceSpy = jasmine.createSpyObj('HeroService', ['getHeroes']);
|
const heroServiceSpy = jasmine.createSpyObj('HeroService', ['getHeroes']);
|
||||||
|
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
|
||||||
providers: [
|
providers: [
|
||||||
{provide: HeroService, useValue: heroServiceSpy}, {provide: Router, useValue: routerSpy}
|
{ provide: HeroService, useValue: heroServiceSpy },
|
||||||
|
{ provide: Router, useValue: routerSpy }
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
// #enddocregion router-spy
|
// #enddocregion router-spy
|
||||||
.compileComponents()
|
.compileComponents().then(() => {
|
||||||
.then(() => {
|
|
||||||
fixture = TestBed.createComponent(DashboardComponent);
|
fixture = TestBed.createComponent(DashboardComponent);
|
||||||
comp = fixture.componentInstance;
|
comp = fixture.componentInstance;
|
||||||
|
|
||||||
@ -89,20 +93,23 @@ function compileAndCreate() {
|
|||||||
function tests(heroClick: () => void) {
|
function tests(heroClick: () => void) {
|
||||||
|
|
||||||
it('should NOT have heroes before ngOnInit', () => {
|
it('should NOT have heroes before ngOnInit', () => {
|
||||||
expect(comp.heroes.length).toBe(0, 'should not have heroes before ngOnInit');
|
expect(comp.heroes.length).toBe(0,
|
||||||
|
'should not have heroes before ngOnInit');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should NOT have heroes immediately after ngOnInit', () => {
|
it('should NOT have heroes immediately after ngOnInit', () => {
|
||||||
fixture.detectChanges(); // runs initial lifecycle hooks
|
fixture.detectChanges(); // runs initial lifecycle hooks
|
||||||
|
|
||||||
expect(comp.heroes.length).toBe(0, 'should not have heroes until service promise resolves');
|
expect(comp.heroes.length).toBe(0,
|
||||||
|
'should not have heroes until service promise resolves');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('after get dashboard heroes', () => {
|
describe('after get dashboard heroes', () => {
|
||||||
|
|
||||||
let router: Router;
|
let router: Router;
|
||||||
|
|
||||||
// Trigger component so it gets heroes and binds to them
|
// Trigger component so it gets heroes and binds to them
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
router = fixture.debugElement.injector.get(Router);
|
router = fixture.debugElement.injector.get(Router);
|
||||||
fixture.detectChanges(); // runs ngOnInit -> getHeroes
|
fixture.detectChanges(); // runs ngOnInit -> getHeroes
|
||||||
fixture.whenStable() // No need for the `lastPromise` hack!
|
fixture.whenStable() // No need for the `lastPromise` hack!
|
||||||
@ -110,8 +117,8 @@ function tests(heroClick: () => void) {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
it('should HAVE heroes', () => {
|
it('should HAVE heroes', () => {
|
||||||
expect(comp.heroes.length)
|
expect(comp.heroes.length).toBeGreaterThan(0,
|
||||||
.toBeGreaterThan(0, 'should have heroes after service promise resolves');
|
'should have heroes after service promise resolves');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should DISPLAY heroes', () => {
|
it('should DISPLAY heroes', () => {
|
||||||
@ -123,6 +130,7 @@ function tests(heroClick: () => void) {
|
|||||||
|
|
||||||
// #docregion navigate-test
|
// #docregion navigate-test
|
||||||
it('should tell ROUTER to navigate when hero clicked', () => {
|
it('should tell ROUTER to navigate when hero clicked', () => {
|
||||||
|
|
||||||
heroClick(); // trigger click on first inner <div class="hero">
|
heroClick(); // trigger click on first inner <div class="hero">
|
||||||
|
|
||||||
// args passed to router.navigateByUrl() spy
|
// args passed to router.navigateByUrl() spy
|
||||||
@ -131,8 +139,10 @@ function tests(heroClick: () => void) {
|
|||||||
|
|
||||||
// expecting to navigate to id of the component's first hero
|
// expecting to navigate to id of the component's first hero
|
||||||
const id = comp.heroes[0].id;
|
const id = comp.heroes[0].id;
|
||||||
expect(navArgs).toBe('/heroes/' + id, 'should nav to HeroDetail for first hero');
|
expect(navArgs).toBe('/heroes/' + id,
|
||||||
|
'should nav to HeroDetail for first hero');
|
||||||
});
|
});
|
||||||
// #enddocregion navigate-test
|
// #enddocregion navigate-test
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,23 +1,18 @@
|
|||||||
// tslint:disable-next-line:no-unused-variable
|
// tslint:disable-next-line:no-unused-variable
|
||||||
import { fakeAsync, tick, waitForAsync } from '@angular/core/testing';
|
import { async, fakeAsync, tick } from '@angular/core/testing';
|
||||||
import { interval, of } from 'rxjs';
|
import { interval, of } from 'rxjs';
|
||||||
import { delay, take } from 'rxjs/operators';
|
import { delay, take } from 'rxjs/operators';
|
||||||
|
|
||||||
describe('Angular async helper', () => {
|
describe('Angular async helper', () => {
|
||||||
|
|
||||||
describe('async', () => {
|
describe('async', () => {
|
||||||
let actuallyDone = false;
|
let actuallyDone = false;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => { actuallyDone = false; });
|
||||||
actuallyDone = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(() => { expect(actuallyDone).toBe(true, 'actuallyDone should be true'); });
|
||||||
expect(actuallyDone).toBe(true, 'actuallyDone should be true');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run normal test', () => {
|
it('should run normal test', () => { actuallyDone = true; });
|
||||||
actuallyDone = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should run normal async test', (done: DoneFn) => {
|
it('should run normal async test', (done: DoneFn) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -26,50 +21,39 @@ describe('Angular async helper', () => {
|
|||||||
}, 0);
|
}, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run async test with task', waitForAsync(() => {
|
it('should run async test with task',
|
||||||
setTimeout(() => {
|
async(() => { setTimeout(() => { actuallyDone = true; }, 0); }));
|
||||||
actuallyDone = true;
|
|
||||||
}, 0);
|
|
||||||
}));
|
|
||||||
|
|
||||||
it('should run async test with task', waitForAsync(() => {
|
it('should run async test with task', async(() => {
|
||||||
const id = setInterval(() => {
|
const id = setInterval(() => {
|
||||||
actuallyDone = true;
|
actuallyDone = true;
|
||||||
clearInterval(id);
|
clearInterval(id);
|
||||||
}, 100);
|
}, 100);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should run async test with successful promise', waitForAsync(() => {
|
it('should run async test with successful promise', async(() => {
|
||||||
const p = new Promise(resolve => {
|
const p = new Promise(resolve => { setTimeout(resolve, 10); });
|
||||||
setTimeout(resolve, 10);
|
p.then(() => { actuallyDone = true; });
|
||||||
});
|
|
||||||
p.then(() => {
|
|
||||||
actuallyDone = true;
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should run async test with failed promise', waitForAsync(() => {
|
it('should run async test with failed promise', async(() => {
|
||||||
const p = new Promise((resolve, reject) => {
|
const p = new Promise((resolve, reject) => { setTimeout(reject, 10); });
|
||||||
setTimeout(reject, 10);
|
p.catch(() => { actuallyDone = true; });
|
||||||
});
|
|
||||||
p.catch(() => {
|
|
||||||
actuallyDone = true;
|
|
||||||
});
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
// Use done. Can also use async or fakeAsync.
|
// Use done. Can also use async or fakeAsync.
|
||||||
it('should run async test with successful delayed Observable', (done: DoneFn) => {
|
it('should run async test with successful delayed Observable', (done: DoneFn) => {
|
||||||
const source = of(true).pipe(delay(10));
|
const source = of (true).pipe(delay(10));
|
||||||
source.subscribe(val => actuallyDone = true, err => fail(err), done);
|
source.subscribe(val => actuallyDone = true, err => fail(err), done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should run async test with successful delayed Observable', waitForAsync(() => {
|
it('should run async test with successful delayed Observable', async(() => {
|
||||||
const source = of(true).pipe(delay(10));
|
const source = of (true).pipe(delay(10));
|
||||||
source.subscribe(val => actuallyDone = true, err => fail(err));
|
source.subscribe(val => actuallyDone = true, err => fail(err));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should run async test with successful delayed Observable', fakeAsync(() => {
|
it('should run async test with successful delayed Observable', fakeAsync(() => {
|
||||||
const source = of(true).pipe(delay(10));
|
const source = of (true).pipe(delay(10));
|
||||||
source.subscribe(val => actuallyDone = true, err => fail(err));
|
source.subscribe(val => actuallyDone = true, err => fail(err));
|
||||||
|
|
||||||
tick(10);
|
tick(10);
|
||||||
@ -80,9 +64,7 @@ describe('Angular async helper', () => {
|
|||||||
// #docregion fake-async-test-tick
|
// #docregion fake-async-test-tick
|
||||||
it('should run timeout callback with delay after call tick with millis', fakeAsync(() => {
|
it('should run timeout callback with delay after call tick with millis', fakeAsync(() => {
|
||||||
let called = false;
|
let called = false;
|
||||||
setTimeout(() => {
|
setTimeout(() => { called = true; }, 100);
|
||||||
called = true;
|
|
||||||
}, 100);
|
|
||||||
tick(100);
|
tick(100);
|
||||||
expect(called).toBe(true);
|
expect(called).toBe(true);
|
||||||
}));
|
}));
|
||||||
@ -91,9 +73,7 @@ describe('Angular async helper', () => {
|
|||||||
// #docregion fake-async-test-tick-new-macro-task-sync
|
// #docregion fake-async-test-tick-new-macro-task-sync
|
||||||
it('should run new macro task callback with delay after call tick with millis',
|
it('should run new macro task callback with delay after call tick with millis',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
function nestedTimer(cb: () => any): void {
|
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); }
|
||||||
setTimeout(() => setTimeout(() => cb()));
|
|
||||||
}
|
|
||||||
const callback = jasmine.createSpy('callback');
|
const callback = jasmine.createSpy('callback');
|
||||||
nestedTimer(callback);
|
nestedTimer(callback);
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
@ -106,9 +86,7 @@ describe('Angular async helper', () => {
|
|||||||
// #docregion fake-async-test-tick-new-macro-task-async
|
// #docregion fake-async-test-tick-new-macro-task-async
|
||||||
it('should not run new macro task callback with delay after call tick with millis',
|
it('should not run new macro task callback with delay after call tick with millis',
|
||||||
fakeAsync(() => {
|
fakeAsync(() => {
|
||||||
function nestedTimer(cb: () => any): void {
|
function nestedTimer(cb: () => any): void { setTimeout(() => setTimeout(() => cb())); }
|
||||||
setTimeout(() => setTimeout(() => cb()));
|
|
||||||
}
|
|
||||||
const callback = jasmine.createSpy('callback');
|
const callback = jasmine.createSpy('callback');
|
||||||
nestedTimer(callback);
|
nestedTimer(callback);
|
||||||
expect(callback).not.toHaveBeenCalled();
|
expect(callback).not.toHaveBeenCalled();
|
||||||
@ -134,9 +112,7 @@ describe('Angular async helper', () => {
|
|||||||
// need to add `import 'zone.js/dist/zone-patch-rxjs-fake-async'
|
// need to add `import 'zone.js/dist/zone-patch-rxjs-fake-async'
|
||||||
// to patch rxjs scheduler
|
// to patch rxjs scheduler
|
||||||
let result = null;
|
let result = null;
|
||||||
of('hello').pipe(delay(1000)).subscribe(v => {
|
of ('hello').pipe(delay(1000)).subscribe(v => { result = v; });
|
||||||
result = v;
|
|
||||||
});
|
|
||||||
expect(result).toBeNull();
|
expect(result).toBeNull();
|
||||||
tick(1000);
|
tick(1000);
|
||||||
expect(result).toBe('hello');
|
expect(result).toBe('hello');
|
||||||
@ -157,18 +133,12 @@ describe('Angular async helper', () => {
|
|||||||
describe('use jasmine.clock()', () => {
|
describe('use jasmine.clock()', () => {
|
||||||
// need to config __zone_symbol__fakeAsyncPatchLock flag
|
// need to config __zone_symbol__fakeAsyncPatchLock flag
|
||||||
// before loading zone.js/dist/zone-testing
|
// before loading zone.js/dist/zone-testing
|
||||||
beforeEach(() => {
|
beforeEach(() => { jasmine.clock().install(); });
|
||||||
jasmine.clock().install();
|
afterEach(() => { jasmine.clock().uninstall(); });
|
||||||
});
|
|
||||||
afterEach(() => {
|
|
||||||
jasmine.clock().uninstall();
|
|
||||||
});
|
|
||||||
it('should auto enter fakeAsync', () => {
|
it('should auto enter fakeAsync', () => {
|
||||||
// is in fakeAsync now, don't need to call fakeAsync(testFn)
|
// is in fakeAsync now, don't need to call fakeAsync(testFn)
|
||||||
let called = false;
|
let called = false;
|
||||||
setTimeout(() => {
|
setTimeout(() => { called = true; }, 100);
|
||||||
called = true;
|
|
||||||
}, 100);
|
|
||||||
jasmine.clock().tick(100);
|
jasmine.clock().tick(100);
|
||||||
expect(called).toBe(true);
|
expect(called).toBe(true);
|
||||||
});
|
});
|
||||||
@ -182,7 +152,7 @@ describe('Angular async helper', () => {
|
|||||||
}
|
}
|
||||||
// need to config __zone_symbol__supportWaitUnResolvedChainedPromise flag
|
// need to config __zone_symbol__supportWaitUnResolvedChainedPromise flag
|
||||||
// before loading zone.js/dist/zone-testing
|
// before loading zone.js/dist/zone-testing
|
||||||
it('should wait until promise.then is called', waitForAsync(() => {
|
it('should wait until promise.then is called', async(() => {
|
||||||
let finished = false;
|
let finished = false;
|
||||||
new Promise((res, rej) => {
|
new Promise((res, rej) => {
|
||||||
jsonp('localhost:8080/jsonp', () => {
|
jsonp('localhost:8080/jsonp', () => {
|
||||||
@ -198,4 +168,5 @@ describe('Angular async helper', () => {
|
|||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
// #enddocregion async-test-promise-then
|
// #enddocregion async-test-promise-then
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -24,18 +24,17 @@ import { FormsModule } from '@angular/forms';
|
|||||||
// Forms symbols imported only for a specific test below
|
// Forms symbols imported only for a specific test below
|
||||||
import { NgModel, NgControl } from '@angular/forms';
|
import { NgModel, NgControl } from '@angular/forms';
|
||||||
|
|
||||||
import {
|
import { async, ComponentFixture, fakeAsync, inject, TestBed, tick
|
||||||
ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync
|
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { addMatchers, click } from '../../testing';
|
import { addMatchers, newEvent, click } from '../../testing';
|
||||||
|
|
||||||
export class NotProvided extends ValueService { /* example below */ }
|
export class NotProvided extends ValueService { /* example below */}
|
||||||
beforeEach(addMatchers);
|
beforeEach( addMatchers );
|
||||||
|
|
||||||
describe('demo (with TestBed):', () => {
|
describe('demo (with TestBed):', () => {
|
||||||
|
|
||||||
//////// Service Tests /////////////
|
//////// Service Tests /////////////
|
||||||
|
|
||||||
// #docregion ValueService
|
// #docregion ValueService
|
||||||
describe('ValueService', () => {
|
describe('ValueService', () => {
|
||||||
@ -65,13 +64,13 @@ describe('demo (with TestBed):', () => {
|
|||||||
// #enddocregion testbed-get-w-null
|
// #enddocregion testbed-get-w-null
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test should wait for ValueService.getPromiseValue', waitForAsync(() => {
|
it('test should wait for ValueService.getPromiseValue', async(() => {
|
||||||
service.getPromiseValue().then(
|
service.getPromiseValue().then(
|
||||||
value => expect(value).toBe('promise value')
|
value => expect(value).toBe('promise value')
|
||||||
);
|
);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('test should wait for ValueService.getObservableValue', waitForAsync(() => {
|
it('test should wait for ValueService.getObservableValue', async(() => {
|
||||||
service.getObservableValue().subscribe(
|
service.getObservableValue().subscribe(
|
||||||
value => expect(value).toBe('observable value')
|
value => expect(value).toBe('observable value')
|
||||||
);
|
);
|
||||||
@ -151,7 +150,7 @@ describe('demo (with TestBed):', () => {
|
|||||||
TestBed.configureTestingModule({ providers: [ValueService] });
|
TestBed.configureTestingModule({ providers: [ValueService] });
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(waitForAsync(inject([ValueService], (service: ValueService) => {
|
beforeEach(async(inject([ValueService], (service: ValueService) => {
|
||||||
service.getPromiseValue().then(value => serviceValue = value);
|
service.getPromiseValue().then(value => serviceValue = value);
|
||||||
})));
|
})));
|
||||||
|
|
||||||
@ -160,11 +159,11 @@ describe('demo (with TestBed):', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
/////////// Component Tests //////////////////
|
/////////// Component Tests //////////////////
|
||||||
|
|
||||||
describe('TestBed component tests', () => {
|
describe('TestBed component tests', () => {
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed
|
TestBed
|
||||||
.configureTestingModule({
|
.configureTestingModule({
|
||||||
imports: [DemoModule],
|
imports: [DemoModule],
|
||||||
@ -249,7 +248,7 @@ describe('demo (with TestBed):', () => {
|
|||||||
// #enddocregion ButtonComp
|
// #enddocregion ButtonComp
|
||||||
|
|
||||||
// ngModel is async so we must wait for it with promise-based `whenStable`
|
// ngModel is async so we must wait for it with promise-based `whenStable`
|
||||||
it('should support entering text in input box (ngModel)', waitForAsync(() => {
|
it('should support entering text in input box (ngModel)', async(() => {
|
||||||
const expectedOrigName = 'John';
|
const expectedOrigName = 'John';
|
||||||
const expectedNewName = 'Sally';
|
const expectedNewName = 'Sally';
|
||||||
|
|
||||||
@ -274,11 +273,9 @@ describe('demo (with TestBed):', () => {
|
|||||||
expect(comp.name).toBe(expectedOrigName,
|
expect(comp.name).toBe(expectedOrigName,
|
||||||
`comp.name should still be ${expectedOrigName} after value change, before binding happens`);
|
`comp.name should still be ${expectedOrigName} after value change, before binding happens`);
|
||||||
|
|
||||||
// Dispatch a DOM event so that Angular learns of input value change.
|
// dispatch a DOM event so that Angular learns of input value change.
|
||||||
// then wait while ngModel pushes input.box value to comp.name
|
// then wait while ngModel pushes input.box value to comp.name
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
input.dispatchEvent(newEvent('input'));
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
return fixture.whenStable();
|
return fixture.whenStable();
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@ -314,11 +311,9 @@ describe('demo (with TestBed):', () => {
|
|||||||
expect(comp.name).toBe(expectedOrigName,
|
expect(comp.name).toBe(expectedOrigName,
|
||||||
`comp.name should still be ${expectedOrigName} after value change, before binding happens`);
|
`comp.name should still be ${expectedOrigName} after value change, before binding happens`);
|
||||||
|
|
||||||
// Dispatch a DOM event so that Angular learns of input value change.
|
// dispatch a DOM event so that Angular learns of input value change.
|
||||||
// then wait a tick while ngModel pushes input.box value to comp.name
|
// then wait a tick while ngModel pushes input.box value to comp.name
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
input.dispatchEvent(newEvent('input'));
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
tick();
|
tick();
|
||||||
expect(comp.name).toBe(expectedNewName,
|
expect(comp.name).toBe(expectedNewName,
|
||||||
`After ngModel updates the model, comp.name should be ${expectedNewName} `);
|
`After ngModel updates the model, comp.name should be ${expectedNewName} `);
|
||||||
@ -339,12 +334,10 @@ describe('demo (with TestBed):', () => {
|
|||||||
// simulate user entering new name in input
|
// simulate user entering new name in input
|
||||||
input.value = inputText;
|
input.value = inputText;
|
||||||
|
|
||||||
// Dispatch a DOM event so that Angular learns of input value change.
|
// dispatch a DOM event so that Angular learns of input value change.
|
||||||
// then wait a tick while ngModel pushes input.box value to comp.text
|
// then wait a tick while ngModel pushes input.box value to comp.text
|
||||||
// and Angular updates the output span
|
// and Angular updates the output span
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
input.dispatchEvent(newEvent('input'));
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
tick();
|
tick();
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
expect(span.textContent).toBe(expectedText, 'output span');
|
expect(span.textContent).toBe(expectedText, 'output span');
|
||||||
@ -421,7 +414,7 @@ describe('demo (with TestBed):', () => {
|
|||||||
declarations: [TestProvidersComponent],
|
declarations: [TestProvidersComponent],
|
||||||
})
|
})
|
||||||
.overrideComponent(TestProvidersComponent, {
|
.overrideComponent(TestProvidersComponent, {
|
||||||
remove: { providers: [ValueService] },
|
remove: { providers: [ValueService]},
|
||||||
add: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
|
add: { providers: [{ provide: ValueService, useClass: FakeValueService }] },
|
||||||
|
|
||||||
// Or replace them all (this component has only one provider)
|
// Or replace them all (this component has only one provider)
|
||||||
@ -460,7 +453,7 @@ describe('demo (with TestBed):', () => {
|
|||||||
|
|
||||||
// TestComponent is parent of TestProvidersComponent
|
// TestComponent is parent of TestProvidersComponent
|
||||||
@Component({ template: '<my-service-comp></my-service-comp>' })
|
@Component({ template: '<my-service-comp></my-service-comp>' })
|
||||||
class TestComponent { }
|
class TestComponent {}
|
||||||
|
|
||||||
// 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent
|
// 3 levels of ValueService provider: module, TestCompomponent, TestProvidersComponent
|
||||||
const fixture = TestBed.configureTestingModule({
|
const fixture = TestBed.configureTestingModule({
|
||||||
@ -622,7 +615,7 @@ describe('demo (with TestBed):', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// must be async test to see child flow to parent
|
// must be async test to see child flow to parent
|
||||||
it('changed child value flows to parent', waitForAsync(() => {
|
it('changed child value flows to parent', async(() => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
getChild();
|
getChild();
|
||||||
|
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
import { ComponentFixture, fakeAsync, inject, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import {
|
||||||
|
async, ComponentFixture, fakeAsync, inject, TestBed, tick
|
||||||
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ActivatedRoute, ActivatedRouteStub, asyncData, click
|
ActivatedRoute, ActivatedRouteStub, asyncData, click, newEvent
|
||||||
} from '../../testing';
|
} from '../../testing';
|
||||||
|
|
||||||
import { Hero } from '../model/hero';
|
import { Hero } from '../model/hero';
|
||||||
@ -33,44 +36,49 @@ describe('HeroDetailComponent', () => {
|
|||||||
function overrideSetup() {
|
function overrideSetup() {
|
||||||
// #docregion hds-spy
|
// #docregion hds-spy
|
||||||
class HeroDetailServiceSpy {
|
class HeroDetailServiceSpy {
|
||||||
testHero: Hero = {id: 42, name: 'Test Hero'};
|
testHero: Hero = {id: 42, name: 'Test Hero' };
|
||||||
|
|
||||||
/* emit cloned test hero */
|
/* emit cloned test hero */
|
||||||
getHero = jasmine.createSpy('getHero').and.callFake(
|
getHero = jasmine.createSpy('getHero').and.callFake(
|
||||||
() => asyncData(Object.assign({}, this.testHero)));
|
() => asyncData(Object.assign({}, this.testHero))
|
||||||
|
);
|
||||||
|
|
||||||
/* emit clone of test hero, with changes merged in */
|
/* emit clone of test hero, with changes merged in */
|
||||||
saveHero = jasmine.createSpy('saveHero')
|
saveHero = jasmine.createSpy('saveHero').and.callFake(
|
||||||
.and.callFake((hero: Hero) => asyncData(Object.assign(this.testHero, hero)));
|
(hero: Hero) => asyncData(Object.assign(this.testHero, hero))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #enddocregion hds-spy
|
// #enddocregion hds-spy
|
||||||
|
|
||||||
// the `id` value is irrelevant because ignored by service stub
|
// the `id` value is irrelevant because ignored by service stub
|
||||||
beforeEach(() => activatedRoute.setParamMap({id: 99999}));
|
beforeEach(() => activatedRoute.setParamMap({ id: 99999 }));
|
||||||
|
|
||||||
// #docregion setup-override
|
// #docregion setup-override
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
imports: [ HeroModule ],
|
||||||
imports: [HeroModule],
|
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ActivatedRoute, useValue: activatedRoute},
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
{provide: Router, useValue: routerSpy},
|
{ provide: Router, useValue: routerSpy},
|
||||||
// #enddocregion setup-override
|
// #enddocregion setup-override
|
||||||
// HeroDetailService at this level is IRRELEVANT!
|
// HeroDetailService at this level is IRRELEVANT!
|
||||||
{provide: HeroDetailService, useValue: {}}
|
{ provide: HeroDetailService, useValue: {} }
|
||||||
// #docregion setup-override
|
// #docregion setup-override
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
// Override component's own provider
|
// Override component's own provider
|
||||||
// #docregion override-component-method
|
// #docregion override-component-method
|
||||||
.overrideComponent(
|
.overrideComponent(HeroDetailComponent, {
|
||||||
HeroDetailComponent,
|
set: {
|
||||||
{set: {providers: [{provide: HeroDetailService, useClass: HeroDetailServiceSpy}]}})
|
providers: [
|
||||||
|
{ provide: HeroDetailService, useClass: HeroDetailServiceSpy }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
// #enddocregion override-component-method
|
// #enddocregion override-component-method
|
||||||
|
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
@ -80,7 +88,7 @@ function overrideSetup() {
|
|||||||
// #docregion override-tests
|
// #docregion override-tests
|
||||||
let hdsSpy: HeroDetailServiceSpy;
|
let hdsSpy: HeroDetailServiceSpy;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
createComponent();
|
createComponent();
|
||||||
// get the component's injected HeroDetailServiceSpy
|
// get the component's injected HeroDetailServiceSpy
|
||||||
hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any;
|
hdsSpy = fixture.debugElement.injector.get(HeroDetailService) as any;
|
||||||
@ -99,10 +107,7 @@ function overrideSetup() {
|
|||||||
const newName = 'New Name';
|
const newName = 'New Name';
|
||||||
|
|
||||||
page.nameInput.value = newName;
|
page.nameInput.value = newName;
|
||||||
|
page.nameInput.dispatchEvent(newEvent('input')); // tell Angular
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
|
||||||
page.nameInput.dispatchEvent(new Event('input')); // tell Angular
|
|
||||||
|
|
||||||
expect(component.hero.name).toBe(newName, 'component hero has new name');
|
expect(component.hero.name).toBe(newName, 'component hero has new name');
|
||||||
expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save');
|
expect(hdsSpy.testHero.name).toBe(origName, 'service hero unchanged before save');
|
||||||
@ -119,6 +124,7 @@ function overrideSetup() {
|
|||||||
it('fixture injected service is not the component injected service',
|
it('fixture injected service is not the component injected service',
|
||||||
// inject gets the service from the fixture
|
// inject gets the service from the fixture
|
||||||
inject([HeroDetailService], (fixtureService: HeroDetailService) => {
|
inject([HeroDetailService], (fixtureService: HeroDetailService) => {
|
||||||
|
|
||||||
// use `fixture.debugElement.injector` to get service from component
|
// use `fixture.debugElement.injector` to get service from component
|
||||||
const componentService = fixture.debugElement.injector.get(HeroDetailService);
|
const componentService = fixture.debugElement.injector.get(HeroDetailService);
|
||||||
|
|
||||||
@ -133,19 +139,18 @@ const firstHero = getTestHeroes()[0];
|
|||||||
|
|
||||||
function heroModuleSetup() {
|
function heroModuleSetup() {
|
||||||
// #docregion setup-hero-module
|
// #docregion setup-hero-module
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
imports: [ HeroModule ],
|
||||||
imports: [HeroModule],
|
|
||||||
// #enddocregion setup-hero-module
|
// #enddocregion setup-hero-module
|
||||||
// declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION
|
// declarations: [ HeroDetailComponent ], // NO! DOUBLE DECLARATION
|
||||||
// #docregion setup-hero-module
|
// #docregion setup-hero-module
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ActivatedRoute, useValue: activatedRoute},
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
{provide: HeroService, useClass: TestHeroService},
|
{ provide: HeroService, useClass: TestHeroService },
|
||||||
{provide: Router, useValue: routerSpy},
|
{ provide: Router, useValue: routerSpy},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
@ -156,9 +161,9 @@ function heroModuleSetup() {
|
|||||||
describe('when navigate to existing hero', () => {
|
describe('when navigate to existing hero', () => {
|
||||||
let expectedHero: Hero;
|
let expectedHero: Hero;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
expectedHero = firstHero;
|
expectedHero = firstHero;
|
||||||
activatedRoute.setParamMap({id: expectedHero.id});
|
activatedRoute.setParamMap({ id: expectedHero.id });
|
||||||
createComponent();
|
createComponent();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -200,10 +205,9 @@ function heroModuleSetup() {
|
|||||||
// simulate user entering a new name into the input box
|
// simulate user entering a new name into the input box
|
||||||
nameInput.value = 'quick BROWN fOx';
|
nameInput.value = 'quick BROWN fOx';
|
||||||
|
|
||||||
// Dispatch a DOM event so that Angular learns of input value change.
|
// dispatch a DOM event so that Angular learns of input value change.
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
// use newEvent utility function (not provided by Angular) for better browser compatibility
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
nameInput.dispatchEvent(newEvent('input'));
|
||||||
nameInput.dispatchEvent(new Event('input'));
|
|
||||||
|
|
||||||
// Tell Angular to update the display binding through the title pipe
|
// Tell Angular to update the display binding through the title pipe
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
@ -218,7 +222,7 @@ function heroModuleSetup() {
|
|||||||
|
|
||||||
// #docregion route-no-id
|
// #docregion route-no-id
|
||||||
describe('when navigate with no hero id', () => {
|
describe('when navigate with no hero id', () => {
|
||||||
beforeEach(waitForAsync(createComponent));
|
beforeEach(async( createComponent ));
|
||||||
|
|
||||||
it('should have hero.id === 0', () => {
|
it('should have hero.id === 0', () => {
|
||||||
expect(component.hero.id).toBe(0);
|
expect(component.hero.id).toBe(0);
|
||||||
@ -232,8 +236,8 @@ function heroModuleSetup() {
|
|||||||
|
|
||||||
// #docregion route-bad-id
|
// #docregion route-bad-id
|
||||||
describe('when navigate to non-existent hero id', () => {
|
describe('when navigate to non-existent hero id', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
activatedRoute.setParamMap({id: 99999});
|
activatedRoute.setParamMap({ id: 99999 });
|
||||||
createComponent();
|
createComponent();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -251,7 +255,8 @@ function heroModuleSetup() {
|
|||||||
expect(
|
expect(
|
||||||
// Throws because `inject` only has access to TestBed's injector
|
// Throws because `inject` only has access to TestBed's injector
|
||||||
// which is an ancestor of the component's injector
|
// which is an ancestor of the component's injector
|
||||||
inject([HeroDetailService], (hds: HeroDetailService) => service = hds))
|
inject([HeroDetailService], (hds: HeroDetailService) => service = hds )
|
||||||
|
)
|
||||||
.toThrowError(/No provider for HeroDetailService/);
|
.toThrowError(/No provider for HeroDetailService/);
|
||||||
|
|
||||||
// get `HeroDetailService` with component's own injector
|
// get `HeroDetailService` with component's own injector
|
||||||
@ -266,26 +271,25 @@ import { TitleCasePipe } from '../shared/title-case.pipe';
|
|||||||
|
|
||||||
function formsModuleSetup() {
|
function formsModuleSetup() {
|
||||||
// #docregion setup-forms-module
|
// #docregion setup-forms-module
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
imports: [ FormsModule ],
|
||||||
imports: [FormsModule],
|
declarations: [ HeroDetailComponent, TitleCasePipe ],
|
||||||
declarations: [HeroDetailComponent, TitleCasePipe],
|
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ActivatedRoute, useValue: activatedRoute},
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
{provide: HeroService, useClass: TestHeroService},
|
{ provide: HeroService, useClass: TestHeroService },
|
||||||
{provide: Router, useValue: routerSpy},
|
{ provide: Router, useValue: routerSpy},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
// #enddocregion setup-forms-module
|
// #enddocregion setup-forms-module
|
||||||
|
|
||||||
it('should display 1st hero\'s name', waitForAsync(() => {
|
it('should display 1st hero\'s name', async(() => {
|
||||||
const expectedHero = firstHero;
|
const expectedHero = firstHero;
|
||||||
activatedRoute.setParamMap({id: expectedHero.id});
|
activatedRoute.setParamMap({ id: expectedHero.id });
|
||||||
createComponent().then(() => {
|
createComponent().then(() => {
|
||||||
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
|
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
|
||||||
});
|
});
|
||||||
@ -297,26 +301,25 @@ import { SharedModule } from '../shared/shared.module';
|
|||||||
|
|
||||||
function sharedModuleSetup() {
|
function sharedModuleSetup() {
|
||||||
// #docregion setup-shared-module
|
// #docregion setup-shared-module
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
const routerSpy = createRouterSpy();
|
const routerSpy = createRouterSpy();
|
||||||
|
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
imports: [ SharedModule ],
|
||||||
imports: [SharedModule],
|
declarations: [ HeroDetailComponent ],
|
||||||
declarations: [HeroDetailComponent],
|
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ActivatedRoute, useValue: activatedRoute},
|
{ provide: ActivatedRoute, useValue: activatedRoute },
|
||||||
{provide: HeroService, useClass: TestHeroService},
|
{ provide: HeroService, useClass: TestHeroService },
|
||||||
{provide: Router, useValue: routerSpy},
|
{ provide: Router, useValue: routerSpy},
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
// #enddocregion setup-shared-module
|
// #enddocregion setup-shared-module
|
||||||
|
|
||||||
it('should display 1st hero\'s name', waitForAsync(() => {
|
it('should display 1st hero\'s name', async(() => {
|
||||||
const expectedHero = firstHero;
|
const expectedHero = firstHero;
|
||||||
activatedRoute.setParamMap({id: expectedHero.id});
|
activatedRoute.setParamMap({ id: expectedHero.id });
|
||||||
createComponent().then(() => {
|
createComponent().then(() => {
|
||||||
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
|
expect(page.nameDisplay.textContent).toBe(expectedHero.name);
|
||||||
});
|
});
|
||||||
@ -344,21 +347,11 @@ function createComponent() {
|
|||||||
// #docregion page
|
// #docregion page
|
||||||
class Page {
|
class Page {
|
||||||
// getter properties wait to query the DOM until called.
|
// getter properties wait to query the DOM until called.
|
||||||
get buttons() {
|
get buttons() { return this.queryAll<HTMLButtonElement>('button'); }
|
||||||
return this.queryAll<HTMLButtonElement>('button');
|
get saveBtn() { return this.buttons[0]; }
|
||||||
}
|
get cancelBtn() { return this.buttons[1]; }
|
||||||
get saveBtn() {
|
get nameDisplay() { return this.query<HTMLElement>('span'); }
|
||||||
return this.buttons[0];
|
get nameInput() { return this.query<HTMLInputElement>('input'); }
|
||||||
}
|
|
||||||
get cancelBtn() {
|
|
||||||
return this.buttons[1];
|
|
||||||
}
|
|
||||||
get nameDisplay() {
|
|
||||||
return this.query<HTMLElement>('span');
|
|
||||||
}
|
|
||||||
get nameInput() {
|
|
||||||
return this.query<HTMLInputElement>('input');
|
|
||||||
}
|
|
||||||
|
|
||||||
gotoListSpy: jasmine.Spy;
|
gotoListSpy: jasmine.Spy;
|
||||||
navigateSpy: jasmine.Spy;
|
navigateSpy: jasmine.Spy;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync
|
import { async, ComponentFixture, fakeAsync, TestBed, tick
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
@ -6,13 +6,14 @@ import { DebugElement } from '@angular/core';
|
|||||||
|
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
|
|
||||||
import { addMatchers } from '../../testing';
|
import { addMatchers, newEvent } from '../../testing';
|
||||||
import { HeroService } from '../model/hero.service';
|
|
||||||
import { getTestHeroes, TestHeroService } from '../model/testing/test-hero.service';
|
import { getTestHeroes, TestHeroService } from '../model/testing/test-hero.service';
|
||||||
|
|
||||||
import { HeroModule } from './hero.module';
|
import { HeroModule } from './hero.module';
|
||||||
import { HeroListComponent } from './hero-list.component';
|
import { HeroListComponent } from './hero-list.component';
|
||||||
import { HighlightDirective } from '../shared/highlight.directive';
|
import { HighlightDirective } from '../shared/highlight.directive';
|
||||||
|
import { HeroService } from '../model/hero.service';
|
||||||
|
|
||||||
const HEROES = getTestHeroes();
|
const HEROES = getTestHeroes();
|
||||||
|
|
||||||
@ -23,16 +24,16 @@ let page: Page;
|
|||||||
/////// Tests //////
|
/////// Tests //////
|
||||||
|
|
||||||
describe('HeroListComponent', () => {
|
describe('HeroListComponent', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
|
beforeEach(async(() => {
|
||||||
addMatchers();
|
addMatchers();
|
||||||
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
|
const routerSpy = jasmine.createSpyObj('Router', ['navigate']);
|
||||||
|
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
|
||||||
imports: [HeroModule],
|
imports: [HeroModule],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: HeroService, useClass: TestHeroService},
|
{ provide: HeroService, useClass: TestHeroService },
|
||||||
{provide: Router, useValue: routerSpy}
|
{ provide: Router, useValue: routerSpy}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
.compileComponents()
|
.compileComponents()
|
||||||
@ -53,10 +54,7 @@ describe('HeroListComponent', () => {
|
|||||||
it('should select hero on click', fakeAsync(() => {
|
it('should select hero on click', fakeAsync(() => {
|
||||||
const expectedHero = HEROES[1];
|
const expectedHero = HEROES[1];
|
||||||
const li = page.heroRows[1];
|
const li = page.heroRows[1];
|
||||||
|
li.dispatchEvent(newEvent('click'));
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
|
||||||
li.dispatchEvent(new Event('click'));
|
|
||||||
tick();
|
tick();
|
||||||
// `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
|
// `.toEqual` because selectedHero is clone of expectedHero; see FakeHeroService
|
||||||
expect(comp.selectedHero).toEqual(expectedHero);
|
expect(comp.selectedHero).toEqual(expectedHero);
|
||||||
@ -65,10 +63,7 @@ describe('HeroListComponent', () => {
|
|||||||
it('should navigate to selected hero detail on click', fakeAsync(() => {
|
it('should navigate to selected hero detail on click', fakeAsync(() => {
|
||||||
const expectedHero = HEROES[1];
|
const expectedHero = HEROES[1];
|
||||||
const li = page.heroRows[1];
|
const li = page.heroRows[1];
|
||||||
|
li.dispatchEvent(newEvent('click'));
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
|
||||||
li.dispatchEvent(new Event('click'));
|
|
||||||
tick();
|
tick();
|
||||||
|
|
||||||
// should have navigated
|
// should have navigated
|
||||||
@ -80,6 +75,7 @@ describe('HeroListComponent', () => {
|
|||||||
const navArgs = page.navSpy.calls.first().args[0];
|
const navArgs = page.navSpy.calls.first().args[0];
|
||||||
expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
|
expect(navArgs[0]).toContain('heroes', 'nav to heroes detail URL');
|
||||||
expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
|
expect(navArgs[1]).toBe(expectedHero.id, 'expected hero.id');
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should find `HighlightDirective` with `By.directive', () => {
|
it('should find `HighlightDirective` with `By.directive', () => {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
// #docregion without-toBlob-macrotask
|
// #docregion without-toBlob-macrotask
|
||||||
import { fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { TestBed, async, tick, fakeAsync } from '@angular/core/testing';
|
||||||
|
|
||||||
import { CanvasComponent } from './canvas.component';
|
import { CanvasComponent } from './canvas.component';
|
||||||
|
|
||||||
describe('CanvasComponent', () => {
|
describe('CanvasComponent', () => {
|
||||||
@ -11,18 +10,18 @@ describe('CanvasComponent', () => {
|
|||||||
(window as any).__zone_symbol__FakeAsyncTestMacroTask = [
|
(window as any).__zone_symbol__FakeAsyncTestMacroTask = [
|
||||||
{
|
{
|
||||||
source: 'HTMLCanvasElement.toBlob',
|
source: 'HTMLCanvasElement.toBlob',
|
||||||
callbackArgs: [{size: 200}],
|
callbackArgs: [{ size: 200 }],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
// #enddocregion enable-toBlob-macrotask
|
// #enddocregion enable-toBlob-macrotask
|
||||||
// #docregion without-toBlob-macrotask
|
// #docregion without-toBlob-macrotask
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
declarations: [
|
||||||
declarations: [CanvasComponent],
|
CanvasComponent
|
||||||
})
|
],
|
||||||
.compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should be able to generate blob data from canvas', fakeAsync(() => {
|
it('should be able to generate blob data from canvas', fakeAsync(() => {
|
||||||
|
@ -3,6 +3,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing';
|
|||||||
import { By } from '@angular/platform-browser';
|
import { By } from '@angular/platform-browser';
|
||||||
|
|
||||||
import { HighlightDirective } from './highlight.directive';
|
import { HighlightDirective } from './highlight.directive';
|
||||||
|
import { newEvent } from '../../testing';
|
||||||
|
|
||||||
// #docregion test-component
|
// #docregion test-component
|
||||||
@Component({
|
@Component({
|
||||||
@ -58,12 +59,9 @@ describe('HighlightDirective', () => {
|
|||||||
const input = des[2].nativeElement as HTMLInputElement;
|
const input = des[2].nativeElement as HTMLInputElement;
|
||||||
expect(input.style.backgroundColor).toBe('cyan', 'initial backgroundColor');
|
expect(input.style.backgroundColor).toBe('cyan', 'initial backgroundColor');
|
||||||
|
|
||||||
|
// dispatch a DOM event so that Angular responds to the input value change.
|
||||||
input.value = 'green';
|
input.value = 'green';
|
||||||
|
input.dispatchEvent(newEvent('input'));
|
||||||
// Dispatch a DOM event so that Angular responds to the input value change.
|
|
||||||
// In older browsers, such as IE, you might need a CustomEvent instead. See
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
|
|
||||||
input.dispatchEvent(new Event('input'));
|
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
expect(input.style.backgroundColor).toBe('green', 'changed backgroundColor');
|
expect(input.style.backgroundColor).toBe('green', 'changed backgroundColor');
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
// #docplaster
|
// #docplaster
|
||||||
import { fakeAsync, ComponentFixture, TestBed, tick, waitForAsync } from '@angular/core/testing';
|
import { async, fakeAsync, ComponentFixture, TestBed, tick } from '@angular/core/testing';
|
||||||
|
|
||||||
import { asyncData, asyncError } from '../../testing';
|
import { asyncData, asyncError } from '../../testing';
|
||||||
|
|
||||||
import { of, throwError } from 'rxjs';
|
import { of, throwError } from 'rxjs';
|
||||||
|
|
||||||
import { last } from 'rxjs/operators';
|
import { last } from 'rxjs/operators';
|
||||||
|
|
||||||
import { TwainComponent } from './twain.component';
|
|
||||||
import { TwainService } from './twain.service';
|
import { TwainService } from './twain.service';
|
||||||
|
import { TwainComponent } from './twain.component';
|
||||||
|
|
||||||
describe('TwainComponent', () => {
|
describe('TwainComponent', () => {
|
||||||
let component: TwainComponent;
|
let component: TwainComponent;
|
||||||
@ -31,12 +32,14 @@ describe('TwainComponent', () => {
|
|||||||
// Create a fake TwainService object with a `getQuote()` spy
|
// Create a fake TwainService object with a `getQuote()` spy
|
||||||
const twainService = jasmine.createSpyObj('TwainService', ['getQuote']);
|
const twainService = jasmine.createSpyObj('TwainService', ['getQuote']);
|
||||||
// Make the spy return a synchronous Observable with the test data
|
// Make the spy return a synchronous Observable with the test data
|
||||||
getQuoteSpy = twainService.getQuote.and.returnValue(of(testQuote));
|
getQuoteSpy = twainService.getQuote.and.returnValue( of(testQuote) );
|
||||||
// #enddocregion spy
|
// #enddocregion spy
|
||||||
|
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [TwainComponent],
|
declarations: [ TwainComponent ],
|
||||||
providers: [{provide: TwainService, useValue: twainService}]
|
providers: [
|
||||||
|
{ provide: TwainService, useValue: twainService }
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
fixture = TestBed.createComponent(TwainComponent);
|
fixture = TestBed.createComponent(TwainComponent);
|
||||||
@ -69,7 +72,8 @@ describe('TwainComponent', () => {
|
|||||||
// #docregion error-test
|
// #docregion error-test
|
||||||
it('should display error when TwainService fails', fakeAsync(() => {
|
it('should display error when TwainService fails', fakeAsync(() => {
|
||||||
// tell spy to return an error observable
|
// tell spy to return an error observable
|
||||||
getQuoteSpy.and.returnValue(throwError('TwainService test failure'));
|
getQuoteSpy.and.returnValue(
|
||||||
|
throwError('TwainService test failure'));
|
||||||
|
|
||||||
fixture.detectChanges(); // onInit()
|
fixture.detectChanges(); // onInit()
|
||||||
// sync spy errors immediately after init
|
// sync spy errors immediately after init
|
||||||
@ -121,7 +125,7 @@ describe('TwainComponent', () => {
|
|||||||
// #enddocregion fake-async-test
|
// #enddocregion fake-async-test
|
||||||
|
|
||||||
// #docregion async-test
|
// #docregion async-test
|
||||||
it('should show quote after getQuote (async)', waitForAsync(() => {
|
it('should show quote after getQuote (async)', async(() => {
|
||||||
fixture.detectChanges(); // ngOnInit()
|
fixture.detectChanges(); // ngOnInit()
|
||||||
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
|
expect(quoteEl.textContent).toBe('...', 'should show placeholder');
|
||||||
|
|
||||||
@ -138,7 +142,7 @@ describe('TwainComponent', () => {
|
|||||||
it('should show last quote (quote done)', (done: DoneFn) => {
|
it('should show last quote (quote done)', (done: DoneFn) => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
|
|
||||||
component.quote.pipe(last()).subscribe(() => {
|
component.quote.pipe( last() ).subscribe(() => {
|
||||||
fixture.detectChanges(); // update view with quote
|
fixture.detectChanges(); // update view with quote
|
||||||
expect(quoteEl.textContent).toBe(testQuote);
|
expect(quoteEl.textContent).toBe(testQuote);
|
||||||
expect(errorMessage()).toBeNull('should not show error');
|
expect(errorMessage()).toBeNull('should not show error');
|
||||||
|
@ -14,6 +14,18 @@ export function advance(f: ComponentFixture<any>): void {
|
|||||||
f.detectChanges();
|
f.detectChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create custom DOM event the old fashioned way
|
||||||
|
*
|
||||||
|
* https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent
|
||||||
|
* Although officially deprecated, some browsers (phantom) don't accept the preferred "new Event(eventName)"
|
||||||
|
*/
|
||||||
|
export function newEvent(eventName: string, bubbles = false, cancelable = false) {
|
||||||
|
const evt = document.createEvent('CustomEvent'); // MUST be 'CustomEvent'
|
||||||
|
evt.initCustomEvent(eventName, bubbles, cancelable, null);
|
||||||
|
return evt;
|
||||||
|
}
|
||||||
|
|
||||||
// See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
|
// See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
|
||||||
// #docregion click-event
|
// #docregion click-event
|
||||||
/** Button events to pass to `DebugElement.triggerEventHandler` for RouterLink event handler */
|
/** Button events to pass to `DebugElement.triggerEventHandler` for RouterLink event handler */
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
|
||||||
import { of } from 'rxjs';
|
|
||||||
|
|
||||||
import { HeroSearchComponent } from '../hero-search/hero-search.component';
|
|
||||||
import { HeroService } from '../hero.service';
|
|
||||||
import { HEROES } from '../mock-heroes';
|
|
||||||
|
|
||||||
import { DashboardComponent } from './dashboard.component';
|
import { DashboardComponent } from './dashboard.component';
|
||||||
|
import { HeroSearchComponent } from '../hero-search/hero-search.component';
|
||||||
|
|
||||||
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
|
import { of } from 'rxjs';
|
||||||
|
import { HEROES } from '../mock-heroes';
|
||||||
|
import { HeroService } from '../hero.service';
|
||||||
|
|
||||||
describe('DashboardComponent', () => {
|
describe('DashboardComponent', () => {
|
||||||
let component: DashboardComponent;
|
let component: DashboardComponent;
|
||||||
@ -14,16 +14,23 @@ describe('DashboardComponent', () => {
|
|||||||
let heroService;
|
let heroService;
|
||||||
let getHeroesSpy;
|
let getHeroesSpy;
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
heroService = jasmine.createSpyObj('HeroService', ['getHeroes']);
|
heroService = jasmine.createSpyObj('HeroService', ['getHeroes']);
|
||||||
getHeroesSpy = heroService.getHeroes.and.returnValue(of(HEROES));
|
getHeroesSpy = heroService.getHeroes.and.returnValue( of(HEROES) );
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
declarations: [
|
||||||
declarations: [DashboardComponent, HeroSearchComponent],
|
DashboardComponent,
|
||||||
imports: [RouterTestingModule.withRoutes([])],
|
HeroSearchComponent
|
||||||
providers: [{provide: HeroService, useValue: heroService}]
|
],
|
||||||
|
imports: [
|
||||||
|
RouterTestingModule.withRoutes([])
|
||||||
|
],
|
||||||
|
providers: [
|
||||||
|
{ provide: HeroService, useValue: heroService }
|
||||||
|
]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -40,11 +47,12 @@ describe('DashboardComponent', () => {
|
|||||||
expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes');
|
expect(fixture.nativeElement.querySelector('h3').textContent).toEqual('Top Heroes');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call heroService', waitForAsync(() => {
|
it('should call heroService', async(() => {
|
||||||
expect(getHeroesSpy.calls.any()).toBe(true);
|
expect(getHeroesSpy.calls.any()).toBe(true);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should display 4 links', waitForAsync(() => {
|
it('should display 4 links', async(() => {
|
||||||
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
|
expect(fixture.nativeElement.querySelectorAll('a').length).toEqual(4);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit, Input } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
|
|
||||||
@ -11,7 +11,7 @@ import { HeroService } from '../hero.service';
|
|||||||
styleUrls: [ './hero-detail.component.css' ]
|
styleUrls: [ './hero-detail.component.css' ]
|
||||||
})
|
})
|
||||||
export class HeroDetailComponent implements OnInit {
|
export class HeroDetailComponent implements OnInit {
|
||||||
hero: Hero;
|
@Input() hero: Hero;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<!-- Polyfills -->
|
<!-- Polyfills -->
|
||||||
<script src="node_modules/core-js/client/shim.min.js"></script>
|
<script src="node_modules/core-js/client/shim.min.js"></script>
|
||||||
|
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
<script src="node_modules/systemjs/dist/system.src.js"></script>
|
||||||
|
|
||||||
<script src="systemjs.config.1.js"></script>
|
<script src="systemjs.config.1.js"></script>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<script src="phone-detail/phone-detail.module.js"></script>
|
<script src="phone-detail/phone-detail.module.js"></script>
|
||||||
|
|
||||||
<script src="/node_modules/core-js/client/shim.min.js"></script>
|
<script src="/node_modules/core-js/client/shim.min.js"></script>
|
||||||
<script src="/node_modules/zone.js/bundles/zone.umd.min.js"></script>
|
<script src="/node_modules/zone.js/dist/zone.min.js"></script>
|
||||||
|
|
||||||
<script>window.module = 'aot';</script>
|
<script>window.module = 'aot';</script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
// #docregion activatedroute
|
// #docregion activatedroute
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
// #enddocregion activatedroute
|
// #enddocregion activatedroute
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
|
|
||||||
|
import { async, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { PhoneDetailComponent } from './phone-detail.component';
|
import { PhoneDetailComponent } from './phone-detail.component';
|
||||||
import { Phone, PhoneData } from '../core/phone/phone.service';
|
import { Phone, PhoneData } from '../core/phone/phone.service';
|
||||||
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
|
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
|
||||||
|
|
||||||
function xyzPhoneData(): PhoneData {
|
function xyzPhoneData(): PhoneData {
|
||||||
return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
|
return {
|
||||||
|
name: 'phone xyz',
|
||||||
|
snippet: '',
|
||||||
|
images: ['image/url1.png', 'image/url2.png']
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockPhone {
|
class MockPhone {
|
||||||
@ -28,9 +34,10 @@ class ActivatedRouteMock {
|
|||||||
// #enddocregion activatedroute
|
// #enddocregion activatedroute
|
||||||
|
|
||||||
describe('PhoneDetailComponent', () => {
|
describe('PhoneDetailComponent', () => {
|
||||||
|
|
||||||
// #docregion activatedroute
|
// #docregion activatedroute
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
|
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
|
||||||
providers: [
|
providers: [
|
||||||
@ -48,4 +55,5 @@ describe('PhoneDetailComponent', () => {
|
|||||||
const compiled = fixture.debugElement.nativeElement;
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
|
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
// #docregion
|
// #docregion
|
||||||
import {SpyLocation} from '@angular/common/testing';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import {NO_ERRORS_SCHEMA} from '@angular/core';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
import { Observable, of } from 'rxjs';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import {Observable, of} from 'rxjs';
|
import { SpyLocation } from '@angular/common/testing';
|
||||||
|
|
||||||
import {Phone, PhoneData} from '../core/phone/phone.service';
|
import { PhoneListComponent } from './phone-list.component';
|
||||||
|
import { Phone, PhoneData } from '../core/phone/phone.service';
|
||||||
import {PhoneListComponent} from './phone-list.component';
|
|
||||||
|
|
||||||
class ActivatedRouteMock {
|
class ActivatedRouteMock {
|
||||||
constructor(public snapshot: any) {}
|
constructor(public snapshot: any) {}
|
||||||
@ -17,7 +16,8 @@ class ActivatedRouteMock {
|
|||||||
class MockPhone {
|
class MockPhone {
|
||||||
query(): Observable<PhoneData[]> {
|
query(): Observable<PhoneData[]> {
|
||||||
return of([
|
return of([
|
||||||
{name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
|
{name: 'Nexus S', snippet: '', images: []},
|
||||||
|
{name: 'Motorola DROID', snippet: '', images: []}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,16 +25,16 @@ class MockPhone {
|
|||||||
let fixture: ComponentFixture<PhoneListComponent>;
|
let fixture: ComponentFixture<PhoneListComponent>;
|
||||||
|
|
||||||
describe('PhoneList', () => {
|
describe('PhoneList', () => {
|
||||||
beforeEach(waitForAsync(() => {
|
|
||||||
TestBed
|
beforeEach(async(() => {
|
||||||
.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [PhoneListComponent],
|
declarations: [ PhoneListComponent ],
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
|
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) },
|
||||||
{provide: Location, useClass: SpyLocation},
|
{ provide: Location, useClass: SpyLocation },
|
||||||
{provide: Phone, useClass: MockPhone},
|
{ provide: Phone, useClass: MockPhone },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [ NO_ERRORS_SCHEMA ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
@ -47,15 +47,20 @@ describe('PhoneList', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let compiled = fixture.debugElement.nativeElement;
|
let compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
|
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
|
||||||
expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
|
expect(
|
||||||
.toContain('Motorola DROID');
|
compiled.querySelector('.phone-list-item:nth-child(1)').textContent
|
||||||
expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
|
).toContain('Motorola DROID');
|
||||||
.toContain('Nexus S');
|
expect(
|
||||||
|
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
|
||||||
|
).toContain('Nexus S');
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('should set the default value of orderProp model', () => {
|
xit('should set the default value of orderProp model', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let compiled = fixture.debugElement.nativeElement;
|
let compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelector('select option:last-child').selected).toBe(true);
|
expect(
|
||||||
|
compiled.querySelector('select option:last-child').selected
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -3,7 +3,7 @@ var fsExtra = require('fs-extra');
|
|||||||
var resources = [
|
var resources = [
|
||||||
// polyfills
|
// polyfills
|
||||||
'node_modules/core-js/client/shim.min.js',
|
'node_modules/core-js/client/shim.min.js',
|
||||||
'node_modules/zone.js/bundles/zone.umd.min.js',
|
'node_modules/zone.js/dist/zone.min.js',
|
||||||
// css
|
// css
|
||||||
'app/app.css',
|
'app/app.css',
|
||||||
'app/app.animations.css',
|
'app/app.animations.css',
|
||||||
@ -20,7 +20,6 @@ var resources = [
|
|||||||
'app/phone-detail/phone-detail.module.js'
|
'app/phone-detail/phone-detail.module.js'
|
||||||
];
|
];
|
||||||
resources.map(function(sourcePath) {
|
resources.map(function(sourcePath) {
|
||||||
// Need to rename zone.umd.min.js to zone.min.js
|
var destPath = `aot/${sourcePath}`;
|
||||||
var destPath = `aot/${sourcePath}`.replace('.umd.min.js', '.min.js');
|
|
||||||
fsExtra.copySync(sourcePath, destPath);
|
fsExtra.copySync(sourcePath, destPath);
|
||||||
});
|
});
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
<!-- #docregion angular -->
|
<!-- #docregion angular -->
|
||||||
<script src="/node_modules/core-js/client/shim.min.js"></script>
|
<script src="/node_modules/core-js/client/shim.min.js"></script>
|
||||||
<script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="/node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="/node_modules/systemjs/dist/system.src.js"></script>
|
<script src="/node_modules/systemjs/dist/system.src.js"></script>
|
||||||
<!-- #enddocregion angular -->
|
<!-- #enddocregion angular -->
|
||||||
<script src="/systemjs.config.1.js"></script>
|
<script src="/systemjs.config.1.js"></script>
|
||||||
|
@ -21,8 +21,8 @@ module.exports = function(config) {
|
|||||||
'node_modules/core-js/client/shim.js',
|
'node_modules/core-js/client/shim.js',
|
||||||
|
|
||||||
// zone.js
|
// zone.js
|
||||||
'node_modules/zone.js/bundles/zone.umd.js',
|
'node_modules/zone.js/dist/zone.js',
|
||||||
'node_modules/zone.js/bundles/zone-testing.umd.js',
|
'node_modules/zone.js/dist/zone-testing.js',
|
||||||
|
|
||||||
// RxJs.
|
// RxJs.
|
||||||
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
|
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
|
||||||
|
@ -31,8 +31,8 @@ module.exports = function(config) {
|
|||||||
'node_modules/core-js/client/shim.js',
|
'node_modules/core-js/client/shim.js',
|
||||||
|
|
||||||
// zone.js
|
// zone.js
|
||||||
'node_modules/zone.js/bundles/zone.umd.js',
|
'node_modules/zone.js/dist/zone.js',
|
||||||
'node_modules/zone.js/bundles/zone-testing.umd.js',
|
'node_modules/zone.js/dist/zone-testing.js',
|
||||||
|
|
||||||
// RxJs
|
// RxJs
|
||||||
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
|
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
// #docregion
|
// #docregion
|
||||||
// #docregion activatedroute
|
// #docregion activatedroute
|
||||||
import { TestBed, waitForAsync } from '@angular/core/testing';
|
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
|
|
||||||
// #enddocregion activatedroute
|
// #enddocregion activatedroute
|
||||||
import { Observable, of } from 'rxjs';
|
import { Observable, of } from 'rxjs';
|
||||||
|
|
||||||
|
import { async, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { PhoneDetailComponent } from './phone-detail.component';
|
import { PhoneDetailComponent } from './phone-detail.component';
|
||||||
import { Phone, PhoneData } from '../core/phone/phone.service';
|
import { Phone, PhoneData } from '../core/phone/phone.service';
|
||||||
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
|
import { CheckmarkPipe } from '../core/checkmark/checkmark.pipe';
|
||||||
|
|
||||||
function xyzPhoneData(): PhoneData {
|
function xyzPhoneData(): PhoneData {
|
||||||
return {name: 'phone xyz', snippet: '', images: ['image/url1.png', 'image/url2.png']};
|
return {
|
||||||
|
name: 'phone xyz',
|
||||||
|
snippet: '',
|
||||||
|
images: ['image/url1.png', 'image/url2.png']
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class MockPhone {
|
class MockPhone {
|
||||||
@ -28,9 +34,10 @@ class ActivatedRouteMock {
|
|||||||
// #enddocregion activatedroute
|
// #enddocregion activatedroute
|
||||||
|
|
||||||
describe('PhoneDetailComponent', () => {
|
describe('PhoneDetailComponent', () => {
|
||||||
|
|
||||||
// #docregion activatedroute
|
// #docregion activatedroute
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
|
declarations: [ CheckmarkPipe, PhoneDetailComponent ],
|
||||||
providers: [
|
providers: [
|
||||||
@ -48,4 +55,5 @@ describe('PhoneDetailComponent', () => {
|
|||||||
const compiled = fixture.debugElement.nativeElement;
|
const compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
|
expect(compiled.querySelector('h1').textContent).toContain(xyzPhoneData().name);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
/* tslint:disable */
|
/* tslint:disable */
|
||||||
// #docregion routestuff
|
// #docregion routestuff
|
||||||
import {SpyLocation} from '@angular/common/testing';
|
import { NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
import {NO_ERRORS_SCHEMA} from '@angular/core';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import {ComponentFixture, TestBed, waitForAsync} from '@angular/core/testing';
|
import { Observable, of } from 'rxjs';
|
||||||
import {ActivatedRoute} from '@angular/router';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import {Observable, of} from 'rxjs';
|
import { SpyLocation } from '@angular/common/testing';
|
||||||
|
|
||||||
import {Phone, PhoneData} from '../core/phone/phone.service';
|
import { PhoneListComponent } from './phone-list.component';
|
||||||
|
import { Phone, PhoneData } from '../core/phone/phone.service';
|
||||||
import {PhoneListComponent} from './phone-list.component';
|
|
||||||
|
|
||||||
// #enddocregion routestuff
|
// #enddocregion routestuff
|
||||||
|
|
||||||
@ -19,7 +18,8 @@ class ActivatedRouteMock {
|
|||||||
class MockPhone {
|
class MockPhone {
|
||||||
query(): Observable<PhoneData[]> {
|
query(): Observable<PhoneData[]> {
|
||||||
return of([
|
return of([
|
||||||
{name: 'Nexus S', snippet: '', images: []}, {name: 'Motorola DROID', snippet: '', images: []}
|
{name: 'Nexus S', snippet: '', images: []},
|
||||||
|
{name: 'Motorola DROID', snippet: '', images: []}
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -27,18 +27,18 @@ class MockPhone {
|
|||||||
let fixture: ComponentFixture<PhoneListComponent>;
|
let fixture: ComponentFixture<PhoneListComponent>;
|
||||||
|
|
||||||
describe('PhoneList', () => {
|
describe('PhoneList', () => {
|
||||||
|
|
||||||
// #docregion routestuff
|
// #docregion routestuff
|
||||||
|
|
||||||
beforeEach(waitForAsync(() => {
|
beforeEach(async(() => {
|
||||||
TestBed
|
TestBed.configureTestingModule({
|
||||||
.configureTestingModule({
|
declarations: [ PhoneListComponent ],
|
||||||
declarations: [PhoneListComponent],
|
|
||||||
providers: [
|
providers: [
|
||||||
{provide: ActivatedRoute, useValue: new ActivatedRouteMock({params: {'phoneId': 1}})},
|
{ provide: ActivatedRoute, useValue: new ActivatedRouteMock({ params: { 'phoneId': 1 } }) },
|
||||||
{provide: Location, useClass: SpyLocation},
|
{ provide: Location, useClass: SpyLocation },
|
||||||
{provide: Phone, useClass: MockPhone},
|
{ provide: Phone, useClass: MockPhone },
|
||||||
],
|
],
|
||||||
schemas: [NO_ERRORS_SCHEMA]
|
schemas: [ NO_ERRORS_SCHEMA ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
@ -52,15 +52,20 @@ describe('PhoneList', () => {
|
|||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let compiled = fixture.debugElement.nativeElement;
|
let compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
|
expect(compiled.querySelectorAll('.phone-list-item').length).toBe(2);
|
||||||
expect(compiled.querySelector('.phone-list-item:nth-child(1)').textContent)
|
expect(
|
||||||
.toContain('Motorola DROID');
|
compiled.querySelector('.phone-list-item:nth-child(1)').textContent
|
||||||
expect(compiled.querySelector('.phone-list-item:nth-child(2)').textContent)
|
).toContain('Motorola DROID');
|
||||||
.toContain('Nexus S');
|
expect(
|
||||||
|
compiled.querySelector('.phone-list-item:nth-child(2)').textContent
|
||||||
|
).toContain('Nexus S');
|
||||||
});
|
});
|
||||||
|
|
||||||
xit('should set the default value of orderProp model', () => {
|
xit('should set the default value of orderProp model', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
let compiled = fixture.debugElement.nativeElement;
|
let compiled = fixture.debugElement.nativeElement;
|
||||||
expect(compiled.querySelector('select option:last-child').selected).toBe(true);
|
expect(
|
||||||
|
compiled.querySelector('select option:last-child').selected
|
||||||
|
).toBe(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
<link rel="stylesheet" href="app.css" />
|
<link rel="stylesheet" href="app.css" />
|
||||||
|
|
||||||
<script src="/node_modules/core-js/client/shim.min.js"></script>
|
<script src="/node_modules/core-js/client/shim.min.js"></script>
|
||||||
<script src="/node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="/node_modules/zone.js/dist/zone.js"></script>
|
||||||
<script src="/node_modules/systemjs/dist/system.src.js"></script>
|
<script src="/node_modules/systemjs/dist/system.src.js"></script>
|
||||||
<!-- #enddocregion full -->
|
<!-- #enddocregion full -->
|
||||||
<script src="/systemjs.config.1.js"></script>
|
<script src="/systemjs.config.1.js"></script>
|
||||||
|
@ -31,8 +31,8 @@ module.exports = function(config) {
|
|||||||
'node_modules/core-js/client/shim.js',
|
'node_modules/core-js/client/shim.js',
|
||||||
|
|
||||||
// zone.js
|
// zone.js
|
||||||
'node_modules/zone.js/bundles/zone.umd.js',
|
'node_modules/zone.js/dist/zone.js',
|
||||||
'node_modules/zone.js/bundles/zone-testing.umd.js',
|
'node_modules/zone.js/dist/zone-testing.js',
|
||||||
|
|
||||||
// RxJs
|
// RxJs
|
||||||
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
|
{ pattern: 'node_modules/rxjs/**/*.js', included: false, watched: false },
|
||||||
|
@ -31,7 +31,7 @@ For example:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extends": "../tsconfig.json",
|
"extends": "../tsconfig.base.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"experimentalDecorators": true,
|
"experimentalDecorators": true,
|
||||||
...
|
...
|
||||||
|
@ -62,7 +62,7 @@ In the following example, the `@Component()` metadata object and the class const
|
|||||||
@Component({
|
@Component({
|
||||||
selector: 'app-typical',
|
selector: 'app-typical',
|
||||||
template: '<div>A typical component for {{data.name}}</div>'
|
template: '<div>A typical component for {{data.name}}</div>'
|
||||||
})
|
)}
|
||||||
export class TypicalComponent {
|
export class TypicalComponent {
|
||||||
@Input() data: TypicalData;
|
@Input() data: TypicalData;
|
||||||
constructor(private someService: SomeService) { ... }
|
constructor(private someService: SomeService) { ... }
|
||||||
|
@ -124,9 +124,9 @@ Data binding plays an important role in communication between a template and its
|
|||||||
|
|
||||||
Angular pipes let you declare display-value transformations in your template HTML. A class with the `@Pipe` decorator defines a function that transforms input values to output values for display in a view.
|
Angular pipes let you declare display-value transformations in your template HTML. A class with the `@Pipe` decorator defines a function that transforms input values to output values for display in a view.
|
||||||
|
|
||||||
Angular defines various pipes, such as the [date](api/common/DatePipe) pipe and [currency](api/common/CurrencyPipe) pipe; for a complete list, see the [Pipes API list](api?type=pipe). You can also define new pipes.
|
Angular defines various pipes, such as the [date](https://angular.io/api/common/DatePipe) pipe and [currency](https://angular.io/api/common/CurrencyPipe) pipe; for a complete list, see the [Pipes API list](https://angular.io/api?type=pipe). You can also define new pipes.
|
||||||
|
|
||||||
To specify a value transformation in an HTML template, use the [pipe operator (|)](guide/template-expression-operators#pipe).
|
To specify a value transformation in an HTML template, use the [pipe operator (|)](https://angular.io/guide/template-expression-operators#pipe).
|
||||||
|
|
||||||
`{{interpolated_value | pipe_name}}`
|
`{{interpolated_value | pipe_name}}`
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ An NgModule is defined by a class decorated with `@NgModule()`. The `@NgModule()
|
|||||||
|
|
||||||
* `imports`: Other modules whose exported classes are needed by component templates declared in *this* NgModule.
|
* `imports`: Other modules whose exported classes are needed by component templates declared in *this* NgModule.
|
||||||
|
|
||||||
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level.)
|
* `providers`: Creators of [services](guide/architecture-services) that this NgModule contributes to the global collection of services; they become accessible in all parts of the app. (You can also specify providers at the component level, which is often preferred.)
|
||||||
|
|
||||||
* `bootstrap`: The main application view, called the *root component*, which hosts all other app views. Only the *root NgModule* should set the `bootstrap` property.
|
* `bootstrap`: The main application view, called the *root component*, which hosts all other app views. Only the *root NgModule* should set the `bootstrap` property.
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ Attributes can be changed by `setAttribute()`, which re-initializes correspondin
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
For more information, see the [MDN Interfaces documentation](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) which has API docs for all the standard DOM elements and their properties.
|
For more information, see the [MDN Interfaces documentation](https://developer.mozilla.org/en-US/docs/Web/API#Interfaces) which has API docs for all the standard DOM elements and their properties.
|
||||||
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation.
|
Comparing the [`<td>` attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/td) attributes to the [`<td>` properties](https://developer.mozilla.org/en-US/docs/Web/API/HTMLTableCellElement) provides a helpful example for differentiation.
|
||||||
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`.
|
In particular, you can navigate from the attributes page to the properties via "DOM interface" link, and navigate the inheritance hierarchy up to `HTMLTableCellElement`.
|
||||||
|
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ To control the state of the button, set the `disabled` *property*,
|
|||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
Though you could technically set the `[attr.disabled]` attribute binding, the values are different in that the property binding requires to be a boolean value, while its corresponding attribute binding relies on whether the value is `null` or not. Consider the following:
|
Though you could technically set the `[attr.disabled]` attribute binding, the values are different in that the property binding requires to a boolean value, while its corresponding attribute binding relies on whether the value is `null` or not. Consider the following:
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<input [disabled]="condition ? true : false">
|
<input [disabled]="condition ? true : false">
|
||||||
|
@ -12,12 +12,14 @@ Every application has at least one Angular module, the _root_ module,
|
|||||||
which must be present for bootstrapping the application on launch.
|
which must be present for bootstrapping the application on launch.
|
||||||
By convention and by default, this NgModule is named `AppModule`.
|
By convention and by default, this NgModule is named `AppModule`.
|
||||||
|
|
||||||
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` looks like the following:
|
When you use the [Angular CLI](cli) command `ng new` to generate an app, the default `AppModule` is as follows.
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
/* JavaScript imports */
|
/* JavaScript imports */
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
import { FormsModule } from '@angular/forms';
|
||||||
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
@ -27,7 +29,9 @@ import { AppComponent } from './app.component';
|
|||||||
AppComponent
|
AppComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule
|
BrowserModule,
|
||||||
|
FormsModule,
|
||||||
|
HttpClientModule
|
||||||
],
|
],
|
||||||
providers: [],
|
providers: [],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
@ -86,6 +90,8 @@ A declarable can only belong to one module, so only declare it in
|
|||||||
one `@NgModule`. When you need it elsewhere,
|
one `@NgModule`. When you need it elsewhere,
|
||||||
import the module that has the declarable you need in it.
|
import the module that has the declarable you need in it.
|
||||||
|
|
||||||
|
**Only `@NgModule` references** go in the `imports` array.
|
||||||
|
|
||||||
|
|
||||||
### Using directives with `@NgModule`
|
### Using directives with `@NgModule`
|
||||||
|
|
||||||
@ -116,6 +122,9 @@ Now you could use your `ItemDirective` in a component. This example uses `AppMod
|
|||||||
|
|
||||||
Remember, components, directives, and pipes belong to one module only. You only need to declare them once in your app because you share them by importing the necessary modules. This saves you time and helps keep your app lean.
|
Remember, components, directives, and pipes belong to one module only. You only need to declare them once in your app because you share them by importing the necessary modules. This saves you time and helps keep your app lean.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a imports}
|
{@a imports}
|
||||||
|
|
||||||
## The `imports` array
|
## The `imports` array
|
||||||
@ -123,22 +132,14 @@ Remember, components, directives, and pipes belong to one module only. You only
|
|||||||
The module's `imports` array appears exclusively in the `@NgModule` metadata object.
|
The module's `imports` array appears exclusively in the `@NgModule` metadata object.
|
||||||
It tells Angular about other NgModules that this particular module needs to function properly.
|
It tells Angular about other NgModules that this particular module needs to function properly.
|
||||||
|
|
||||||
<code-example
|
|
||||||
path="bootstrapping/src/app/app.module.ts"
|
|
||||||
region="imports"
|
|
||||||
header="src/app/app.module.ts (excerpt)">
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
This list of modules are those that export components, directives, or pipes
|
This list of modules are those that export components, directives, or pipes
|
||||||
that component templates in this module reference. In this case, the component is
|
that the component templates in this module reference. In this case, the component is
|
||||||
`AppComponent`, which references components, directives, or pipes in `BrowserModule`,
|
`AppComponent`, which references components, directives, or pipes in `BrowserModule`,
|
||||||
`FormsModule`, or `HttpClientModule`.
|
`FormsModule`, or `HttpClientModule`.
|
||||||
A component template can reference another component, directive,
|
A component template can reference another component, directive,
|
||||||
or pipe when the referenced class is declared in this module or
|
or pipe when the referenced class is declared in this module or
|
||||||
the class was imported from another module.
|
the class was imported from another module.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{@a bootstrap-array}
|
{@a bootstrap-array}
|
||||||
|
|
||||||
## The `providers` array
|
## The `providers` array
|
||||||
|
@ -526,7 +526,7 @@ For example:
|
|||||||
// __Zone_enable_cross_context_check = true;
|
// __Zone_enable_cross_context_check = true;
|
||||||
</script>
|
</script>
|
||||||
<!-- zone.js required by Angular -->
|
<!-- zone.js required by Angular -->
|
||||||
<script src="node_modules/zone.js/bundles/zone.umd.js"></script>
|
<script src="node_modules/zone.js/dist/zone.js"></script>
|
||||||
|
|
||||||
<!-- application polyfills -->
|
<!-- application polyfills -->
|
||||||
</code-example>
|
</code-example>
|
||||||
|
@ -140,7 +140,7 @@ Angular provides *value accessors* for all of the basic HTML form elements and t
|
|||||||
|
|
||||||
You can't apply `[(ngModel)]` to a non-form native element or a
|
You can't apply `[(ngModel)]` to a non-form native element or a
|
||||||
third-party custom component until you write a suitable value accessor. For more information, see
|
third-party custom component until you write a suitable value accessor. For more information, see
|
||||||
the API documentation on [DefaultValueAccessor](api/forms/DefaultValueAccessor).
|
the API documentation on [DefaultValueAccessor](https://angular.io/api/forms/DefaultValueAccessor).
|
||||||
|
|
||||||
You don't need a value accessor for an Angular component that
|
You don't need a value accessor for an Angular component that
|
||||||
you write because you can name the value and event properties
|
you write because you can name the value and event properties
|
||||||
|
@ -42,11 +42,11 @@ For example, your `myBuilder` folder could contain the following files.
|
|||||||
| `src/my-builder.ts` | Main source file for the builder definition. |
|
| `src/my-builder.ts` | Main source file for the builder definition. |
|
||||||
| `src/my-builder.spec.ts` | Source file for tests. |
|
| `src/my-builder.spec.ts` | Source file for tests. |
|
||||||
| `src/schema.json` | Definition of builder input options. |
|
| `src/schema.json` | Definition of builder input options. |
|
||||||
| `builders.json` | Builders definition. |
|
| `builders.json` | Testing configuration. |
|
||||||
| `package.json` | Dependencies. See https://docs.npmjs.com/files/package.json. |
|
| `package.json` | Dependencies. See https://docs.npmjs.com/files/package.json. |
|
||||||
| `tsconfig.json` | [TypeScript configuration](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). |
|
| `tsconfig.json` | [TypeScript configuration](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). |
|
||||||
|
|
||||||
You can publish the builder to `npm` (see [Publishing your Library](guide/creating-libraries#publishing-your-library)). If you publish it as `@example/my-builder`, you can install it using the following command.
|
You can publish the builder to `npm` (see [Publishing your Library](https://angular.io/guide/creating-libraries#publishing-your-library)). If you publish it as `@example/my-builder`, you can install it using the following command.
|
||||||
|
|
||||||
<code-example language="sh">
|
<code-example language="sh">
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ Emulated is the default and most commonly used view encapsulation. For more info
|
|||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
The shadow-piercing descendant combinator is deprecated and [support is being removed from major browsers](https://www.chromestatus.com/feature/6750456638341120) and tools.
|
The shadow-piercing descendant combinator is deprecated and [support is being removed from major browsers](https://www.chromestatus.com/features/6750456638341120) and tools.
|
||||||
As such we plan to drop support in Angular (for all 3 of `/deep/`, `>>>` and `::ng-deep`).
|
As such we plan to drop support in Angular (for all 3 of `/deep/`, `>>>` and `::ng-deep`).
|
||||||
Until then `::ng-deep` should be preferred for a broader compatibility with the tools.
|
Until then `::ng-deep` should be preferred for a broader compatibility with the tools.
|
||||||
|
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
# Creating libraries
|
# Creating libraries
|
||||||
|
|
||||||
This page provides a conceptual overview of how you can create and publish new libraries to extend Angular functionality.
|
You can create and publish new libraries to extend Angular functionality. If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
|
||||||
|
|
||||||
If you find that you need to solve the same problem in more than one app (or want to share your solution with other developers), you have a candidate for a library.
|
|
||||||
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
|
A simple example might be a button that sends users to your company website, that would be included in all apps that your company builds.
|
||||||
|
|
||||||
|
<div class="alert is-helpful">
|
||||||
|
<p>For more details on how a library project is structured you can refer the <a href="guide/file-structure#library-project-files">Library Project Files</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
## Getting started
|
## Getting started
|
||||||
|
|
||||||
Use the Angular CLI to generate a new library skeleton in a new workspace with the following commands.
|
Use the Angular CLI to generate a new library skeleton with the following command:
|
||||||
|
|
||||||
<code-example language="bash">
|
<code-example language="bash">
|
||||||
ng new my-workspace --create-application=false
|
ng new my-workspace --create-application=false
|
||||||
@ -15,18 +18,12 @@ Use the Angular CLI to generate a new library skeleton in a new workspace with t
|
|||||||
ng generate library my-lib
|
ng generate library my-lib
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
The `ng generate` command creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
|
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
<p>You can use the monorepo model to use the same workspace for multiple projects. See <a href="guide/file-structure#multiple-projects">Setting up for a multi-project workspace</a>.</p>
|
||||||
For more details on how a library project is structured, refer to the [Library project files](guide/file-structure#library-project-files) section of the [Project File Structure guide](guide/file-structure).
|
|
||||||
|
|
||||||
You can use the monorepo model to use the same workspace for multiple projects.
|
|
||||||
See [Setting up for a multi-project workspace](guide/file-structure#multiple-projects).
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
When you generate a new library, the workspace configuration file, `angular.json`, is updated with a project of type `library`.
|
This creates the `projects/my-lib` folder in your workspace, which contains a component and a service inside an NgModule.
|
||||||
|
The workspace configuration file, `angular.json`, is updated with a project of type 'library'.
|
||||||
|
|
||||||
<code-example format="json">
|
<code-example format="json">
|
||||||
"projects": {
|
"projects": {
|
||||||
@ -72,30 +69,35 @@ Here are some things to consider in migrating application functionality to a lib
|
|||||||
|
|
||||||
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components.
|
* Components should expose their interactions through inputs for providing context, and outputs for communicating events to other components.
|
||||||
|
|
||||||
|
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
|
||||||
|
|
||||||
|
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
|
||||||
|
|
||||||
* Check all internal dependencies.
|
* Check all internal dependencies.
|
||||||
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated.
|
* For custom classes or interfaces used in components or service, check whether they depend on additional classes or interfaces that also need to be migrated.
|
||||||
* Similarly, if your library code depends on a service, that service needs to be migrated.
|
* Similarly, if your library code depends on a service, that service needs to be migrated.
|
||||||
* If your library code or its templates depend on other libraries (such as Angular Material, for instance), you must configure your library with those dependencies.
|
* If your library code or its templates depend on other libraries (such a Angular Material, for instance), you must configure your library with those dependencies.
|
||||||
|
|
||||||
* Consider how you provide services to client applications.
|
## Reusable code and schematics
|
||||||
|
|
||||||
* Services should declare their own providers (rather than declaring providers in the NgModule or a component), so that they are *tree-shakable*. This allows the compiler to leave the service out of the bundle if it never gets injected into the application that imports the library. For more about this, see [Tree-shakable providers](guide/dependency-injection-providers#tree-shakable-providers).
|
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
|
||||||
|
A library is packaged into an npm package for publishing and sharing, and this package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic skeleton app with `ng generate component`.
|
||||||
|
A schematic that is combined with a library can, for example, provide the Angular CLI with the information it needs to generate a particular component defined in that library.
|
||||||
|
|
||||||
* If you register global service providers or share providers across multiple NgModules, use the [`forRoot()` and `forChild()` design patterns](guide/singleton-services) provided by the [RouterModule](api/router/RouterModule).
|
What you include in your library is determined by the kind of task you are trying to accomplish.
|
||||||
|
For example, if you want a dropdown with some canned data to show how to add it to your app, your library could define a schematic to create it.
|
||||||
|
For a component like a dropdown that would contain different passed-in values each time, you could provide it as a component in a shared library.
|
||||||
|
|
||||||
* If your library provides optional services that might not be used by all client applications, support proper tree-shaking for that case by using the [lightweight token design pattern](guide/lightweight-injection-tokens).
|
Suppose you want to read a configuration file and then generate a form based on that configuration.
|
||||||
|
If that form will need additional customization by the user, it might work best as a schematic.
|
||||||
|
However, if the forms will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
|
||||||
|
In general, the more complex the customization, the more useful the schematic approach.
|
||||||
|
|
||||||
{@a integrating-with-the-cli}
|
{@a integrating-with-the-cli}
|
||||||
|
|
||||||
## Integrating with the CLI using code-generation schematics
|
## Integrating with the CLI
|
||||||
|
|
||||||
A library typically includes *reusable code* that defines components, services, and other Angular artifacts (pipes, directives, and so on) that you simply import into a project.
|
A library can include [schematics](guide/glossary#schematic) that allow it to integrate with the Angular CLI.
|
||||||
A library is packaged into an npm package for publishing and sharing.
|
|
||||||
This package can also include [schematics](guide/glossary#schematic) that provide instructions for generating or transforming code directly in your project, in the same way that the CLI creates a generic new component with `ng generate component`.
|
|
||||||
A schematic that is packaged with a library can, for example, provide the Angular CLI with the information it needs to generate a component that configures and uses a particular feature, or set of features, defined in that library.
|
|
||||||
One example of this is Angular Material's navigation schematic which configures the CDK's `BreakpointObserver` and uses it with Material's `MatSideNav` and `MatToolbar` components.
|
|
||||||
|
|
||||||
You can create and include the following kinds of schematics.
|
|
||||||
|
|
||||||
* Include an installation schematic so that `ng add` can add your library to a project.
|
* Include an installation schematic so that `ng add` can add your library to a project.
|
||||||
|
|
||||||
@ -103,15 +105,6 @@ You can create and include the following kinds of schematics.
|
|||||||
|
|
||||||
* Include an update schematic so that `ng update` can update your library’s dependencies and provide migrations for breaking changes in new releases.
|
* Include an update schematic so that `ng update` can update your library’s dependencies and provide migrations for breaking changes in new releases.
|
||||||
|
|
||||||
What you include in your library depends on your task.
|
|
||||||
For example, you could define a schematic to create a dropdown that is pre-populated with canned data to show how to add it to an app.
|
|
||||||
If you want a dropdown that would contain different passed-in values each time, your library could define a schematic to create it with a given configuration. Developers could then use `ng generate` to configure an instance for their own app.
|
|
||||||
|
|
||||||
Suppose you want to read a configuration file and then generate a form based on that configuration.
|
|
||||||
If that form will need additional customization by the developer who is using your library, it might work best as a schematic.
|
|
||||||
However, if the form will always be the same and not need much customization by developers, then you could create a dynamic component that takes the configuration and generates the form.
|
|
||||||
In general, the more complex the customization, the more useful the schematic approach.
|
|
||||||
|
|
||||||
To learn more, see [Schematics Overview](guide/schematics) and [Schematics for Libraries](guide/schematics-for-libraries).
|
To learn more, see [Schematics Overview](guide/schematics) and [Schematics for Libraries](guide/schematics-for-libraries).
|
||||||
|
|
||||||
## Publishing your library
|
## Publishing your library
|
||||||
|
@ -448,13 +448,13 @@ When targeting older browsers, [polyfills](guide/browser-support#polyfills) can
|
|||||||
|
|
||||||
To maximize compatibility, you could ship a single bundle that includes all your compiled code, plus any polyfills that may be needed.
|
To maximize compatibility, you could ship a single bundle that includes all your compiled code, plus any polyfills that may be needed.
|
||||||
Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.
|
Users with modern browsers, however, shouldn't have to pay the price of increased bundle size that comes with polyfills they don't need.
|
||||||
Differential loading, which is supported in Angular CLI version 8 and higher, can help solve this problem.
|
Differential loading, which is supported by default in Angular CLI version 8 and higher, solves this problem.
|
||||||
|
|
||||||
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled the CLI builds two separate bundles as part of your deployed application.
|
Differential loading is a strategy that allows your web application to support multiple browsers, but only load the necessary code that the browser needs. When differential loading is enabled (which is the default) the CLI builds two separate bundles as part of your deployed application.
|
||||||
|
|
||||||
* The first bundle contains modern ES2015 syntax. This bundle takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
|
* The first bundle contains modern ES2015 syntax, takes advantage of built-in support in modern browsers, ships fewer polyfills, and results in a smaller bundle size.
|
||||||
|
|
||||||
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This second bundle is larger, but supports older browsers.
|
* The second bundle contains code in the old ES5 syntax, along with all necessary polyfills. This results in a larger bundle size, but supports older browsers.
|
||||||
|
|
||||||
### Differential builds
|
### Differential builds
|
||||||
|
|
||||||
@ -463,9 +463,9 @@ The [`ng build` CLI command](cli/build) queries the browser configuration and th
|
|||||||
|
|
||||||
The following configurations determine your requirements.
|
The following configurations determine your requirements.
|
||||||
|
|
||||||
* Browserslist
|
* Browsers list
|
||||||
|
|
||||||
The Browserslist configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
|
The `browserslist` configuration file is included in your application [project structure](guide/file-structure#application-configuration-files) and provides the minimum browsers your application supports. See the [Browserslist spec](https://github.com/browserslist/browserslist) for complete configuration options.
|
||||||
|
|
||||||
* TypeScript configuration
|
* TypeScript configuration
|
||||||
|
|
||||||
@ -509,27 +509,16 @@ Each script tag has a `type="module"` or `nomodule` attribute. Browsers with nat
|
|||||||
|
|
||||||
### Configuring differential loading
|
### Configuring differential loading
|
||||||
|
|
||||||
To include differential loading in your application builds, you must configure the Browserslist and TypeScript configuration files in your application project.
|
Differential loading is supported by default with version 8 and later of the Angular CLI.
|
||||||
|
For each application project in your workspace, you can configure how builds are produced based on the `browserslist` and `tsconfig.json` configuration files in your application project.
|
||||||
|
|
||||||
The following examples show a `.browserslistrc` and `tsconfig.json` file for a newly created Angular application. In this configuration, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
|
For a newly created Angular application, legacy browsers such as IE 9-11 are ignored, and the compilation target is ES2015.
|
||||||
|
|
||||||
<code-example language="none" header=".browserslistrc">
|
<code-example language="none" header="browserslist">
|
||||||
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
|
> 0.5%
|
||||||
# For additional information regarding the format and rule options, please see:
|
last 2 versions
|
||||||
# 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
|
Firefox ESR
|
||||||
|
not dead
|
||||||
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
not IE 9-11 # For IE 9-11 support, remove 'not'.
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
@ -560,24 +549,36 @@ not IE 9-11 # For IE 9-11 support, remove 'not'.
|
|||||||
|
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
|
The default configuration creates two builds, with differential loading enabled.
|
||||||
|
|
||||||
<div class="alert is-important">
|
<div class="alert is-important">
|
||||||
|
|
||||||
To see which browsers are supported and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
|
To see which browsers are supported with the default configuration and determine which settings meet to your browser support requirements, see the [Browserslist compatibility page](https://browserl.ist/?q=%3E+0.5%25%2C+last+2+versions%2C+Firefox+ESR%2C+not+dead%2C+not+IE+9-11).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
The Browserslist configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
|
The `browserslist` configuration allows you to ignore browsers without ES2015 support. In this case, a single build is produced.
|
||||||
|
|
||||||
If your Browserslist configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
|
If your `browserslist` configuration includes support for any legacy browsers, the build target in the TypeScript configuration determines whether the build will support differential loading.
|
||||||
|
|
||||||
{@a configuration-table }
|
{@a configuration-table }
|
||||||
|
|
||||||
| Browserslist | ES target | Build result |
|
| browserslist | ES target | Build result |
|
||||||
| -------- | -------- | -------- |
|
| -------- | -------- | -------- |
|
||||||
| ES5 support disabled | es2015 | Single build, ES5 not required |
|
| ES5 support disabled | es2015 | Single build, ES5 not required |
|
||||||
| ES5 support enabled | es5 | Single build w/conditional polyfills for ES5 only |
|
| ES5 support enabled | es5 | Single build w/conditional polyfills for ES5 only |
|
||||||
| ES5 support enabled | es2015 | Differential loading (two builds w/conditional polyfills) |
|
| ES5 support enabled | es2015 | Differential loading (two builds w/conditional polyfills) |
|
||||||
|
|
||||||
|
|
||||||
|
### Opting out of differential loading
|
||||||
|
|
||||||
|
Differential loading can be explicitly disabled if it causes unexpected issues, or if you need to target ES5 specifically for legacy browser support.
|
||||||
|
|
||||||
|
To explicitly disable differential loading and create an ES5 build:
|
||||||
|
|
||||||
|
- Enable the `dead` or `IE` browsers in the `browserslist` configuration file by removing the `not` keyword in front of them.
|
||||||
|
- To create a single ES5 build, set the target in the `compilerOptions` to `es5`.
|
||||||
|
|
||||||
{@a test-and-serve}
|
{@a test-and-serve}
|
||||||
|
|
||||||
## Local development in older browsers
|
## Local development in older browsers
|
||||||
|
@ -58,12 +58,12 @@ v9 - v12
|
|||||||
| `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 |
|
| `@angular/core` | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | <!--v9--> v11 |
|
||||||
| `@angular/router` | [`loadChildren` string syntax](#loadChildren) | <!--v9--> v11 |
|
| `@angular/router` | [`loadChildren` string syntax](#loadChildren) | <!--v9--> v11 |
|
||||||
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
|
| `@angular/core/testing` | [`TestBed.get`](#testing) | <!--v9--> v12 |
|
||||||
| `@angular/core/testing` | [`async`](#testing) | <!--v9--> v12 |
|
|
||||||
| `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified |
|
| `@angular/router` | [`ActivatedRoute` params and `queryParams` properties](#activatedroute-props) | unspecified |
|
||||||
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
|
| template syntax | [`/deep/`, `>>>`, and `::ng-deep`](#deep-component-style-selector) | <!--v7--> unspecified |
|
||||||
| browser support | [`IE 9 and 10, IE mobile`](#ie-9-10-and-mobile) | <!--v10--> v11 |
|
| browser support | [`IE 9 and 10, IE mobile`](#ie-9-10-and-mobile) | <!--v10--> v11 |
|
||||||
|
|
||||||
For information about Angular CDK and Angular Material deprecations, see the [changelog](https://github.com/angular/components/blob/master/CHANGELOG.md).
|
|
||||||
|
|
||||||
|
|
||||||
## Deprecated APIs
|
## Deprecated APIs
|
||||||
|
|
||||||
@ -109,7 +109,6 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i
|
|||||||
| API | Replacement | Deprecation announced | Notes |
|
| API | Replacement | Deprecation announced | Notes |
|
||||||
| --- | ----------- | --------------------- | ----- |
|
| --- | ----------- | --------------------- | ----- |
|
||||||
| [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. |
|
| [`TestBed.get`](api/core/testing/TestBed#get) | [`TestBed.inject`](api/core/testing/TestBed#inject) | v9 | Same behavior, but type safe. |
|
||||||
| [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v10 | Same behavior, but rename to avoid confusion. |
|
|
||||||
|
|
||||||
|
|
||||||
{@a forms}
|
{@a forms}
|
||||||
|
@ -119,14 +119,7 @@ The recently-developed [custom elements](https://developer.mozilla.org/en-US/doc
|
|||||||
|
|
||||||
In browsers that support Custom Elements natively, the specification requires developers use ES2015 classes to define Custom Elements - developers can opt-in to this by setting the `target: "es2015"` property in their project's [TypeScript configuration file](/guide/typescript-configuration). As Custom Element and ES2015 support may not be available in all browsers, developers can instead choose to use a polyfill to support older browsers and ES5 code.
|
In browsers that support Custom Elements natively, the specification requires developers use ES2015 classes to define Custom Elements - developers can opt-in to this by setting the `target: "es2015"` property in their project's [TypeScript configuration file](/guide/typescript-configuration). As Custom Element and ES2015 support may not be available in all browsers, developers can instead choose to use a polyfill to support older browsers and ES5 code.
|
||||||
|
|
||||||
Use the [Angular CLI](cli) to automatically set up your project with the correct polyfill:
|
Use the [Angular CLI](cli) to automatically set up your project with the correct polyfill: `ng add @angular/elements --project=*your_project_name*`.
|
||||||
|
|
||||||
<code-example language="sh">
|
|
||||||
|
|
||||||
ng add @angular/elements --project=*your_project_name*
|
|
||||||
|
|
||||||
</code-example>
|
|
||||||
|
|
||||||
- For more information about polyfills, see [polyfill documentation](https://www.webcomponents.org/polyfills).
|
- For more information about polyfills, see [polyfill documentation](https://www.webcomponents.org/polyfills).
|
||||||
|
|
||||||
- For more information about Angular browser support, see [Browser Support](guide/browser-support).
|
- For more information about Angular browser support, see [Browser Support](guide/browser-support).
|
||||||
|
@ -76,12 +76,6 @@ All router components must be entry components. Because this would require you t
|
|||||||
|
|
||||||
## The `entryComponents` array
|
## The `entryComponents` array
|
||||||
|
|
||||||
<div class="alert is-helpful">
|
|
||||||
|
|
||||||
Since 9.0.0 with Ivy, the `entryComponents` property is no longer necessary. See [deprecations guide](guide/deprecations#entryComponents).
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
Though the `@NgModule` decorator has an `entryComponents` array, most of the time
|
Though the `@NgModule` decorator has an `entryComponents` array, most of the time
|
||||||
you won't have to explicitly set any entry components because Angular adds components listed in `@NgModule.bootstrap` and those in route definitions to entry components automatically. Though these two mechanisms account for most entry components, if your app happens to bootstrap or dynamically load a component by type imperatively,
|
you won't have to explicitly set any entry components because Angular adds components listed in `@NgModule.bootstrap` and those in route definitions to entry components automatically. Though these two mechanisms account for most entry components, if your app happens to bootstrap or dynamically load a component by type imperatively,
|
||||||
you must add it to `entryComponents` explicitly.
|
you must add it to `entryComponents` explicitly.
|
||||||
|
@ -79,7 +79,7 @@ To incorporate the feature module into your app, you have to let the root module
|
|||||||
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
|
<code-example path="feature-modules/src/app/app.module.ts" region="app-module" header="src/app/app.module.ts"></code-example>
|
||||||
|
|
||||||
|
|
||||||
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules don’t expose their components by default.
|
Now the `AppModule` knows about the feature module. If you were to add any service providers to the feature module, `AppModule` would know about those too, as would any other feature modules. However, NgModules don’t expose their components.
|
||||||
|
|
||||||
|
|
||||||
## Rendering a feature module’s component template
|
## Rendering a feature module’s component template
|
||||||
|
@ -40,7 +40,8 @@ The top level of the workspace contains workspace-wide configuration files, conf
|
|||||||
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
|
| `package-lock.json` | Provides version information for all packages installed into `node_modules` by the npm client. See [npm documentation](https://docs.npmjs.com/files/package-lock.json) for details. If you use the yarn client, this file will be [yarn.lock](https://yarnpkg.com/lang/en/docs/yarn-lock/) instead. |
|
||||||
| `src/` | Source files for the root-level application project. |
|
| `src/` | Source files for the root-level application project. |
|
||||||
| `node_modules/` | Provides [npm packages](guide/npm-packages) to the entire workspace. Workspace-wide `node_modules` dependencies are visible to all projects. |
|
| `node_modules/` | Provides [npm packages](guide/npm-packages) to the entire workspace. Workspace-wide `node_modules` dependencies are visible to all projects. |
|
||||||
| `tsconfig.json` | The base [TypeScript](https://www.typescriptlang.org/) configuration for projects in the workspace. All other configuration files inherit from this base file. For more information, see the [Configuration inheritance with extends](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#configuration-inheritance-with-extends) section of the TypeScript documentation.|
|
| `tsconfig.json` | The `tsconfig.json` file is a ["Solution Style"](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-9.html#support-for-solution-style-tsconfigjson-files) TypeScript configuration file. Code editors and TypeScript’s language server use this file to improve development experience. Compilers do not use this file. |
|
||||||
|
| `tsconfig.base.json` | The base [TypeScript](https://www.typescriptlang.org/) configuration for projects in the workspace. All other configuration files inherit from this base file. For more information, see the [Configuration inheritance with extends](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html#configuration-inheritance-with-extends) section of the TypeScript documentation.|
|
||||||
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for projects in the workspace. |
|
| `tslint.json` | Default [TSLint](https://palantir.github.io/tslint/) configuration for projects in the workspace. |
|
||||||
|
|
||||||
|
|
||||||
@ -102,7 +103,7 @@ Angular components, templates, and styles go here.
|
|||||||
The application-specific configuration files for the root application reside at the workspace root level.
|
The application-specific configuration files for the root application reside at the workspace root level.
|
||||||
For a multi-project workspace, project-specific configuration files are in the project root, under `projects/project-name/`.
|
For a multi-project workspace, project-specific configuration files are in the project root, under `projects/project-name/`.
|
||||||
|
|
||||||
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.json`, and project-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
|
Project-specific [TypeScript](https://www.typescriptlang.org/) configuration files inherit from the workspace-wide `tsconfig.base.json`, and project-specific [TSLint](https://palantir.github.io/tslint/) configuration files inherit from the workspace-wide `tslint.json`.
|
||||||
|
|
||||||
| APPLICATION-SPECIFIC CONFIG FILES | PURPOSE |
|
| APPLICATION-SPECIFIC CONFIG FILES | PURPOSE |
|
||||||
| :--------------------- | :------------------------------------------|
|
| :--------------------- | :------------------------------------------|
|
||||||
|
@ -627,11 +627,6 @@ The [npm package manager](https://docs.npmjs.com/getting-started/what-is-npm) is
|
|||||||
|
|
||||||
Learn more about how Angular uses [Npm Packages](guide/npm-packages).
|
Learn more about how Angular uses [Npm Packages](guide/npm-packages).
|
||||||
|
|
||||||
{@ ngc}
|
|
||||||
## ngc
|
|
||||||
`ngc` is a Typescript-to-Javascript transpiler that processes Angular decorators, metadata, and templates, and emits JavaScript code.
|
|
||||||
The most recent implementation is internally refered to as `ngtsc` because it's a minimalistic wrapper around the TypeScript compiler `tsc` that adds a transform for processing Angular code.
|
|
||||||
|
|
||||||
{@a O}
|
{@a O}
|
||||||
|
|
||||||
{@a observable}
|
{@a observable}
|
||||||
@ -872,7 +867,7 @@ To learn more, see [Introduction to Services and Dependency Injection](guide/arc
|
|||||||
|
|
||||||
## structural directives
|
## structural directives
|
||||||
|
|
||||||
A category of [directive](#directive) that is responsible for shaping HTML layout by modifying the DOM—that is, adding, removing, or manipulating elements and their children.
|
A category of [directive](#directive) that is responsible for shaping HTML layout by modifying the DOM&mdashthat is, adding, removing, or manipulating elements and their children.
|
||||||
|
|
||||||
To learn more, see [Structural Directives](guide/structural-directives).
|
To learn more, see [Structural Directives](guide/structural-directives).
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ While following these steps, you can [explore the translated example app](#app-p
|
|||||||
|
|
||||||
The following are optional practices that may be required in special cases:
|
The following are optional practices that may be required in special cases:
|
||||||
|
|
||||||
* [Set the source locale manually](#set-source-manually) if you need to set the [LOCALE_ID](api/core/LOCALE_ID "API reference for LOCALE_ID") token.
|
* [Set the source locale manually](#set-source-manually) if you need to set the [LOCALE_ID](https://angular.io/api/core/LOCALE_ID "API reference for LOCALE_ID") token.
|
||||||
* [Import global variants of the locale data](#import-locale) for extra locale data.
|
* [Import global variants of the locale data](#import-locale) for extra locale data.
|
||||||
* [Manage marked text with custom IDs](#custom-id) if you require more control over matching translations.
|
* [Manage marked text with custom IDs](#custom-id) if you require more control over matching translations.
|
||||||
|
|
||||||
@ -77,7 +77,7 @@ This command updates your project's `package.json` and `polyfills.ts` files to i
|
|||||||
|
|
||||||
<div class="alert is-helpful">
|
<div class="alert is-helpful">
|
||||||
|
|
||||||
For more information about `package.json` and polyfill packages, see [Workspace npm dependencies](guide/npm-packages).
|
For more information about `package.json` and polyfill packages, see [Workspace npm dependencies](https://angular.io/guide/npm-packages).
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -766,11 +766,9 @@ The HTML `base` tag with the `href` attribute specifies the base URI, or URL, fo
|
|||||||
"i18n": {
|
"i18n": {
|
||||||
"sourceLocale": "en-US",
|
"sourceLocale": "en-US",
|
||||||
"locales": {
|
"locales": {
|
||||||
"fr": {
|
"fr": "src/locale/messages.fr.xlf"
|
||||||
"translation": "src/locale/messages.fr.xlf",
|
|
||||||
"baseHref": ""
|
"baseHref": ""
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"architect": {
|
"architect": {
|
||||||
...
|
...
|
||||||
@ -806,7 +804,7 @@ The following tabs show the example app and its translation files:
|
|||||||
|
|
||||||
The following are optional practices that may be required in special cases:
|
The following are optional practices that may be required in special cases:
|
||||||
|
|
||||||
* [Set the source locale manually](#set-source-manually) by setting the [LOCALE_ID](api/core/LOCALE_ID "API reference for LOCALE_ID") token.
|
* [Set the source locale manually](#set-source-manually) by setting the [LOCALE_ID](https://angular.io/api/core/LOCALE_ID "API reference for LOCALE_ID") token.
|
||||||
* [Import global variants of the locale data](#import-locale) for extra locale data.
|
* [Import global variants of the locale data](#import-locale) for extra locale data.
|
||||||
* [Manage marked text with custom IDs](#custom-id) if you require more control over matching translations.
|
* [Manage marked text with custom IDs](#custom-id) if you require more control over matching translations.
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ about the event and gives that data to the parent.
|
|||||||
The child's template has two controls. The first is an HTML `<input>` with a
|
The child's template has two controls. The first is an HTML `<input>` with a
|
||||||
[template reference variable](guide/template-reference-variables) , `#newItem`,
|
[template reference variable](guide/template-reference-variables) , `#newItem`,
|
||||||
where the user types in an item name. Whatever the user types
|
where the user types in an item name. Whatever the user types
|
||||||
into the `<input>` gets stored in the `value` property of the `#newItem` variable.
|
into the `<input>` gets stored in the `#newItem` variable.
|
||||||
|
|
||||||
<code-example path="inputs-outputs/src/app/item-output/item-output.component.html" region="child-output" header="src/app/item-output/item-output.component.html"></code-example>
|
<code-example path="inputs-outputs/src/app/item-output/item-output.component.html" region="child-output" header="src/app/item-output/item-output.component.html"></code-example>
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ an event binding because the part to the left of the equal
|
|||||||
sign is in parentheses, `(click)`.
|
sign is in parentheses, `(click)`.
|
||||||
|
|
||||||
The `(click)` event is bound to the `addNewItem()` method in the child component class which
|
The `(click)` event is bound to the `addNewItem()` method in the child component class which
|
||||||
takes as its argument whatever the value of `#newItem.value` property is.
|
takes as its argument whatever the value of `#newItem` is.
|
||||||
|
|
||||||
Now the child component has an `@Output()`
|
Now the child component has an `@Output()`
|
||||||
for sending data to the parent and a method for raising an event.
|
for sending data to the parent and a method for raising an event.
|
||||||
|
@ -11,11 +11,11 @@ That said, some applications will likely need to apply some manual updates.
|
|||||||
In version 10, [a few deprecated APIs have been removed](guide/updating-to-version-10#removals) and there are a [few breaking changes](guide/updating-to-version-10#breaking-changes) unrelated to Ivy.
|
In version 10, [a few deprecated APIs have been removed](guide/updating-to-version-10#removals) and there are a [few breaking changes](guide/updating-to-version-10#breaking-changes) unrelated to Ivy.
|
||||||
If you're seeing errors after updating to version 9, you'll first want to rule those changes out.
|
If you're seeing errors after updating to version 9, you'll first want to rule those changes out.
|
||||||
|
|
||||||
To do so, temporarily [turn off Ivy](guide/ivy#opting-out-of-angular-ivy) in your `tsconfig.json` and re-start your app.
|
To do so, temporarily [turn off Ivy](guide/ivy#opting-out-of-angular-ivy) in your `tsconfig.base.json` and re-start your app.
|
||||||
|
|
||||||
If you're still seeing the errors, they are not specific to Ivy. In this case, you may want to consult the [general version 10 guide](guide/updating-to-version-10). If you've opted into any of the new, stricter type-checking settings, you may also want to check out the [template type-checking guide](guide/template-typecheck).
|
If you're still seeing the errors, they are not specific to Ivy. In this case, you may want to consult the [general version 10 guide](guide/updating-to-version-10). If you've opted into any of the new, stricter type-checking settings, you may also want to check out the [template type-checking guide](guide/template-typecheck).
|
||||||
|
|
||||||
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.json` and review the list of expected changes below.
|
If the errors are gone, switch back to Ivy by removing the changes to the `tsconfig.base.json` and review the list of expected changes below.
|
||||||
|
|
||||||
{@a payload-size-debugging}
|
{@a payload-size-debugging}
|
||||||
### Payload size debugging
|
### Payload size debugging
|
||||||
|
@ -87,7 +87,7 @@ To make one, enter the following command in the terminal, where `customers` is t
|
|||||||
ng generate module customers --route customers --module app.module
|
ng generate module customers --route customers --module app.module
|
||||||
</code-example>
|
</code-example>
|
||||||
|
|
||||||
This creates a `customers` folder having the new lazy-loadable feature module `CustomersModule` defined in the `customers.module.ts` file and the routing module `CustomersRoutingModule` defined in the `customers-routing.module.ts` file. The command automatically declares the `CustomersComponent` and imports `CustomersRoutingModule` inside the new feature module.
|
This creates a `customers` folder with the new lazy-loadable module `CustomersModule` defined in the `customers.module.ts` file. The command automatically declares the `CustomersComponent` inside the new feature module.
|
||||||
|
|
||||||
Because the new module is meant to be lazy-loaded, the command does NOT add a reference to the new feature module in the application's root module file, `app.module.ts`.
|
Because the new module is meant to be lazy-loaded, the command does NOT add a reference to the new feature module in the application's root module file, `app.module.ts`.
|
||||||
Instead, it adds the declared route, `customers` to the `routes` array declared in the module provided as the `--module` option.
|
Instead, it adds the declared route, `customers` to the `routes` array declared in the module provided as the `--module` option.
|
||||||
|
@ -62,8 +62,6 @@ Angular executes hook methods in the following sequence. You can use them to per
|
|||||||
|
|
||||||
Called before `ngOnInit()` and whenever one or more data-bound input properties change.
|
Called before `ngOnInit()` and whenever one or more data-bound input properties change.
|
||||||
|
|
||||||
Note that if your component has no inputs or you use it without providing any inputs, the framework will not call `ngOnChanges()`.
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr style='vertical-align:top'>
|
<tr style='vertical-align:top'>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user